(一)测试前准备工作
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的碰撞检测(二)”继续探讨吧。
如果这篇文章对你有帮助,请给作者点个赞吧!