Unity碰撞检测:射线与胶囊体投射/Layer(层)、LayerMask(遮罩层)

一、Physics碰撞检测

1.Physics.Raycast射线投射

Physics.Raycast 是 Unity 中用于执行射线检测(Raycasting)的方法。它允许你从一个点沿特定方向发射一条无形的“射线”,并检查这条射线是否与场景中的任何碰撞体相交。这个功能非常有用,可以用来检测玩家前方是否有障碍物、确定点击位置的对象等。

使用场景:用于检测射线是否与场景中的物体发生碰撞
触发条件:通过发射一条射线来检测碰撞
参数:参数包括射线的起点、方向、最大距离、层掩码等

bool hit = Physics.Raycast(transform.position, transform.forward, out RaycastHit hitInfo, 100f);
if (hit) {
    Debug.Log("Ray hit: " + hitInfo.collider.gameObject.name);
}

2.Physics.CapsuleCast胶囊体投射

Physics.CapsuleCast 是 Unity 中用于执行胶囊体投射(Capsule Cast)的方法。与 Raycast 类似,但它基于胶囊形状而非直线,这使得它非常适合用于检测具有类似胶囊形状的对象(如大多数游戏角色使用的碰撞体)在移动时是否会遇到障碍物。

使用场景: 用于检测一个胶囊体形状的射线是否与场景中的物体发生碰撞
触发条件: 通过发射一个胶囊体形状的射线来检测碰撞
参数: 参数包括起点、方向、胶囊体的半径、高度、最大距离、层掩码等

bool hit = Physics.CapsuleCast(transform.position, transform.position + Vector3.up * 2f, 1f, transform.forward, out RaycastHit hitInfo, 100f);
if (hit) {
    Debug.Log("CapsuleCast hit: " + hitInfo.collider.gameObject.name);
}

二、Layer(层)、LayerMask(遮罩层)

Layers通常被摄像机用来渲染部分场景,和灯光照射部分场景使用。但是它们也可以用来做射线检测时忽略一些collder或Collision使用

Unity中是用int32来表示32个Layer层。int32表示二进制一共有32位(0—31)

在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共有24个(8—31层),官方已使用的是0—7层,默认不可编辑!

1,layer层查看与创建

任意选择场景中的一个GameObject即可查看该GameObject所在的层

 点击 Add Layer...(前面的序号是所在层序号)

 在可以编辑的地方取个一个层名即可

 新建的 layer 就会显示在层中

2.LayerMask 的介绍和使用

LayerMask 实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。

Unity 中的使用:

LayerMask mask = 1 << 3;表示开启Layer3。

LayerMask mask = 0 << 8;表示关闭Layer8。

LayerMask mask = 1<<1|1<<9;表示开启Layer1和Layer9。

LayerMask mask = 0<<4|0<<5;表示关闭Layer4和Layer5。

LayerMask mask = ~(1 << 0) 打开所有的层。

LayerMask mask = ~(1 << 9) 打开除了第9之外的层。

//LayerMask 的使用(Physics.Raycast)

[SerializeField] private LayerMask ClearCounterLayerMask;

float interactDictance = 2.0f;

if (Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDictance, ClearCounterLayerMask))
{
    if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter))
    {
        clearCounter.Interact();
    }
}

### 实现第一人称视角角色地面接触检测 在 Unity 中,为了确保第一人称控制器能够正确判断是否站在地面上,通常会采用射线投射 (Raycast) 或者触发器 (Trigger Collider) 的方法来实现这一功能。 #### 使用 Raycast 进行地面检测 通过 `Physics.Raycast` 函数可以向下方发射一条射线并检查是否有碰撞被击中。如果存在,则认为玩家处于地面之上;反之则不在地上。这种方法简单高效,在许多游戏中广泛应用[^1]。 ```csharp private bool IsGrounded() { Vector3 origin = transform.position; float distanceToCheck = 0.1f; // 射线长度 RaycastHit hitInfo; if(Physics.Raycast(origin, Vector3.down, out hitInfo, distanceToCheck)) return true; return false; } ``` 此代码片段展示了如何定义一个名为 `IsGrounded()` 的函数用于检测当前物是否位于地面附近。当返回值为真时表明已触底[^2]。 #### 利用 Rigidbody 和 Colliders 组件优化检测机制 对于更复杂的情况,比如斜坡行走或是跳跃动作后的落地判定,建议给主角模型附加刚组件 (`Rigidbody`) 并设置合适的物理材质参数。同时配合胶囊形碰撞盒或其他形式的包围框作为脚部探测区域,这样不仅提高了精度还能更好地模拟现实世界中的运动规律[^3]。 ```csharp public class PlayerMovement : MonoBehaviour { private CharacterController controller; public Transform groundCheckPoint; public LayerMask groundLayer; private const float GroundDistanceThreshold = .4f; void Start() { controller = GetComponent<CharacterController>(); } void Update(){ JumpLogic(); } private void JumpLogic(){ if(controller.isGrounded){ Debug.Log("Player is grounded"); if(Input.GetKeyDown(KeyCode.Space)){ // Add jump force here... } } else{ Debug.Log("Not on the ground!"); } } } ``` 上述 C# 脚本提供了一个完整的例子,其中包含了基于 `CharacterController` 类型的角色控制逻辑以及利用 `isGrounded` 属性来进行基本的跳躍操作前的地表状态验证过程[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值