Menu
CoddyTech

Линия видимости

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 39 из 71.

Быть рядом с охранником — не то же самое, что быть у него на виду: стена между вами закрывает обзор. Чтобы проверить прямую видимость, направь луч от глаза к цели и проверь, что первым он попадает именно в цель. Направление — это позиция цели минус твоя позиция, а луч такой длины достигает цели:

public Transform target;

bool CanSee()
{
    Vector3 toTarget = target.position - transform.position;
    if (Physics.Raycast(transform.position, toTarget, out RaycastHit hit, toTarget.magnitude))
    {
        return hit.transform == target;
    }
    return false;
}

Камера наблюдения на столбе записывает I see you, пока CanSee() возвращает true. Если цель находится на открытом месте, луч первым попадает в цель. Если цель находится за ящиком, луч сначала попадает в ящик, hit.transform указывает на ящик, и результат — false. Сам по себе Physics.Raycast тоже возвращает true для ящика, поэтому попадание сравнивается с целью.

У цели должен быть коллайдер, чтобы луч мог её обнаружить. Направление луча не нужно нормализовать, поскольку его длина задаётся через maxDistance. Physics.Linecast(from, to) проверяет обратное: находится ли какой-либо коллайдер между двумя точками. !Physics.Linecast(eye, target.position, wallMask) означает, что на пути нет стены.

challenge icon

Задание

Средне

Окрасьте часового в красный цвет, когда он видит игрока, и в зелёный в противном случае.

  1. Напишите bool CanSee(): задайте Vector3 toPlayer = player.position - transform.position;, возвращайте false, когда toPlayer.magnitude > range.
  2. Затем выполните проверку с помощью Physics.Raycast(transform.position, toPlayer, out RaycastHit hit, range) и возвращайте hit.transform == player; если попадания нет, возвращайте false.
  3. В Update() задайте башне красный или зелёный цвет с помощью Color.red или Color.green в зависимости от результата CanSee().

Нажмите «Играть» и пройдите за стену. Затем нажмите «Проверить».

Попробуйте сами

using UnityEngine;

public class Sentry : MonoBehaviour
{
    public Transform player;
    public float range = 8f;

    void Update()
    {
        // Красный, пока турель видит игрока, в противном случае — зелёный.
    }
}

Все уроки раздела Физика и игровой процесс

Потренируйтесь самостоятельно: Песочница Unity