OverlapSphere 和 SphereCast
本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 40 课,共 71 课。
射线查询的是一条线。Physics.OverlapSphere(center, radius)查询的是一个球形区域:它会返回与以center为中心的球体接触的所有碰撞体组成的数组,不涉及方向或距离。这枚炸弹爆炸时会摧毁 3 个单位范围内的所有木箱:
void Explode()
{
Collider[] hits = Physics.OverlapSphere(transform.position, 3f);
foreach (Collider c in hits)
{
if (c.CompareTag("Crate"))
{
Destroy(c.gameObject);
}
}
Destroy(gameObject);
}这个数组包含范围内的所有对象:地面、墙壁和炸弹自身的碰撞体,因为重叠检测不会跳过其起点所在的碰撞体。这就是循环在执行操作前检查标签的原因。每个碰撞体的attachedRigidbody就是它所属的 Rigidbody;对于地面这类静态对象,该属性为null。
Physics.SphereCast(origin, radius, direction, out hit, maxDistance)是一条有厚度的射线:它会沿着直线扫过一个球体,并报告球体会撞上的第一个碰撞体。一个半径为 1 的巨石滚向两根柱子之间宽 1.5 的间隙时,可以用它来判断巨石能否通过:穿过间隙中间的一条细射线什么也碰不到,而球体投射会碰到柱子。和射线一样,球体投射会跳过起点处已经接触到的碰撞体。
挑战
中等使用 Physics.SphereCast 给大炮加上一个较宽的射束。
- 按下 Space 时,扫过一个球体:
Physics.SphereCast(transform.position, radius, transform.forward, out RaycastHit hit, range)。 - 命中时,记录
"Hit " + hit.collider.name(第一发会记录Hit Pole),并销毁该对象。 - 未命中时,记录
Miss。
按下 Play 并开火三次:Pole 消失,然后是 Crate,最后一次未命中。然后点击 Check。
亲手试试
using UnityEngine;
public class Beam : MonoBehaviour
{
public float radius = 0.5f;
public float range = 12f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
// 向前扫掠一个半径为 radius 的球体:销毁它碰到的第一个物体。
}
}
}
物理与游戏玩法中的所有课
自己练习: Unity 在线编辑器