Unity3 碰撞之间的关系

本文深入探讨Unity中碰撞器的类型与应用,包括静态碰撞器、刚体碰撞器、运动学刚体碰撞器及触发器的工作原理及区别。特别强调了碰撞检测与触发事件的触发条件,并提供了一个实例代码,演示如何利用碰撞信息实现特定的游戏逻辑。

 

几个类型碰撞器:
1. 静态碰撞器: 就是只有碰撞器,但没有刚体的
2.刚体碰撞器: 带Rigidbody的碰撞器,这个是最基本的碰撞器
3.运动学刚体碰撞器: 带Rigidbody, 而且Rigidbody的IsKinematic打勾的,注意这个碰撞器是不能加力的,只能修改他的transform才能移动

Triggers 触发器

仅需要选中Inspector中的IsTrigger属性选择框。触发器不受物理引擎控制,当和一个触发器发生碰撞时会发出三个独特的触发信息,为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体.

今天遇到的一个情况是:如果刚体碰撞器不动,静态碰撞器去碰撞,则不会触发任何信息,而如果静态碰撞器不动,刚体碰撞器(包括运动学刚体碰撞器)去碰撞静态碰撞器,则会触发碰撞,如果是触发器,则会触发事件。所以下面的表格提供了触发的条件,但主动性大家也还需要注意,不然要纠结一段时间的。



Collision detection occurs and messages are sent upon collision
碰撞后有碰撞检测并有碰撞信息发出
  Static Collider
静态碰撞器
Rigidbody Collider
刚体碰撞器
Kinematic 
Rigidbody Collider
运动学刚体碰撞器
Static 
Trigger Collider
静态触发碰撞器
Rigidbody 
Trigger Collider
刚体触发碰撞器
Kinematic Rigidbody 
Trigger Collider
运动学刚体触发碰撞器
Static Collider 静态碰撞器   Y        
Rigidbody Collider 刚体碰撞器 Y Y Y      
Kinematic Rigidbody Collider 
运动学刚体碰撞器
  Y        
Static Trigger Collider
静态触发碰撞器
           
Rigidbody Trigger Collider
刚体触发碰撞器
           
Kinematic Rigidbody Trigger Collider
运动学刚体触发碰撞器
           
Trigger messages are sent upon collision
碰撞后有触发信息
  Static Collider
静态碰撞器
Rigidbody Collider
刚体碰撞器
Kinematic 
Rigidbody Collider
运动学刚体碰撞器
Static 
Trigger Collider
静态触发碰撞器
Rigidbody 
Trigger Collider
刚体触发碰撞器
Kinematic Rigidbody 
Trigger Collider
运动学刚体触发碰撞器
Static Collider 静态碰撞器         Y Y
Rigidbody Collider 刚体碰撞器       Y Y Y
Kinematic Rigidbody Collider
运动学刚体碰撞器
      Y Y Y
Static Trigger Collider 静态触发碰撞器   Y Y   Y Y
Rigidbody Trigger Collider
刚体触发碰撞器
Y Y Y Y Y Y
Kinematic Rigidbody Trigger Collider
运动学刚体触发碰撞器
Y Y Y Y Y Y
 
 
 
 
 
上面这个老外用的是 OnControllerColliderHit(),这个是用于角色碰撞的,物体如果附加了Charactor Controller(Unity自带的用于角色控制的脚本)则使用这个函数检测碰撞,这是不需要加刚体的。一般的刚体之间碰撞使用OnCollisionEnter(),范围触发用OnTriggerEnter(),如果你是让两个CUBE碰撞,请确保其中一个附加了RigidBody,然后这样写(我用C#):
void OnCollisionEnter(Collision collision)
{
Debug.Log("You touch me");
}
collision是个变量,通过它可以获得你所碰撞的目标的属性以及碰撞点信息和相对速度,如:
collision.collider.某个组件或脚本。 
void OnCollisionEnter(Collision collision)
{
if(collision.collider.tag=="enemy")//tag是物体的标签,相当于物体的类别名称。在每一个物体的组件栏(也就是加脚本的那个区域)的最上面可以找到,默认的是UnTagged,也就是没有标签,你找找,然后点击会出现一个下拉列表,默认的已有几个Tag,你也可以加自定义的,点击下拉列表最下方的Add Tag就可以加Tag,最后选择一个Tag作为物体的名称就可以了。
{
Destroy(collision.collider.gameObject);//如果检测到对方是敌人,则消灭对方。
}
}
 
 

 

### 单向碰撞机制概述 在 Unity3D 中,单向碰撞通常用于创建特定类的交互逻辑,例如平台跳跃游戏中玩家可以从下方穿过平台但在上方站立的情况。为了实现这种效果,可以通过调整刚体组件和碰撞器的行为来达成目标。 对于完全不动且需检测碰撞的对象,在配置上应将其视为具有无限质量不可移动的对象,这能最小化性能消耗并仅允许其与动态2D刚体发生碰撞[^3]。然而,针对三维环境中的单向碰撞,则涉及更复杂的设定。 ### 实现方法一:通过脚本控制接触状态 一种常见的做法是在两个物体之间建立条件性的碰撞响应关系。具体来说,就是利用 `OnCollisionEnter` 和其他相关事件处理函数配合自定义逻辑判断是否应该执行碰撞反应: ```csharp using UnityEngine; public class OneWayPlatform : MonoBehaviour { private void OnCollisionEnter(Collision collision) { Rigidbody rb = collision.collider.GetComponent<Rigidbody>(); if (rb != null && IsBelow(collision)) { // 如果是从下往上撞到平台 rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z); // 清除Y轴速度分量 ContactPoint[] contacts = collision.contacts; foreach(ContactPoint contact in contacts){ Debug.DrawLine(contact.point, contact.point + transform.up * 0.1f, Color.red); // 手动添加力使角色保持停留在平台上 rb.AddForceAtPosition(Vector3.up * Mathf.Abs(rb.mass * Physics.gravity.y), contact.thisCollider.bounds.center); } } else { Physics.IgnoreCollision(collision.collider, GetComponent<Collider>(), true); } } bool IsBelow(Collision col){ return col.transform.position.y < transform.position.y; } } ``` 此代码片段展示了如何让带有该脚本的游戏对象作为“单向平台”,即只对来自底部方向的撞击做出回应,并阻止顶部或其他侧面接近时发生的碰撞。 ### 实现方法二:使用触发器区域 另一种方式是采用触发器(Trigger)功能加上额外的空间划分技巧。可以围绕希望成为单向障碍物的部分构建一个较大的包围盒形触发区,内部再放置实际的小碰撞器。当较大范围内的任何实体进入这个触发体积时,便检查它们相对于中心点的位置矢量角度;如果满足一定条件就激活或禁用小碰撞之间的相互作用。 这种方法适用于那些不需要精确模拟物理特性的场景,因为所有的碰撞都发生在较小的真实几何形状周围而不在外部的大边界框内。 ### 配置建议 考虑到上述两种方案各有优劣,可以根据项目需求灵活选用。值得注意的是,无论采取哪种策略,都应该注意优化资源利用率以及确保游戏运行流畅稳定。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值