Xlua hotfix C# case

1 Xlua calls C# method and passes parameters

Lua calls the C# coroutine and passes the Action type parameter. The Action type parameter in C# can be directly replaced by function

public void TestFuntion()
    {
        Action<string> callBack = (res) =>
        {
            Debug.Log("res is " + res);
        };
        StartCoroutine(TextEnumerator(callBack));
    }

    IEnumerator TextEnumerator(Action<string> callBack)
    {
        yield return new WaitForSeconds(0.1f);
        Debug.Log("finish waite in unity");
        callBack?.Invoke("excute callback");
    }

Lua hotfix rewrites TestFuntion method

xlua.hotfix( CS.GameMain, {
	TestFuntion = function(self)
		local endAction = function(res)
			print("lua endAction", res)
		end
		self:StartCoroutine(self:TextEnumerator(endAction))
	end;

})

Results of the
insert image description here

Lua calls the C# coroutine and passes the set type parameters. The set type parameters in C# can be directly replaced by table type data

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }

    public User(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }
}
......

public void ShowDictionary(Dictionary<string, User> dic)
    {
        foreach (var VARIABLE in dic)
        {
            Debug.Log("dic info is " + VARIABLE.Key + ":" + VARIABLE.Value.Name);
        }
    }

Lua calls the c# method, and the parameter type is Dictionary<string, User>

xlua.hotfix( CS.GameMain, {
	TestFuntion = function(self)
		local tab={}
		tab["dd"] = CS.User("tom", 22)
		tab["ff"] = CS.User("jeck", 18)
		--调用C#方法,参数是
		self:ShowDictionary(tab)
	end;
})

Results of the
insert image description here

2 Rewrite the coroutine method

IEnumerator TextEnumerator(Action<string> callBack)
    {
        yield return new WaitForSeconds(0.1f);
        Debug.Log("finish waite in unity");
        callBack?.Invoke("excute callback");
    }

When lua rewrites the coroutine method, the cs_generator method in the tool script util provided by xlua should be used. The tool location is in XLua/Resources/xlua/util.lua.txt

local util = require("xlua.util")

xlua.hotfix( CS.GameMain, {
	
	TextEnumerator = function(self, endAction)
		return util.cs_generator(function()
			coroutine.yield(UnityEngine.WaitForSeconds(0.1))
			print("wait 0.1 second finish")
			coroutine.yield(0)
			print("wait finish")
			endAction("lua excute callback ")
		end)
	end;


})

Running results
insert image description here
.

3 Create C# collection type data object in lua

lua code

local UnityEngine = CS.UnityEngine
local util = require("xlua.util")

local TestDictionary = function (  )
		--创建list
		local List_V3 = CS.System.Collections.Generic.List(UnityEngine.Vector3)
		local v3List = List_V3()
		v3List:Add(UnityEngine.Vector3(1,1,1))
		v3List:Add(UnityEngine.Vector3(2,1,1))
		v3List:Add(UnityEngine.Vector3(3,1,1))
		for i=0,v3List.Count-1 do
				print(v3List[i])
		end
		--创建字典 key:string, value:string
		local Dic_String_String=CS.System.Collections.Generic.Dictionary(CS.System.String, CS.System.String)
		local dicString=Dic_String_String()
		dicString:Add("ddd", "this is dictionary test")
		print(dicString:get_Item("ddd"))

		local vect3 = UnityEngine.Vector3(1,11,111)
		print(vect3)

		--创建字典 key:string, value:Vector3
		local Dic_String_V3=CS.System.Collections.Generic.Dictionary(CS.System.String, UnityEngine.Vector3)
		local dic3=Dic_String_V3()
		dic3:Add("s0",UnityEngine.Vector3.right)
		dic3:Add("s1",UnityEngine.Vector3.zero)
		-- lua中创建的字典若键不是int类型 需要使用set_Item, get_Item特殊的访问方式
		print(dic3:get_Item("s0"))
		print("s1 is", dic3:get_Item("s1"))
		dic3:set_Item("s0", CS.UnityEngine.Vector3(1,11,111))
		for i,v in pairs(dic3) do
			print("Dictionary item:",i,v)
		end
end;


xlua.hotfix( CS.GameMain, {
	
	TestFuntion = function(self)
		TestDictionary()
	end;


})

Unity execution result
insert image description here

It can be executed normally in unity, but in IL2Cpp mode, after packaged and installed on the mobile phone, an error will be reported for which no ahead of time (AOT) code was generated. The reason for the error seems to be that the calling object type is not defined.

LuaException: c# exception:Attempting to call method 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::.ctor' for which no ahead of time (AOT) code was generated.,stack:  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0 
  at XLua.OverloadMethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 
  at XLua.MethodWrap.Call (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 
  at XLua.StaticLuaCallbacks.FixCSFunction (System.IntPtr L) [0x00000] in <00000000000000000000000000000000>:0 
stack traceback:
        [C]: in local 'Dic_String_V3'
        mylua.lua:25: in upvalue 'TestDictionary'
        mylua.lua:41: in function <mylua.lua:40>

When I was testing here, I found that if there is a dictionary type object of this type created in C#, Lua will not report an error on the mobile phone when it is called again. For example, the c#
code is written like this

public void TestFuntion()
    {
        Action<string> callBack = (res) =>
        {
            Debug.Log("res is " + res);
        };
        StartCoroutine(TextEnumerator(callBack));
        //创建 Dictionary<string, Vector3>
        Dictionary<string, Vector3> dic = new Dictionary<string, Vector3>();
    }

4 Generic methods

c# json serialization test

[Serializable]
public class Book
{
    public string name ;
    public string price;
    public int pageNum;

    public Book(string name, string price, int page)
    {
        this.name = name;
        this.price = price;
        this.pageNum = page;
    }

}
......

public void JsonTest()
    {
        Book u = new Book("Unity 入门到放弃", "$99", 10000);
        string json = JsonUtility.ToJson(u).ToString();
        Debug.Log(json);
        Book bb = FromJsone<Book>(json);
        Debug.Log(bb.name);
    }

    public T FromJsone<T>(string json)
    {
       T res = JsonUtility.FromJson<T>(json);
       return res;
    }

Lua calls the json deserialization method

xlua.hotfix( CS.GameMain, {
	
	JsonTest = function(self)
		local u = CS.Book("lua 入门到放弃", "$88", 8888)
		local json = CS.UnityEngine.JsonUtility.ToJson(u)
		print(json)
		--定义泛型方法
		local methord = xlua.get_generic_method(CS.GameMain,"FromJsone")
		--定义泛型参数类型
		local fromJson = methord(CS.Book)
		--调用泛型方法,第一个参数是调用对象,后面是方法参数
		local bb = fromJson(self, json)
		print(bb.name)
	end;

})

operation result
insert image description here

Guess you like

Origin blog.csdn.net/u011484013/article/details/125658387