- A+
首先来看一下,一些常用的管理类方法写成了一个简单的方法,方便调用,从这里出发就可以看到出现了两个管理类了,一个是EventManager管理类,负责的是减少脚本文件之间的相互引用也能相互传递信息。还有一个就是TriggerManager管理类,这个是负责一些Unity事件的触发和注册,比如点击、滑动等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
local TriggerManager = require("Manager.TriggerManager") local EventManager = require("Manager.EventManager") function handler(target,func) return function(...) return func(target,...) end end function registTrigger(go,type,handler) TriggerManager:GetInstance():RegistEvent(go,type,handler) end function callTrigger(go,type,eventData) TriggerManager:GetInstance():CallEvent(go,type,eventData) end function registEvent(key,handler) return EventManager:GetInstance():RegistEvent(key,handler) end function callEvent(key,...) EventManager:GetInstance():CallEvent(key,...) end function removeEvent(key,handler) EventManager:GetInstance():RemoveEvent(key,handler) end |
先来看看EventManager吧,在需要接受其他类传递的信息时就可以注册一个事件,在别的类触发这个事件就可以了,比较简单就不多说了,直接看代码吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
--事件管理器,中心机制,完成类与类之间的交互解耦 local EventManager = class("Manager.EventManager") function EventManager:ctor() self.events = {} end function EventManager:GetInstance() if self.instance == nil then self.instance = EventManager:new() end return self.instance end function EventManager:RegistEvent(key,handler) if not self.events[key] then self.events[key] = {} end table.insert(self.events[key],handler) return handler end function EventManager:CallEvent(key,...) local eves = self.events[key] if eves then for i,v in ipairs(eves) do v(...) end end end function EventManager:RemoveEvent(key,handler) local eves = self.events[key] if eves then for i,v in ipairs(eves) do if v == handler then table.remove(eves,i) return true end end end end return EventManager |
再来看看TriggerManager吧,说到这个就要将Unity那边的工具类EventTriggerListener了还有lua这边的工具类UtilityManager了,说起来好乱了,稍微整理一下流程吧。首先在场景中已经可以获取到UI的物体了,但是还不知道怎么触发点击等交互事件,此时Unity那边就需要一个监听这些事件了,那这个工具脚本EventTriggerListener就诞生了,对应的lua这边就需要TriggerManager就负责把那个c#脚本挂载到物体上,并记录打开事件开关,完成事件的监听了。好了,此时EventTriggerListener就可以触发相应的事件方法了,那么需要把事件的调用转移到lua虚拟机这边来,所以需要提供一个lua方法给c#那边,没错,那就是callTrigger方法了,他是通过工具类UtilityManager初始化方法中传递过去了。
EventTriggerListener在事件触发的时候会调用Main里面的InvokeEventCall,传递触发的物体和事件类型及触发参数过去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
public class EventTriggerListener : EventTrigger { public int hashCode; public GameObject go; private Dictionary<string,bool> events = new Dictionary<string, bool>(); public static EventTriggerListener Get(GameObject go) { EventTriggerListener listener = go.GetComponent<EventTriggerListener>(); if (listener == null) listener = go.AddComponent<EventTriggerListener>(); listener.go = go; listener.hashCode = go.GetHashCode(); return listener; } public void RegistEvent(string eve) { events.Add(eve, true); } public void RemoveEvent(string eve) { if(CheckEvent(eve)) events.Remove(eve); } private bool CheckEvent(string key) { if (events.ContainsKey(key)) return true; return false; } public override void OnPointerEnter(PointerEventData eventData) { if (CheckEvent("OnPointerEnter")) Main.Instance.InvokeEventCall(go, "OnPointerEnter", eventData); } public override void OnPointerExit(PointerEventData eventData) { if (CheckEvent("OnPointerExit")) Main.Instance.InvokeEventCall(go, "OnPointerExit", eventData); } public override void OnPointerDown(PointerEventData eventData) { if (CheckEvent("OnPointerDown")) Main.Instance.InvokeEventCall(go, "OnPointerDown", eventData); } public override void OnPointerUp(PointerEventData eventData) { if (CheckEvent("OnPointerUp")) Main.Instance.InvokeEventCall(go, "OnPointerUp", eventData); } public override void OnPointerClick(PointerEventData eventData) { if (CheckEvent("OnPointerClick")) Main.Instance.InvokeEventCall(go, "OnPointerClick", eventData); } public override void OnInitializePotentialDrag(PointerEventData eventData) { if (CheckEvent("OnInitializePotentialDrag")) Main.Instance.InvokeEventCall(go, "OnInitializePotentialDrag", eventData); } public override void OnBeginDrag(PointerEventData eventData) { if (CheckEvent("OnBeginDrag")) Main.Instance.InvokeEventCall(go, "OnBeginDrag", eventData); } public override void OnDrag(PointerEventData eventData) { if (CheckEvent("OnDrag")) Main.Instance.InvokeEventCall(go, "OnDrag", eventData); } public override void OnEndDrag(PointerEventData eventData) { if (CheckEvent("OnEndDrag")) Main.Instance.InvokeEventCall(go, "OnEndDrag", eventData); } public override void OnDrop(PointerEventData eventData) { if (CheckEvent("OnDrop")) Main.Instance.InvokeEventCall(go, "OnDrop", eventData); } public override void OnScroll(PointerEventData eventData) { if (CheckEvent("OnScroll")) Main.Instance.InvokeEventCall(go, "OnScroll", eventData); } public override void OnUpdateSelected(BaseEventData eventData) { if (CheckEvent("OnUpdateSelected")) Main.Instance.InvokeEventCall(go, "OnUpdateSelected", eventData); } public override void OnSelect(BaseEventData eventData) { if (CheckEvent("OnSelect")) Main.Instance.InvokeEventCall(go, "OnSelect", eventData); } public override void OnDeselect(BaseEventData eventData) { if (CheckEvent("OnDeselect")) Main.Instance.InvokeEventCall(go, "OnDeselect", eventData); } public override void OnMove(AxisEventData eventData) { if (CheckEvent("OnMove")) Main.Instance.InvokeEventCall(go, "OnMove", eventData); } public override void OnSubmit(BaseEventData eventData) { if (CheckEvent("OnSubmit")) Main.Instance.InvokeEventCall(go, "OnSubmit", eventData); } public override void OnCancel(BaseEventData eventData) { if (CheckEvent("OnCancel")) Main.Instance.InvokeEventCall(go, "OnCancel", eventData); ; } } |
InvokeEventCall调用的是通过RegisterEventCall传递过来的lua方法,这里还有一个方法是将byte数据保存为文件的,这里直接提及了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using UnityEngine; using LuaInterface; using System; using System.IO; public class Main : MonoBehaviour { public LuaState luaState = null; public static Main Instance = null; private LuaFunction onEventCall = null; private LuaLooper loop = null; private bool useRemoteRes = false; private void Awake() { Main.Instance = this; InitLuaEvn(); } public void RegistEventCall(LuaFunction func) { this.onEventCall = func; } public void InvokeEventCall(GameObject go,string type,object o) { if (this.onEventCall != null) { this.onEventCall.BeginPCall(); this.onEventCall.Push(go); this.onEventCall.Push(type); this.onEventCall.Push(o); this.onEventCall.PCall(); this.onEventCall.EndPCall(); } } public void SaveDownLoadData(string path,byte[] datas) { string s = path.Substring(0, path.LastIndexOf('/')); DirectoryInfo directoryInfo = new DirectoryInfo(s); if(!directoryInfo.Exists) Directory.CreateDirectory(s); FileInfo file = new FileInfo(@path); Stream sw; sw = file.Create(); //全部重下 sw.Write(datas, 0, datas.Length); sw.Flush(); sw.Close(); sw.Dispose(); } } |
可以看到注册到那边的lua方法就是callTrigger方法了,它实际调用的就是TriggerManager里面的方法了。同样的这里也提供了调用c#Main保存byte数据的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
--管理与c# Main 相关的东西 local UtilityManager = class("Manager.UtilityManager") function UtilityManager:GetInstance() if self.instance == nil then self.instance = UtilityManager:new() end return self.instance end function UtilityManager:Init() Main.Instance:RegistEventCall(callTrigger) end function UtilityManager:SaveDownLoadData(savePath,saveData) Main.Instance:SaveDownLoadData(savePath,saveData) end function UtilityManager:GetUseRemoteRes() return useRemoteRes end return UtilityManager |
这个管理器干活最多的了,其他的也只是传递传递信息而已,这里在注册事件的时候会为注册事件的物体添加EventTriggerListerer组件,并打开事件开关,同时保存了事件的回调方法,在事件触发的时候,通过传回来的物体和事件类型辨别找到相应的回调并调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
--对标c#的 EventTriggerListener 管理交互事件的集合 并区别调用 --因为常用 所以写成全局的调用方法在 functions 里面 所以一般不引用 local TriggerManager = class("Manager.TriggerManager") local EventTriggerListener = EventTriggerListener function TriggerManager:ctor() self.triggerEvents = {} end function TriggerManager:GetInstance() if self.instance == nil then self.instance = TriggerManager:new() end return self.instance end function TriggerManager:RegistEvent(go,type,handler) local trigger = EventTriggerListener.Get(go) local hashCode = go:GetHashCode() if not self.triggerEvents[hashCode] then self.triggerEvents[hashCode] = {} end local event = {} event.type = type event.handler = handler self.triggerEvents[hashCode][type] = event trigger:RegistEvent(type) end function TriggerManager:RemoveEvent(go,type) local trigger = EventTriggerListener.Get(btn) local hashCode = go:GetHashCode() local events = self.triggerEvents[hashCode] if events and events[type] then events[type] = nil end trigger:RemoveEvent(type) end function TriggerManager:CallEvent(go,type,eventData) local code = go:GetHashCode() local events = self.triggerEvents[code] if events then local event = events[type] if event and event.handler then event.handler(go,eventData) end end end return TriggerManager |
好了,写完了,有点乱,其实确实是很容易的东西,这里只是展示说明一下,后面的文章遇到这些也不好说这些东西,直接这里看看,后面遇到就不懵逼了。