XLua热更新三部曲
一、lua访问C#静态属性与方法
- 基本规则
- lua里头没有new关键字。
- 所有C#相关的都放到CS下,包括构造函数,静态成员属性、方法。
-- 1.实例化一个Unity对象
-- 等价的unity 代码: GameObject newGo = new GameObject();
local newGo = CS.UnityEngine.GameObject() -- unity 中多了一个newGo的空物体
--2. lua查找游戏物体,改名
local TexBeg = CS.UnityEngine.GameObject.Find("TexBeg") --在unity中查找名字为"TexBeg"的物体
TexBeg.name = "Begin" --把TexBeg 改名为 Begin
local TexStart = TexBeg:GetComponent("UnityEngine.UI.Text")
TexStart.text = "修改为Start" --把TexBeg的文本 改名为"修改为Start"
二、lua访问C#常用方式
调用自定义c#类
local IsInvoke = CS.IsInvokedClass -- 找到IsInvokedClass类
local classObj = IsInvoke() -- 调用父类和子类的构造函数
-- 输出:先后调用父类和子类的构造函数
-- IsInvokedClass是父类构造函数
-- IsInvokedClass是子类构造函数
访问成员属性与方法
| 方式 | 用法 |
|---|---|
| 读成员属性 | classobj.DMF |
| 写成员属性 | classobj.DMF = 1024 |
| 调用成员方法 | classobj:DMFunc() |
注意:
- lua中使用冒号,表示成员方法的调用。它自动完成把当前对象作为一 个参数,传入方法。
- lua中使用点,则表示静态属性与方法调用。它需要手工往方法中传递 当前对象。
--4.调用普通方法
classObj:Method1() --子类方法
classObj:ShowFatherInfo() -- 父类方法
--5.调用重载方法
---lua的类型远远不如C#丰富,存在一对多的情况
---比如C#的int,float,double都对应于lua的number。只能调用到其中一个(生成代码中排前面的那个)
classObj:Method1(1,2)
classObj:Method1("你好","再见")
--6.调用c#中带有params关键字的方法
local res = classObj:Method2(10,20,"a","b","c","qwe","rrr")
print("调用c#中带有params关键字的方法,返回值 = "..res);
-- 输出:调用c#中带有params关键字的方法,返回值 = 30
--7.Lua 映射c#结构体及接口参数
--- 调用结构体
myStruct = {x = "apple", y = "banana"}
classObj:Method3(myStruct) -- 传入结构体
-- 输出:p.x = apple p.y = banana
---调用接口
myInterface = {
x = 1000,
y = 800,
speak = function()
print("Lua中speak方法调用")
end
}
classObj:Method4(myInterface)-- 传入接口
-- 输出:p.x p.x = 1000 p.y = 800
--8.Lua 映射c#委托
---num是从c#中获取的“88”,调用是通过lua调用
myDelegate = function(num)
print("Lua 映射委托的方法,参数为"..num)
end
classObj:Method5(myDelegate)
--输出: LUA: Lua 映射委托的方法,参数为88
--9.LUA 调用多返回值的方法
/* c#代码
*/
local num1 = 10
local num2 = 20
local num3 = 30
local res1,res2,res3 = classObj:Method6(num1,num2,num3)
print("res1 "..res1)
print("res2 "..res2)
print("res3 "..res3)
调用泛型为参数的方法
/* c#代码
public void Method7(List<string> strArray)
{
Debug.Log("定义一个泛型为参数的方法");
foreach(var item in strArray)
{
Debug.Log("泛型集合: " + item);
}
}
*/
mytable = {"apple","banana","peach","pear"}
classObj:Method7(mytable)
-- 输出:所有mytable元素
---C#调用自定义泛型方法
classObj:Method_InvokeGen()
---C#调用扩展方法
classObj:Method_InvokeGenExtensionGen()
--lua传参: 拓展方法才能传参数。原方法会报错
maxNum = CS.MyGengerric():ExtGetMax(888,666)
print("用扩展方法传参数"..maxNum)
附录
LuaScripts.Lua (调用脚本)
--- Lua调用unity系统的api
--1.实例化一个Unity对象
--对应unity: GameObject newGo = new GameObject();
local newGo = CS.UnityEngine.GameObject() -- unity 中多了一个newGo的空物体
--2. 查找游戏物体,改名
local TexBeg = CS.UnityEngine.GameObject.Find("TexBeg")
TexBeg.name = "Begin" --把TexBeg 改名为 Begin
local TexStart = TexBeg:GetComponent("UnityEngine.UI.Text")
TexStart.text = "修改为Start" --把TexBeg的文本 改名为"修改为Start"
--3. 调用自定义c#类
local IsInvoke = CS.IsInvokedClass -- 找到IsInvokedClass类
local classObj = IsInvoke() -- 调用父类和子类的构造函数
--4.调用普通方法
classObj:Method1() --子类方法
classObj:ShowFatherInfo() -- 父类方法
--5.调用重载方法
---lua的类型远远不如C#丰富,存在一对多的情况
---比如C#的int,float,double都对应于lua的number。只能调用到其中一个(生成代码中排前面的那个)
classObj:Method1(1,2)
classObj:Method1("你好","再见")
--6.调用c#中带有params关键字的方法
local res = classObj:Method2(10,20,"a","b","c","qwe","rrr")
print("调用c#中带有params关键字的方法,返回值 = "..res);
--7.Lua 映射c#结构体及接口参数
--- 调用结构体
myStruct = {x = "apple", y = "banana"}
classObj:Method3(myStruct) -- 传入结构体
---调用接口
myInterface = {
x = 1000,
y = 800,
speak = function()
print("Lua中speak方法调用")
end
}
classObj:Method4(myInterface)-- 传入接口
--8.Lua 映射c#委托
---num是从c#中获取的“88”,调用是通过lua调用
myDelegate = function(num)
print("Lua 映射委托的方法,参数为"..num)
end
classObj:Method5(myDelegate)
--9.LUA 调用多返回值的方法
local num1 = 10
local num2 = 20
local num3 = 30
local res1,res2,res3 = classObj:Method6(num1,num2,num3)
print("res1 "..res1)
print("res2 "..res2)
print("res3 "..res3)
--10.定义一个泛型为参数的方法
mytable = {"apple","banana","peach","pear"}
classObj:Method7(mytable)
---C#调用自定义泛型方法
classObj:Method_InvokeGen()
---C#调用扩展方法
classObj:Method_InvokeGenExtensionGen()
--拓展方法才能传参数。原方法会报错
maxNum = CS.MyGengerric():ExtGetMax(888,666)
print("用扩展方法传参数"..maxNum)
IsInvokedClass.CS(lua主要调用的类)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using XLua.LuaDLL;
public class IsInvokedClass : IsInvoked_Father
{
public string ChildClassName = " 子类字段";
public IsInvokedClass()
{
Debug.Log(" IsInvokedClass是子类构造函数");
}
//重载方法
public void Method1()
{
Debug.Log(" IsInvokedClass子类的Method1方法");
}
public void Method1(int num1, int num2)
{
Debug.Log(" Method1(int num1, int num2):" + num1 + num2);
}
public void Method1(string num1, string num2)
{
Debug.Log(" Method1(string num1, string num2):" + num1 + num2);
}
//6.定义带有返回值,参数,params关键字的方法
public int Method2(int num1, int num2, params string[] strArray)
{
Debug.Log("带params关键字的方法");
foreach(string item in strArray)
{
Debug.Log("输出参数内容:" + item);
}
return num1 + num2;
}
//7.Lua 映射c#结构体
public void Method3(MyStruct p)
{
Debug.Log("Lua 映射c#结构体");
Debug.Log("p.x = " + p.x + "p.y = " + p.y);
}
//7.Lua 映射c#接口参数
public void Method4(MyInterface p)
{
Debug.Log("6.Lua 映射c#接口参数");
Debug.Log("p.x = " + p.x + " p.y = " + p.y);
}
//8.Lua 映射c#委托
public void Method5(MyDelegate p)
{
Debug.Log("8.Lua 映射c#委托");
p.Invoke(88);
}
//9.LUA 调用多返回值的方法
public int Method6(int num1, out int num2, ref int num3)
{
Debug.Log("9.LUA 调用多返回值的方法");
num2 = 3000;
num3 = 1000;
return num1 + 100;
}
//10.定义一个泛型为参数的方法
public void Method7(List<string> strArray)
{
Debug.Log("定义一个泛型为参数的方法");
foreach(var item in strArray)
{
Debug.Log("泛型集合: " + item);
}
}
//C#调用自定义泛型方法
public void Method_InvokeGen()
{
int maxNum = 0;
int num1 = 100;
int num2 = 200;
MyGengerric obj = new MyGengerric();
maxNum = obj.GetMax<int>(num1, num2);
Debug.Log("C#中比大小:" + maxNum);
}
//C#调用扩展方法
public void Method_InvokeGenExtensionGen()
{
int maxNum = 0;
int num1 = 600;
int num2 = 800;
MyGengerric obj = new MyGengerric();
maxNum = obj.ExtGetMax(num1, num2);
Debug.Log("C#中扩展方法比大小:" + maxNum);
}
}
public struct MyStruct
{
public string x, y;
}
[CSharpCallLua]
//调用接口,必须引用xlua包 + 打标签
public interface MyInterface
{
int x { get; set; }
int y { get; set; }
void speak();
}
[CSharpCallLua]
//委托
public delegate void MyDelegate(int num);
IsInvoked_Father.cs(父类)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IsInvoked_Father
{
public string FatherClassName = " 父类字段";
public IsInvoked_Father()
{
Debug.Log(" IsInvokedClass是父类构造函数");
}
public void ShowFatherInfo()
{
Debug.Log(" IsInvoked_Father父类的ShowFatherInfo方法");
}
}
MyGengerric.cs(自定义泛型)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyGengerric
{
public T GetMax<T>(T num1, T num2) where T : IComparable
{
if(num1.CompareTo(num2) < 0)
{ return num2;}
else
{return num1;}
}
}
Extention_myGene(定义拓展方法)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
//注意:是LuaCallCSharp,不是反过来的
[LuaCallCSharp]
// 定义拓展方法
public static class Extention_myGene
{
//被拓展类作为第一个参数this MyGengerric gen
//要加this
public static int ExtGetMax(this MyGengerric gen, int num1, int num2)
{
if(num1 < num2)
{
return num2;
}
else
{
return num1;
}
}
}
HelloWorld.cs (调用lua函数)
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class HelloWorld : MonoBehaviour
{
LuaEnv env = null;
// Start is called before the first frame update
void Start()
{
env = new LuaEnv();
env.AddLoader(HelloWorld.CustomMyLoader); // 调用方法
env.DoString("require 'LuaScripts'");
}
public static byte[] CustomMyLoader(ref string fileName)
{
byte[] byArrayReture = null;
//脚本的路径
string luaPath = Application.dataPath + "/Scripts/LuaScripts/" + fileName + ".lua";
//读取lua路径中指定的lua文件
string strLuaContent = File.ReadAllText(luaPath);
//数据类型转换
byArrayReture = System.Text.Encoding.UTF8.GetBytes(strLuaContent);
return byArrayReture;
}
private void OnDestroy()
{
//释放env
env.Dispose();
}
}