柚子快報(bào)激活碼778899分享:Lua調(diào)用C#
柚子快報(bào)激活碼778899分享:Lua調(diào)用C#
?Lua沒有辦法直接訪問C#,一定是先從C#調(diào)用Lua后
才把核心邏輯交給Lua來編輯
Lua使用C#類
Main.cs:
public class Main : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
LuaMgr.GetInstance().Init();
LuaMgr.GetInstance().DoLuaFile("Main");
}
// Update is called once per frame
void Update()
{
}
}
LuaCallCSharp.cs
public class Test
{
public void Speak(string str)
{
Debug.Log("Test1" + str);
}
}
namespace MrTang
{
public class Test2
{
public void Speak(string str)
{
Debug.Log("Test2" + str);
}
}
}
public class LuaCallCSharp : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Main.lua:
print("主Lua啟動(dòng)")
--Unity中寫lua執(zhí)行
--xlua幫我們處理
--只要使執(zhí)行l(wèi)ua腳本 都會(huì)自動(dòng)進(jìn)入重定向函數(shù)中找文件
--require("Test")
require("Lesson1_CallClass")
Lesson1_CallClass.lua
print("*************Lua調(diào)用C#類相關(guān)知識(shí)點(diǎn)***************")
--lua中使用c#的類的固定套路
--CS.命名空間.類名
--Unity的類 比如GameObject Transform 都再UnityEngine命名空間下 —— CS.UnityEngine.類名
--例如 CS.UnityEngine.GameObject
--通過C#中的類 實(shí)例化一個(gè)對(duì)象 lua中沒有new 所以我們直接類名括號(hào)就是實(shí)例化對(duì)象
--默認(rèn)調(diào)用無參構(gòu)造
local obj1 = CS.UnityEngine.GameObject()
local obj2 = CS.UnityEngine.GameObject("Test")
--為了方便使用和節(jié)省性能 定義全局變量存儲(chǔ) C#中的類
GameObject = CS.UnityEngine.GameObject
local obj3 = GameObject("Test2")
--類中的靜態(tài)對(duì)象 可以直接使用.來調(diào)用
local obj4 = GameObject.Find("Test")
--得到對(duì)象中的成員變量 直接對(duì)象.即可
print(obj4.transform.position)
Debug = CS.UnityEngine.Debug
Debug.Log(obj4.transform.position)
Vector3 = CS.UnityEngine.Vector3
--如果使用對(duì)象中的成員方法 一定要加:
obj4.transform:Translate(Vector3.right)
Debug.Log(obj4.transform.position)
--自定義類使用方法相同 只是命名空間不同
local t = CS.Test()
t:Speak("test說話")
local t2 = CS.MrTang.Test2()
t2:Speak("test2說話")
--繼承了Mono的類 不能直接new
local obj5 = GameObject("加腳本測試")
--通過GameObject的AddComponent添加腳本
--xlua提供了一個(gè)重要方法 typeof 可以得到類的type
--xlua不支持 無參泛型函數(shù) 所以我們要用另一個(gè)重載
obj5:AddComponent(typeof(CS.LuaCallCSharp))
Lua使用C#枚舉
print("*************Lua調(diào)用C#枚舉相關(guān)知識(shí)點(diǎn)***************")
--枚舉調(diào)用
--調(diào)用Unity中的枚舉
--枚舉的調(diào)用規(guī)則和類的調(diào)用規(guī)則是一樣的
--CS.命名空間.枚舉名.枚舉成員
PrimitiveType = CS.UnityEngine.PrimitiveType
GameObject = CS.UnityEngine.GameObject
local obj = GameObject.CreatePrimitive(PrimitiveType.Cube)
--自定義枚舉使用方法一樣 只是要注意命名空間
E_MyEnum = CS.E_MyEnum
local c = E_MyEnum.Idle
print(c)
--枚舉轉(zhuǎn)換相關(guān)
--數(shù)值轉(zhuǎn)枚舉
local a = E_MyEnum.__CastFrom(1)
print(a)
--字符串轉(zhuǎn)枚舉
local b = E_MyEnum.__CastFrom("Atk")
print(b)
Lua使用C#數(shù)組、list和字典
print("*************Lua調(diào)用C#數(shù)組相關(guān)知識(shí)點(diǎn)***************")
local obj = CS.Lesson3()
--Lua使用C#相關(guān)知識(shí)
--長度 userdata數(shù)據(jù)類型
--C#怎么獲取 lua就怎么獲取 不能用lua中的#去獲取長度
print(obj.array.Length)
--訪問元素
print(obj.array[0])
--遍歷 要注意 lua中索引從1開始
--但是 數(shù)組是C#那邊的規(guī)則 所以還是得按C#的來
--注意最大值要-1
for i=0,obj.array.Length-1 do
print(obj.array[i])
end
--在Lua中創(chuàng)建一個(gè)C#的數(shù)組 Lua中表示數(shù)組和List可以用表
--但是 我們要使用C#中的Array類中的靜態(tài)方法即可(Lua中不能用new)
local array2 = CS.System.Array.CreateInstance(typeof(CS.System.Int32),10)
print(array2.Length)
print(array2[0])
print(array2[1])
print(array2)
print("*************Lua調(diào)用C#list相關(guān)知識(shí)點(diǎn)***************")
--調(diào)用成員方法用:
obj.list:Add(1)
obj.list:Add(2)
obj.list:Add(3)
--長度
print(obj.list.Count)
--遍歷
for i = 0 , obj.list.Count - 1 do
print(obj.list[i])
end
print(obj.list)
--在Lua中創(chuàng)建一個(gè)List對(duì)象
--老版本
local list2 = CS.System.Collections.Generic["List`1[System.String]"]()
print(list2)
list2:Add("123")
print(list2[0])
--新版本 >v2.1.12
--相當(dāng)于得到了一個(gè)List
local List_String = CS.System.Collections.Generic.List(CS.System.String)
local list3 = List_String()
list3:Add("10238910823")
print(list3[0])
print("*************Lua調(diào)用C#Dictionary相關(guān)知識(shí)點(diǎn)***************")
--使用和C#一致
obj.dic:Add (1,"123")
print(obj.dic[1])
for k,v in pairs(obj.dic) do
print(k,v)
end
--在Lua中創(chuàng)建一個(gè)字典對(duì)象
local Dic_String_Vector3 = CS.System.Collections.Generic.Dictionary(CS.System.String,CS.UnityEngine.Vector3)
local dic2 = Dic_String_Vector3()
dic2:Add("123",CS.UnityEngine.Vector3.right)
for k,v in pairs(dic2) do
print(k,v)
end
--在Lua中創(chuàng)建的字典 直接通過中括號(hào)得不到 結(jié)果是nil
print(dic2["123"])
print(dic2:TryGetValue("123"))
--如果要通過鍵獲取值 要通過這個(gè)固定方法
print(dic2:get_Item("123"))
dic2:set_Item("123",nil)
print(dic2:get_Item("123"))
Lua使用C#拓展方法
public static class Tools
{
public static void Move(this Lesson4 obj)
{
Debug.Log(obj.name + "移動(dòng)");
}
}
public class Lesson4
{
public string name = "123123";
public void Speak(string str)
{
Debug.Log("str");
}
public static void Eat()
{
Debug.Log("吃東西");
}
}
print("*************Lua調(diào)用C#拓展方法相關(guān)知識(shí)點(diǎn)***************")
Lesson4 = CS.Lesson4
--使用靜態(tài)方法
--CS.命名空間.類名.靜態(tài)方法名
Lesson4.Eat()
--成員方法 實(shí)例化出來用
local obj = Lesson4()
--成員方法一定要用冒號(hào)
obj:Speak("string")
--使用拓展方法 和使用成員方法一致
--要調(diào)用 C#某個(gè)類中的拓展方法 一定要在拓展方法的靜態(tài)類前加上LuaCallCSharp特性 并在Unity中生成Lua代碼
obj:Move()
Lua使用C# ref和out函數(shù)
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, ref int b, ref 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;
}
}
print("*************Lua調(diào)用C#ref和out方法相關(guān)知識(shí)點(diǎn)***************")
Lesson5 = CS.Lesson5
local obj = Lesson5()
--ref參數(shù) 會(huì)以多返回值的形式返回lua
--如果函數(shù)存在返回值那么第一個(gè)值就是改返回值
--之后的返回值就是ref的結(jié)果 從左到右一一對(duì)應(yīng)
--ref參數(shù)需要傳入一個(gè)默認(rèn)值來占位置 如果不傳剩余空位會(huì)傳入默認(rèn)值
--a 相當(dāng)于函數(shù)返回值
--b 第一個(gè)ref
--c 第二個(gè)ref
local a,b,c = obj:RefFun(1,0,0,1)
print(a)
print(b)
print(c)
--out參數(shù) 會(huì)以多返回值的形式返回lua
--如果函數(shù)存在返回值那么第一個(gè)值就是改返回值
--之后的返回值就是out的結(jié)果 從左到右一一對(duì)應(yīng)
--out參數(shù) 不需要傳占位置的值
print("****************************")
local a,b,c = obj:OutFun(20,30)
print(a)
print(b)
print(c)
--綜合使用時(shí) 綜合上面的規(guī)則
--ref 需要站位 out不需要
--第一個(gè)是函數(shù)的返回值 之后從左到右依次對(duì)應(yīng)ref或out
print("****************************")
local a,b,c = obj:RefOutFun(20,1)
print(a)
print(b)
print(c)
Lua使用C#重載函數(shù)
public class Lesson6
{
public int Calc()
{
return 100;
}
public int Calc(int a,int b)
{
return a + b;
}
public int Calc(int a)
{
return a;
}
public float Calc(float a)
{
return a;
}
}
print("*************Lua調(diào)用C#重載函數(shù)相關(guān)知識(shí)點(diǎn)***************")
local obj = CS.Lesson6()
--雖然Lua自己不支持重載函數(shù)
--但是Lua支持調(diào)用C#中的重載函數(shù)
print(obj:Calc())
print(obj:Calc(1,3))
--Lua雖然支持調(diào)用C#重載函數(shù)
--但是因?yàn)長ua中的數(shù)值類型只有Number
--所以對(duì)C#中多精度重載函數(shù)支持不好 會(huì)分不清
--在使用時(shí)會(huì)出現(xiàn)意想不到的事
print(obj:Calc(10))
print(obj:Calc(10.3))--輸出了0
--解決重載函數(shù)含糊問題
--xLua提供了解決方案 反射機(jī)制
--這種方法盡量別用 效率低
--Type是反射的關(guān)鍵類
local m1 = typeof(CS.Lesson6):GetMethod("Calc",{typeof(CS.System.Int32)})
local m2 = typeof(CS.Lesson6):GetMethod("Calc",{typeof(CS.System.Single)})
--通過Xlua提供的方法 把它轉(zhuǎn)換成lua函數(shù)來使用
--一般我們轉(zhuǎn)一次 然后重復(fù)使用
local f1 = xlua.tofunction(m1)
local f2 = xlua.tofunction(m2)
--成員方法 第一個(gè)參數(shù)傳對(duì)象
--靜態(tài)方法不用傳對(duì)象
print(f1(obj,10))
print(f2(obj,10.9))
Lua使用C#委托和事件
public class Lesson7
{
//聲明委托和事件
public UnityAction del;
public event UnityAction eventAction;
public void DoEvent()
{
if(eventAction != null)
eventAction();
}
public void ClearEvent()
{
eventAction = null;
}
}
print("*************Lua調(diào)用C#委托相關(guān)知識(shí)點(diǎn)***************")
local obj = CS.Lesson7()
--委托可以用來裝函數(shù)
--使用C#中的委托 裝lua中的函數(shù)
local fun = function ( )
print("Lua函數(shù)")
end
print("****************************")
--Lua中沒有復(fù)合運(yùn)算符 不能+=
--如果第一次往委托中加函數(shù) 因?yàn)槭莕il 不能直接+
--所以第一次要先賦值=
obj.del = fun
--obj.del = obj.del + fun
obj.del = obj.del + fun
--不建議這么寫 最好是先聲明再加(類似于匿名函數(shù),在委托中刪不掉)
obj.del = obj.del + function ()
print("臨時(shí)聲明的函數(shù)")
end
--委托執(zhí)行
obj.del()
print("****************************")
obj.del = obj.del -fun
obj.del = obj.del -fun
obj.del()
--清空所有的函數(shù)
obj.del = nil
--清空后要先賦值
obj.del = fun
obj.del()
print("*************Lua調(diào)用C#事件相關(guān)知識(shí)點(diǎn)***************")
local fun2 = function ()
print("Action")
end
print("****************************")
--事件加減函數(shù)和委托非常不一樣
--lua中使用C#事件 加函數(shù)
--有點(diǎn)類似于使用成員方法 冒號(hào)事件名("+",函數(shù)變量)
obj:eventAction("+",fun2)
--最好不要這么寫
obj:eventAction("+",function ()
print("Action")
end)
obj:DoEvent()
print("****************************")
obj:eventAction("-",fun2)
obj:DoEvent()
--清楚事件 不能直接設(shè)空
--obj.eventAction=nil會(huì)報(bào)錯(cuò)
obj:ClearEvent()
obj:DoEvent()
Lua使用C#二維數(shù)組
public class Lesson8
{
public int[,] array = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
}
print("*************Lua調(diào)用C#二維數(shù)組相關(guān)知識(shí)點(diǎn)***************")
local obj = CS.Lesson8()
--獲取長度
print("行:"..obj.array:GetLength(0))
print("列:"..obj.array:GetLength(1))
--獲取元素
--不能通過[0,0]或[0][0]來訪問元素 會(huì)報(bào)錯(cuò)
print(obj.array:GetValue(0,0))
print(obj.array:GetValue(1,0))
for i = 0,obj.array:GetLength(0)-1 do
for j=0,obj.array:GetLength(1)-1 do
print(obj.array:GetValue(i,j))
end
end
Lua使用C#的null和nil比較
//為object 拓展一個(gè)方法
[LuaCallCSharp]
public static class Lesson9
{
//拓展一個(gè)為Objcet判空的方法 主要給Lua用 lua沒法用null和nil比較
public static bool IsNull(this Object obj)
{
return obj == null;
}
}
print("*************Lua調(diào)用C# nil和null比較相關(guān)知識(shí)點(diǎn)***************")
--往場景對(duì)象上添加一個(gè)腳本 如果不存在就加 存在就不加
GameObject = CS.UnityEngine.GameObject
Rigidbody = CS.UnityEngine.Rigidbody
local obj = GameObject("添加測試腳本")
--得到身上的剛體組件 如果沒有就加 有就不加
local rig = obj:GetComponent(typeof(Rigidbody))
print(rig)
--判斷空
--nil和null沒法進(jìn)行==比較(rig == nil)
--第一種方法:rig:Equals(nil) then
--[[if rig:Equals(nil) then
print("123")
rig = obj:AddComponent(typeof(Rigidbody))
end]]
--第二種
--[[if IsNull(rig) then
print("123")
rig = obj:AddComponent(typeof(Rigidbody))
end]]
--第三種 在C#中添加方法
if rig:IsNull() then
print("123")
rig = obj:AddComponent(typeof(Rigidbody))
end
print(rig)
Lua和系統(tǒng)類或委托相互使用
public static class Lesson10
{
[CSharpCallLua]
public static List
{
//在這里面加上需要加上[CSharpCallLua]特性的type
typeof(UnityAction
};
[LuaCallCSharp]
public static List
{
typeof(GameObject),
typeof(Rigidbody)
};
}
GameObject = CS.UnityEngine.GameObject
UI = CS.UnityEngine.UI
local slider = GameObject.Find("Slider")
print(slider)
local sliderScript = slider:GetComponent(typeof(UI.Slider))
print(sliderScript)
sliderScript.onValueChanged:AddListener(function (f)
print(f)
end)
Lua使用C#協(xié)程
print("*************Lua調(diào)用C# 協(xié)程相關(guān)知識(shí)點(diǎn)***************")
--xlua提供的一個(gè)工具表
--一定是要通過require調(diào)用后才能用
util = require("xlua.util")
--C#中協(xié)程啟動(dòng)都是通過繼承了Mono的類 通過里面的啟動(dòng)函數(shù)StartCoroutine
GameObject = CS.UnityEngine.GameObject
WaitForSeconds = CS.UnityEngine.WaitForSeconds
--在場景中新建一個(gè)空物體 掛一個(gè)腳本上去 腳本繼承mono使用它來開啟協(xié)程
local obj = GameObject("Coroutine")
local mono = obj:AddComponent(typeof(CS.LuaCallCSharp))
--希望用來被開啟的協(xié)程函數(shù)
fun = function ()
local a = 1
while true do
--Lua中不能直接使用C#中的yield return
--就使用Lua中的協(xié)程返回
coroutine.yield(WaitForSeconds(1))
print(a)
a = a + 1
if a>5 then
mono:StopCoroutine(b)
end
end
end
--我們不能直接將lua函數(shù)傳入開啟協(xié)程
--如果要把lua函數(shù)當(dāng)做協(xié)程函數(shù)傳入
--必須先調(diào)用xlua.util中的cs_generator(lua函數(shù))
b = mono:StartCoroutine(util.cs_generator(fun))
Lua使用C#泛型函數(shù)
print("*************Lua調(diào)用C# 泛型函數(shù)相關(guān)知識(shí)點(diǎn)***************")
local obj = CS.Lesson12()
local child = CS.Lesson12.TestChild()
local father = CS.Lesson12.TestFather()
--支持有約束有參數(shù)的泛型函數(shù)
obj:TestFun1(child,father)
obj:TestFun1(father,child)
--lua中不支持沒有約束的泛型函數(shù)
--obj:TestFun2(child)
--Lua中不支持有約束但是沒有參數(shù)的泛型函數(shù)
--obj:TestFun3()
--Lua中不支持 非Class的約束
--obj:TestFun4(child)
--有一定使用限制
--Mono打包 這種方式支持使用
--il2cpp打包 如果泛型參數(shù)是引用類型才可以使用
--il2cpp打包 如果泛型參數(shù)是值類型 除非C#那邊已經(jīng)調(diào)用過了 同類型的泛型參數(shù)lua中才能調(diào)用
--補(bǔ)充知識(shí) 讓上面不支持使用的泛型函數(shù) 變得能夠使用
--得到通用函數(shù)
--設(shè)置泛型類型再使用
--xlua.get_generic_method(類,"函數(shù)名")
local testFun2 = xlua.get_generic_method(CS.Lesson12,"TestFun2")
local testFun2_R = testFun2(CS.System.Int32)
--調(diào)用
--成員方法 第一個(gè)參數(shù) 傳調(diào)用函數(shù)的對(duì)象 如果是靜態(tài)函數(shù)就不用傳
testFun2_R(obj,1)
public class Lesson12
{
public interface ITest
{
}
public class TestFather
{
}
public class TestChild:TestFather,ITest
{
}
public void TestFun1
{
Debug.Log("有參數(shù) 有約束的泛型方法");
}
public void TestFun2
{
Debug.Log("有參數(shù) 沒約束的泛型方法");
}
public void TestFun3
{
Debug.Log("有約束 沒參數(shù)的泛型函數(shù)");
}
public void TestFun4
{
Debug.Log("有約束有參數(shù) 但是約束不是類");
}
}
柚子快報(bào)激活碼778899分享:Lua調(diào)用C#
好文閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。