当前位置: 首页 > news >正文

如果你会建网站不知怎么入门

如果你会建网站,不知怎么入门,中国航空技术北京有限公司,怎样php网站建设上篇链接#xff1a;【Lua热更新】上篇 文章目录 三、xLua热更新#x1f4d6;1.概述#x1f4da;︎2.导入xLua框架#x1f516;3. C#调用Lua3.1Lua解析器3.2Lua文件夹的重定向3.3Lua解析器管理器3.4全局变量获取3.5全局函数获取3.6映射到List和Dictionary3.7映射到类3.8映…上篇链接【Lua热更新】上篇 文章目录 三、xLua热更新1.概述︎2.导入xLua框架3. C#调用Lua3.1Lua解析器3.2Lua文件夹的重定向3.3Lua解析器管理器3.4全局变量获取3.5全局函数获取3.6映射到List和Dictionary3.7映射到类3.8映射到接口3.9映射到LuaTable 4.Lua调用C#1.Lua使用C#类2.Lua使用C#枚举3.Lua使用C#数组、List、字典4.Lua使用C#拓展方法5.Lua使用C#ref和out6.Lua使用C#重载函数7.Lua使用C#委托和事件8.Lua使用C#二维数组9.Lua使用C#的null和nil的比较10.Lua和系统类或委托相互使用11.Lua使用C#协程12.Lua使用C#泛型函数 5.xLua热补丁 三、xLua热更新 1.概述 C#代码和Resoureces文件夹不能实现热更新所以需要使用Lua通过AB包来进行更新脚本 ︎2.导入xLua框架 1.获得xLua包GitHub地址Tencent/xLua: xLua is a lua programming solution for C# 2.导入文件夹 增加了xLua编辑栏导入成功 3.点击Generate Code生成相关代码 4.导入AssetBundles-Browser GitHub地址Unity-Technologies/ AssetBundles -Browser 如果有报错删除文件中的报错的Test文件即可 3. C#调用Lua 3.1Lua解析器 Lua解析器让我们在Unity中执行Lua 简述一下原理就是Lua是一种解释型语言代码在运行时才被解释器一行行动态翻译和执行先由Lua编译器编译为字节码然后交给Lua虚拟机执行将Lua虚拟机源代码整合给Unity使用实现之间的交互 // 创建一个解析器 LuaEnv luaEnv new LuaEnv(); // 使用Lua解析器执行Lua语言 luaEnv.DoString(print(First Lua)); // Lua垃圾回收手动释放对象 luaEnv.Tick(); // 销毁Lua解析器 luaEnv.Dispose();Lua默认调用Resources文件夹下的Lua脚本 执行以下代码会发现脚本报错没有找到脚本原因是因为.lua不是Unity中的文件格式所以我们需要给.lua在添加一个.txt后缀才能查找到这个查找函数的源码估计是通过Resourece.Load加载所以查找不到Lua文件 luaEnv.DoString(require(FistTest));❓存在的问题从Resources文件夹下读取无法进行热更新其次每个文件都要手动添加.txt后缀十分麻烦所以后续需要进行文件夹的重定向和自动 3.2Lua文件夹的重定向 通过AddLoader方法进行重定向进行自定义加载Lua文件规则 void Start() {luaEnv.AddLoader(MyCustomLoader);luaEnv.DoString(require(FistTest)); }private byte[] MyCustomLoader(ref string path) {string newPath Application.dataPath /Lua/ path .lua;if (File.Exists(newPath))return File.ReadAllBytes(newPath);elseDebug.Log(重定向失败 path);return null; }我们看一下AddLoader源码 传入一个委托添加到 List 列表中在我们使用require(文件名)时如果在列表中按顺序查找该文件那么最后将在Resoureces文件夹中查找 ❓存在问题最终我们需要在AB包中进行加载 3.3Lua解析器管理器 通过实现Lua解析器管理器保证解析器的唯一性 ️LuaMgr管理器源码 public class LuaMgr : BaseManagerLuaMgr {private const string LUA_PATH Lua;private LuaEnv luaEnv;public LuaTable Global {get luaEnv.Global;} // 获得_G表// 初始化解析器public void Init(){if (luaEnv ! null) return;luaEnv new LuaEnv();luaEnv.AddLoader(MyCustomLoader); // 后缀.lua时日常开发重定向到的位置luaEnv.AddLoader(MyCustomABLoader); // 后缀.txt使用AB包时重定向到的位置}// 重定向加载AB包中的Lua脚本private byte[] MyCustomABLoader(ref string path){TextAsset txtLua ABMgr.GetInstance().LoadResTextAsset(LUA_PATH, path .lua);if (txtLua null){Debug.LogError(在AB包中重定向失败);return null;}return txtLua.bytes;}private byte[] MyCustomLoader(ref string path){string newPath Application.dataPath / LUA_PATH / path .lua;if (File.Exists(newPath)){return File.ReadAllBytes(newPath);}else{Debug.LogError(重定向失败 path);}return null;}// 执行lua语言public void DoString(string filename){if (luaEnv null){Debug.LogError(解析器未初始化);return;}luaEnv.DoString(string.Format(require({0}), filename));}// 释放垃圾public void Tick(){if (luaEnv null){Debug.LogError(解析器未初始化);return;}luaEnv.Tick();}// 销毁解析器public void Dispose(){luaEnv.Dispose();luaEnv null;} }️BaseManager 源码 //1.C#中 泛型的知识 //2.设计模式中 单例模式的知识 public class BaseManagerT where T:new() {private static T instance;public static T GetInstance(){if (instance null)instance new T();return instance;} }❓现在只实现了重定向文件夹并没有实现重定向AB包加载接下来继续完成将Lua脚本放在AB包中通过AB包加载脚本。需要注意的是AB包加载文本后缀不能使用.Lua所以在打包时需要将后缀改为.txt不过这一步后续将改成自动的 我们将后缀暂时手动的修改后缀为.txt进行进行打包如果打包过程中存在报错XLua → Clear Generated Code即可 打包成功后刷新界面 重定向加载AB包 这里建议实际开发中仍然使用.Lua后缀那么将重定向读取普通文件夹进行热更新时在修改为.txt后缀重定向到AB包文件夹 // 重定向加载AB包中的Lua脚本 private byte[] MyCustomABLoader(ref string path) {string newPath Application.streamingAssetsPath / LUA_PATH;AssetBundle ab AssetBundle.LoadFromFile(newPath); // 加载AB包TextAsset tx ab.LoadAssetTextAsset(path .lua); // 加载Lua文件return tx.bytes; } 3.4全局变量获取 ️Main.Lua源码 print( Main ) require(FirstTest) -- 在Unity中已经重定向️FirstTest.Lua 源码 print( First Test ) myNumber 1 myFloat 1.2 myBool true myString OvO️Unity中代码 无法直接获得local本地变量因为不在_G表中 LuaMgr.GetInstance().Init(); LuaMgr.GetInstance().DoString(Main);// Get int myNumber LuaMgr.GetInstance().Global.Getint(myNumber); float myFloat LuaMgr.GetInstance().Global.Getfloat(myFloat); bool myBool LuaMgr.GetInstance().Global.Getbool(myBool); string myString LuaMgr.GetInstance().Global.Getstring(myString);// Set LuaMgr.GetInstance().Global.Set(myNumber, 99); myNumber LuaMgr.GetInstance().Global.Getint(myNumber);3.5全局函数获取 ️FirstTest.Lua 源码 myFun1 function ()print(这是一个无参无返回的函数) endmyFun2 function (x)print(这是一个有参有返回的函数)return x x endmyFun3 function ()print(这是一个多返回值的函数)return 99, apple, 1.2f endmyFun4 function (x, ...)print(这是一个变长参数的函数)arg {...}for k, v in pairs(arg) doprint(k, v)end end无参数无返回函数获取 // Unity自带委托 UnityAction ua1 LuaMgr.GetInstance().Global.GetUnityAction(myFun1); ua1.Invoke(); // C#委托 Action ac LuaMgr.GetInstance().Global.GetAction(myFun1); // xLua提供不建议使用 LuaFunction lf LuaMgr.GetInstance().Global.GetLuaFunction(myFun1); lf.Call();有参数有返回函数获取 定义一个委托需要使用特性否则Lua无法识别XLua → Generate Code在编译器重新生成一下代码否则也会报错 [CSharpCallLua] public delegate int MyFunc2(int x);调用函数 MyFunc2 ua2 LuaMgr.GetInstance().Global.GetmyFunc2(myFun2); int x ua2.Invoke(2); print(返回值是 x);或者使用C#封装的委托如果报错就XLua → Generate Code Funcint, int ua2 LuaMgr.GetInstance().Global.GetFuncint, int(myFun2); int x ua2.Invoke(2); print(返回值是 x);多返回值函数获取 // 第一个返回值即委托返回值 // 之后的返回值使用out或者ref [CSharpCallLua] public delegate int MyFun3(int x, out string fruit, out float value);调用 MyFun3 fc3 LuaMgr.GetInstance().Global.GetMyFun3(myFun3); string fruit; float value; int a fc3.Invoke(12, out fruit, out value);或者使用xLua自带的获取方法 LuaFunction lf3 LuaMgr.GetInstance().Global.GetLuaFunction(myFun3); object[] ojb lf3.Call(100);多返回值函数获取 // 如果变长参数每个类型都不确定传入Object [CSharpCallLua] public delegate void MyFun4(string a, params int[] args);3.6映射到List和Dictionary ️FirstTest.Lua 源码 testList {1, 2, 3, 4} testDic {[a] 1,[b] 2,[c] 3 }获取 LuaMgr.GetInstance().Init(); LuaMgr.GetInstance().DoLuaFile(Main);Listint testList LuaMgr.GetInstance().Global.GetListint(testList); Dictionarystring, int testDic LuaMgr.GetInstance().Global.GetDictionarystring, int(testDic);3.7映射到类 ️FirstTest.Lua 源码 testClass {name 咪咪,age 1,eat function ()print(吃猫粮)end }C#中声明该类成员名称必须和lua中一致类名可以不需要一致成员必须是公共的 // 少于lua中的变量则获取不到多余lua中的变量则不会赋值并不会报错 public class TestClass {public string name;public int age;public UnityAction eat; }3.8映射到接口 声明接口接口中不允许声明成员变量所以使用成员属性来接收 接口拷贝是引用拷贝在C#中修改值Lua中也会被修改 [CSharpCallLua] // 需要特性 public interface MyInterface {public string name { get; set; }public int age { get; set; }public UnityAction eat{ get; set; } }获取 MyInterface myInterface LuaMgr.GetInstance().Global.GetMyInterface(TestClass);3.9映射到LuaTable 官方不建议使用LuaTable和LuaFunction会有垃圾占用LuaTable需要手动销毁否则会一致占用内存 LuaTable table LuaMgr.GetInstance().Global.GetLuaTable(TestClass); // 获得 string name table.Getstring(name); int age table.Getint(age); UnityAction ac table.GetUnityAction(eat);// 修改 table.Set(age, 55); // 释放table垃圾 table.Dispose();4.Lua调用C# 1.Lua使用C#类 C#创建Lua解析器调用Lua脚本运行 LuaMgr.GetInstance().Init(); LuaMgr.GetInstance().DoLuaFile(Main);Lua调用C#类需要使用完整路径CS.命名空间.类名 ​ Lua中创建对象不需要使用new调用构造函数即可 local obj1 CS.UnityEngine.GameObject()为了方便使用和节约性能定义全局变量存储C#中的类 GameObject CS.UnityEngine.GameObject local obj2 GameObject(MyObject) -- 调用有参构造函数可以直接使用类中的静态方法 local obj3 GameObject.Find(MyObject)对象可以调用成员变量和成员方法 ​ 需要注意的是成员方法需要使用冒号调用 -- 得到对象成员变量 print(obj3.transform.position) -- Lua中调用对象的成员方法要使用冒号调用 Vector3 CS.UnityEngine.Vector3 obj3.transform:Translate(Vector3.forward)Lua中调用一个自定义类不继承MonoBehaviour namespace MySpace // 命名空间 {public class MyClass // 类名{public string value;public void Speak(string str) { Debug.Log(str); }} }local myClass CS.MySpace.MyClass() myClass:Speak(调用了一个自定义C#类)为物体添加组件即获得继承MonoBehaviour类 public class StuLua : MonoBehaviour {void Start(){Debug.Log(添加成功);} }local obj GameObject.Find(MyObject) obj:AddComponent(typeof(CS.StuLua)) -- xLua不支持无参泛型xLua可以通过typeof获得泛型2.Lua使用C#枚举 枚举调用和类调用是类似的CS.命名空间.枚举名.枚举成员 ​ 我们也可以调用自定义枚举使用方法相同所以略过 GameObject CS.UnityEngine.GameObject PrimitiveType CS.UnityEngine.PrimitiveTypelocal cube GameObject.CreatePrimitive(PrimitiveType.Cube)数值转、字符串转枚举__CastFrom local eValue PrimitiveType.__CastFrom(1) -- 数值 print(eValue) GameObject.CreatePrimitive(eValue)evalue PrimitiveType.__CastFrom(Sphere) -- 字符串 print(evalue) GameObject.CreatePrimitive(evalue)3.Lua使用C#数组、List、字典 数组 local myClass CS.MySpace.MyClass()-- 长度获取要按照c#中使用不能用lua中的#获取长度 print(myClass.myIntArray.Length) -- 获得长度 print(myClass.myIntArray[0]) -- 获得元素 for i 0, myClass.myIntArray.Length - 1 doprint(myClass.myIntArray[i]) endLua中创建C#数组数组的本质是Array我们通过Array类来创建数组 local array CS.System.Array.CreateInstance(typeof(CS.System.Int32), 10)List myClass.myIntList:Add(1) myClass.myIntList:Add(2) print(myClass.myIntList.Count) for i 0, myClass.myIntList.Count - 1 doprint(myClass.myIntList[i]) endLua中创建C#List通过xLua中提供的方法来创建,需要两步先获得list泛型类在创建对象 -- 得到一个Liststring的类 local List_String CS.System.Collections.List(CS.System.String) -- 创建一个Liststring对象 local list List_String() list:Add(apple)字典 myClass.myDict:Add(1, orange) print(myClass.myDict[1]) for k,v in pairs(myClass.myDict) doprint(k, v) endLua中创建C# Dictionary -- 得到一个DictionaryString, Vector3的类 local dic_str_vec3 CS.System.Collections.Generic.Dictionary(CS.System.String, CS.UnityEngine.Vector3) -- 创建一个DictionaryString, Vector3对象 local dic dic_str_vec3()dic:Add(up, CS.UnityEngine.Vector3.up) for k, v in pairs(dic) doprint(k, v) endLua中自己创建的字典无法通过[]获得需要使用方法get_Item、set_Item print(dic[up]) -- 这个是错误的 print(dic:get_Item(up)) -- 需要使用方法 dic:set_Item(up, nil) -- 需要使用方法 print(dic:get_Item(up))4.Lua使用C#拓展方法 需要使用特性[LuaCallCSharp]另外如果是Lua中使用的类都建议加上特性可以提升性能否则Lua都是通过反射调用的效率比较低 C#代码 [LuaCallCSharp] public static class Tool {public static void Func(this MyClass obj){Debug.Log(这是一个MyClass的拓展方法 obj.ToString());} }Lua代码 MyClass CS.MySpace.MyClass local my MyClass() my:Func();5.Lua使用C#ref和out public class MyClass {public int RefFun(int a, ref int b){return a b 1;}public int OutFun(int a, out int b){b a 1;return a b;}public int AllFun(int a, ref int b, out int c){c a b;return a b c;} }ref和out都通过多返回值获得ref必须传入参数out参数省略 MyClass CS.MySpace.MyClass local my MyClass()local back, b my:RefFun(2, 3); print(b)local back, b my:OutFun(2) print(b)local back, b, c my:AllFun(2, 4 ,5) pint(b) pint(c)6.Lua使用C#重载函数 public string Call(string a) {Debug.Log(a);return a; } public string Call(string a, string b) {Debug.Log(a b);return a b; } public void Call(int x) {Debug.Log(int type function x); } public void Call(float x) {Debug.Log(float type function x); }对于参数个数不同的函数虽然Lua本身不支持调用重载函数都是Lua支持调用C#中的重载函数 my:Call(apple) my:Call(apple, orange)但是对于参数个数相同类型不同的number类型时Lua可能会出现一些问题因为Lua数值类型只有number无法区分int和float 所以在调用void Call(float x)和void Call(int x)会有意想不到的结果不建议这样使用xLua有反射方法可以解决但是性能不高 7.Lua使用C#委托和事件 public UnityAction ac; public event UnityAction ev;public void CallEvent() // 事件无法在类外调用 {ev?.Invoke(); }委托的使用 local func function( )print(这是一个无参无返回的函数) end-- 第一次赋值必须使用 不能使用 my.ac func -- 添加函数 my.ac my.ac func -- 调用委托 print(add) my.ac()-- 删除委托 my.ac my.ac - func print(del) my.ac()-- 清空委托 my.ac nil事件的使用Lua中使用事件比较特殊语法类似成员函数调用事件的调用和清空无法在外部直接控制只能通过类方法包装后在外部使用方法 print(事件) -- 添加函数 my:ev(, func) my:ev(, func) -- 调用事件通过成员方法因为事件无法在类外被调用 my:CallEvent()print( after ) -- 删除函数 my:ev(-, func) my:CallEvent()8.Lua使用C#二维数组 public int[,] array new int [,] { { 1, 2, 3 }, { 4, 5, 6 } };主要是通过Array中封装的方法去使用 -- 获取行数列数 -- GetLength是C#中的方法传递0表示行数传递1表示列数 print(行数 .. my.array:GetLength(0)) print(列数 .. my.array:GetLength(1))-- 获取元素不能通过[][]或者[,]获得通过Array中的方法使用 print((1, 1) : .. my.array:GetValue(1, 1))-- 遍历 for i 0, my.array:GetLength(0) - 1 dofor j 0, my.array:GetLength(1) - 1 doprint(i..j.. : ..my.array:GetValue(i, j))end end9.Lua使用C#的null和nil的比较 判断物体上是否有刚体组件如果没有则添加刚体 nil和null无法进行相等比较 GameObject CS.UnityEngine.GameObject Rigidbody CS.UnityEngine.Rigidbody-- 创建对象 local obj GameObject(test object) -- Lua中无法使用泛型所以我们使用参数为type的方法 local rig obj:GetComponent(typeof(Rigidbody))if rig nil then -- 这样是错误的无法判断print(添加一个rigibody)obj:AddComponent(typeof(Rigidbody)) elseprint(rigibody已经存在) end我们可以通过Equals方法来判断所以我们将 rig nil → rig:Equals(nil) 但是可能对象本身就是空的所以通常我们会将判空封装成一个方法 rig:Equals(nil) → IsNull(rig) function IsNull(obj)if obj nil or obj:Equals(nil) thenreturn trueendreturn false end或者我们在C#中为Object类添加拓展方法来判断拓展方法记得添加特性和重新生成Lua代码 [LuaCallCSharp] public static class Tool {public static bool IsNull(this Object obj){return obj.Equals(null);} }10.Lua和系统类或委托相互使用 CSharpCallLua当c#中调用Lua委托或接口时使用 LuaCallCSharp当Lua中调用C#拓展方法时使用建议被Lua调用的类都添加可以提高性能效率 ❓我们无法为系统类或者第三方库代码加上这两个特性 通过固定方法为系统类和自定义类统一添加特性 public static class CreateAttribute {[CSharpCallLua] public static ListType csharpCallLuaList new ListType(){typeof(UnityAction),typeof(MyClass)};[LuaCallCSharp] public static ListType luaCallCSharpList new ListType(){typeof(GameObject),typeof(MyClass)}; }11.Lua使用C#协程 Lua中不能直接使用 yield return lua中不能直接传入lua函数所以需要先调用xlua.util中的cs_generator(lua函数) util require(xlua.util) GameObject CS.UnityEngine.GameObject WaitForSeconds CS.UnityEngine.WaitForSecondslocal obj GameObject(myObject) local comp obj:AddComponent(typeof(CS.StuLua))fun function ()local x 1while true docoroutine.yield(WaitForSeconds(1)) -- Lua中不能直接使用 yield return print(x)x x 1if x 10 thencomp:StopCoroutine(myIE) -- 停止协程和C#中一样endend end-- lua中不能直接传入lua函数所以需要先调用xlua.util中的cs_generator(lua函数) myIE comp:StartCoroutine(util.cs_generator(fun)) 12.Lua使用C#泛型函数 lua中支持有约束有参数的泛型 lua中不支持没有约束、没有参数、约束为接口的泛型函数 public void FuncT(T a) where T : Enum {Debug.Log(这是一个有参数有约束的方法); }MyClass CS.MySpace.MyClass local my MyClass()my:Func(1)5.xLua热补丁
http://www.hkea.cn/news/14261279/

