碰撞器及触发器的优化用法
发表于2017-09-30
在游戏项目中,我们经常会用到 碰撞器检测或者触发器检测。而我们在做检测的时候都要在物体上挂载脚本,然后添加OnTriggerEnter\OnCollisionExit等函数
而有些物体,比如英雄身上的武器、技能上的特效,需要在物体上挂载脚本 再在脚本里去做碰撞检测后的逻辑。
这样的操作维护成本太高 而且耦合性也会增加。
介于所述缺点,可以使用今天教给大家的方式试下~~
上代码:
using UnityEngine;
using System.Collections;
using System;
public class ColliderDetect : MonoBehaviour
{
#region 事件
public Action<GameObject> onTriggerEnterEvent;
public Action<GameObject> onTriggerStayEvent;
public Action<GameObject> onTriggerExitEvent;
public Action<GameObject> onCollisionEnterEvent;
public Action<GameObject> onCollisionStayEvent;
public Action<GameObject> onCollisionExitEvent;
#endregion
/// <summary>
/// 给物体添加BoxCollider
/// </summary>
public void AddBoxCollider(bool isTrigger, Vector3 center = default(Vector3), Vector3 size = default(Vector3), PhysicMaterial material = null)
{
Rigidbody rigidBody = GetComponent<Rigidbody>();
if (rigidBody == null)
rigidBody = gameObject.AddComponent<Rigidbody>();
rigidBody.useGravity = false;
BoxCollider collider = GetComponent<BoxCollider>();
if (collider == null)
collider = gameObject.AddComponent<BoxCollider>();
collider.isTrigger = isTrigger;
collider.center = center;
collider.size = size;
collider.material = material;
}
/// <summary>
/// 给物体添加SphereCollider
/// </summary>
public void AddSphereCollider(bool isTrigger, Vector3 center = default(Vector3), float radius = default(float), PhysicMaterial material = null)
{
Rigidbody rigidBody = GetComponent<Rigidbody>();
if (rigidBody == null)
rigidBody = gameObject.AddComponent<Rigidbody>();
rigidBody.useGravity = false;
SphereCollider collider = GetComponent<SphereCollider>();
if (collider == null)
collider = gameObject.AddComponent<SphereCollider>();
collider.isTrigger = isTrigger;
collider.center = center;
collider.radius = radius;
collider.material = material;
}
#region 检测
private void OnTriggerEnter(Collider other)
{
if (onTriggerEnterEvent != null)
onTriggerEnterEvent(other.gameObject);
}
private void OnTriggerStay(Collider other)
{
if (onTriggerStayEvent != null)
onTriggerStayEvent(other.gameObject);
}
private void OnTriggerExit(Collider other)
{
if (onTriggerExitEvent != null)
onTriggerExitEvent(other.gameObject);
}
private void OnCollisionEnter(Collision collision)
{
if (onCollisionEnterEvent != null)
onCollisionEnterEvent(collision.gameObject);
}
private void OnCollisionStay(Collision collision)
{
if (onCollisionStayEvent != null)
onCollisionStayEvent(collision.gameObject);
}
private void OnCollisionExit(Collision collision)
{
if (onCollisionExitEvent != null)
onCollisionExitEvent(collision.gameObject);
}
#endregion
}
测试脚本:
public class Test : MonoBehaviour {
public GameObject cube; // 需要做碰撞或触发检测的物体
void Start()
{
ColliderDetect detect = cube.AddComponent<ColliderDetect>();
detect.AddBoxCollider(true, default(Vector3), Vector3.one); // 添加Collider及刚体组件
detect.onTriggerEnterEvent = OnCubeTriggerEnter; // 监听TriggerEnter事件
}
void OnCubeTriggerEnter(GameObject target)
{
Debug.Log("OnCubeTriggerEnter " target.name);
}
}
测试方法:
一、在空场景里创建一个Cube和Sphere,让它俩分开点距离,我们的目的是给Cube添加触发器检测,检测是否碰撞到Sphere
二、将Test.ts脚本挂载在摄像机,给Test脚本的cube变量复制
三、拖动Sphere到Cube位置,看看是否输出了内容了呢

