(一)测试前准备工作
1.创建两个游戏对象,分别取名为”Player”和”Enemy”,并且为名为”Player”的游戏对象设置Tag也为”Player”,二者在场景中如图1所示:
 
 
  2.编写脚本组件”TriggerTest”,并挂载到Enemy上,代码如下所示:
using UnityEngine;
public class TriggerTest : MonoBehaviour
{
    /*碰撞器为触发器的碰撞检测方法如下三个*/
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player")) Debug.Log("Trigger Enter");
    }
    private void OnTriggerStay2D(Collider2D other)
    {
        if (other.CompareTag("Player")) Debug.Log("Trigger");
    }
    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("Player")) Debug.Log("Trigger Exit");
    }
    /*碰撞器不为触发器的碰撞检测方法如下三个*/
    private void OnCollisionEnter2D(Collision2D other)
    {
        if (other.transform.CompareTag("Player")) Debug.Log("Collider Enter");
    }
    private void OnCollisionStay2D(Collision2D other)
    {
        if (other.transform.CompareTag("Player")) Debug.Log("Collider");
    }
    private void OnCollisionExit2D(Collision2D other)
    {
        if (other.transform.CompareTag("Player")) Debug.Log("Collider Exit");
    }
}3.Trigger输出:输出”Trigger Enter”或”Trigger”或”Trigger Exit”;
4.Collider输出:输出”Collider Enter”或” Collider”或” Collider Exit”。
(二)测试用例
(1)测试约定:
碰撞器统一使用BoxCollider2D组件,刚体统一使用Rigidbody2D组件,测试涉及更改的属性有且仅有碰撞器的激活或禁用和IsTrigger两个属性,刚体的挂载或卸载,且二者默认属性分别如图2和图3所示:
 
 
   
 
  (2)非法测试用例:
A2、A3、A6、A7、A11、A12、A14、A15与(一)中预设冲突,故舍弃。
B1、B4、B5、B8、B9、B10、B13、B16与(一)中预设冲突,故舍弃。
A9、A10、A13、A16未挂载碰撞器是一定不可能发生碰撞的测试用例,故舍弃。
B11、B12、B14、B15未挂载碰撞器是一定不可能发生碰撞的测试用例,故舍弃。
| 游戏对象 | 用例序号 | 是否激活碰撞器 | 是否挂载刚体 | 是否挂载TriggerTest | 碰撞器是否为触发器 | 
| Player | A1 | √ | × | × | × | 
| A2 | √ | x | √ | × | |
| A3 | √ | x | √ | √ | |
| A4 | √ | × | × | √ | |
| A5 | √ | √ | × | × | |
| A6 | √ | √ | √ | × | |
| A7 | √ | √ | √ | √ | |
| A8 | √ | √ | × | √ | |
| A9 | × | × | × | × | |
| A10 | × | √ | × | × | |
| A11 | × | √ | √ | × | |
| A12 | × | √ | √ | √ | |
| A13 | × | √ | × | √ | |
| A14 | × | × | √ | × | |
| A15 | × | × | √ | √ | |
| A16 | × | × | × | √ | |
| Enemy | B1 | √ | × | × | × | 
| B2 | √ | x | √ | × | |
| B3 | √ | x | √ | √ | |
| B4 | √ | × | × | √ | |
| B5 | √ | √ | × | × | |
| B6 | √ | √ | √ | × | |
| B7 | √ | √ | √ | √ | |
| B8 | √ | √ | × | √ | |
| B9 | × | × | × | × | |
| B10 | × | √ | × | × | |
| B11 | × | √ | √ | × | |
| B12 | × | √ | √ | √ | |
| B13 | × | √ | × | √ | |
| B14 | × | × | √ | × | |
| B15 | × | × | √ | √ | |
| B16 | × | × | × | √ | 
| 组合序号 | 测试用例组合 | 控制台输出 | 
| G1 | A1、B2 | 无 | 
| G2 | A1、B3 | 无 | 
| G3 | A1、B6 | 无 | 
| G4 | A1、B7 | Trigger输出 | 
| G5 | A4、B2 | 无 | 
| G6 | A4、B3 | 无 | 
| G7 | A4、B6 | Trigger输出 | 
| G8 | A4、B7 | Trigger输出 | 
| G9 | A5、B2 | 无 | 
| G10 | A5、B3 | Trigger输出 | 
| G11 | A5、B6 | 无 | 
| G12 | A5、B7 | Trigger输出 | 
| G13 | A8、B2 | Trigger输出 | 
| G14 | A8、B3 | Trigger输出 | 
| G15 | A8、B6 | Trigger输出 | 
| G16 | A8、B7 | Trigger输出 | 
(三)测试总结
分析1:对比G4、G8、G12、G16可知,当Enemy具备触发器+刚体时,无论Player的碰撞器是否为触发器或者是否具备刚体,都执行触发器的检测。
分析2:对比G7和G8可知,当Player仅具备触发器且Enemy具备刚体时,无论Enemy的碰撞器是否为触发器均执行触发器的检测。
分析3:对比G10和G12可知,当Player具备碰撞器+刚体且Enemy具备触发器时,无论Enemy是否具备刚体均执行触发器的检测。
分析4:对比G13-G16可知,当Player具备触发器+刚体时,无论Enemy的碰撞器是否为触发器或者是否具备刚体,都执行触发器的检测。
由分析1-4可知,有效触发的必要条件如下:
结论1:两个游戏对象必须有至少一个触发器。
结论2:两个游戏对象至少有一个具备刚体。
(四)碰撞检测相关的API
(1)OnCollisionEnter()和OnCollisionEnter2D();
(2)OnCollisionStay()和OnCollisionStay2D();
(3)OnCollisionExit()和OnCollisionExit2D();
(4)OnTriggerEnter()和OnTriggerEnter2D();
(5)OnTriggerStay()和OnTriggerStay2D();
(6)OnTriggerExit()和OnTriggerExit2D();
具体看官方关于Monobehaviour类的说明。
(五)问题
在上面的测试中我们并没有得到Collider输出,所有的输出都是Trigger输出,这个问题的原因是啥?我们在下一篇“Unity的碰撞检测(二)”继续探讨吧。
如果这篇文章对你有帮助,请给作者点个赞吧!



















