Menu
CoddyTech

视线检测

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 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;
}

柱子上的监控摄像头会在 CanSee() 为 true 时记录 I see you。目标处于开阔地带时,射线命中的第一个物体就是目标。目标躲在箱子后面时,射线会先命中箱子,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;,当 toPlayer.magnitude > range 时返回 false。
  2. 然后执行射线检测:Physics.Raycast(transform.position, toPlayer, out RaycastHit hit, range),并返回 hit.transform == player;未命中时返回 false。
  3. 在 Update() 中,根据 CanSee() 将塔的颜色设为 Color.red 或 Color.green。

按“开始”,然后走到墙后面。接着按“检查”。

亲手试试

using UnityEngine;

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

    void Update()
    {
        // 哨兵能看到玩家时显示红色,否则显示绿色。
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器