相关文章:

  • 优化后的网站网站网站平台建设方案
  • 免费建立个人网站做海报哪个网站好
  • 一般网站建设电话wordpress支付宝移动端
  • 昌吉 建设局 网站南昌网站推广排名
  • 高校二级网站建设要求自己做网站花多少钱
  • 设计师常用的灵感网站wordpress 板块
  • 广州做网站优化怎么建设游戏网站
  • 建一个购物网站需要什么条件望野古诗带拼音
  • 怎么查公司网站有没有中文域名江苏屹峰建设网站
  • 北京 个人网站 备案wordpress主题免刷新
  • 中国互联网公司排名湖北短视频搜索seo
  • jquery 网站根目录设计营销型网站域名
  • 企业官方网站应该怎么样建设网站建设套
  • 深圳品牌网站制作报价中级经济师考试
  • 桂林手机网站建设江苏常州网站建设公司
  • 成立网站要多少钱广州做一个网站多少钱
  • 重庆网站建设网站建设政务网站建设的三个核心功能是什么
  • soho网站建设绵阳模板网站
  • 网站建设加盟代理wordpress后台禁止更新
  • 哪些人可以做网站网络舆情监测适合女生嘛
  • 用什么软件做网站布局股票做T网站
  • 支付网站设计汽车用品网站建设
  • 广州企业自助建站WP Rocket-WordPress
  • 郑州 服装网站建设百度搜索排名优化哪家好
  • 南京建设监理协会网站打不开网站彩铃怎么做的
  • 重庆建站公司网站模板一分钟建站
  • wordpress全站启用ssl网站logo制作教程
  • 上海外贸网站推广服务如何开发一款app软件
  • 计算机网站设计网站开发的具体流程图
  • 张家口购物网站开发设计js做网站