本文共 9202 字,大约阅读时间需要 30 分钟。
我在工作中经常看到别人写trigger,我自己一直很想写,由于工作的原因写了一个最简单的,这个trigger还不包括triggercondition 我这里没有条件分支,只有节点逻辑,这个东西也是以后需要扩展的。
triggerview.cs脚本(可以挂在gameObject上先选择一个触发类型,然后点+然后填写相关的参数 然后在你的脚本中通常和triggerview在同一个节点上或者同一个节点数上去触发trigger,至于什么时候触发那是逻辑的事情) triggersystem.cs脚本 (在triggerview中构建 ) TriggerCollider处理具体的实务逻辑 这里就是开关碰撞盒子 简化了一些无用的逻辑代码(当然你也可以构建一个定时检测的任务,开一个定时器检测比如飞剑特效飞行的距离,距离到了执行xx触发器之类的) 具体exe怎么执行可以自行改造
using UnityEngine;
using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif#if UNITY_EDITOR
[CustomEditor(typeof(TriggerView))] public class TriggerViewDataEditor: Editor // 编辑器和实现写在一个类中了建议分开 { TriggerView self;public List<TriggerHandle> _handles = new List<TriggerHandle>();
public void OnEnable() { self = target as TriggerView; } public override void OnInspectorGUI() { self = target as TriggerView; if (self == null) return;EditorGUI.BeginChangeCheck();
self.m_eventDefine = (TriggerDefine.TriggerEventDefine)EditorGUILayout.Popup((int)self.m_eventDefine, TriggerDefine.TriggerEnumString); GUILayout.BeginHorizontal(); if(GUILayout.Button("+")) { if(self.m_eventDefine == TriggerDefine.TriggerEventDefine.hideOrShow_caster) { var obj = new TriggerHideOrShowRole(); obj.triggerType = (int)TriggerDefine.TriggerEventDefine.hideOrShow_caster; obj.jsonData = obj.ToStringEx(); _handles.Add(obj); } } if(GUILayout.Button("-")) { if(_handles.Count == 0 ) { return; } var removeIndex = (_handles.Count - 1); _handles.RemoveAt(removeIndex); self.stringObjects.RemoveAt(removeIndex); EditorUtility.SetDirty(self.gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh();}
GUILayout.EndHorizontal(); GUILayout.BeginVertical(); for (int i = 0; i < self.stringObjects.Count; i++) { if(i >= _handles.Count || _handles[i] == null) { var obj = TriggerHandle.CreateByString(self.stringObjects[i]); if(i >= _handles.Count) { _handles.Add(obj); } else { _handles[i] = obj; } obj.DrawInspector(this, i); } else { _handles[i].DrawInspector(this, i); } } GUILayout.EndVertical();if (EditorGUI.EndChangeCheck())
{ if (_handles.Count > 0) { self.stringObjects.Clear(); } for (int i = 0; i < _handles.Count; i++) { self.stringObjects.Add(TriggerHandle.ToStringEx(_handles[i], this, i)); } EditorUtility.SetDirty(self.gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } }}
#endifpublic class TriggerView : MonoBehaviour
{ public List<string> stringObjects = new List<string>(); [HideInInspector] public List<TriggerHandle> handles = new List<TriggerHandle>(); public Dictionary<int, TriggerHandle> triggerMap = new Dictionary<int, TriggerHandle>(); public TriggerDefine.TriggerEventDefine m_eventDefine = TriggerDefine.TriggerEventDefine.Add_Effect_LifeTime; private TriggerSystem m_triggerSystem;private void Awake()
{ handles.Clear(); for (int i = 0; i < stringObjects.Count; i++) { handles.Add(TriggerHandle.CreateByString(stringObjects[i])); if(triggerMap.ContainsKey(handles[i].triggerId)) { Debug.LogError("存在相同的triggerId"); } triggerMap.Add(handles[i].triggerId, handles[i]); } Debug.Log("打印triggerMap"); foreach(var item in triggerMap) { Debug.Log(item.Key); } m_triggerSystem = new TriggerSystem().Attach(this.gameObject); RegisterAllTrigger(); // 注册所有的trigger }private void RegisterAllTrigger()
{ for (int i = 0; i < handles.Count; i++) { m_triggerSystem.RegisterTrigger( handles[i].triggerId); } }public void TriggerId(int id) // 触发trigger的接口
{ m_triggerSystem.Trigger(id); } }triggerSystem.cs脚本
using System.Collections;
using System.Collections.Generic; using UnityEngine; using System.Linq; using System.Reflection; public partial class TriggerSystem { private GameObject m_go; private TriggerView m_view; private FieldInfo[] eventFiledInfos; private Dictionary<int, TriggerHandle> triggerHandlers = new Dictionary<int, TriggerHandle>(); public TriggerSystem Attach(GameObject go) { m_go = go; return this; }public void RegisterTrigger(int triggerId)
{ var view = GetTriggerView(); TriggerHandle handle = view.triggerMap[triggerId]; triggerHandlers.Add(triggerId, handle); } public void Trigger(int triggerId) { if (!triggerHandlers.ContainsKey(triggerId)) { return; } triggerHandlers[triggerId].Exe(m_go,m_view,this); }public void RemoveRrigger(int triggerId)
{ if (!triggerHandlers.ContainsKey(triggerId)) return; triggerHandlers.Remove(triggerId); }public TriggerView GetTriggerView()
{ if (m_view == null) m_view = m_go.GetComponent<TriggerView>(); return m_view; }}
triggerDefine.cs
using System;public static class TriggerDefine
{ public enum TriggerEventDefine { Add_Effect_LifeTime = 0, Create_effect, open_close_collider, create_sub_emiter, Timer_Check, end_track, hideOrShow_caster, }public static Type[] typeArr =
{ typeof(TriggerCollider), }; public static string[] TriggerEnumString = { "开启关闭碰撞", }; }TriggerHandle.cs
using UnityEngine;
using System.Collections.Generic; using rkt; using System.Text; using LitJson;#if UNITY_EDITOR
using UnityEditor; #endif public interface ITriggerHandle { #if UNITY_EDITOR public void DrawInspector(TriggerViewDataEditor self, int index); public string ToStringEx(); #endif public TriggerHandle CreateByStringMap(Dictionary<string, string> dataMap); }[System.Serializable]
public class TriggerHandle : ITriggerHandle { [SerializeField] public int triggerType = 0; [SerializeField] public int triggerId; [SerializeField] public bool bAfterTriggerDestroy; // 触发后销毁public virtual void Exe(GameObject go,TriggerView view,TriggerSystem triggerSys)
{}
public virtual TriggerHandle CreateByStringMap(Dictionary<string, string> dataMap)
{ this.triggerId = int.Parse(dataMap["triggerId"]); this.triggerType = int.Parse(dataMap["triggerType"]); if(dataMap.ContainsKey("bAfterTriggerDestroy")) { this.bAfterTriggerDestroy = bool.Parse(dataMap["bAfterTriggerDestroy"]); } return this; }public static TriggerHandle CreateByString(string jsondata)
{ Dictionary<string, string> dataMap = new Dictionary<string, string>(); var arr1 = jsondata.Split('#'); for (int i = 0; i < arr1.Length; i++) { if (!string.IsNullOrEmpty(arr1[i])) { var arr2 = arr1[i].Split('-'); dataMap.Add(arr2[0], arr2[1]); } }var ty = TriggerDefine.typeArr[int.Parse(dataMap["triggerType"])];
var tmp = System.Activator.CreateInstance(ty) as TriggerHandle; tmp.CreateByStringMap(dataMap); return tmp; }#if UNITY_EDITOR
public string jsonData;public virtual void DrawInspector(TriggerViewDataEditor self, int index)
{ triggerId = EditorGUILayout.IntField("triggerId", triggerId); EditorGUILayout.TextField("触发器类型",TriggerDefine.TriggerEnumString[triggerType]); this.bAfterTriggerDestroy = EditorGUILayout.Toggle("触发后是否删除", bAfterTriggerDestroy); } public virtual string ToStringEx() { return ""; } public static string ToStringEx(TriggerHandle handle, TriggerViewDataEditor view,int index) { string str = handle.ToStringEx(); //var methodInfo = TriggerDefine.typeArr[handle.triggerType].GetMethod("ToStringEx"); //string str = (string) methodInfo.Invoke(handle, new object[] { }); if(string.IsNullOrEmpty(str)) { return handle.jsonData; } return str; //if (handle is TriggerAddEffectLifeTime) //{ // return (handle as TriggerAddEffectLifeTime).ToStringEx(); //} //if (handle is TriggerCreateEffect) //{ // return (handle as TriggerCreateEffect).ToStringEx(); //} } #endif }TriggerCollider.cs
using UnityEngine;
using System.Collections.Generic; using rkt; using System.Text; using LitJson; #if UNITY_EDITOR using UnityEditor; #endif [System.Serializable] public class TriggerCollider : TriggerHandle { [SerializeField] public int openOrClose = 1; // 1开启 非1关闭//trigger触发的方法 在TriggerSystem中注册该方法
public override void Exe(GameObject go, TriggerView view, TriggerSystem triggerSys)
{ var triggerView = view; if (triggerView == null) return; TriggerCollider triggerCollider = triggerView.triggerMap[triggerId] as TriggerCollider;Debug.Log("触发了trigger" + triggerCollider.triggerId);
var colider = go.GetComponent<Collider2D>(); if (colider != null) { colider.enabled = triggerCollider.openOrClose == 1; } if (triggerCollider.bAfterTriggerDestroy) { triggerSys.RemoveRrigger(triggerId); } } public override TriggerHandle CreateByStringMap(Dictionary<string, string> dataMap) { base.CreateByStringMap(dataMap); this.openOrClose = int.Parse(dataMap["openOrClose"]); return this; }#if UNITY_EDITOR
private bool isFoldOut = true; public override void DrawInspector(TriggerViewDataEditor self, int index) {EditorGUI.BeginChangeCheck();
isFoldOut = EditorGUILayout.Foldout(isFoldOut, index.ToString()); if (isFoldOut) { base.DrawInspector(self, index); this.openOrClose = EditorGUILayout.IntField("1表示开启0表示关闭碰撞", this.openOrClose); } if (EditorGUI.EndChangeCheck()) { jsonData = ToStringEx(); EditorUtility.SetDirty((self.target as TriggerView).gameObject); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }}
public override string ToStringEx() { var fieldArr = typeof(TriggerCollider).GetFields(); StringBuilder sb = new StringBuilder(); foreach (var field in fieldArr) { object[] attrs = field.GetCustomAttributes(true); for (int i = 0; i < attrs.Length; i++) { if (attrs[i].GetType() == typeof(UnityEngine.SerializeField)) { sb.Append(field.Name + "-" + field.GetValue(this) + "#"); break; } } } jsonData = sb.ToString(); return jsonData;}
#endif
}转载地址:https://blog.csdn.net/yangjie6898862/article/details/118639597 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!