【唐老狮】Unity——物理系统(碰撞检测)

本文详细介绍了Unity中的物理系统,包括碰撞检测的必要条件、刚体组件参数解析、各种碰撞盒组件的使用,以及物理材质对碰撞表现的影响。通过实例展示了如何通过代码检测碰撞和触发事件的不同阶段,帮助读者理解和掌握Unity中物体碰撞和触发器的实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【学习目标】

碰撞检测

  1. 能够让两个游戏物体之间产生碰撞

  2. 能够让两个物体碰撞时表现出不同效果

  3. 能够通过代码检测到碰撞产生的不同阶段

  4. 能够使用触发器让两个物体相互穿透

  5. 能够通过代码检测到触发产生的不同阶段



【碰撞检测】

【碰撞的必要条件】

两个游戏物体(GameObject)之间

至少有一个物体有刚体组件(Rigidbody)

并且两个物体都有碰撞盒组件(Collider)



【实例】

 

 

上方物体挂载了刚体和碰撞盒

下方物体挂载了碰撞盒

运行后由于上方物体有刚体组件

并且Use Gravity默认勾选

所以它会受重力影响自由下落

图片

 



【刚体组件】

让游戏物体(GameObject)

受到力的作用

参数说明

红色字为重要参数

其余了解即可

Mass

对象的质量(默认为千克)

Drag

根据力移动对象时影响对象的空气阻力大小。0 表示没有空气阻力,无穷大使对象立即停止移动

Angular Drag

根据扭矩旋转对象时影响对象的空气阻力大小。0 表示没有空气阻力。请注意,如果直接将对象的 Angular Drag 属性设置为无穷大,无法使对象停止旋转。

Use Gravity

如果启用此属性,则对象将受重力影响。

Is Kinematic

如果启用此选项,则对象将不会被物理引擎驱动,只能通过 (Transform) 对其进行操作。对于移动平台,或者如果要动画化附加了 HingeJoint 的刚体,此属性将非常有用。

Interpolate

仅当在刚体运动中看到急动时才尝试使用提供的选项之一。

-None

不应用插值。

-Interpolate

根据前一帧的变换来平滑变换。

-Extrapolate

根据下一帧的估计变换来平滑变换。

Collision Detection

用于防止快速移动的对象穿过其他对象而不检测碰撞。

-Discrete

对场景中的所有其他碰撞体使用离散碰撞检测。其他碰撞体在测试碰撞时会使用离散碰撞检测。用于正常碰撞(这是默认值)。

-Continuous

对动态碰撞体(具有刚体)使用离散碰撞检测,并对静态碰撞体(没有刚体)使用基于扫掠的连续碰撞检测。设置为_连续动态 (Continuous Dynamic) 的刚体将在测试与该刚体的碰撞时使用连续碰撞检测。其他刚体将使用离散碰撞检测。用于连续动态 (Continuous Dynamic) 检测需要碰撞的对象。(此属性对物理性能有很大影响,如果没有快速对象的碰撞问题,请将其保留为 Discrete 设置)

-Continuous Dynamic

对设置为连续 (Continuous)和连续动态 (Continuous Dynamic)碰撞的游戏对象使用基于扫掠的连续碰撞检测。还将对静态碰撞体(没有刚体)使用连续碰撞检测。对于所有其他碰撞体,使用离散碰撞检测。用于快速移动的对象。

-Continuous Speculative

对刚体和碰撞体使用推测性连续碰撞检测。这也是可以设置运动物体的唯一 CCD 模式。该方法通常比基于扫掠的连续碰撞检测的成本更低。

Constraints

对刚体运动的限制。

-Freeze Position

有选择地停止刚体沿世界 X、Y 和 Z 轴的移动。

### Unity 中的碰撞检测实现方法 在 Unity 的开发过程中,碰撞检测是一个非常重要的功能模块。以下是几种常见的碰撞检测方式及其具体实现: #### 射线检测 射线检测是一种常用的碰撞检测技术,在许多场景下用于判断物体之间的交互关系。通过 `Physics.Raycast` 函数可以轻松实现这一目标[^1]。 ```csharp using UnityEngine; public class RaycastExample : MonoBehaviour { void Update() { Vector3 origin = transform.position; Vector3 direction = transform.forward; if (Physics.Raycast(origin, direction, out RaycastHit hit)) { Debug.Log($"Hit object: {hit.collider.name}"); } } } ``` 上述代码展示了如何使用射线投射来检测前方是否有对象被命中,并打印出该对象的名字。 --- #### 静态方法调用 Input 类 Unity 提供了许多内置工具帮助开发者快速完成输入处理工作。例如,`Input.GetAxis` 是一种获取用户输入的方式之一。需要注意的是,这些函数均为静态方法,因此可以直接通过类名访问而无需创建实例[^2]。 如果尝试在一个非静态上下文中操作,则可能会遇到错误提示:“无法从静态字段或属性中引用非静态成员”。这表明当前环境不允许此类行为发生。 --- #### 扇形范围内的点判定 对于某些特殊需求来说,可能需要知道某一点是否位于特定角度范围内(比如技能释放区域)。此时可以通过计算两个向量间夹角的方法来进行验证[^3]。 假设我们已经得到了玩家位置至目标位置的方向矢量以及技能发射方向矢量,则可通过如下逻辑得出结论: ```csharp float angleThreshold = Mathf.Deg2Rad * maxAngle / 2f; // Convert degree to radian and half it. Vector3 normalizedA = a.normalized; Vector3 normalizedB = b.normalized; if(Vector3.Dot(normalizedA, normalizedB) >= Math.Cos(angleThreshold)){ // Inside the cone area. } else { // Outside the cone area. } ``` 这里的关键在于理解三角学中的余弦定理应用——当两单位长度向量做内积运算结果大于等于给定阈值时即满足条件。 --- ### 总结 以上介绍了三种不同类型的碰撞或者空间关系查询手段:基于物理引擎的传统射线测试;针对键盘鼠标事件捕捉机制下的简单指令执行模式切换;还有就是几何图形算法方面的基础运用案例分析。每种都有其适用场合,合理选用才能达到最佳效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值