碰撞器及触发器的优化用法
发表于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位置,看看是否输出了内容了呢