Unity碰撞检测中OnTriggerXXX和OnCollisionXXX的功能注解
2014-09-15 22:08
435 查看
OnTriggerXXX指的是OnTriggerEnter、OnTriggerExit和OnTriggerStay这三个消息,OnCollisionXXX指的是OnCollisionEnter、OnCollisionExit和OnCollisionStay这三个消息,它们都是用来处理不同物体在不同状态下消息的反馈,对它们的使用说明如下。
设现有A、B两个物体,且A物体正向B移动,B物体保持静止状态,如图10-22:
则:
(1)若A中无Rigidbody组件,则B中无论是否含有Rigidbody组件,A都将穿越B物体,并且A和B脚本中的OnTriggerXXX和OnCollisionXXX方法都不会被调用。
(2)若A中含有Rigidbody组件,则B中无论是否还有Rigidbody组件,只要B中含有Collider类组件,A和B脚本中的OnTriggerXXX方法或OnCollisionXXX方法会被调用,到底调用哪静态方法要看A和B物体中Collider类组件中的IsTrigger是否被选中(参考第(3)、(4)条)。总之,要激活OnTriggerXXX方法或OnCollisionXXX方法必须使得移动的物体中含有Rigidbody组件。
(3)若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中Collider类组件的IsTrigger都没有选中时(即在Inspector面板中IsTrigger不要打勾),A和B脚本中的OnCollisionXXX类的方法就会被调用,而OnTriggerXXX静态方法则不会被调用。
(4)若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中的Collider类组件的IsTrigger至少有一个被选中时,A和B物体脚本中的OnTriggerXXX静态方法会被调用,而OnCollisionXXX静态方法不会被调用。
(5)当符合OnCollisionXXX静态方法激活条件时,A不可穿越B物体,A会与B发生弹性碰撞。
(6)当符合OnTriggerXXX静态方法激活条件时,A会穿越B物体,即A、B物体的运动行为互不影响,只是反馈了两个物体的接触状态:未接触、开始接触、接触中、互相分离。
(7)OnTriggerEnter或OnCollisionEnter方法会在A刚开始接触B时被调用,且在A、B分离前只被调用一次。
(8)OnTriggerStay或OnCollisionStay方法会在A和B保持接触状态时被调用,且在A、B分离前每帧都会被调用。
(9)OnTriggerExit或OnCollisionExit方法会在A、B刚分离时被调用,且只被调用一次。
实例演示:下面通过实例演示OnTriggerXXX类方法和OnCollisionXXX类方法的使用,在本实例演示中,包括主程序脚本和物体A、B中的脚本。
主程序脚本,用于控制A、B的移动。
在这段代码中,首先声明了两个GameObject类型的变量A和B,然后在Start方法中将A、B物体的初始位置赋给p_a和p_b,用于重置物体时使用,最后在OnGUI方法中定义了五个不同功能的Button,用于演示OnTriggerXXX类方法和OnCollisionXXX类方法的不同作用,具体请参考代码中注释。
A物体的脚本(B物体的脚本与此类似,不再赘述。)
在这段代码中,只是在OnTriggerXXX类方法和OnCollisionXXX类方法中打印出A物体被接触或被碰撞后的相应信息,请读者自行运行程序,观察在不同操作条件下的Debug输出结果。
本文章摘自图书《Unity API解析》,源码下载地址:http://www.ituring.com.cn/book/1474
设现有A、B两个物体,且A物体正向B移动,B物体保持静止状态,如图10-22:
则:
(1)若A中无Rigidbody组件,则B中无论是否含有Rigidbody组件,A都将穿越B物体,并且A和B脚本中的OnTriggerXXX和OnCollisionXXX方法都不会被调用。
(2)若A中含有Rigidbody组件,则B中无论是否还有Rigidbody组件,只要B中含有Collider类组件,A和B脚本中的OnTriggerXXX方法或OnCollisionXXX方法会被调用,到底调用哪静态方法要看A和B物体中Collider类组件中的IsTrigger是否被选中(参考第(3)、(4)条)。总之,要激活OnTriggerXXX方法或OnCollisionXXX方法必须使得移动的物体中含有Rigidbody组件。
(3)若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中Collider类组件的IsTrigger都没有选中时(即在Inspector面板中IsTrigger不要打勾),A和B脚本中的OnCollisionXXX类的方法就会被调用,而OnTriggerXXX静态方法则不会被调用。
(4)若A中含有Rigidbody组件,B中含有Collider类组件,当A和B物体中的Collider类组件的IsTrigger至少有一个被选中时,A和B物体脚本中的OnTriggerXXX静态方法会被调用,而OnCollisionXXX静态方法不会被调用。
(5)当符合OnCollisionXXX静态方法激活条件时,A不可穿越B物体,A会与B发生弹性碰撞。
(6)当符合OnTriggerXXX静态方法激活条件时,A会穿越B物体,即A、B物体的运动行为互不影响,只是反馈了两个物体的接触状态:未接触、开始接触、接触中、互相分离。
(7)OnTriggerEnter或OnCollisionEnter方法会在A刚开始接触B时被调用,且在A、B分离前只被调用一次。
(8)OnTriggerStay或OnCollisionStay方法会在A和B保持接触状态时被调用,且在A、B分离前每帧都会被调用。
(9)OnTriggerExit或OnCollisionExit方法会在A、B刚分离时被调用,且只被调用一次。
实例演示:下面通过实例演示OnTriggerXXX类方法和OnCollisionXXX类方法的使用,在本实例演示中,包括主程序脚本和物体A、B中的脚本。
主程序脚本,用于控制A、B的移动。
usingUnityEngine; usingSystem.Collections; public classTriggerOrCollision_ts : MonoBehaviour { public GameObject A, B; Vector3 p_a, p_b; int which_change = -1; //将物体A、B的初始位置赋给p_a和p_b,用于重置物体组件时使用 void Start() { p_a = A.transform.position; p_b = B.transform.position; } //控制物体A的移动 void FixedUpdate() { if (which_change == 0) { A.transform.Translate(Vector3.forward *Time.deltaTime); } } void OnGUI() { //当A物体无Rigidbody组件时 //无论B是否有Rigidbody都不会激活A和B物体的脚本中的OnCollisionXXX或OnTriggerXXX方法 if (GUI.Button(newRect(10.0f, 10.0f, 280.0f, 45.0f), "A物体无Rigidbody组件")) { inists(); which_change = 0; if (A.GetComponent<Rigidbody>()) { Destroy(A.GetComponent<Rigidbody>()); } } //当A物体有Rigidbody组件时 //一定会激活A和B物体的脚本中的OnCollisionXXX或OnTriggerXXX方法 if (GUI.Button(newRect(10.0f, 60.0f, 280.0f, 45.0f), "A有Rigidbody组件,B无Rigidbody组件")) { inists(); which_change = 1; if (!A.GetComponent<Rigidbody>()) { A.AddComponent<Rigidbody>(); A.rigidbody.useGravity = false; } if (B.GetComponent<Rigidbody>()) { Destroy(B.GetComponent<Rigidbody>()); } A.rigidbody.velocity = Vector3.forward; } //当A物体有Rigidbody组件时 //且A与B物体IsTrigger都未选中时,只会激活A和B物体的脚本中的OnCollisionXXX方法 if (GUI.Button(newRect(10.0f, 110.0f, 280.0f, 45.0f), "A与B物体IsTrigger都未选中")) { inists(); which_change = 2; A.GetComponent<Collider>().isTrigger =false; B.GetComponent<Collider>().isTrigger =false; if (!A.GetComponent<Rigidbody>()) { A.AddComponent<Rigidbody>(); A.rigidbody.useGravity = false; } A.rigidbody.velocity = Vector3.forward; } //当A物体有Rigidbody组件时 //且A与B物体IsTrigger至少有一个被选中时,只会激活A和B物体的脚本中的OnTriggerXXX方法 if (GUI.Button(newRect(10.0f, 160.0f, 280.0f, 45.0f), "A物体IsTrigger被选中")) { inists(); which_change = 3; A.GetComponent<Collider>().isTrigger =true; if (!A.GetComponent<Rigidbody>()) { A.AddComponent<Rigidbody>(); A.rigidbody.useGravity = false; } A.rigidbody.velocity = Vector3.forward; } if (GUI.Button(newRect(10.0f, 210.0f, 280.0f, 45.0f), "重置")) { inists(); which_change = 4; } } //初始化数据 void inists() { if (A.GetComponent<Rigidbody>()) { A.rigidbody.velocity = Vector3.zero; A.rigidbody.angularVelocity = Vector3.zero; } if (B.GetComponent<Rigidbody>()) { B.rigidbody.velocity = Vector3.zero; B.rigidbody.angularVelocity = Vector3.zero; } A.transform.position = p_a; A.transform.rotation = Quaternion.identity; B.transform.position = p_b; B.transform.rotation = Quaternion.identity; } }
在这段代码中,首先声明了两个GameObject类型的变量A和B,然后在Start方法中将A、B物体的初始位置赋给p_a和p_b,用于重置物体时使用,最后在OnGUI方法中定义了五个不同功能的Button,用于演示OnTriggerXXX类方法和OnCollisionXXX类方法的不同作用,具体请参考代码中注释。
A物体的脚本(B物体的脚本与此类似,不再赘述。)
usingUnityEngine; usingSystem.Collections; public classATorC_ts : MonoBehaviour { //开始接触 void OnTriggerEnter(Collider other) { Debug.Log("A物体的OnTriggerEnter被调用,被接触的物体为" + other.name); } //结束接触 void OnTriggerExit(Collider other) { Debug.Log("A物体的OnTriggerExit被调用,被接触的物体为" + other.name); } //保持接触 void OnTriggerStay(Collider other) { Debug.Log("A物体的OnTriggerStay被调用,被接触的物体为" + other.name); } //开始碰撞 void OnCollisionEnter(Collision collision) { Debug.Log("A物体的OnCollisionEnter被调用,被碰撞的物体为" + collision.gameObject.name); } //退出碰撞 void OnCollisionExit(Collision collision) { Debug.Log("A物体的OnCollisionExit被调用,被碰撞的物体为" +collision.gameObject.name); } //保持碰撞 void OnCollisionStay(Collision collision) { Debug.Log("A物体的OnCollisionStay被调用,被碰撞的物体为" + collision.gameObject.name); } }
在这段代码中,只是在OnTriggerXXX类方法和OnCollisionXXX类方法中打印出A物体被接触或被碰撞后的相应信息,请读者自行运行程序,观察在不同操作条件下的Debug输出结果。
本文章摘自图书《Unity API解析》,源码下载地址:http://www.ituring.com.cn/book/1474
相关文章推荐
- OnTriggerEnter与Rigidbody-Unity碰撞检测
- Unity 碰撞检测 OnTriggerEnter 入门
- Unity3d 物体碰撞检测前提条件(OnTrigger触发条件)
- [Unity 3D] 簡單瞭解「Collision碰撞」與「Trigger觸發」
- Unity中OnTrigger和OnCollision的触发条件
- Unity 3D 的 Collision碰撞 与 Trigger 触发的 区别
- Rigidbody.OnCollisionEnter 碰撞速度检测
- unity OnTrigger和List使用
- Unity 碰撞检测
- 优化了碰撞检测与回复模块,增加了Sleep功能.
- [Unity3D插件]2dToolKit系列三 碰撞检测功能的实现以及障碍物的随机摆放 推荐
- [Unity-4] 碰撞检测
- 【Unity3D】OnTriggerEnter与OnCollisionEnter
- Unity鼠标抓取gameobject(类似碰撞检测)
- Unity实现简单的碰撞检测
- unity基础开发----导入模型碰撞检测
- Unity OnTriggerEnter问题
- Rigidbody.detectCollisions 碰撞检测
- Unity3D碰撞检测 及 Trigger触发器的使用及注意事项
- 关于unity3的中的碰撞检测