网站用图片,网络营销方式优势,网页设计师培训大全,seo综合查询平台官网Unity使用Xlua的常用编码方式#xff0c;做一下记录
1、C#调用lua
1、Lua解析器
private LuaEnv env new LuaEnv();//保持它的唯一性void Start(){env.DoString(print(你好lua));//env.DoString(require(Main)); 默认在resources文件夹下面//帮助…Unity使用Xlua的常用编码方式做一下记录
1、C#调用lua
1、Lua解析器
private LuaEnv env new LuaEnv();//保持它的唯一性void Start(){env.DoString(print(你好lua));//env.DoString(require(Main)); 默认在resources文件夹下面//帮助我们清除lua中我们没有手动释放的对象 垃圾回收env.Tick();//销毁lua解释器用的较少env.Dispose();}
2、自定义loader private void Start(){//xlua路径重定向方法_env.AddLoader(MyLoader);_env.DoString(require(Main));}private byte[] MyLoader(ref string filepath){//传入的filepath是 require执行的lua脚本文件名,在这里是mainstring path Application.dataPath /Lua/ filepath .lua;//判断文件是否存在if (File.Exists(path)){return File.ReadAllBytes(path);}else{Debug.Log(重定向失败文件名为filepath);}return null;}3、Lua管理器
/// summary
/// lua管理器
/// 提供lua解析器
/// 保证解析器的唯一性
/// /summary
public class LuaMgr
{private static LuaMgr _instance;public static LuaMgr Instance{get{if (_instancenull){_instance new LuaMgr();}return _instance;}}private LuaEnv _luaEnv;/// summary/// 得到lua中的_G/// /summarypublic LuaTable Gloabl _luaEnv.Global;/// summary/// 初始化/// /summarypublic void Init(){if (_luaEnv!null) return;_luaEnv new LuaEnv();_luaEnv.AddLoader(MyLoader);_luaEnv.AddLoader(MyABLoader);}#region 标准内容/// summary/// 传入文件名执行脚本/// /summary/// param namefileName/parampublic void DoLuaFile(string fileName){string str $require({fileName});DoString(str);}public void DoString(string str){if(_luaEnvnull){Debug.Log(解析器未初始化);return;}_luaEnv.DoString(str);}/// summary/// 释放lua垃圾/// /summarypublic void Tick(){if(_luaEnvnull){Debug.Log(解析器未初始化);return;}_luaEnv.Tick();}/// summary/// 销毁解析器/// /summarypublic void Dispose(){if(_luaEnvnull){Debug.Log(解析器未初始化);return;}_luaEnv.Dispose();_luaEnv null;}//自动执行private byte[] MyLoader(ref string filepath){//传入的filepath是 require执行的lua脚本文件名,在这里是mainstring path Application.dataPath /Lua/ filepath .lua;//判断文件是否存在if (File.Exists(path)){return File.ReadAllBytes(path);}else{Debug.Log(重定向失败文件名为filepath);}return null;}//重定向加载AB包中的lua脚本private byte[] MyABLoader(ref string filepath){//加载路径string path Application.streamingAssetsPath /lua;//加载AB包AssetBundle abAssetBundle.LoadFromFile(path); TextAsset tx ab.LoadAssetTextAsset(filepath.lua);//加载Lua文件返回//加载lua文件byte数组return tx.bytes;}//Lua脚本最终会放在ab包中#endregion
}
4、全局变量获取 private void Start(){LuaMgr.Instance.Init();LuaMgr.Instance.DoLuaFile(Main);int i LuaMgr.Instance.Gloabl.Getint(testNumber);var i2 LuaMgr.Instance.Gloabl.Getbool(testBool);var i3 LuaMgr.Instance.Gloabl.Getfloat(testFloat);var i4 LuaMgr.Instance.Gloabl.Getstring(testString);//值拷贝不会修改lua中的值可以用setLuaMgr.Instance.Gloabl.Set(testNumber,1000);i LuaMgr.Instance.Gloabl.Getint(testNumber);Debug.Log(testNumberi);} 虽然lua中只有number一种数值类型但是我们可以根据它具体的值用对应的C#变量类型来存储 5、全局函数的获取
public delegate void CustomCall();
public delegate void CustomCall2(int a);
//加一个特性只有添加特性才能被调用加完特性后还要一部分工作就是点击Xlua-Generatedate
[CSharpCallLua]
public delegate int CustomCall3(int a);
[CSharpCallLua] //使用out来接
public delegate int CustomCall4(int a,out int b,out bool c,out string d,out int e);[CSharpCallLua] //使用ref来接
public delegate int CustomCall5(int a,ref int b,ref bool c,ref string d,ref int e);//变长函数如果边长函数中类型多种多样那就使用object
[CSharpCallLua]
public delegate void CustomCall6(string a,params int[] args);
public class Lesson5_CallFunction : MonoBehaviour
{ void Start(){LuaMgr.Instance.Init();// LuaMgr.Instance.DoString(require(Main)); LuaMgr.Instance.DoLuaFile(Main);//无参无返回值var call1 LuaMgr.Instance.Gloabl.GetUnityAction(testFun1);call1();//有参有返回值var call2 LuaMgr.Instance.Gloabl.GetCustomCall3(testFun2);// Debug.Log(call2(2));var call3 LuaMgr.Instance.Gloabl.GetFuncint,int(testFun2);// Debug.Log(Func: call3(2));//有参多返回值var call4 LuaMgr.Instance.Gloabl.GetCustomCall4(testFun3);int b;bool c;string d;int e;// Debug.Log(call4(51,out b,out c,out d,out e));var call5 LuaMgr.Instance.Gloabl.GetCustomCall5(testFun3);int b1 0;bool c1 true;string d1;int e10;// Debug.Log(call5(51,ref b1,ref c1,ref d1,ref e1));var call6 LuaMgr.Instance.Gloabl.GetCustomCall6(testFun4);call6(你好,1,5,6,5,4);// LuaFunction lf LuaMgr.Instance.Gloabl.GetLuaFunction(testFun4);// lf.Call(你好, 1, 5, 6, 5, 4);}print(Variable启动)
-- 无参无返回
testFun1 function()print(无参无返回)
end-- 有参有返回
testFun2 function(a)print(有参有返回)return a 1
end
-- 多返回
testFun3 function(a)print(多返回)return 1, 2, false, 123, a
end
-- 变长参数
testFun4 function(a, ...)print(变长参数)print(a)arg { ... }for k, v in pairs(arg) doprint(k, v)end
end6、List和Dictionary private void Start(){LuaMgr.Instance.Init();LuaMgr.Instance.DoLuaFile(Main);#region ListListint list LuaMgr.Instance.Gloabl.GetListint(testList);for (int i 0; i list.Count; i){Debug.Log(----list[i]);}//不确定类型用objectListobject list2 LuaMgr.Instance.Gloabl.GetListobject(testList2);for (int i 0; i list2.Count; i){Debug.Log(----list2[i]);}#endregion#region 字典Dictionarystring, int dic LuaMgr.Instance.Gloabl.GetDictionarystring, int(testDic);foreach (var item in dic){Debug.Log(item.Key____item.Value);}Dictionaryobject, object dic2 LuaMgr.Instance.Gloabl.GetDictionaryobject, object(testDic2);foreach (var item in dic2){Debug.Log(item.Key____item.Value);}#endregion}
7、类映射table
//Lua
testClas{testInt2,testBooltrue,testFloat1.2,testString123,testFunfunction()print(NIHAO)end
}
//C#
public class CallLuaClass
{//在类中去生命成员变量名字要和lua那边一样//注意。一定是公有的不然不能赋值。//这个自定义中的变量可以多也可以少public int testInt;public bool testBool;public float testFloat;public string testString;public UnityAction testFun;//方法
}
public class Lesson7_Table : MonoBehaviour
{private void Start(){LuaMgr.Instance.Init();LuaMgr.Instance.DoLuaFile(Main);CallLuaClass callLuaClass LuaMgr.Instance.Gloabl.GetCallLuaClass(testClas);Debug.Log(callLuaClass.testString);callLuaClass.testFun();}
}8、接口映射table 注意接口是引用拷贝。改了值后lua值也会改变 //接口中不允许有成员变量
//我们用属性
[CSharpCallLua]
public interface ICSharpCallInterface
{int testInt { get; set; }bool testBool { get; set; }float testFloat { get; set; }string testString { get; set; }UnityAction testFun { get; set; }
}public class Lesson_Interface : MonoBehaviour
{void Start(){LuaMgr.Instance.Init();LuaMgr.Instance.DoLuaFile(Main);ICSharpCallInterface callInterface LuaMgr.Instance.Gloabl.GetICSharpCallInterface(testClas);Debug.Log(callInterface.testFloat);}
}9、luatable映射到table //不过官方不建议使用luaTable和luaFunctionvoid Start(){LuaMgr.Instance.Init();LuaMgr.Instance.DoLuaFile(Main);LuaTable table LuaMgr.Instance.Gloabl.GetLuaTable(testClas);Debug.Log(table.Getint(testInt));table.GetLuaFunction(testFun).Call();table.Dispose();//使用完了dispose }2、lua调用C#重点
用的较多。
1、Lua使用C#类
print(************Lua调用C#相关知识点*************)
-- lua中使用C#的类非常简单
-- 固定套路
-- Cs.命名空间.类名
-- Unity的类比如GameObject Transform等等 ---CS.UnityEngine.类名-- 通过C#中的类实例化一个对象,注意lua中没有new
-- 默认调用的相当于无参构造
local obj1 CS.UnityEngine.GameObject()
local obj2 CS.UnityEngine.GameObject(郑毅)-- 为了方便使用并且节约性能定义全局变量储存C#中的类
-- 相当于取了一个别名这也是一种优化方式
GameObject CS.UnityEngine.GameObject
local obj3 GameObject(第三个)-- 类中的静态对象可以直接使用 .来调用
local obj4 GameObject.Find(郑毅)
--得到对象中的成员变量直接对象.就可以了
print(obj4.transform.position)
Vector3 CS.UnityEngine.Vector3;
--使用对象中的成员方法一定要加
obj4.transform:Translate(Vector3.right)
print(obj4.transform.position)-- 调用自定义的类
local t CS.Test()
t:Speak(你好)
--有命名空间的
local t CS.MyClass.Test2()
t:Speak(你好)--继承mono的类
--继承mono的类是不能直接new的
--lua不支持使用无惨的泛型的
local obj5 GameObject(加脚本测试)
-- Xlua提供了一个重要防范typeof 可以得到类的类型
obj5:AddComponent(typeof(CS.LuaCallC))
---- c#
public class Test
{public void Speak(string str){Debug.Log(test1str);}
}namespace MyClass
{public class Test2{public void Speak(string str){Debug.Log(test2str);}}
}
public class LuaCallC : MonoBehaviour
{}2、枚举
PrimitiveType CS.UnityEngine.PrimitiveType
GameObject CS.UnityEngine.GameObject
local obj GameObject.CreatePrimitive(PrimitiveType.Cube)---获取自定义美剧
myEnumCS.MyEnum
local cmyEnum.Idle
print(c)
--枚举转换
--数值转枚举
local amyEnum.__CastFrom(1)
print(a)
--字符串转枚举
local bmyEnum.__CastFrom(Atk )
print(b)3、调用C#数组和list和字典
public class Lesson
{public int[] array new int[5] { 1, 2, 3, 4, 5 };public Listint list new Listint();public Dictionaryint, string dic new Dictionaryint, string();
}local obj CS.Lesson()
-- Lua使用数组相关知识
-- 长度
print(obj.array.Length)
print(obj.array[2])
--遍历,虽然lua索引是从1开始
--但是要按照C#来从0开始
for i 0, obj.array.Length - 1 doprint(obj.array[i])
end--创建数组 数组的底层是array类使用静态方法CreateInstance
local array2 CS.System.Array.CreateInstance(typeof(CS.System.Int32), 10)
print(array2.Length)---list
obj.list:Add(10)
obj.list:Add(20)
obj.list:Add(30)
obj.list:Add(40)for i 0, obj.list.Count - 1 doprint(obj.list[i])
end
--创建list 相当于得到一个Listint的一个类的别名需要再实例化
local list_string CS.System.Collections.Generic.List(CS.System.Int32)
local list3 list_string()
list3:Add(50)
print(list3.Count)
print(list3[0])--- 字典
obj.dic:Add(1, 你好)
print(obj.dic[1])for k, v in pairs(obj.dic) doprint(k, v)
end--创建字典
local dicStringCS.System.Collections.Generic.Dictionary(CS.System.String,CS.UnityEngine.Vector3)
local dic2dicString()
dic2:Add(001,CS.UnityEngine.Vector3.right)print(dic2[001])---这里有个坑自己创建的字典这样是访问不到的
print(dic2:get_Item(001)) --只有通过这种方法才可以
dic2:set_Item(001,CS.UnityEngine.Vector3.up)
print(dic2:get_Item(001)) --只有通过这种方法才可以
print(dic2:TryGetValue(001))--多返回值4、拓展方法
//拓展方法
//拓展方法的写法
//想要在lua中使用拓展方法一定要在工具类前面加上特性
//如果不加该特性除了拓展方法以外都不会报错
//但是lua是通过反射机制去调用C#类的效率较低
//加上可提高性能
[LuaCallCSharp]
public static class Tools
{public static void Move(this Lesson4 obj){Debug.Log(obj.name移动);}
}
public class Lesson4
{public string name 名称;public void Speak(string str){Debug.Log(str);}public static void Eat(){Debug.Log(吃东西);}
}
public class LuaCallC : MonoBehaviour
{private void Start(){Lesson4 lesson4 new Lesson4();lesson4.Move();//拓展方法对象可以直接调用}
}Lesson4 CS.Lesson4
Lesson4.Eat()
--成员方法
local a Lesson4()
a:Speak(说话了啊)
--使用拓展方法
a:Move()5、ref out
public class Lesson5
{public int RefFun(int a,ref int b,ref int c,int d){b a d;c a - d;return 100;}public int OutFun(int a,out int b,out int c,int d){b a;c d;return 200;}public int RefOutFun(int a,out int b,ref int c){b a * 10;c a * 20;return 300;}
}Lesson5 CS.Lesson5
local obj Lesson5()--ref 参数会以多返回值的形式返回给lua
local a, b, c obj:RefFun(1, 0, 0, 1)
print(a)
print(b)
print(c)--out 参数会以多返回值的形式返回给lua
--out参数不需要传占位置的值
local a, b, c obj:OutFun(1, 30)
print(a)
print(b)
print(c)--综合起来
-- out不用占位值 ref需要占位
local a, b, c obj:OutFun(1, 30)
print(a)
print(b)
print(c)6、C#函数重载
public class Lesson6
{public int Cal(){return 100;}public int Cal(int a,int b){return a b;}public int Cal(int a){return a;}public float Cal(float a){return a;}
}Lesson6 CS.Lesson6
local obj Lesson6()print(obj:Cal())
print(obj:Cal(1))
print(obj:Cal(15,20))
--对于C#中多精度的重载函数支持不好
print(obj:Cal(1.25))--如果要解决重载函数模糊不清的问题
--xlua提供了解决方案反射机制但这种方法只做了解
--另外能不用就不用
local m2 typeof(CS.Lesson6):GetMethod(Cal, { typeof(CS.System.Single) })
--通过xlua提供的一个方法把它转换成lua函数来使用。
--一般我们转一次然后重复使用
local f2 xlua.tofunction(m2)
print(f2(obj,10.2))
7、委托 事件
public class Lesson8
{public UnityAction del;public event UnityAction eventAction;public void DoEvent(){if (eventAction ! null) eventAction();}
}Lesson8 CS.Lesson8
local obj Lesson8()-- 委托
local funcfunction()print(这是lua函数)
end
-- 注意lua没有复合运算符没有
-- 如果第一次往委托中加函数因为是niu 不能直接
-- 所以第一次 要先等
obj.delfunc
--第二次可以
obj.delobj.delfunc
obj.del()
--委托清除
obj.delnil---事件,事件和委托特别不一样
---有点类似于成员方法
obj:eventAction(,func)
obj:DoEvent()
--事件不能直接设置为空8、二维数组
使用GetValue获取 [LuaCallCSharp]
public class Book : MonoBehaviour
{public int[,] INTArray;void Awake(){INTArray new int[3, 3]{{1,2,3},{2,4,5},{6,7,8}};}public int GetArrayValue(int x,int y){return INTArray[x, y];}public void SetArrayValue(int x,int y,int value){INTArray[x, y] value;}
}local book CS.Book
local go GameObject(二维数组)local obj go:AddComponent(typeof(book))-- 调用 GetArrayValue 方法
local c obj:GetArrayValue(1, 1)
print(c)9、nil
PrimitiveTypeCS.UnityEngine.PrimitiveType
RigidbodyCS.UnityEngine.Rigidbody
local GameObject CS.UnityEngine.GameObject;
local obj GameObject(Cube)
local obj2 GameObject.CreatePrimitive(PrimitiveType.Cube)
local rig obj2:GetComponent(typeof(Rigidbody))
-- nil和Null没法进行 比较
if rig nil thenprint(空啊)
end
print(不为空吗)--可用这样
if rig:Equals(nil) thenobj2:AddComponent(typeof(Rigidbody))
end
-- 全局函数
print(IsNull(rig))
-- 在C#中
print(rig:Equ())-- 判断全局函数
function IsNull(obj)if objnil or obj:Equals(nil) thenreturn trueendreturn false
end10、C# 扩展方法
[LuaCallCSharp]
public static class ObjTest
{public static bool Equ(this Object obj){return objnull;}
}
11、特殊问题 CSharpCallLua 委托、接口 LuaCallCSharp拓展方法时、建议每个类都加 无法为系统类或者第三方库代码加上这两个特性
Obj CS.UnityEngine.GameObject
Ui CS.UnityEngine.UI
local sidObj.Find(Slider)
local sliderssid:GetComponent(typeof(Ui.Slider))
sliders.onValueChanged:AddListener(function(f)print(你好)
end)---------------------------------------------------------------
public static class Lesson10
{[CSharpCallLua]public static ListType cSharpCallLua new ListType(){typeof(UnityActionfloat)};[LuaCallCSharp]public static ListType luaCallCSharpnew ListType(){typeof(GameObject)};
}
----------------------------------------------------------------local aniObj.Find(Btn)
local btnani:GetComponent(typeof(Ui.Button))
btn.onClick:AddListener(function()print(鼠标点击了)
end)---还可以这样
local cCS.UnityEngine.Events.UnityAction(function()print(鼠标点击了)
end)12、协程
--xlua提供的一个工具表一定要通过require调用后才能用
local utilrequire(xlua.util)
GameObject CS.UnityEngine.GameObject
WaitForSeconds CS.UnityEngine.WaitForSeconds
--在场景中创建一个空物体然后添加一个脚本
local obj GameObject(Coroutine)
local mono obj:AddComponent(typeof(CS.LuaCallC))
--希望用来被开启的协程函数
fun function()local a 1while true docoroutine.yield(WaitForSeconds(1))print(a)a a 1if a10 then--关闭协程mono:StopCoroutine(b)endend
end
--我们不能直接将lua函数传入到开启协程中
--如果要把lua函数当做协程函数传入
--必须先调用xlua.util 中的cs_generator(fun)
bmono:StartCoroutine(util.cs_generator(fun))13、泛型 支持有约束有参数的泛型函数 不支持没有约束的泛型番薯 不支持有约束但是没有参数的泛型函数 不支持非Class的约束 public class Lesson12
{public class TestFather{}public class TestChild:TestFather{}public void TestFun1T(T a,T b) where T:TestFather{Debug.Log(有参数有约束的泛型方法);}public void TestFun2T(T a,T b) {Debug.Log(有参数无约束的泛型方法);}public void TestFun3T(T a) {Debug.Log(有参数);}public void TestFun3T() where T:TestFather{Debug.Log(有参数);} }local objCS.Lesson12()
local childCS.Lesson12.TestChild()
local fatherCS.Lesson12.TestFather()------------默认情况下支持----------
--支持有约束有参数的泛型函数
obj:TestFun1(child,father)
-----------------------------------注意 如果是mono 这种方式支持使用
--但是如果是iLcpp打包 泛型参数是引用类型才可以--要使得可用用
--设置泛型类型再使用
local testFun2xlua.get_generic_method(CS.Lesson12,TestFun3)
local testFun2_RtestFun2(CS.System.Int32)
--调用
testFun2_R(obj,10)--设置泛型类型再使用
local testFun3xlua.get_generic_method(CS.Lesson12,TestFun2)
local testFun3_RtestFun3(CS.System.Int32)
--调用
testFun3_R(obj,10,20)