LuaFramework_UGUI_V2 https://github.com/jarjin/LuaFramework_UGUI_V2
usingUnityEngine; usingLuaInterface; usingSystem.Collections; usingSystem.Collections.Generic; usingSystem; usingUnityEngine.UI; namespaceLuaFramework { public classLuaBehaviour : View { private string data = null; private Dictionary<string, LuaFunction> buttons = new Dictionary<string, LuaFunction>(); protected voidAwake() { Util.CallMethod(name, "Awake", gameObject); } protected voidStart() { Util.CallMethod(name, "Start"); } protected voidOnClick() { Util.CallMethod(name, "OnClick"); } protected voidOnClickEvent(GameObject go) { Util.CallMethod(name, "OnClick", go); } /// <summary> ///添加单击事件 /// </summary> public voidAddClick(GameObject go, LuaFunction luafunc) { if (go == null || luafunc == null) return; buttons.Add(go.name, luafunc); go.GetComponent<Button>().onClick.AddListener( delegate() { luafunc.Call(go); } ); } /// <summary> ///删除单击事件 /// </summary> /// <param name="go"></param> public voidRemoveClick(GameObject go) { if (go == null) return; LuaFunction luafunc = null; if (buttons.TryGetValue(go.name, outluafunc)) { luafunc.Dispose(); luafunc = null; buttons.Remove(go.name); } } /// <summary> ///清除单击事件 /// </summary> public voidClearClick() { foreach (var de inbuttons) { if (de.Value != null) { de.Value.Dispose(); } } buttons.Clear(); } //----------------------------------------------------------------- protected voidOnDestroy() { ClearClick(); #if ASYNC_MODE string abName = name.ToLower().Replace("panel", ""); ResManager.UnloadAssetBundle(abName +AppConst.ExtName); #endif Util.ClearMemory(); Debug.Log("~" + name + "was destroy!"); } } }
usingUnityEngine; usingSystem.Collections; usingSystem.IO; usingLuaInterface; namespaceLuaFramework { /// <summary> ///集成自LuaFileUtils,重写里面的ReadFile, /// </summary> public classLuaLoader : LuaFileUtils { privateResourceManager m_resMgr; ResourceManager resMgr { get{ if (m_resMgr == null) m_resMgr = AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource); returnm_resMgr; } } //Use this for initialization publicLuaLoader() { instance = this; beZip =AppConst.LuaBundleMode; } /// <summary> ///添加打入Lua代码的AssetBundle /// </summary> /// <param name="bundle"></param> public void AddBundle(stringbundleName) { string url = Util.DataPath +bundleName.ToLower(); if(File.Exists(url)) { var bytes =File.ReadAllBytes(url); //已注释, CreateFromMemoryImmediate从5.3开始改为LoadFromMemory,需要用的请自行取消注释~ //AssetBundle bundle = AssetBundle.CreateFromMemoryImmediate(bytes); AssetBundle bundle =AssetBundle.LoadFromMemory(bytes); if (bundle != null) { bundleName = bundleName.Replace("lua/", "").Replace(".unity3d", ""); base.AddSearchBundle(bundleName.ToLower(), bundle); } } } /// <summary> ///当LuaVM加载Lua文件的时候,这里就会被调用, ///用户可以自定义加载行为,只要返回byte[]即可。 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public override byte[] ReadFile(stringfileName) { return base.ReadFile(fileName); } } }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; namespaceLuaFramework { public classAppConst { public const bool DebugMode = false; //调试模式-用于内部测试 /// <summary> ///如果想删掉框架自带的例子,那这个例子模式必须要 ///关闭,否则会出现一些错误。 /// </summary> public const bool ExampleMode = true; //例子模式 /// <summary> ///如果开启更新模式,前提必须启动框架自带服务器端。 ///否则就需要自己将StreamingAssets里面的所有内容 ///复制到自己的Webserver上面,并修改下面的WebUrl。 /// </summary> public const bool UpdateMode = false; //更新模式-默认关闭 public const bool LuaByteMode = false; //Lua字节码模式-默认关闭 public const bool LuaBundleMode = true; //Lua代码AssetBundle模式 public const int TimerInterval = 1; public const int GameFrameRate = 30; //游戏帧频 public const string AppName = "LuaFramework"; //应用程序名称 public const string LuaTempDir = "Lua/"; //临时目录 public const string AppPrefix = AppName + "_"; //应用程序前缀 public const string ExtName = ".unity3d"; //素材扩展名 public const string AssetDir = "StreamingAssets"; //素材目录 public const string WebUrl = "http://localhost:6688/"; //测试更新地址 public static string UserId = string.Empty; //用户ID public static int SocketPort = 0; //Socket服务器端口 public static string SocketAddress = string.Empty; //Socket服务器地址 public static stringFrameworkRoot { get{ return Application.dataPath + "/" +AppName; } } } }
usingUnityEngine; usingSystem.Collections; namespaceLuaFramework { public classManagerName { public const string Lua = "LuaManager"; public const string Game = "GameManager"; public const string Timer = "TimeManager"; public const string Sound = "SoundManager"; public const string Panel = "PanelManager"; public const string Network = "NetworkManager"; public const string Resource = "ResourceManager"; public const string Thread = "ThreadManager"; public const string ObjectPool = "ObjectPoolManager"; } }
usingUnityEngine; usingSystem.Collections; public classNotiConst { /// <summary> ///Controller层消息通知 /// </summary> public const string START_UP = "StartUp"; //启动框架 public const string DISPATCH_MESSAGE = "DispatchMessage"; //派发信息 /// <summary> ///View层消息通知 /// </summary> public const string UPDATE_MESSAGE = "UpdateMessage"; //更新消息 public const string UPDATE_EXTRACT = "UpdateExtract"; //更新解包 public const string UPDATE_DOWNLOAD = "UpdateDownload"; //更新下载 public const string UPDATE_PROGRESS = "UpdateProgress"; //更新进度 }
usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingLuaFramework; public classSocketCommand : ControllerCommand { public override voidExecute(IMessage message) { object data =message.Body; if (data == null) return; KeyValuePair<int, ByteBuffer> buffer = (KeyValuePair<int, ByteBuffer>)data; switch(buffer.Key) { default: Util.CallMethod("Network", "OnSocket", buffer.Key, buffer.Value); break; } } }
usingUnityEngine; usingSystem.Collections; usingLuaFramework; public classStartUpCommand : ControllerCommand { public override voidExecute(IMessage message) { if (!Util.CheckEnvironment()) return; GameObject gameMgr = GameObject.Find("GlobalGenerator"); if (gameMgr != null) { AppView appView = gameMgr.AddComponent<AppView>(); } //-----------------关联命令----------------------- AppFacade.Instance.RegisterCommand(NotiConst.DISPATCH_MESSAGE, typeof(SocketCommand)); //-----------------初始化管理器----------------------- AppFacade.Instance.AddManager<LuaManager>(ManagerName.Lua); AppFacade.Instance.AddManager<PanelManager>(ManagerName.Panel); AppFacade.Instance.AddManager<SoundManager>(ManagerName.Sound); AppFacade.Instance.AddManager<TimerManager>(ManagerName.Timer); AppFacade.Instance.AddManager<NetworkManager>(ManagerName.Network); AppFacade.Instance.AddManager<ResourceManager>(ManagerName.Resource); AppFacade.Instance.AddManager<ThreadManager>(ManagerName.Thread); AppFacade.Instance.AddManager<ObjectPoolManager>(ManagerName.ObjectPool); AppFacade.Instance.AddManager<GameManager>(ManagerName.Game); } }
usingUnityEngine; usingSystem.Collections; usingLuaFramework; usingSystem.Collections.Generic; public classBase : MonoBehaviour { privateAppFacade m_Facade; privateLuaManager m_LuaMgr; privateResourceManager m_ResMgr; privateNetworkManager m_NetMgr; privateSoundManager m_SoundMgr; privateTimerManager m_TimerMgr; privateThreadManager m_ThreadMgr; privateObjectPoolManager m_ObjectPoolMgr; /// <summary> ///注册消息 /// </summary> /// <param name="view"></param> /// <param name="messages"></param> protected void RegisterMessage(IView view, List<string>messages) { if (messages == null || messages.Count == 0) return; Controller.Instance.RegisterViewCommand(view, messages.ToArray()); } /// <summary> ///移除消息 /// </summary> /// <param name="view"></param> /// <param name="messages"></param> protected void RemoveMessage(IView view, List<string>messages) { if (messages == null || messages.Count == 0) return; Controller.Instance.RemoveViewCommand(view, messages.ToArray()); } protectedAppFacade facade { get{ if (m_Facade == null) { m_Facade =AppFacade.Instance; } returnm_Facade; } } protectedLuaManager LuaManager { get{ if (m_LuaMgr == null) { m_LuaMgr = facade.GetManager<LuaManager>(ManagerName.Lua); } returnm_LuaMgr; } } protectedResourceManager ResManager { get{ if (m_ResMgr == null) { m_ResMgr = facade.GetManager<ResourceManager>(ManagerName.Resource); } returnm_ResMgr; } } protectedNetworkManager NetManager { get{ if (m_NetMgr == null) { m_NetMgr = facade.GetManager<NetworkManager>(ManagerName.Network); } returnm_NetMgr; } } protectedSoundManager SoundManager { get{ if (m_SoundMgr == null) { m_SoundMgr = facade.GetManager<SoundManager>(ManagerName.Sound); } returnm_SoundMgr; } } protectedTimerManager TimerManager { get{ if (m_TimerMgr == null) { m_TimerMgr = facade.GetManager<TimerManager>(ManagerName.Timer); } returnm_TimerMgr; } } protectedThreadManager ThreadManager { get{ if (m_ThreadMgr == null) { m_ThreadMgr = facade.GetManager<ThreadManager>(ManagerName.Thread); } returnm_ThreadMgr; } } protectedObjectPoolManager ObjPoolManager { get{ if (m_ObjectPoolMgr == null) { m_ObjectPoolMgr = facade.GetManager<ObjectPoolManager>(ManagerName.ObjectPool); } returnm_ObjectPoolMgr; } } }
/* LuaFramework Code By Jarjin lee */ usingSystem; usingSystem.Collections.Generic; usingUnityEngine; /// <summary> ///事件命令 /// </summary> public classControllerCommand : ICommand { public virtual voidExecute(IMessage message) { } } public classFacade { protectedIController m_controller; staticGameObject m_GameManager; static Dictionary<string, object> m_Managers = new Dictionary<string, object>(); GameObject AppGameManager { get{ if (m_GameManager == null) { m_GameManager = GameObject.Find("GameManager"); } returnm_GameManager; } } protectedFacade() { InitFramework(); } protected virtual voidInitFramework() { if (m_controller != null) return; m_controller =Controller.Instance; } public virtual void RegisterCommand(stringcommandName, Type commandType) { m_controller.RegisterCommand(commandName, commandType); } public virtual void RemoveCommand(stringcommandName) { m_controller.RemoveCommand(commandName); } public virtual bool HasCommand(stringcommandName) { returnm_controller.HasCommand(commandName); } public void RegisterMultiCommand(Type commandType, params string[] commandNames) { int count =commandNames.Length; for (int i = 0; i < count; i++) { RegisterCommand(commandNames[i], commandType); } } public void RemoveMultiCommand(params string[] commandName) { int count =commandName.Length; for (int i = 0; i < count; i++) { RemoveCommand(commandName[i]); } } public void SendMessageCommand(string message, object body = null) { m_controller.ExecuteCommand(newMessage(message, body)); } /// <summary> ///添加管理器 /// </summary> public void AddManager(string typeName, objectobj) { if (!m_Managers.ContainsKey(typeName)) { m_Managers.Add(typeName, obj); } } /// <summary> ///添加Unity对象 /// </summary> public T AddManager<T>(string typeName) whereT : Component { object result = null; m_Managers.TryGetValue(typeName, outresult); if (result != null) { return(T)result; } Component c = AppGameManager.AddComponent<T>(); m_Managers.Add(typeName, c); return default(T); } /// <summary> ///获取系统管理器 /// </summary> public T GetManager<T>(string typeName) where T : class{ if (!m_Managers.ContainsKey(typeName)) { return default(T); } object manager = null; m_Managers.TryGetValue(typeName, outmanager); return(T)manager; } /// <summary> ///删除管理器 /// </summary> public void RemoveManager(stringtypeName) { if (!m_Managers.ContainsKey(typeName)) { return; } object manager = null; m_Managers.TryGetValue(typeName, outmanager); Type type =manager.GetType(); if (type.IsSubclassOf(typeof(MonoBehaviour))) { GameObject.Destroy((Component)manager); } m_Managers.Remove(typeName); } }
usingUnityEngine; usingSystem.Collections; usingLuaFramework; public classManager : Base, IManager { //Use this for initialization voidStart () { } //Update is called once per frame voidUpdate () { } }
/* LuaFramework Code By Jarjin lee */ usingSystem; public classMessage : IMessage { public Message(stringname) : this(name, null, null) { } public Message(string name, objectbody) : this(name, body, null) { } public Message(string name, object body, stringtype) { m_name =name; m_body =body; m_type =type; } /// <summary> ///Get the string representation of the <c>Notification instance</c> /// </summary> /// <returns>The string representation of the <c>Notification</c>instance</returns> public override stringToString() { string msg = "Notification Name: " +Name; msg += "Body:" + ((Body == null) ? "null": Body.ToString()); msg += "Type:" + ((Type == null) ? "null": Type); returnmsg; } /// <summary> ///The name of the <c>Notification</c>instance /// </summary> public virtual stringName { get { returnm_name; } } /// <summary> ///The body of the <c>Notification</c>instance /// </summary> /// <remarks>This accessor is thread safe</remarks> public virtual objectBody { get { //Setting and getting of reference types is atomic, no need to lock here returnm_body; } set { //Setting and getting of reference types is atomic, no need to lock here m_body =value; } } /// <summary> ///The type of the <c>Notification</c>instance /// </summary> /// <remarks>This accessor is thread safe</remarks> public virtual stringType { get { //Setting and getting of reference types is atomic, no need to lock here returnm_type; } set { //Setting and getting of reference types is atomic, no need to lock here m_type =value; } } /// <summary> ///The name of the notification instance /// </summary> private stringm_name; /// <summary> ///The type of the notification instance /// </summary> private stringm_type; /// <summary> ///The body of the notification instance /// </summary> private objectm_body; }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingLuaInterface; usingLuaFramework; public classView : Base, IView { public virtual voidOnMessage(IMessage message) { } }
/* LuaFramework Code By Jarjin lee */ usingSystem; public interfaceICommand { voidExecute(IMessage message); }
/* LuaFramework Code By Jarjin leeibution 3.0 License */ usingSystem; usingSystem.Collections.Generic; public interfaceIController { void RegisterCommand(stringmessageName, Type commandType); void RegisterViewCommand(IView view, string[] commandNames); voidExecuteCommand(IMessage message); void RemoveCommand(stringmessageName); void RemoveViewCommand(IView view, string[] commandNames); bool HasCommand(stringmessageName); }
/* LuaFramework Code By Jarjin leeibution 3.0 License */ usingUnityEngine; usingSystem.Collections; public interfaceIManager { }
/* LuaFramework Code By Jarjin lee */ usingSystem; public interfaceIMessage { string Name { get; } object Body { get; set; } string Type { get; set; } stringToString(); }
usingSystem; public interfaceIView { voidOnMessage(IMessage message); }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; public classAppFacade : Facade { private staticAppFacade _instance; public AppFacade() : base() { } public staticAppFacade Instance { get{ if (_instance == null) { _instance = newAppFacade(); } return_instance; } } override protected voidInitFramework() { base.InitFramework(); RegisterCommand(NotiConst.START_UP, typeof(StartUpCommand)); } /// <summary> ///启动框架 /// </summary> public voidStartUp() { SendMessageCommand(NotiConst.START_UP); RemoveMultiCommand(NotiConst.START_UP); } }
usingSystem; usingSystem.Collections; namespaceLuaFramework { public interfaceITimerBehaviour { voidTimerUpdate(); } }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingLuaInterface; usingSystem.Reflection; usingSystem.IO; namespaceLuaFramework { public classGameManager : Manager { protected static bool initialize = false; private List<string> downloadFiles = new List<string>(); /// <summary> ///初始化游戏管理器 /// </summary> voidAwake() { Init(); } /// <summary> ///初始化 /// </summary> voidInit() { DontDestroyOnLoad(gameObject); //防止销毁自己 CheckExtractResource(); //释放资源 Screen.sleepTimeout =SleepTimeout.NeverSleep; Application.targetFrameRate =AppConst.GameFrameRate; } /// <summary> ///释放资源 /// </summary> public voidCheckExtractResource() { bool isExists = Directory.Exists(Util.DataPath) && Directory.Exists(Util.DataPath + "lua/") && File.Exists(Util.DataPath + "files.txt"); if (isExists ||AppConst.DebugMode) { StartCoroutine(OnUpdateResource()); return; //文件已经解压过了,自己可添加检查文件列表逻辑 } StartCoroutine(OnExtractResource()); //启动释放协成 } IEnumerator OnExtractResource() { string dataPath = Util.DataPath; //数据目录 string resPath = Util.AppContentPath(); //游戏包资源目录 if (Directory.Exists(dataPath)) Directory.Delete(dataPath, true); Directory.CreateDirectory(dataPath); string infile = resPath + "files.txt"; string outfile = dataPath + "files.txt"; if(File.Exists(outfile)) File.Delete(outfile); string message = "正在解包文件:>files.txt"; Debug.Log(infile); Debug.Log(outfile); if (Application.platform ==RuntimePlatform.Android) { WWW www = newWWW(infile); yield returnwww; if(www.isDone) { File.WriteAllBytes(outfile, www.bytes); } yield return 0; } else File.Copy(infile, outfile, true); yield return newWaitForEndOfFrame(); //释放所有文件到数据目录 string[] files =File.ReadAllLines(outfile); foreach (var file infiles) { string[] fs = file.Split('|'); infile = resPath + fs[0]; // outfile = dataPath + fs[0]; message = "正在解包文件:>" + fs[0]; Debug.Log("正在解包文件:>" +infile); facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); string dir =Path.GetDirectoryName(outfile); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); if (Application.platform ==RuntimePlatform.Android) { WWW www = newWWW(infile); yield returnwww; if(www.isDone) { File.WriteAllBytes(outfile, www.bytes); } yield return 0; } else{ if(File.Exists(outfile)) { File.Delete(outfile); } File.Copy(infile, outfile, true); } yield return newWaitForEndOfFrame(); } message = "解包完成!!!"; facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); yield return new WaitForSeconds(0.1f); message = string.Empty; //释放完成,开始启动更新资源 StartCoroutine(OnUpdateResource()); } /// <summary> ///启动更新下载,这里只是个思路演示,此处可启动线程下载更新 /// </summary> IEnumerator OnUpdateResource() { if (!AppConst.UpdateMode) { OnResourceInited(); yield break; } string dataPath = Util.DataPath; //数据目录 string url =AppConst.WebUrl; string message = string.Empty; string random = DateTime.Now.ToString("yyyymmddhhmmss"); string listUrl = url + "files.txt?v=" +random; Debug.LogWarning("LoadUpdate---->>>" +listUrl); WWW www = new WWW(listUrl); yield returnwww; if (www.error != null) { OnUpdateFailed(string.Empty); yield break; } if (!Directory.Exists(dataPath)) { Directory.CreateDirectory(dataPath); } File.WriteAllBytes(dataPath + "files.txt", www.bytes); string filesText =www.text; string[] files = filesText.Split(''); for (int i = 0; i < files.Length; i++) { if (string.IsNullOrEmpty(files[i])) continue; string[] keyValue = files[i].Split('|'); string f = keyValue[0]; string localfile = (dataPath +f).Trim(); string path =Path.GetDirectoryName(localfile); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string fileUrl = url + f + "?v=" +random; bool canUpdate = !File.Exists(localfile); if (!canUpdate) { string remoteMd5 = keyValue[1].Trim(); string localMd5 =Util.md5file(localfile); canUpdate = !remoteMd5.Equals(localMd5); if(canUpdate) File.Delete(localfile); } if (canUpdate) { //本地缺少文件 Debug.Log(fileUrl); message = "downloading>>" +fileUrl; facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); /* www = new WWW(fileUrl); yield return www; if (www.error != null) { OnUpdateFailed(path); // yield break; } File.WriteAllBytes(localfile, www.bytes); */ //这里都是资源文件,用线程下载 BeginDownload(fileUrl, localfile); while (!(IsDownOK(localfile))) { yield return newWaitForEndOfFrame(); } } } yield return newWaitForEndOfFrame(); message = "更新完成!!"; facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); OnResourceInited(); } void OnUpdateFailed(stringfile) { string message = "更新失败!>" +file; facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message); } /// <summary> ///是否下载完成 /// </summary> bool IsDownOK(stringfile) { returndownloadFiles.Contains(file); } /// <summary> ///线程下载 /// </summary> void BeginDownload(string url, string file) { //线程下载 object[] param = new object[2] { url, file }; ThreadEvent ev = newThreadEvent(); ev.Key =NotiConst.UPDATE_DOWNLOAD; ev.evParams.AddRange(param); ThreadManager.AddEvent(ev, OnThreadCompleted); //线程下载 } /// <summary> ///线程完成 /// </summary> /// <param name="data"></param> voidOnThreadCompleted(NotiData data) { switch(data.evName) { case NotiConst.UPDATE_EXTRACT: //解压一个完成 // break; case NotiConst.UPDATE_DOWNLOAD: //下载一个完成 downloadFiles.Add(data.evParam.ToString()); break; } } /// <summary> ///资源初始化结束 /// </summary> public voidOnResourceInited() { #if ASYNC_MODE ResManager.Initialize(AppConst.AssetDir, delegate() { Debug.Log("Initialize OK!!!"); this.OnInitialize(); }); #else ResManager.Initialize(); this.OnInitialize(); #endif } voidOnInitialize() { LuaManager.InitStart(); LuaManager.DoFile("Logic/Game"); //加载游戏 LuaManager.DoFile("Logic/Network"); //加载网络 NetManager.OnInit(); //初始化网络 Util.CallMethod("Game", "OnInitOK"); //初始化完成 initialize = true; //类对象池测试 var classObjPool = ObjPoolManager.CreatePool<TestObjectClass>(OnPoolGetElement, OnPoolPushElement); //方法1 //objPool.Release(new TestObjectClass("abcd", 100, 200f)); //var testObj1 = objPool.Get(); //方法2 ObjPoolManager.Release<TestObjectClass>(new TestObjectClass("abcd", 100, 200f)); var testObj1 = ObjPoolManager.Get<TestObjectClass>(); Debugger.Log("TestObjectClass--->>>" +testObj1.ToString()); //游戏对象池测试 var prefab = Resources.Load("TestGameObjectPrefab", typeof(GameObject)) asGameObject; var gameObjPool = ObjPoolManager.CreatePool("TestGameObject", 5, 10, prefab); var gameObj = Instantiate(prefab) asGameObject; gameObj.name = "TestGameObject_01"; gameObj.transform.localScale =Vector3.one; gameObj.transform.localPosition =Vector3.zero; ObjPoolManager.Release("TestGameObject", gameObj); var backObj = ObjPoolManager.Get("TestGameObject"); backObj.transform.SetParent(null); Debug.Log("TestGameObject--->>>" +backObj); } /// <summary> ///当从池子里面获取时 /// </summary> /// <param name="obj"></param> voidOnPoolGetElement(TestObjectClass obj) { Debug.Log("OnPoolGetElement--->>>" +obj); } /// <summary> ///当放回池子里面时 /// </summary> /// <param name="obj"></param> voidOnPoolPushElement(TestObjectClass obj) { Debug.Log("OnPoolPushElement--->>>" +obj); } /// <summary> ///析构函数 /// </summary> voidOnDestroy() { if (NetManager != null) { NetManager.Unload(); } if (LuaManager != null) { LuaManager.Close(); } Debug.Log("~GameManager was destroyed"); } } }
usingUnityEngine; usingSystem.Collections; usingLuaInterface; namespaceLuaFramework { public classLuaManager : Manager { privateLuaState lua; privateLuaLoader loader; private LuaLooper loop = null; //Use this for initialization voidAwake() { loader = newLuaLoader(); lua = newLuaState(); this.OpenLibs(); lua.LuaSetTop(0); LuaBinder.Bind(lua); DelegateFactory.Init(); LuaCoroutine.Register(lua, this); } public voidInitStart() { InitLuaPath(); InitLuaBundle(); this.lua.Start(); //启动LUAVM this.StartMain(); this.StartLooper(); } voidStartLooper() { loop = gameObject.AddComponent<LuaLooper>(); loop.luaState =lua; } //cjson 比较特殊,只new了一个table,没有注册库,这里注册一下 protected voidOpenCJson() { lua.LuaGetField(LuaIndexes.LUA_REGISTRYINDEX, "_LOADED"); lua.OpenLibs(LuaDLL.luaopen_cjson); lua.LuaSetField(-2, "cjson"); lua.OpenLibs(LuaDLL.luaopen_cjson_safe); lua.LuaSetField(-2, "cjson.safe"); } voidStartMain() { lua.DoFile("Main.lua"); LuaFunction main = lua.GetFunction("Main"); main.Call(); main.Dispose(); main = null; } /// <summary> ///初始化加载第三方库 /// </summary> voidOpenLibs() { lua.OpenLibs(LuaDLL.luaopen_pb); lua.OpenLibs(LuaDLL.luaopen_sproto_core); lua.OpenLibs(LuaDLL.luaopen_protobuf_c); lua.OpenLibs(LuaDLL.luaopen_lpeg); lua.OpenLibs(LuaDLL.luaopen_bit); lua.OpenLibs(LuaDLL.luaopen_socket_core); this.OpenCJson(); } /// <summary> ///初始化Lua代码加载路径 /// </summary> voidInitLuaPath() { if(AppConst.DebugMode) { string rootPath =AppConst.FrameworkRoot; lua.AddSearchPath(rootPath + "/Lua"); lua.AddSearchPath(rootPath + "/ToLua/Lua"); } else{ lua.AddSearchPath(Util.DataPath + "lua"); } } /// <summary> ///初始化LuaBundle /// </summary> voidInitLuaBundle() { if(loader.beZip) { loader.AddBundle("lua/lua.unity3d"); loader.AddBundle("lua/lua_math.unity3d"); loader.AddBundle("lua/lua_system.unity3d"); loader.AddBundle("lua/lua_system_reflection.unity3d"); loader.AddBundle("lua/lua_unityengine.unity3d"); loader.AddBundle("lua/lua_common.unity3d"); loader.AddBundle("lua/lua_logic.unity3d"); loader.AddBundle("lua/lua_view.unity3d"); loader.AddBundle("lua/lua_controller.unity3d"); loader.AddBundle("lua/lua_misc.unity3d"); loader.AddBundle("lua/lua_protobuf.unity3d"); loader.AddBundle("lua/lua_3rd_cjson.unity3d"); loader.AddBundle("lua/lua_3rd_luabitop.unity3d"); loader.AddBundle("lua/lua_3rd_pbc.unity3d"); loader.AddBundle("lua/lua_3rd_pblua.unity3d"); loader.AddBundle("lua/lua_3rd_sproto.unity3d"); } } public void DoFile(stringfilename) { lua.DoFile(filename); } //Update is called once per frame public object[] CallFunction(string funcName, params object[] args) { LuaFunction func =lua.GetFunction(funcName); if (func != null) { returnfunc.LazyCall(args); } return null; } public voidLuaGC() { lua.LuaGC(LuaGCOptions.LUA_GCCOLLECT); } public voidClose() { loop.Destroy(); loop = null; lua.Dispose(); lua = null; loader = null; } } }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; usingLuaInterface; namespaceLuaFramework { public classNetworkManager : Manager { privateSocketClient socket; static readonly object m_lockObject = new object(); static Queue<KeyValuePair<int, ByteBuffer>> mEvents = new Queue<KeyValuePair<int, ByteBuffer>>(); SocketClient SocketClient { get{ if (socket == null) socket = newSocketClient(); returnsocket; } } voidAwake() { Init(); } voidInit() { SocketClient.OnRegister(); } public voidOnInit() { CallMethod("Start"); } public voidUnload() { CallMethod("Unload"); } /// <summary> ///执行Lua方法 /// </summary> public object[] CallMethod(string func, params object[] args) { return Util.CallMethod("Network", func, args); } ///------------------------------------------------------------------------------------ public static void AddEvent(int_event, ByteBuffer data) { lock(m_lockObject) { mEvents.Enqueue(new KeyValuePair<int, ByteBuffer>(_event, data)); } } /// <summary> ///交给Command,这里不想关心发给谁。 /// </summary> voidUpdate() { if (mEvents.Count > 0) { while (mEvents.Count > 0) { KeyValuePair<int, ByteBuffer> _event =mEvents.Dequeue(); facade.SendMessageCommand(NotiConst.DISPATCH_MESSAGE, _event); } } } /// <summary> ///发送链接请求 /// </summary> public voidSendConnect() { SocketClient.SendConnect(); } /// <summary> ///发送SOCKET消息 /// </summary> public voidSendMessage(ByteBuffer buffer) { SocketClient.SendMessage(buffer); } /// <summary> ///析构函数 /// </summary> new voidOnDestroy() { SocketClient.OnRemove(); Debug.Log("~NetworkManager was destroy"); } } }
usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine.Events; namespaceLuaFramework { /// <summary> ///对象池管理器,分普通类对象池+资源游戏对象池 /// </summary> public classObjectPoolManager : Manager { private Transform m_PoolRootObject = null; private Dictionary<string, object> m_ObjectPools = new Dictionary<string, object>(); private Dictionary<string, GameObjectPool> m_GameObjectPools = new Dictionary<string, GameObjectPool>(); Transform PoolRootObject { get{ if (m_PoolRootObject == null) { var objectPool = new GameObject("ObjectPool"); objectPool.transform.SetParent(transform); objectPool.transform.localScale =Vector3.one; objectPool.transform.localPosition =Vector3.zero; m_PoolRootObject =objectPool.transform; } returnm_PoolRootObject; } } public GameObjectPool CreatePool(string poolName, int initSize, intmaxSize, GameObject prefab) { var pool = newGameObjectPool(poolName, prefab, initSize, maxSize, PoolRootObject); m_GameObjectPools[poolName] =pool; returnpool; } public GameObjectPool GetPool(stringpoolName) { if(m_GameObjectPools.ContainsKey(poolName)) { returnm_GameObjectPools[poolName]; } return null; } public GameObject Get(stringpoolName) { GameObject result = null; if(m_GameObjectPools.ContainsKey(poolName)) { GameObjectPool pool =m_GameObjectPools[poolName]; result =pool.NextAvailableObject(); if (result == null) { Debug.LogWarning("No object available in pool. Consider setting fixedSize to false.: " +poolName); } } else{ Debug.LogError("Invalid pool name specified: " +poolName); } returnresult; } public void Release(stringpoolName, GameObject go) { if(m_GameObjectPools.ContainsKey(poolName)) { GameObjectPool pool =m_GameObjectPools[poolName]; pool.ReturnObjectToPool(poolName, go); } else{ Debug.LogWarning("No pool available with name: " +poolName); } } ///----------------------------------------------------------------------------------------------- public ObjectPool<T> CreatePool<T>(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) where T : class{ var type = typeof(T); var pool = new ObjectPool<T>(actionOnGet, actionOnRelease); m_ObjectPools[type.Name] =pool; returnpool; } public ObjectPool<T> GetPool<T>() where T : class{ var type = typeof(T); ObjectPool<T> pool = null; if(m_ObjectPools.ContainsKey(type.Name)) { pool = m_ObjectPools[type.Name] as ObjectPool<T>; } returnpool; } public T Get<T>() where T : class{ var pool = GetPool<T>(); if (pool != null) { returnpool.Get(); } return default(T); } public void Release<T>(T obj) where T : class{ var pool = GetPool<T>(); if (pool != null) { pool.Release(obj); } } } }
usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingUnityEngine.UI; usingLuaInterface; namespaceLuaFramework { public classPanelManager : Manager { privateTransform parent; Transform Parent { get{ if (parent == null) { GameObject go = GameObject.FindWithTag("GuiCamera"); if (go != null) parent =go.transform; } returnparent; } } /// <summary> ///������壬������Դ������ /// </summary> /// <param name="type"></param> public void CreatePanel(string name, LuaFunction func = null) { string assetName = name + "Panel"; string abName = name.ToLower() +AppConst.ExtName; if (Parent.Find(name) != null) return; #if ASYNC_MODE ResManager.LoadPrefab(abName, assetName, delegate(UnityEngine.Object[] objs) { if (objs.Length == 0) return; GameObject prefab = objs[0] asGameObject; if (prefab == null) return; GameObject go = Instantiate(prefab) asGameObject; go.name =assetName; go.layer = LayerMask.NameToLayer("Default"); go.transform.SetParent(Parent); go.transform.localScale =Vector3.one; go.transform.localPosition =Vector3.zero; go.AddComponent<LuaBehaviour>(); if (func != null) func.Call(go); Debug.LogWarning("CreatePanel::>> " + name + " " +prefab); }); #else GameObject prefab = ResManager.LoadAsset<GameObject>(name, assetName); if (prefab == null) return; GameObject go = Instantiate(prefab) asGameObject; go.name =assetName; go.layer = LayerMask.NameToLayer("Default"); go.transform.SetParent(Parent); go.transform.localScale =Vector3.one; go.transform.localPosition =Vector3.zero; go.AddComponent<LuaBehaviour>(); if (func != null) func.Call(go); Debug.LogWarning("CreatePanel::>> " + name + " " +prefab); #endif } /// <summary> ///�ر���� /// </summary> /// <param name="name"></param> public void ClosePanel(stringname) { var panelName = name + "Panel"; var panelObj =Parent.Find(panelName); if (panelObj == null) return; Destroy(panelObj.gameObject); } } }
#if ASYNC_MODE usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingSystem; usingSystem.IO; usingLuaInterface; using UObject =UnityEngine.Object; public classAssetBundleInfo { publicAssetBundle m_AssetBundle; public intm_ReferencedCount; publicAssetBundleInfo(AssetBundle assetBundle) { m_AssetBundle =assetBundle; m_ReferencedCount = 0; } } namespaceLuaFramework { public classResourceManager : Manager { string m_BaseDownloadingURL = ""; string[] m_AllManifest = null; AssetBundleManifest m_AssetBundleManifest = null; Dictionary<string, string[]> m_Dependencies = new Dictionary<string, string[]>(); Dictionary<string, AssetBundleInfo> m_LoadedAssetBundles = new Dictionary<string, AssetBundleInfo>(); Dictionary<string, List<LoadAssetRequest>> m_LoadRequests = new Dictionary<string, List<LoadAssetRequest>>(); classLoadAssetRequest { publicType assetType; public string[] assetNames; publicLuaFunction luaFunc; public Action<UObject[]>sharpFunc; } //Load AssetBundleManifest. public void Initialize(stringmanifestName, Action initOK) { m_BaseDownloadingURL =Util.GetRelativePath(); LoadAsset<AssetBundleManifest>(manifestName, new string[] { "AssetBundleManifest" }, delegate(UObject[] objs) { if (objs.Length > 0) { m_AssetBundleManifest = objs[0] asAssetBundleManifest; m_AllManifest =m_AssetBundleManifest.GetAllAssetBundles(); } if (initOK != null) initOK(); }); } public void LoadPrefab(string abName, string assetName, Action<UObject[]>func) { LoadAsset<GameObject>(abName, new string[] { assetName }, func); } public void LoadPrefab(string abName, string[] assetNames, Action<UObject[]>func) { LoadAsset<GameObject>(abName, assetNames, func); } public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) { LoadAsset<GameObject>(abName, assetNames, null, func); } string GetRealAssetPath(stringabName) { if(abName.Equals(AppConst.AssetDir)) { returnabName; } abName =abName.ToLower(); if (!abName.EndsWith(AppConst.ExtName)) { abName +=AppConst.ExtName; } if (abName.Contains("/")) { returnabName; } //string[] paths = m_AssetBundleManifest.GetAllAssetBundles(); 产生GC,需要缓存结果 for (int i = 0; i < m_AllManifest.Length; i++) { int index = m_AllManifest[i].LastIndexOf('/'); string path = m_AllManifest[i].Remove(0, index + 1); //字符串操作函数都会产生GC if(path.Equals(abName)) { returnm_AllManifest[i]; } } Debug.LogError("GetRealAssetPath Error:>>" +abName); return null; } /// <summary> ///载入素材 /// </summary> void LoadAsset<T>(string abName, string[] assetNames, Action<UObject[]> action = null, LuaFunction func = null) whereT : UObject { abName =GetRealAssetPath(abName); LoadAssetRequest request = newLoadAssetRequest(); request.assetType = typeof(T); request.assetNames =assetNames; request.luaFunc =func; request.sharpFunc =action; List<LoadAssetRequest> requests = null; if (!m_LoadRequests.TryGetValue(abName, outrequests)) { requests = new List<LoadAssetRequest>(); requests.Add(request); m_LoadRequests.Add(abName, requests); StartCoroutine(OnLoadAsset<T>(abName)); } else{ requests.Add(request); } } IEnumerator OnLoadAsset<T>(string abName) whereT : UObject { Debug.Log(abName); AssetBundleInfo bundleInfo =GetLoadedAssetBundle(abName); if (bundleInfo == null) { yield return StartCoroutine(OnLoadAssetBundle(abName, typeof(T))); bundleInfo =GetLoadedAssetBundle(abName); if (bundleInfo == null) { m_LoadRequests.Remove(abName); Debug.LogError("OnLoadAsset--->>>" +abName); yield break; } } List<LoadAssetRequest> list = null; if (!m_LoadRequests.TryGetValue(abName, outlist)) { m_LoadRequests.Remove(abName); yield break; } for (int i = 0; i < list.Count; i++) { string[] assetNames =list[i].assetNames; List<UObject> result = new List<UObject>(); AssetBundle ab =bundleInfo.m_AssetBundle; for (int j = 0; j < assetNames.Length; j++) { string assetPath =assetNames[j]; AssetBundleRequest request =ab.LoadAssetAsync(assetPath, list[i].assetType); yield returnrequest; result.Add(request.asset); //T assetObj = ab.LoadAsset<T>(assetPath); //result.Add(assetObj); } if (list[i].sharpFunc != null) { list[i].sharpFunc(result.ToArray()); list[i].sharpFunc = null; } if (list[i].luaFunc != null) { list[i].luaFunc.Call((object)result.ToArray()); list[i].luaFunc.Dispose(); list[i].luaFunc = null; } bundleInfo.m_ReferencedCount++; } m_LoadRequests.Remove(abName); } IEnumerator OnLoadAssetBundle(stringabName, Type type) { string url = m_BaseDownloadingURL +abName; WWW download = null; if (type == typeof(AssetBundleManifest)) download = newWWW(url); else{ string[] dependencies =m_AssetBundleManifest.GetAllDependencies(abName); if (dependencies.Length > 0) { m_Dependencies.Add(abName, dependencies); for (int i = 0; i < dependencies.Length; i++) { string depName =dependencies[i]; AssetBundleInfo bundleInfo = null; if (m_LoadedAssetBundles.TryGetValue(depName, outbundleInfo)) { bundleInfo.m_ReferencedCount++; } else if (!m_LoadRequests.ContainsKey(depName)) { yield returnStartCoroutine(OnLoadAssetBundle(depName, type)); } } } download = WWW.LoadFromCacheOrDownload(url, m_AssetBundleManifest.GetAssetBundleHash(abName), 0); } yield returndownload; AssetBundle assetObj =download.assetBundle; if (assetObj != null) { m_LoadedAssetBundles.Add(abName, newAssetBundleInfo(assetObj)); } } AssetBundleInfo GetLoadedAssetBundle(stringabName) { AssetBundleInfo bundle = null; m_LoadedAssetBundles.TryGetValue(abName, outbundle); if (bundle == null) return null; //No dependencies are recorded, only the bundle itself is required. string[] dependencies = null; if (!m_Dependencies.TryGetValue(abName, outdependencies)) returnbundle; //Make sure all dependencies are loaded foreach (var dependency independencies) { AssetBundleInfo dependentBundle; m_LoadedAssetBundles.TryGetValue(dependency, outdependentBundle); if (dependentBundle == null) return null; } returnbundle; } /// <summary> ///此函数交给外部卸载专用,自己调整是否需要彻底清除AB /// </summary> /// <param name="abName"></param> /// <param name="isThorough"></param> public void UnloadAssetBundle(string abName, bool isThorough = false) { abName =GetRealAssetPath(abName); Debug.Log(m_LoadedAssetBundles.Count + "assetbundle(s) in memory before unloading " +abName); UnloadAssetBundleInternal(abName, isThorough); UnloadDependencies(abName, isThorough); Debug.Log(m_LoadedAssetBundles.Count + "assetbundle(s) in memory after unloading " +abName); } void UnloadDependencies(string abName, boolisThorough) { string[] dependencies = null; if (!m_Dependencies.TryGetValue(abName, outdependencies)) return; //Loop dependencies. foreach (var dependency independencies) { UnloadAssetBundleInternal(dependency, isThorough); } m_Dependencies.Remove(abName); } void UnloadAssetBundleInternal(string abName, boolisThorough) { AssetBundleInfo bundle =GetLoadedAssetBundle(abName); if (bundle == null) return; if (--bundle.m_ReferencedCount <= 0) { if(m_LoadRequests.ContainsKey(abName)) { return; //如果当前AB处于Async Loading过程中,卸载会崩溃,只减去引用计数即可 } bundle.m_AssetBundle.Unload(isThorough); m_LoadedAssetBundles.Remove(abName); Debug.Log(abName + "has been unloaded successfully"); } } } } #else usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingSystem.IO; usingLuaFramework; usingLuaInterface; using UObject =UnityEngine.Object; namespaceLuaFramework { public classResourceManager : Manager { private string[] m_Variants ={ }; privateAssetBundleManifest manifest; privateAssetBundle shared, assetbundle; private Dictionary<string, AssetBundle>bundles; voidAwake() { } /// <summary> ///初始化 /// </summary> public voidInitialize() { byte[] stream = null; string uri = string.Empty; bundles = new Dictionary<string, AssetBundle>(); uri = Util.DataPath +AppConst.AssetDir; if (!File.Exists(uri)) return; stream =File.ReadAllBytes(uri); assetbundle =AssetBundle.CreateFromMemoryImmediate(stream); manifest = assetbundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); } /// <summary> ///载入素材 /// </summary> public T LoadAsset<T>(string abname, string assetname) whereT : UnityEngine.Object { abname =abname.ToLower(); AssetBundle bundle =LoadAssetBundle(abname); return bundle.LoadAsset<T>(assetname); } public void LoadPrefab(string abName, string[] assetNames, LuaFunction func) { abName =abName.ToLower(); List<UObject> result = new List<UObject>(); for (int i = 0; i < assetNames.Length; i++) { UObject go = LoadAsset<UObject>(abName, assetNames[i]); if (go != null) result.Add(go); } if (func != null) func.Call((object)result.ToArray()); } /// <summary> ///载入AssetBundle /// </summary> /// <param name="abname"></param> /// <returns></returns> public AssetBundle LoadAssetBundle(stringabname) { if (!abname.EndsWith(AppConst.ExtName)) { abname +=AppConst.ExtName; } AssetBundle bundle = null; if (!bundles.ContainsKey(abname)) { byte[] stream = null; string uri = Util.DataPath +abname; Debug.LogWarning("LoadFile::>> " +uri); LoadDependencies(abname); stream =File.ReadAllBytes(uri); bundle = AssetBundle.CreateFromMemoryImmediate(stream); //关联数据的素材绑定 bundles.Add(abname, bundle); } else{ bundles.TryGetValue(abname, outbundle); } returnbundle; } /// <summary> ///载入依赖 /// </summary> /// <param name="name"></param> void LoadDependencies(stringname) { if (manifest == null) { Debug.LogError("Please initialize AssetBundleManifest by calling AssetBundleManager.Initialize()"); return; } //Get dependecies from the AssetBundleManifest object.. string[] dependencies =manifest.GetAllDependencies(name); if (dependencies.Length == 0) return; for (int i = 0; i < dependencies.Length; i++) dependencies[i] =RemapVariantName(dependencies[i]); //Record and load all dependencies. for (int i = 0; i < dependencies.Length; i++) { LoadAssetBundle(dependencies[i]); } } //Remaps the asset bundle name to the best fitting asset bundle variant. string RemapVariantName(stringassetBundleName) { string[] bundlesWithVariant =manifest.GetAllAssetBundlesWithVariant(); //If the asset bundle doesn't have variant, simply return. if (System.Array.IndexOf(bundlesWithVariant, assetBundleName) < 0) returnassetBundleName; string[] split = assetBundleName.Split('.'); int bestFit = int.MaxValue; int bestFitIndex = -1; //Loop all the assetBundles with variant to find the best fit variant assetBundle. for (int i = 0; i < bundlesWithVariant.Length; i++) { string[] curSplit = bundlesWithVariant[i].Split('.'); if (curSplit[0] != split[0]) continue; int found = System.Array.IndexOf(m_Variants, curSplit[1]); if (found != -1 && found <bestFit) { bestFit =found; bestFitIndex =i; } } if (bestFitIndex != -1) returnbundlesWithVariant[bestFitIndex]; else returnassetBundleName; } /// <summary> ///销毁资源 /// </summary> voidOnDestroy() { if (shared != null) shared.Unload(true); if (manifest != null) manifest = null; Debug.Log("~ResourceManager was destroy!"); } } } #endif
usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; namespaceLuaFramework { public classSoundManager : Manager { privateAudioSource audio; private Hashtable sounds = newHashtable(); voidStart() { audio = GetComponent<AudioSource>(); } /// <summary> ///添加一个声音 /// </summary> void Add(stringkey, AudioClip value) { if (sounds[key] != null || value == null) return; sounds.Add(key, value); } /// <summary> ///获取一个声音 /// </summary> AudioClip Get(stringkey) { if (sounds[key] == null) return null; return sounds[key] asAudioClip; } /// <summary> ///载入一个音频 /// </summary> public AudioClip LoadAudioClip(stringpath) { AudioClip ac =Get(path); if (ac == null) { ac = (AudioClip)Resources.Load(path, typeof(AudioClip)); Add(path, ac); } returnac; } /// <summary> ///是否播放背景音乐,默认是1:播放 /// </summary> /// <returns></returns> public boolCanPlayBackSound() { string key = AppConst.AppPrefix + "BackSound"; int i = PlayerPrefs.GetInt(key, 1); return i == 1; } /// <summary> ///播放背景音乐 /// </summary> /// <param name="canPlay"></param> public void PlayBacksound(string name, boolcanPlay) { if (audio.clip != null) { if (name.IndexOf(audio.clip.name) > -1) { if (!canPlay) { audio.Stop(); audio.clip = null; Util.ClearMemory(); } return; } } if(canPlay) { audio.loop = true; audio.clip =LoadAudioClip(name); audio.Play(); } else{ audio.Stop(); audio.clip = null; Util.ClearMemory(); } } /// <summary> ///是否播放音效,默认是1:播放 /// </summary> /// <returns></returns> public boolCanPlaySoundEffect() { string key = AppConst.AppPrefix + "SoundEffect"; int i = PlayerPrefs.GetInt(key, 1); return i == 1; } /// <summary> ///播放音频剪辑 /// </summary> /// <param name="clip"></param> /// <param name="position"></param> public voidPlay(AudioClip clip, Vector3 position) { if (!CanPlaySoundEffect()) return; AudioSource.PlayClipAtPoint(clip, position); } } }
usingSystem.Collections; usingSystem.Threading; usingSystem.Collections.Generic; usingSystem.IO; usingSystem.Diagnostics; usingSystem.Net; usingSystem; public classThreadEvent { public stringKey; public List<object> evParams = new List<object>(); } public classNotiData { public stringevName; public objectevParam; public NotiData(string name, objectparam) { this.evName =name; this.evParam =param; } } namespaceLuaFramework { /// <summary> ///当前线程管理器,同时只能做一个任务 /// </summary> public classThreadManager : Manager { privateThread thread; private Action<NotiData>func; private Stopwatch sw = newStopwatch(); private string currDownFile = string.Empty; static readonly object m_lockObject = new object(); static Queue<ThreadEvent> events = new Queue<ThreadEvent>(); delegate voidThreadSyncEvent(NotiData data); privateThreadSyncEvent m_SyncEvent; voidAwake() { m_SyncEvent =OnSyncEvent; thread = newThread(OnUpdate); } //Use this for initialization voidStart() { thread.Start(); } /// <summary> ///添加到事件队列 /// </summary> public void AddEvent(ThreadEvent ev, Action<NotiData>func) { lock(m_lockObject) { this.func =func; events.Enqueue(ev); } } /// <summary> ///通知事件 /// </summary> /// <param name="state"></param> private voidOnSyncEvent(NotiData data) { if (this.func != null) func(data); //回调逻辑层 facade.SendMessageCommand(data.evName, data.evParam); //通知View层 } //Update is called once per frame voidOnUpdate() { while (true) { lock(m_lockObject) { if (events.Count > 0) { ThreadEvent e =events.Dequeue(); try{ switch(e.Key) { case NotiConst.UPDATE_EXTRACT: { //解压文件 OnExtractFile(e.evParams); } break; case NotiConst.UPDATE_DOWNLOAD: { //下载文件 OnDownloadFile(e.evParams); } break; } } catch(System.Exception ex) { UnityEngine.Debug.LogError(ex.Message); } } } Thread.Sleep(1); } } /// <summary> ///下载文件 /// </summary> void OnDownloadFile(List<object>evParams) { string url = evParams[0].ToString(); currDownFile = evParams[1].ToString(); using (WebClient client = newWebClient()) { sw.Start(); client.DownloadProgressChanged += newDownloadProgressChangedEventHandler(ProgressChanged); client.DownloadFileAsync(newSystem.Uri(url), currDownFile); } } private void ProgressChanged(objectsender, DownloadProgressChangedEventArgs e) { //UnityEngine.Debug.Log(e.ProgressPercentage); /* UnityEngine.Debug.Log(string.Format("{0} MB's / {1} MB's", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"))); */ //float value = (float)e.ProgressPercentage / 100f; string value = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")); NotiData data = newNotiData(NotiConst.UPDATE_PROGRESS, value); if (m_SyncEvent != null) m_SyncEvent(data); if (e.ProgressPercentage == 100 && e.BytesReceived ==e.TotalBytesToReceive) { sw.Reset(); data = newNotiData(NotiConst.UPDATE_DOWNLOAD, currDownFile); if (m_SyncEvent != null) m_SyncEvent(data); } } /// <summary> ///调用方法 /// </summary> void OnExtractFile(List<object>evParams) { UnityEngine.Debug.LogWarning("Thread evParams: >>" +evParams.Count); ///------------------通知更新面板解压完成-------------------- NotiData data = new NotiData(NotiConst.UPDATE_DOWNLOAD, null); if (m_SyncEvent != null) m_SyncEvent(data); } /// <summary> ///应用程序退出 /// </summary> voidOnDestroy() { thread.Abort(); } } }
usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; namespaceLuaFramework { public classTimerInfo { public longtick; public boolstop; public booldelete; publicObject target; public stringclassName; public TimerInfo(stringclassName, Object target) { this.className =className; this.target =target; delete = false; } } public classTimerManager : Manager { private float interval = 0; private List<TimerInfo> objects = new List<TimerInfo>(); public floatInterval { get { returninterval; } set { interval =value; } } //Use this for initialization voidStart() { StartTimer(AppConst.TimerInterval); } /// <summary> ///启动计时器 /// </summary> /// <param name="interval"></param> public void StartTimer(floatvalue) { interval =value; InvokeRepeating("Run", 0, interval); } /// <summary> ///停止计时器 /// </summary> public voidStopTimer() { CancelInvoke("Run"); } /// <summary> ///添加计时器事件 /// </summary> /// <param name="name"></param> /// <param name="o"></param> public voidAddTimerEvent(TimerInfo info) { if (!objects.Contains(info)) { objects.Add(info); } } /// <summary> ///删除计时器事件 /// </summary> /// <param name="name"></param> public voidRemoveTimerEvent(TimerInfo info) { if (objects.Contains(info) && info != null) { info.delete = true; } } /// <summary> ///停止计时器事件 /// </summary> /// <param name="info"></param> public voidStopTimerEvent(TimerInfo info) { if (objects.Contains(info) && info != null) { info.stop = true; } } /// <summary> ///继续计时器事件 /// </summary> /// <param name="info"></param> public voidResumeTimerEvent(TimerInfo info) { if (objects.Contains(info) && info != null) { info.delete = false; } } /// <summary> ///计时器运行 /// </summary> voidRun() { if (objects.Count == 0) return; for (int i = 0; i < objects.Count; i++) { TimerInfo o =objects[i]; if (o.delete || o.stop) { continue; } ITimerBehaviour timer = o.target asITimerBehaviour; timer.TimerUpdate(); o.tick++; } /////////////////////////清除标记为删除的事件/////////////////////////// for (int i = objects.Count - 1; i >= 0; i--) { if(objects[i].delete) { objects.Remove(objects[i]); } } } } }
usingUnityEngine; usingSystem.Collections; usingSystem.IO; usingSystem.Text; usingSystem; usingLuaInterface; namespaceLuaFramework { public classByteBuffer { MemoryStream stream = null; BinaryWriter writer = null; BinaryReader reader = null; publicByteBuffer() { stream = newMemoryStream(); writer = newBinaryWriter(stream); } public ByteBuffer(byte[] data) { if (data != null) { stream = newMemoryStream(data); reader = newBinaryReader(stream); } else{ stream = newMemoryStream(); writer = newBinaryWriter(stream); } } public voidClose() { if (writer != null) writer.Close(); if (reader != null) reader.Close(); stream.Close(); writer = null; reader = null; stream = null; } public void WriteByte(bytev) { writer.Write(v); } public void WriteInt(intv) { writer.Write((int)v); } public void WriteShort(ushortv) { writer.Write((ushort)v); } public void WriteLong(longv) { writer.Write((long)v); } public void WriteFloat(floatv) { byte[] temp =BitConverter.GetBytes(v); Array.Reverse(temp); writer.Write(BitConverter.ToSingle(temp, 0)); } public void WriteDouble(doublev) { byte[] temp =BitConverter.GetBytes(v); Array.Reverse(temp); writer.Write(BitConverter.ToDouble(temp, 0)); } public void WriteString(stringv) { byte[] bytes =Encoding.UTF8.GetBytes(v); writer.Write((ushort)bytes.Length); writer.Write(bytes); } public void WriteBytes(byte[] v) { writer.Write((int)v.Length); writer.Write(v); } public voidWriteBuffer(LuaByteBuffer strBuffer) { WriteBytes(strBuffer.buffer); } public byteReadByte() { returnreader.ReadByte(); } public intReadInt() { return (int)reader.ReadInt32(); } public ushortReadShort() { return (ushort)reader.ReadInt16(); } public longReadLong() { return (long)reader.ReadInt64(); } public floatReadFloat() { byte[] temp =BitConverter.GetBytes(reader.ReadSingle()); Array.Reverse(temp); return BitConverter.ToSingle(temp, 0); } public doubleReadDouble() { byte[] temp =BitConverter.GetBytes(reader.ReadDouble()); Array.Reverse(temp); return BitConverter.ToDouble(temp, 0); } public stringReadString() { ushort len =ReadShort(); byte[] buffer = new byte[len]; buffer =reader.ReadBytes(len); returnEncoding.UTF8.GetString(buffer); } public byte[] ReadBytes() { int len =ReadInt(); returnreader.ReadBytes(len); } publicLuaByteBuffer ReadBuffer() { byte[] bytes =ReadBytes(); return newLuaByteBuffer(bytes); } public byte[] ToBytes() { writer.Flush(); returnstream.ToArray(); } public voidFlush() { writer.Flush(); } } }
/* * Copyright (c) 2008 Jonathan Wagner * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ usingSystem; namespaceLuaFramework { public classConverter { public staticInt32 GetBigEndian(Int32 value) { if(BitConverter.IsLittleEndian) { returnswapByteOrder(value); } else{ returnvalue; } } public staticUInt16 GetBigEndian(UInt16 value) { if(BitConverter.IsLittleEndian) { returnswapByteOrder(value); } else{ returnvalue; } } public staticUInt32 GetBigEndian(UInt32 value) { if(BitConverter.IsLittleEndian) { returnswapByteOrder(value); } else{ returnvalue; } } public staticInt64 GetBigEndian(Int64 value) { if(BitConverter.IsLittleEndian) { returnswapByteOrder(value); } else{ returnvalue; } } public staticDouble GetBigEndian(Double value) { if(BitConverter.IsLittleEndian) { returnswapByteOrder(value); } else{ returnvalue; } } public static float GetBigEndian(floatvalue) { if(BitConverter.IsLittleEndian) { return swapByteOrder((int)value); } else{ returnvalue; } } public staticInt32 GetLittleEndian(Int32 value) { if(BitConverter.IsLittleEndian) { returnvalue; } else{ returnswapByteOrder(value); } } public staticUInt32 GetLittleEndian(UInt32 value) { if(BitConverter.IsLittleEndian) { returnvalue; } else{ returnswapByteOrder(value); } } public staticUInt16 GetLittleEndian(UInt16 value) { if(BitConverter.IsLittleEndian) { returnvalue; } else{ returnswapByteOrder(value); } } public staticDouble GetLittleEndian(Double value) { if(BitConverter.IsLittleEndian) { returnvalue; } else{ returnswapByteOrder(value); } } private staticInt32 swapByteOrder(Int32 value) { Int32 swap = (Int32)((0x000000FF) & (value >> 24) | (0x0000FF00) & (value >> 8) | (0x00FF0000) & (value << 8) | (0xFF000000) & (value << 24)); returnswap; } private staticInt64 swapByteOrder(Int64 value) { UInt64 uvalue =(UInt64)value; UInt64 swap = ((0x00000000000000FF) & (uvalue >> 56) | (0x000000000000FF00) & (uvalue >> 40) | (0x0000000000FF0000) & (uvalue >> 24) | (0x00000000FF000000) & (uvalue >> 8) | (0x000000FF00000000) & (uvalue << 8) | (0x0000FF0000000000) & (uvalue << 24) | (0x00FF000000000000) & (uvalue << 40) | (0xFF00000000000000) & (uvalue << 56)); return(Int64)swap; } private staticUInt16 swapByteOrder(UInt16 value) { return (UInt16)((0x00FF & (value >> 8)) | (0xFF00 & (value << 8))); } private staticUInt32 swapByteOrder(UInt32 value) { UInt32 swap = ((0x000000FF) & (value >> 24) | (0x0000FF00) & (value >> 8) | (0x00FF0000) & (value << 8) | (0xFF000000) & (value << 24)); returnswap; } private staticDouble swapByteOrder(Double value) { Byte[] buffer =BitConverter.GetBytes(value); Array.Reverse(buffer, 0, buffer.Length); return BitConverter.ToDouble(buffer, 0); } } }
namespaceLuaFramework { public classProtocal { ///BUILD TABLE public const int Connect = 101; //连接服务器 public const int Exception = 102; //异常掉线 public const int Disconnect = 103; //正常断线 } }
usingUnityEngine; usingSystem; usingSystem.IO; usingSystem.Net; usingSystem.Net.Sockets; usingSystem.Collections; usingSystem.Collections.Generic; usingLuaFramework; public enumDisType { Exception, Disconnect, } public classSocketClient { private TcpClient client = null; private NetworkStream outStream = null; privateMemoryStream memStream; privateBinaryReader reader; private const int MAX_READ = 8192; private byte[] byteBuffer = new byte[MAX_READ]; public static bool loggedIn = false; //Use this for initialization publicSocketClient() { } /// <summary> ///注册代理 /// </summary> public voidOnRegister() { memStream = newMemoryStream(); reader = newBinaryReader(memStream); } /// <summary> ///移除代理 /// </summary> public voidOnRemove() { this.Close(); reader.Close(); memStream.Close(); } /// <summary> ///连接服务器 /// </summary> void ConnectServer(string host, intport) { client = null; try{ IPAddress[] address =Dns.GetHostAddresses(host); if (address.Length == 0) { Debug.LogError("host invalid"); return; } if (address[0].AddressFamily ==AddressFamily.InterNetworkV6) { client = newTcpClient(AddressFamily.InterNetworkV6); } else{ client = newTcpClient(AddressFamily.InterNetwork); } client.SendTimeout = 1000; client.ReceiveTimeout = 1000; client.NoDelay = true; client.BeginConnect(host, port, new AsyncCallback(OnConnect), null); } catch(Exception e) { Close(); Debug.LogError(e.Message); } } /// <summary> ///连接上服务器 /// </summary> voidOnConnect(IAsyncResult asr) { outStream =client.GetStream(); client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null); NetworkManager.AddEvent(Protocal.Connect, newByteBuffer()); } /// <summary> ///写数据 /// </summary> void WriteMessage(byte[] message) { MemoryStream ms = null; using (ms = newMemoryStream()) { ms.Position = 0; BinaryWriter writer = newBinaryWriter(ms); ushort msglen = (ushort)message.Length; writer.Write(msglen); writer.Write(message); writer.Flush(); if (client != null &&client.Connected) { //NetworkStream stream = client.GetStream(); byte[] payload =ms.ToArray(); outStream.BeginWrite(payload, 0, payload.Length, new AsyncCallback(OnWrite), null); } else{ Debug.LogError("client.connected----->>false"); } } } /// <summary> ///读取消息 /// </summary> voidOnRead(IAsyncResult asr) { int bytesRead = 0; try{ lock (client.GetStream()) { //读取字节流到缓冲区 bytesRead =client.GetStream().EndRead(asr); } if (bytesRead < 1) { //包尺寸有问题,断线处理 OnDisconnected(DisType.Disconnect, "bytesRead < 1"); return; } OnReceive(byteBuffer, bytesRead); //分析数据包内容,抛给逻辑层 lock (client.GetStream()) { //分析完,再次监听服务器发过来的新消息 Array.Clear(byteBuffer, 0, byteBuffer.Length); //清空数组 client.GetStream().BeginRead(byteBuffer, 0, MAX_READ, new AsyncCallback(OnRead), null); } } catch(Exception ex) { //PrintBytes(); OnDisconnected(DisType.Exception, ex.Message); } } /// <summary> ///丢失链接 /// </summary> void OnDisconnected(DisType dis, stringmsg) { Close(); //关掉客户端链接 int protocal = dis == DisType.Exception ? Protocal.Exception : Protocal.Disconnect; ByteBuffer buffer = newByteBuffer(); buffer.WriteShort((ushort)protocal); NetworkManager.AddEvent(protocal, buffer); Debug.LogError("Connection was closed by the server:>" + msg + "Distype:>" +dis); } /// <summary> ///打印字节 /// </summary> /// <param name="bytes"></param> voidPrintBytes() { string returnStr = string.Empty; for (int i = 0; i < byteBuffer.Length; i++) { returnStr += byteBuffer[i].ToString("X2"); } Debug.LogError(returnStr); } /// <summary> ///向链接写入数据流 /// </summary> voidOnWrite(IAsyncResult r) { try{ outStream.EndWrite(r); } catch(Exception ex) { Debug.LogError("OnWrite--->>>" +ex.Message); } } /// <summary> ///接收到消息 /// </summary> void OnReceive(byte[] bytes, intlength) { memStream.Seek(0, SeekOrigin.End); memStream.Write(bytes, 0, length); //Reset to beginning memStream.Seek(0, SeekOrigin.Begin); while (RemainingBytes() > 2) { ushort messageLen =reader.ReadUInt16(); if (RemainingBytes() >=messageLen) { MemoryStream ms = newMemoryStream(); BinaryWriter writer = newBinaryWriter(ms); writer.Write(reader.ReadBytes(messageLen)); ms.Seek(0, SeekOrigin.Begin); OnReceivedMessage(ms); } else{ //Back up the position two bytes memStream.Position = memStream.Position - 2; break; } } //Create a new stream with any leftover bytes byte[] leftover = reader.ReadBytes((int)RemainingBytes()); memStream.SetLength(0); //Clear memStream.Write(leftover, 0, leftover.Length); } /// <summary> ///剩余的字节 /// </summary> private longRemainingBytes() { return memStream.Length -memStream.Position; } /// <summary> ///接收到消息 /// </summary> /// <param name="ms"></param> voidOnReceivedMessage(MemoryStream ms) { BinaryReader r = newBinaryReader(ms); byte[] message = r.ReadBytes((int)(ms.Length -ms.Position)); //int msglen = message.Length; ByteBuffer buffer = newByteBuffer(message); int mainId =buffer.ReadShort(); NetworkManager.AddEvent(mainId, buffer); } /// <summary> ///会话发送 /// </summary> void SessionSend(byte[] bytes) { WriteMessage(bytes); } /// <summary> ///关闭链接 /// </summary> public voidClose() { if (client != null) { if(client.Connected) client.Close(); client = null; } loggedIn = false; } /// <summary> ///发送连接请求 /// </summary> public voidSendConnect() { ConnectServer(AppConst.SocketAddress, AppConst.SocketPort); } /// <summary> ///发送消息 /// </summary> public voidSendMessage(ByteBuffer buffer) { SessionSend(buffer.ToBytes()); buffer.Close(); } }
usingUnityEngine; usingSystem; usingSystem.Collections; usingSystem.Collections.Generic; namespaceLuaFramework { [Serializable] public classPoolInfo { public stringpoolName; publicGameObject prefab; public intpoolSize; public boolfixedSize; } public classGameObjectPool { private intmaxSize; private intpoolSize; private stringpoolName; privateTransform poolRoot; privateGameObject poolObjectPrefab; private Stack<GameObject> availableObjStack = new Stack<GameObject>(); public GameObjectPool(string poolName, GameObject poolObjectPrefab, int initCount, intmaxSize, Transform pool) { this.poolName =poolName; this.poolSize =initCount; this.maxSize =maxSize; this.poolRoot =pool; this.poolObjectPrefab =poolObjectPrefab; //populate the pool for(int index = 0; index < initCount; index++) { AddObjectToPool(NewObjectInstance()); } } //o(1) private voidAddObjectToPool(GameObject go) { //add to pool go.SetActive(false); availableObjStack.Push(go); go.transform.SetParent(poolRoot, false); } privateGameObject NewObjectInstance() { return GameObject.Instantiate(poolObjectPrefab) asGameObject; } publicGameObject NextAvailableObject() { GameObject go = null; if(availableObjStack.Count > 0) { go =availableObjStack.Pop(); } else{ Debug.LogWarning("No object available & cannot grow pool: " +poolName); } go.SetActive(true); returngo; } //o(1) public void ReturnObjectToPool(stringpool, GameObject po) { if(poolName.Equals(pool)) { AddObjectToPool(po); } else{ Debug.LogError(string.Format("Trying to add object to incorrect pool {0} ", poolName)); } } } }
usingSystem.Collections.Generic; usingUnityEngine; usingUnityEngine.Events; namespaceLuaFramework { public class ObjectPool<T> where T : class { private readonly Stack<T> m_Stack = new Stack<T>(); private readonly UnityAction<T>m_ActionOnGet; private readonly UnityAction<T>m_ActionOnRelease; public int countAll { get; private set; } public int countActive { get { return countAll -countInactive; } } public int countInactive { get { returnm_Stack.Count; } } public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T>actionOnRelease) { m_ActionOnGet =actionOnGet; m_ActionOnRelease =actionOnRelease; } publicT Get() { T element =m_Stack.Pop(); if (m_ActionOnGet != null) m_ActionOnGet(element); returnelement; } public voidRelease(T element) { if (m_Stack.Count > 0 &&ReferenceEquals(m_Stack.Peek(), element)) Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); if (m_ActionOnRelease != null) m_ActionOnRelease(element); m_Stack.Push(element); } } }
usingUnityEngine; usingSystem.Collections; namespaceLuaFramework { public classTestObjectClass { public stringname; public intvalue1; public floatvalue2; //Use this for initialization public TestObjectClass(string name, int value1, floatvalue2) { this.name =name; this.value1 =value1; this.value2 =value2; } public stringToString() { return string.Format("name={0} value1={1} = value2={2}", name, value1, value2); } } }
usingUnityEngine; usingSystem.Collections.Generic; usingSystem.Reflection; usingLuaInterface; usingSystem; namespaceLuaFramework { public static classLuaHelper { /// <summary> ///getType /// </summary> /// <param name="classname"></param> /// <returns></returns> public static System.Type GetType(stringclassname) { Assembly assb = Assembly.GetExecutingAssembly(); //.GetExecutingAssembly(); System.Type t = null; t =assb.GetType(classname); ; if (t == null) { t =assb.GetType(classname); } returnt; } /// <summary> ///面板管理器 /// </summary> public staticPanelManager GetPanelManager() { return AppFacade.Instance.GetManager<PanelManager>(ManagerName.Panel); } /// <summary> ///资源管理器 /// </summary> public staticResourceManager GetResManager() { return AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource); } /// <summary> ///网络管理器 /// </summary> public staticNetworkManager GetNetManager() { return AppFacade.Instance.GetManager<NetworkManager>(ManagerName.Network); } /// <summary> ///音乐管理器 /// </summary> public staticSoundManager GetSoundManager() { return AppFacade.Instance.GetManager<SoundManager>(ManagerName.Sound); } /// <summary> ///pbc/pblua函数回调 /// </summary> /// <param name="func"></param> public static voidOnCallLuaFunc(LuaByteBuffer data, LuaFunction func) { if (func != null) func.Call(data); Debug.LogWarning("OnCallLuaFunc length:>>" +data.buffer.Length); } /// <summary> ///cjson函数回调 /// </summary> /// <param name="data"></param> /// <param name="func"></param> public static void OnJsonCallFunc(stringdata, LuaFunction func) { Debug.LogWarning("OnJsonCallback data:>>" + data + "lenght:>>" +data.Length); if (func != null) func.Call(data); } } }
usingUnityEngine; usingSystem; usingSystem.IO; usingSystem.Text; usingSystem.Collections; usingSystem.Collections.Generic; usingSystem.Security.Cryptography; usingSystem.Text.RegularExpressions; usingLuaInterface; usingLuaFramework; #if UNITY_EDITOR usingUnityEditor; #endif namespaceLuaFramework { public classUtil { private static List<string> luaPaths = new List<string>(); public static int Int(objecto) { returnConvert.ToInt32(o); } public static float Float(objecto) { return (float)Math.Round(Convert.ToSingle(o), 2); } public static long Long(objecto) { returnConvert.ToInt64(o); } public static int Random(int min, intmax) { returnUnityEngine.Random.Range(min, max); } public static float Random(float min, floatmax) { returnUnityEngine.Random.Range(min, max); } public static string Uid(stringuid) { int position = uid.LastIndexOf('_'); return uid.Remove(0, position + 1); } public static longGetTime() { TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1, 0, 0, 0).Ticks); return (long)ts.TotalMilliseconds; } /// <summary> ///搜索子物体组件-GameObject版 /// </summary> public static T Get<T>(GameObject go, string subnode) whereT : Component { if (go != null) { Transform sub =go.transform.Find(subnode); if (sub != null) return sub.GetComponent<T>(); } return null; } /// <summary> ///搜索子物体组件-Transform版 /// </summary> public static T Get<T>(Transform go, string subnode) whereT : Component { if (go != null) { Transform sub =go.Find(subnode); if (sub != null) return sub.GetComponent<T>(); } return null; } /// <summary> ///搜索子物体组件-Component版 /// </summary> public static T Get<T>(Component go, string subnode) whereT : Component { return go.transform.Find(subnode).GetComponent<T>(); } /// <summary> ///添加组件 /// </summary> public static T Add<T>(GameObject go) whereT : Component { if (go != null) { T[] ts = go.GetComponents<T>(); for (int i = 0; i < ts.Length; i++) { if (ts[i] != null) GameObject.Destroy(ts[i]); } return go.gameObject.AddComponent<T>(); } return null; } /// <summary> ///添加组件 /// </summary> public static T Add<T>(Transform go) whereT : Component { return Add<T>(go.gameObject); } /// <summary> ///查找子对象 /// </summary> public static GameObject Child(GameObject go, stringsubnode) { returnChild(go.transform, subnode); } /// <summary> ///查找子对象 /// </summary> public static GameObject Child(Transform go, stringsubnode) { Transform tran =go.Find(subnode); if (tran == null) return null; returntran.gameObject; } /// <summary> ///取平级对象 /// </summary> public static GameObject Peer(GameObject go, stringsubnode) { returnPeer(go.transform, subnode); } /// <summary> ///取平级对象 /// </summary> public static GameObject Peer(Transform go, stringsubnode) { Transform tran =go.parent.Find(subnode); if (tran == null) return null; returntran.gameObject; } /// <summary> ///计算字符串的MD5值 /// </summary> public static string md5(stringsource) { MD5CryptoServiceProvider md5 = newMD5CryptoServiceProvider(); byte[] data =System.Text.Encoding.UTF8.GetBytes(source); byte[] md5Data = md5.ComputeHash(data, 0, data.Length); md5.Clear(); string destString = ""; for (int i = 0; i < md5Data.Length; i++) { destString += System.Convert.ToString(md5Data[i], 16).PadLeft(2, '0'); } destString = destString.PadLeft(32, '0'); returndestString; } /// <summary> ///计算文件的MD5值 /// </summary> public static string md5file(stringfile) { try{ FileStream fs = newFileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = newSystem.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal =md5.ComputeHash(fs); fs.Close(); StringBuilder sb = newStringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } returnsb.ToString(); } catch(Exception ex) { throw new Exception("md5file() fail, error:" +ex.Message); } } /// <summary> ///清除所有子节点 /// </summary> public static voidClearChild(Transform go) { if (go == null) return; for (int i = go.childCount - 1; i >= 0; i--) { GameObject.Destroy(go.GetChild(i).gameObject); } } /// <summary> ///清理内存 /// </summary> public static voidClearMemory() { GC.Collect(); Resources.UnloadUnusedAssets(); LuaManager mgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua); if (mgr != null) mgr.LuaGC(); } /// <summary> ///取得数据存放目录 /// </summary> public static stringDataPath { get{ string game =AppConst.AppName.ToLower(); if(Application.isMobilePlatform) { return Application.persistentDataPath + "/" + game + "/"; } if(AppConst.DebugMode) { return Application.dataPath + "/" + AppConst.AssetDir + "/"; } if (Application.platform ==RuntimePlatform.OSXEditor) { int i = Application.dataPath.LastIndexOf('/'); return Application.dataPath.Substring(0, i + 1) + game + "/"; } return "c:/" + game + "/"; } } public static stringGetRelativePath() { if(Application.isEditor) return "file://" + System.Environment.CurrentDirectory.Replace("\", "/") + "/Assets/" + AppConst.AssetDir + "/"; else if (Application.isMobilePlatform ||Application.isConsolePlatform) return "file:///" +DataPath; else //For standalone player. return "file://" + Application.streamingAssetsPath + "/"; } /// <summary> ///取得行文本 /// </summary> public static string GetFileText(stringpath) { returnFile.ReadAllText(path); } /// <summary> ///网络可用 /// </summary> public static boolNetAvailable { get{ return Application.internetReachability !=NetworkReachability.NotReachable; } } /// <summary> ///是否是无线 /// </summary> public static boolIsWifi { get{ return Application.internetReachability ==NetworkReachability.ReachableViaLocalAreaNetwork; } } /// <summary> ///应用程序内容路径 /// </summary> public static stringAppContentPath() { string path = string.Empty; switch(Application.platform) { caseRuntimePlatform.Android: path = "jar:file://" + Application.dataPath + "!/assets/"; break; caseRuntimePlatform.IPhonePlayer: path = Application.dataPath + "/Raw/"; break; default: path = Application.dataPath + "/" + AppConst.AssetDir + "/"; break; } returnpath; } public static void Log(stringstr) { Debug.Log(str); } public static void LogWarning(stringstr) { Debug.LogWarning(str); } public static void LogError(stringstr) { Debug.LogError(str); } /// <summary> ///防止初学者不按步骤来操作 /// </summary> /// <returns></returns> public static intCheckRuntimeFile() { if (!Application.isEditor) return 0; string streamDir = Application.dataPath + "/StreamingAssets/"; if (!Directory.Exists(streamDir)) { return -1; } else{ string[] files =Directory.GetFiles(streamDir); if (files.Length == 0) return -1; if (!File.Exists(streamDir + "files.txt")) { return -1; } } string sourceDir = AppConst.FrameworkRoot + "/ToLua/Source/Generate/"; if (!Directory.Exists(sourceDir)) { return -2; } else{ string[] files =Directory.GetFiles(sourceDir); if (files.Length == 0) return -2; } return 0; } /// <summary> ///执行Lua方法 /// </summary> public static object[] CallMethod(string module, string func, params object[] args) { LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua); if (luaMgr == null) return null; return luaMgr.CallFunction(module + "." +func, args); } /// <summary> ///检查运行环境 /// </summary> public static boolCheckEnvironment() { #if UNITY_EDITOR int resultId =Util.CheckRuntimeFile(); if (resultId == -1) { Debug.LogError("没有找到框架所需要的资源,单击Game菜单下Build xxx Resource生成!!"); EditorApplication.isPlaying = false; return false; } else if (resultId == -2) { Debug.LogError("没有找到Wrap脚本缓存,单击Lua菜单下Gen Lua Wrap Files生成脚本!!"); EditorApplication.isPlaying = false; return false; } if (Application.loadedLevelName == "Test" && !AppConst.DebugMode) { Debug.LogError("测试场景,必须打开调试模式,AppConst.DebugMode = true!!"); EditorApplication.isPlaying = false; return false; } #endif return true; } } }
usingUnityEngine; usingLuaFramework; usingSystem.Collections.Generic; public classAppView : View { private stringmessage; ///<summary> ///监听的消息 ///</summary> List<string>MessageList { get{ return new List<string>() { NotiConst.UPDATE_MESSAGE, NotiConst.UPDATE_EXTRACT, NotiConst.UPDATE_DOWNLOAD, NotiConst.UPDATE_PROGRESS, }; } } voidAwake() { RemoveMessage(this, MessageList); RegisterMessage(this, MessageList); } /// <summary> ///处理View消息 /// </summary> /// <param name="message"></param> public override voidOnMessage(IMessage message) { string name =message.Name; object body =message.Body; switch(name) { case NotiConst.UPDATE_MESSAGE: //更新消息 UpdateMessage(body.ToString()); break; case NotiConst.UPDATE_EXTRACT: //更新解压 UpdateExtract(body.ToString()); break; case NotiConst.UPDATE_DOWNLOAD: //更新下载 UpdateDownload(body.ToString()); break; case NotiConst.UPDATE_PROGRESS: //更新下载进度 UpdateProgress(body.ToString()); break; } } public void UpdateMessage(stringdata) { this.message =data; } public void UpdateExtract(stringdata) { this.message =data; } public void UpdateDownload(stringdata) { this.message =data; } public void UpdateProgress(stringdata) { this.message =data; } voidOnGUI() { GUI.Label(new Rect(10, 120, 960, 50), message); GUI.Label(new Rect(10, 0, 500, 50), "(1) 单击 "Lua/Gen Lua Wrap Files"。"); GUI.Label(new Rect(10, 20, 500, 50), "(2) 运行Unity游戏"); GUI.Label(new Rect(10, 40, 500, 50), "PS: 清除缓存,单击"Lua/Clear LuaBinder File + Wrap Files"。"); GUI.Label(new Rect(10, 60, 900, 50), "PS: 若运行到真机,请设置Const.DebugMode=false,本地调试请设置Const.DebugMode=true"); GUI.Label(new Rect(10, 80, 500, 50), "PS: 加Unity+ulua技术讨论群:>>341746602"); } }
usingUnityEngine; usingSystem.Collections; namespaceLuaFramework { /// <summary> /// </summary> public classMain : MonoBehaviour { voidStart() { AppFacade.Instance.StartUp(); //启动游戏 } } }