当前位置:网站首页>Summary of knowledge points of xlua hot update solution
Summary of knowledge points of xlua hot update solution
2022-07-07 15:44:00 【Listen to the rain outside the window】
XLua Hot update solution knowledge points summary
List of articles
- XLua Hot update solution knowledge points summary
- Preface
- The essence of hot renewal
- C# Call Lua Related knowledge
- Lua Call C# Related knowledge
- The main entry of the program
- Lua call C# Class
- Lua call C# enumeration
- Lua call C# Array of
- Lua call C# Of List
- Lua call C# Of Dictionary
- Lua call C# Extension method of
- Lua Call with ref and out Function of parameter
- Lua Call overloaded functions
- Lua Invoke delegates and events
- Lua Call a special system type
- Lua Of nil and C# Of null
- Lua call C# Cooperation of
- Lua call C# Generic functions of
Preface
Hot update is to realize the installation without repacking , A common scheme for updating clients online . It is generally divided into resource hot update and code hot update , There are many schemes for hot update of code , Which is provided by Tencent xLua
At present Lua A commonly used solution in hot update , This article is only for xLua
Summarize knowledge points , Readers who are interested in various hot updates can refer to my blog which specializes in explaining the basic functions and principles of various hot updates .
The essence of hot renewal
- by Unity Provide Lua The ability to program
- Give Way C# and Lua You can call each other to access
unity Native languages are based on C# Implementation related API, but C# The code needs to be compiled before it can be used , Use it directly C# There are many limitations . therefore , Use a scripting language that does not require compilation Lua The solution of has become a common solution for hot update .Lua Call is not supported by itself C# and U3D Correlation API,xLua
The essence of the scheme is to make Lua To be able to call U3D Provided C# Correlation API, Thus, when the code is hot updated , Conduct Lua Code replacement and update can be achieved .
C# Call Lua Related knowledge
Lua Parser :LuaEnv
xLua
The package provided C# object , Be able to use the relevant API Realization C# Call in LuaThe essence : stay C# In the running environment, a system that can run Lua Virtual environment for , In the virtual environment Lua Various types to C# Conversion of type , And then for C# Provide call access Lua The ability of .
Related to the offer API And explanation of usage
//xLua Namespace references using XLua; //Lua Parser LuaEnv Acquisition LuaEnv env = new LuaEnv(); // perform Lua command env.DoString("Lua command "); // Generally used to load Lua Main entry script // eliminate Lua Garbage collection for objects not manually released in env.Tick(); // It is generally used for timing execution in frame update perhaps Execute when switching scenes // Destruction and release Lua Parser env.Dispose(); //======== Key points : Redirect Loader======= //xLua Default in Resources Download the script In other places Lua Can't load to , Custom loading is required //xLua Provided path redirection method , When executed Lua In language require when , It will automatically callback API Delegate method as a parameter in env.AddLoader(LuaEnv.CustomLoader func); // Form of entrustment Pass in require Parameter reference , Return what needs to be loaded Lua Byte array of script file public delegate byte[] CustomLoader(ref string filepath);
API Points for attention :
Lua
The parser defaults from Resources Download ,u3d Under the Resources The directory is not recognized Lua Script suffix , therefore It has to be for.lua
Add scripts such as .txt Can access and call . AB There is also this special case in the bag , But you can load directly under the custom folder without adding an additional suffix . At the same time, the redirection provided by the parser supports multiple timesBecause of these circumstances , To facilitate development , You can choose to load from the custom folder under the daily compiler without adding a suffix every time , After packaging and launching, it must be AB Package loading can achieve hotter . Then you can realize the small functions under the editor , One click will all the customized folders Lua The script is typed AB Package and add suffix , Later, the author will implement .
LuaManager.cs
encapsulation API, Realization Lua Manager ( Singleton mode and AB Package manager stay AB Bao's blog explained in detail , If you need to know something, you can check )using System.IO; using UnityEngine; using XLua; namespace Common { /// <summary> /// Lua Manager /// External provision Lua A simple call to the parser Guarantee uniqueness /// </summary> public class LuaManager : SingletonLazy<LuaManager> { // perform Lua Functions of language Release the garbage The destruction Redirect private LuaEnv luaEnv; // return Lua The big of the middle G surface _G Provide find Lua Methods of global variables //T obj = Global.Get<T>(" Variable name "); public LuaTable Global { get { //LuaEnv Properties of return luaEnv.Global; } } protected override void Init() { base.Init(); luaEnv = new LuaEnv(); // Load under custom path Assets/Lua Next Convenient for daily development and use luaEnv.AddLoader(MyCustomLoader); //Lua Script redirection stay AB Load in the package Use when packaging and launching //luaEnv.AddLoader(CustomABLoader); } //Lua The script will be placed in AB In bag , Then load the Lua Script resources to execute it //AB The package should also be loaded with text ( The suffix is .lua If you can't recognize, you need to add .txt) private byte[] CustomABLoader(ref string filepath) { // from AB Load in the package Lua file // load AB Under bag Lua file -- adopt AB Package manager TextAsset text = ABManager.Instance.LoadResource<TextAsset>("lua", filepath +".lua"); if(text == null) { Debug.Log(" Redirection failed The file named " + filepath); return null; } // load byte Array return text.bytes; } // Redirect : Custom path delegate method private byte[] MyCustomLoader(ref string filepath) { // Through the logic in the function Go to load Lua file //filepath Namely require File name in // Splice one Lua The path of the file string path = Application.dataPath + "/Lua/" + filepath + ".lua"; // utilize File Read the file // Judge whether the file exists if (File.Exists(path)) { return File.ReadAllBytes(path); } else { Debug.Log(" Redirection failed The file named :" + filepath); } return null; } /// <summary> /// perform Lua Language /// </summary> /// <param name="str">Lua sentence </param> public void DoString(string str) { if(luaEnv == null) { Debug.Log(" Parser is empty , Please check "); return; } luaEnv.DoString(str); } public void DoLuaFile(string fileName) { if (luaEnv == null) { Debug.Log(" Parser is empty , Please check "); return; } string path = string.Format("require('{0}')", fileName); luaEnv.DoString(path); } /// <summary> /// Release the garbage /// </summary> public void Tick() { if (luaEnv == null) { Debug.Log(" Parser is empty , Please check "); return; } luaEnv.Tick(); } /// <summary> /// The destruction Lua Parser /// </summary> public void Dispose() { if (luaEnv == null) { Debug.Log(" Parser is empty , Please check "); return; } luaEnv.Dispose(); luaEnv = null; } } }
C# obtain Lua The type of Foundation
utilize LuaEnv
Provided Global Property to get and set global variables , Note that it cannot be obtained Local The local variable
Global Correlation API And how to use it ( notes : Use the above Lua Manager provides Global Property to call )
// Set up Lua The value of the basic variable in utilize Set function
//Set<Tkey,Tvalue>(" Variable name ", value ) Generally, the first generic type is string Type represents variable name The second is value, Can be used to create / modify Lua Is the value of the variable
LuaManager.Instance.Global.Set<string,int>("testNumber", 100);
// obtain Lua The value of the basic variable in Get<T>(" Variable name "); The generic type is consistent with the return value type
int testNumber = LuaManager.Instance.Global.Get<int>("testNumber");
bool testBool = LuaManager.Instance.Global.Get<bool>("testBool");
float testFloat = LuaManager.Instance.Global.Get<float>("testFloat");
string testString = LuaManager.Instance.Global.Get<string>("testString");
// Pay attention to getting Lua When the number type of , According to Lua The specific value in is determined by int float still double For storage
C# obtain Lua Global function of function
obtain Lua Two main ways of function
- Use delegation to obtain
- utilize
xLua
ProvidedLuaTable
To get ( Low efficiency The first one is recommended )
Get a function with no parameters and no return value
// No parameter, no return value Lua Function acquisition // Custom no parameter no return delegate acquisition Lua function public delegate void CustomCall(); CustomCall call = LuaManager.Instance.Global.Get<CustomCall>("testFun"); // obtain Lua There is no parameter and no return function in testFun call(); // The delegate // utilize C# Provided entrust Action To get --Action No parameter no return Action action = LuaManager.Instance.Global.Get<Action>("testFun"); action(); //Unity Commission provided UnityAction unityAction = LuaManager.Instance.Global.Get<UnityAction>("testFun"); unityAction(); //Xlua Provides a way to get functions --- To use less , Low efficiency LuaFunction luaF = LuaManager.Instance.Global.Get<LuaFunction>("testFun"); luaF.Call();
Get the function with parameters and return values
[CSharpCallLua] // Delegate with parameters and return values -- Note that when the custom delegate is not recognized Be sure to add features and regenerate code public delegate int CustomCall2(int a); // Get the function with parameters and returns ====== CustomCall2 call2 = LuaManager.Instance.Global.Get<CustomCall2>("testFun2"); print(" The return value of the function with parameters and return value is : " + call2(10)); //C# Provided with a return value delegate Func<int, int> func = LuaManager.Instance.Global.Get<Func<int, int>>("testFun2"); print(" The return value of the function with parameters and return value is : " + func(10)); //XLua Provided LuaFunction because Lua The characteristics of multiple return values of functions It's an array LuaFunction luaF2 = LuaManager.Instance.Global.Get<LuaFunction>("testFun2"); print(" The return value of the function with parameters and return value is : " + luaF2.Call(10)[0]); // The returned array takes the first
Acquisition of multi return function ( Note that custom delegates may not be predefined , You need to add features and regenerate the code )
// Delegate definition with multiple return values utilize ref out Construct return value parameters [CSharpCallLua] // if XLua Delegate type is not recognized Need to add this feature And the editor is regenerated XLua Code // Multiple return values -- The first return value is return Of For subsequent return values out/ref receive First define parameters public delegate int CustomCall3(int a,out int var2,out bool var3,ref string var4,out int var5); // Multiple return value function get Entrust with out ref LuaFunction The return value of the call is array Just go through it //C# in Use out ref obtain CustomCall3 call3 = LuaManager.Instance.Global.Get<CustomCall3>("testFun3"); //out There is no need to initialize outside out Only don't come in Initialization will not be passed in int var2; bool var3; string var4 = ""; int var5; //ref It needs to be initialized Because it goes in and out You cannot enter uninitialized values int var1 = call3(10,out var2,out var3,ref var4,out var5); print(string.Format(" The return value of a multi return function {0} {1} {2} {3} {4}",var1,var2,var3,var4,var5)); //XLua Provide LuaFunction LuaFunction luaF3 = LuaManager.Instance.Global.Get<LuaFunction>("testFun3"); // When the parameter types are inconsistent, use obejct Otherwise, it depends on the parameter type object[] objs = luaF3.Call(1000); for (int i = 0; i < objs.Length; i++) print(string.Format(" The first {0} The return values are {1}", i, objs[i]));
Acquisition of variable length parameter function
// Definition of variable parameter delegate Lua The function prototype function(a,...) public delegate void CustomCall4(string a, params int[] args); // Type of variable length parameter It is decided according to the actual situation If the type is inconsistent, use Object // Acquisition of variable length parameter function CustomCall4 call4 = LuaManager.Instance.Global.Get<CustomCall4>("testFun4"); //Lua Pay attention to the use of arrays when traversing in call4("123", 1, 3, 11, 566); //XLua Provide LuaFunction luaF4 = LuaManager.Instance.Global.Get<LuaFunction>("testFun4"); luaF4.Call("123", 1, 3, 11, 566);
C# obtain Lua Table of Table
Lua The table in is very powerful , Can store any data type , You can customize the index or automatically fill the index . commonly C# obtain Lua The tables in can be converted into the following forms .
utilize List List access Lua Of table
//Lua in table The acquisition of is a shallow copy ( Value copy ) //Lua in table Element types are unified List<int> list = LuaManager.Instance.Global.Get<List<int>>("testList"); for (int i = 0; i < list.Count; i++) Debug.Log(list[i]); //Lua If the type of the table in is uncertain, use Object save List<object> list2 = LuaManager.Instance.Global.Get<List<object>>("testList2"); for (int i = 0; i < list2.Count; i++) Debug.Log(list2[i]);
utilize Dictionary Dictionary access Lua Of table
Dictionary<string, int> dic = LuaManager.Instance.Global.Get<Dictionary<string,int>>("testDic"); foreach(var item in dic) { Debug.Log(item.Key+"_"+item.Value); } // Value copy Dictionary<object, object> dic2 = LuaManager.Instance.Global.Get<Dictionary<object, object>>("testDic2"); foreach(var item in dic2) { Debug.Log(item.Key + "_" + item.Value); }
utilize Class Class gets Lua Of table
table When acting as a class What you need to pay attention to when defining classes
- The name of the member variable and Lua The names of the elements in the table must be consistent
- The type must correspond to , Basic types , The function type is delegate or
LuaFunction
, And it must be public Variable - When the number of parameters does not match ,Lua Redundant variables will be discarded ,C# Redundant variables are not assigned .
- table Zhongxu deposit table Variable , Class definitions can also be nested
--lua Provided in table surface testClass = { testInt = 2, testBool = true, testFloat = 1.2, testString = "123", testFunc = function() print("123123") end, testInClass ={ testInInt = 10 } }
[CSharpCallLua] // The custom type is not recognized , You must add features and regenerate the code public class CallLuaClass { // Declare member variables in this class // The name must be with Lua It's the same over there // It must be public Private and protected cannot be assigned public int testInt; public bool testBool; public float testFloat; public float testString; public UnityAction testFunc; // Variables in customization can be more or less , If the variable ratio Lua Few of them ignore and discard it // If the variable ratio Lua Many of them , No assignment public void Test() { Debug.Log(" test "); } public CallLuaInClass testInClass; } // Nested class public class CallLuaInClass { public int testInInt; } // Get still through Get function , It is still a value copy CallLuaClass obj = LuaManager.Instance.Global.Get<CallLuaClass>("testClass");
Using interfaces Interface obtain Lua Of table
namespace ns { // The interface must have features [CSharpCallLua] // Every time the interface is changed, the code needs to be rebuilt after deletion public interface ICharpCallInterface { // Fields are not allowed in the interface Delegation, etc. , Receive with attributes Lua The variables in the int testInt { get; set; } bool testBool { get; set; } float testFloat { get; set; } string testString { get; set; } UnityAction testFunc { get; set; } } public class CallInterface : MonoBehaviour { private void Start() { LuaManager.Instance.DoLuaFile("Main"); ICharpCallInterface obj = LuaManager.Instance.Global.Get<ICharpCallInterface>("testInterface"); print(obj.testInt); obj.testInt = 100000; obj.testFunc(); //================ Interface copy is a deep copy Reference copy Changed the value lua The median value changes accordingly ================== ICharpCallInterface obj2 = LuaManager.Instance.Global.Get<ICharpCallInterface>("testInterface"); print(obj2.testInt); } } }
Be careful : The interface is a deep copy ! It's a deep copy ! It's a deep copy !
utilize
xLua
ProvidedLuaTable
obtain Lua Of table// Not recommended LuaTable and LuaFunction Low efficiency There is also the possibility of memory leaks // Reference object Deep copy ( Reference copy ) LuaTable table = LuaManager.Instance.Global.Get<LuaTable>("testLuaTable"); Debug.Log(table.Get<int>("testInt")); Debug.Log(table.Get<bool>("testBool")); Debug.Log(table.Get<float>("testFloat")); Debug.Log(table.Get<string>("testString")); table.Get<LuaFunction>("testFunc").Call(); // It will change when modifying Lua The value in table.Set("testInt", 55); Debug.Log(table.Get<int>("testInt")); table.Dispose(); // Be sure to destroy it after use .
Be careful :
LuaTable
It's a deep copy !
C# Call Lua There are only interfaces and LuaTable
It's a deep copy , The rest are all shallow copies
Lua Call C# Related knowledge
Usually, when developing related logic that needs hot update , It's usually used Lua To call C# and U3D Develop related classes of , relative C# call Lua, Lua call C# More important .
The main entry of the program
Unity Cannot start directly in Lua Script , Need to pass through C# call Lua In order to start Lua. Generally, a startup will be set Lua Main entrance of Main.lua
Generally used to define some aliases , Start other scripts
--Main.lua Lua The main entry of the program This starts calling other scripts
-- Be careful from Lua In the script require Redirection will still occur , Generally all Lua The scripts are placed in the custom folder
require("Test") -- start-up Test.lua Script
Lua call C# Class
xLua
Provided Lua Use in C# The fixed routine of class : CS. Namespace . Class name
Instantiation C# Class ( Not mono Script ),Lua No middle new Method , You can use it directly CS. Namespace . Class name ()
Scripts generally cannot be used directly new To instantiate , Need to use GameObject
Object supplied AddComponent
Method
Generally, global variables are used to store the C# The type of , Call variables directly when calling again ( Equivalent to taking an alias )
--Lua call C# Fixed routine CS. Namespace . Class name
local obj1 = CS.UnityEngine.GameObject() -- Instantiate a GameObejct object
GameObject = CS.UnityEngine.GameObject -- Define global variable storage classes , Alias
local obj2 = GameObject("mrLiu") -- Use alias to instantiate and pass parameters
-- For static objects in classes , You can use it directly . To call
local obj3 = GameObject.Find("mrLiu");
-- Get the member variables in the instance object direct . call
print(obj3.transform.position)
Vector3 = CS.UnityEngine.Vector3 -- Storage class , names
-- Use member methods in the instance object Be sure to use colons : call ! Otherwise, the report will be wrong
obj3.tranform:Translate(Vector3(5,2,1))
-- Use custom C# class Note that the namespace should match ( The name... Has been defined Test Of C# class No namespace )
local test = CS.Test()
-- A special case , Inherited MonoBehaviour Script class for
local obj4 = GameObject(" Add script test ")
--Lua Generics are not supported , utilize AddComponent overloaded , Provide the type in the parameter typeof yes xLua Access provided C# Method of type
obj4:AddComponent(typeof(CS.Test)) -- Note that member methods are called with colons
Be careful : Calls to member methods must use colons !
Lua call C# enumeration
Enumeration calls are similar to classes :CS. Namespace . Enum name
Enumeration does not require instantiation , Enumeration name does not exist () Usage of There is still the use of aliasing
-- Enumeration call
-- call Unity Enumeration in
-- The calling rules of enumeration and class are the same
--CS. Namespace . Enum name There is no small difference in instantiation
--U3D Some of its own enumeration types PrimitiveType Some types of geometry
-- Create geometry of a specific shape ,GameObject.CreatePrimitive(PrimitiveType type)
-- Alias is also supported
PrimitiveType = CS.UnityEngine.PrimitiveType
GameObject = CS.UnityEngine.GameObject
-- Static member functions are available . call
local obj = GameObject.CreatePrimitive(PrimitiveType.Cube)
-- Custom enumeration Pay attention to namespaces as you use methods
MyEnum = CS.MyEnum
-- Enumeration conversion
-- Numerical value to enumeration
local a = MyEnum.__CastFrom(1)
print(a)
-- String to enumeration
local b = MyEnum.__CastFrom("Attack")
print(b)
Lua call C# Array of
Important nature :Lua Call in C# Related data structures , It still uses its original data structure properties and methods
reason :xLua
call C# when , The essence is to use custom data types userdata
And meta table to achieve storage C# Instance members of various objects in , The purpose of static members and various types of information contained in type objects
--Lua Use C# Array related knowledge points
--Lua Calling it in does not change the structure of the original language Still use the original language method
local obj = CS.LuaCallArray() -- Test use C# class , The related array has been declared inside
-- length Out of commission # It should be provided by the original array object Length attribute
print(obj.arr.Length)
-- Access elements The index is still from 0 Start
print(obj.arr[0])
-- Traversal requires attention from 0 Start ,Lua Ergodic variable range double closure , So the length needs to be reduced by one
for i = 0,obj.arr.Length-1 do
print(obj.arr[i])
end
--Lua Can't go through C# Keywords of define relevant data structures , But it can be achieved by using more general related methods
--Lua Create a C# Array of utilize Array class
--Array.CreateInstance(Type elementType,int length) Static methods
local arr2 = CS.System.Array.CreateInstance(typeof(CS.System.Int32),10)
print(arr2.Length)
print(arr2[0])
print(arr2)
Note the loop traversal time and Lua Table differences
Lua Call two-dimensional array problem ( pit )
Lua Unsupported use [x,y]
or [x][y]
To access a two-dimensional array
You have to use Array Access the relevant methods implemented under
arr.GetValue(x,y);
Access elementsarr.GetLength(0)
; Get the number of linesarr.GetLength(1)
; Get the number of columns
Other traversal and other related operations are based on these API It can be realized normally
Lua call C# Of List
The nature of the acquisition rule is basically the same as that of the array The relevant methods provided are different
The creation is quite different , The relevant methods of the old version and the new version will be introduced
-- The rules follow C#
obj.list:Add(1)
obj.list:Add(2)
print(obj.list.Count) -- utilize Count To obtain the length of the
-- Traverse
for i=0,obj.list.Count-1 do
print("list",obj.list[i])
end
print(obj.list)
-- stay Lua Created in List object
-- The old version xLua
local list2 = CS.System.Collections.Generic["List`1[System.String]"]()
list2:Add("123")
print(list2[0])
-- The new version xLua > v2.1.12
-- Equivalent to one List Generic classes You also need to instantiate
local List_String = CS.System.Collections.Generic.List(CS.System.String)
local list3 = List_String() -- Create objects
list3:Add("55555")
print(list3[0])
Lua call C# Of Dictionary
Dictionary calls are different from list arrays Unable to get [] Brackets call directly , You need to use the relevant methods provided by the dictionary object
obj.dic:Add(1,"1234")
print(obj.dic[1])
-- Traverse
for k,v in pairs(obj.dic) do
print(k,v)
end
-- stay Lua Create a dictionary object in
-- Get alias You need to instantiate
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)
-- Dictionary traversal must use pairs Otherwise, the string index cannot be recognized
for k,v in pairs(dic2) do
print(k,v)
end
-- stay Lua The dictionary created in is directly through [] Get cannot get
print(dic2["123"]) -- I won't support it
--C# The function prototype TryGetValue utilize out receive value, return bool
--Lua Call in TryGetValue Not at the time out keyword , Use multiple return values
-- Two return values bool Does the key exist value The value of the key
print(dic2:TryGetValue("123"))
--xLua by Dictionary The expansion method provided get_Item and set_Item Find and modify the value according to the key
-- utilize get_Item Through this fixed method
print(dic2:get_Item("123")) -- Find dictionary elements
-- For change set_Item
dic2:set_Item("123",nil)
print(dic2:get_Item("123")) --vector3 Can't be empty By default (0,0,0)
Pay attention to the special calling method of the dictionary and You must use pairs
Lua call C# Extension method of
When using the extension method , Be sure to add LuaCallCSharp
Feature and regenerate the code
Suggest Lua This feature is added to all custom classes used in , Will significantly improve performance
Without this feature, the reflection mechanism is used , inefficiency
// Want to be in Lua When using the expansion method in Be sure to add features in front of tool classes
// Suggest Lua Classes to be used in Add this feature Can improve performance
// Do not add this feature May not report an error xLua Using a reflection mechanism Low efficiency
[LuaCallCSharp]
public static class Tools
{
// When the specified object calls this method It is equivalent to passing itself into
public static void Move(this Test obj)
{
Debug.Log(obj.name + " Move ");
}
}
public class Test
{
public void Speak(string str)
{
print(str);
}
}
-- The extension class does not need to be in lua Load in Just add features
obj = Test()
obj:Speak("mrLiu")
-- Using the expansion method is consistent with using the member method Pass yourself into
-- call C# The expansion method of a class in , Be sure to add features to the classes of extension methods
obj:Move()
Lua Call with ref and out Function of parameter
For the use of multiple return values of functions :Lua Function returns multiple values directly and C# You can only return one , The rest passed ref and out Pass on references , Receive values outside the function , Pay attention to the sequence one by one .
public class Test
{
public int RefFunc(int a, int b ,ref int c, ref int d )
{
c = a + b;
d = a - b;
return 100;
}
public int OutFunc(int a, int b, out int c, out int d)
{
c = a;
d = b;
return 200;
}
public int RefOutFunc(int a , out int b, ref int c)
{
b = a * 10;
c = a * 20;
return 300;
}
}
print("*******Lua call C# ref Method related knowledge points **********")
Lesson5 = CS.Test
local obj = Test()
--ref Parameters It will be returned to... In the form of multiple return values lua
-- If the function has a return value, it is the first rest ref One to one correspondence from left to right
local raw,ref1,ref2 = obj:RefFunc(1,1,0,0)
--RefFunc(1,1) Do not give ref The default value of the current type will be passed in by value transfer. The number is 0
-- Be careful : here ref The parameter is at the end and can be omitted , When it is in the middle, it is necessary to occupy the space, which must not be omitted
print(raw,ref1,ref2)
print("*******Lua call C#out Method related knowledge points **********")
--out Parameters It will be returned to... In the form of multiple return values lua
--out Parameters do not need to be transferred out It can be omitted And there is no need to occupy space
local raw,out1,out2 = obj:OutFunc(1,1)
print(raw , out1 , out2)
print("*******Lua call C#ref out Method related knowledge points **********")
-- When mixed The above two rules need to be combined ref Space required out No need to occupy space
local raw,out1,out2 = obj:RefOutFunc(20,30) --out Omit 30 Direct to ref
print(raw , out1 , out2)
Lua Call overloaded functions
public class Test
{
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;
}
}
local obj = CS.Test()
--Lua Defining overloaded functions is not supported by itself
--Lua Support calling C# Overloaded functions in
print(obj:Calc())
print(obj:Calc(10,5))
--Lua There are only Number
--C# There are overloaded functions of various precision in Unable to distinguish
-- Overloading data types There may be problems when using
print(obj:Calc(10))
print(obj:Calc(10.2))
-- Solve the ambiguity of overloaded functions
--XLua Provide reflection mechanism to solve
-- Just to understand As far as possible need not inefficiency
--Type Is the key class of reflection
-- Get the information about the specified function
local fun_int = typeof(CS.Lesson6):GetMethod("Calc",{
typeof(CS.System.Int32)})
local fun_float = typeof(CS.Lesson6):GetMethod("Calc",{
typeof(CS.System.Single)})
-- adopt xlua A method is provided Turn into lua Function USES
-- Usually only turn once And then reuse it Declare functions
local f1 = xlua.tofunction(fun_int)
local f2 = xlua.tofunction(fun_float)
-- Member method The first parameter is passed to the object
-- Static methods There is no need to pass the first parameter
print(f1(obj,10))
print(f2(obj,10.2))
Lua Invoke delegates and events
public class Test
{
// Declare delegates and events
public UnityAction del; //delagate
// event
public event UnityAction eventAction;
// Triggering event
public void DoEvent()
{
if (eventAction != null)
eventAction();
}
// Events do not allow direct external operations , Need packaging method
public void ClearEvent()
{
eventAction = null;
}
}
local obj = CS.Test()
-- Delegates are used to encapsulate functions
-- Use C# Entrustment Can be used to hold Lua function
local fun = function()
print("Lua function fun")
end
--lua There is no matching operator in You can't += Add a delegate
-- If you add a function to a delegate for the first time Should use the = follow-up +=
obj.del = fun
obj.del = obj.del + fun
obj.del()
obj.del = obj.del - fun
print(" Start subtracting function ")
obj.del()
-- Empty all stored functions Delegate support =
obj.del = nil
print("*******Lua call C# Event related knowledge points **********")
local fun2 = function()
print(" Event plus function ")
end
-- Event addition and subtraction function and Delegation is very different
--lua When using events in use lua The fixing method provided
-- object : Event name ("+", The function variables )
obj:eventAction("+",fun2)
obj:eventAction("+",fun2)
obj:DoEvent()
-- The cancellation of the event
obj:eventAction("-",fun2)
obj:DoEvent()
-- Know the event It is not allowed to carry out directly outside the event = Wait for the operation Can only += -=
-- Need to be in C# Encapsulate a function to perform this operation
obj:ClearEvent()
obj:DoEvent()
Pay attention to the registration and cancellation of events C# The events in are very different
Lua Call a special system type
When using some special types of the system for example Unity Provided UnityAction<float>
Entrust, etc ,xLua
The commonly used ones have been prepared in advance , But if generic parameters are complex , Not prepared in advance , Must be in xLua
Register in , Traditional types can add features directly , However, the delegation provided by the system cannot modify the source code and add features directly , Other methods are needed .
- C# Call Lua Where you must register
- There are no predefined delegates ( Custom features can be added , The delegation of the system can only be registered )
- The interface must have features ( Custom interface plus features , System interfaces can only be registered )
// Must be a static class Class names and variable names in classes are not required
public static class Test
{
// by C# call Lua When the system type ( entrust , Interface )
[CSharpCallLua]
public static List<Type> cSharpCallLuaList = new List<Type>()
{
typeof(UnityAction<float>),
};
// by Lua call C# System type ( Development method ) To improve performance, it is recommended to register or add features to everything you use
[LuaCallCSharp]
public static List<Type> luaCallCSharpList = new List<Type>()
{
typeof(GameObject),
typeof(Rigibody),
}
}
Advantages of registration : It will not be constrained by the fact that the system type cannot add features , Put all the features together , No weight, no leakage , Than adding features to classes alone , Structure is clearer .
Lua Of nil and C# Of null
Lua Of nil and C# Of null Unequivalence , If you directly judge a C# object obj == nil
if obj
by null It is false, prove null == nil It's wrong. . Here are three solutions :
utilize C# Object supplied Equals Method
obj:Equals(nil)
-- The most direct , But there are risks , if Lua The data type of does not provide this method , Will report a mistakestay Lua Encapsulate a global method to judge null
function IsNull(obj) if obj == nil or obj:Equals(nil) then return true end return false end
by Object Type expands a method
// Remember to add features to the expansion method [LuaCallCSharp] public static class ExtendFunc { // Expand one for Object Method of judging empty space For giving lua Use lua No use null and nil Compare public static bool IsNull(this Object obj) { return obj == null; } }
Lua call C# Cooperation of
Lua It provides the related calls of the coroutine , But in xLua
What we hope to achieve in is to use Lua Language call C# Correlation API, So what we need to open here is Unity Script coordination , You can't use your own , the Lua Function passed in to Mono In the process of providing assistance .
--xlua A tool list provided
-- Be sure to pass require Only after calling
util = require("xlua.util")
--C# Zhongxie Cheng starts through inheritance Mono Class
-- Through the startup function inside StartCoroutine Start the process
GameObject = CS.UnityEngine.GameObject
WaitForSeconds = CS.UnityEngine.WaitForSeconds
-- Create a new empty object in the scene , Then hang up a script , The script only inherits mono
local obj = GameObject("Coroutine")
local mono = obj:AddComponent(typeof(CS.Test))
-- Hope to start with the collaboration process Lua Middle function
fun = function()
local a = 1
while true do
--lua You can't use C# Medium yield keyword
-- Just use Lua The coroutine in returns
coroutine.yield(WaitForSeconds(1))
print(a)
a = a + 1
if a > 10 then
mono:StopCoroutine(running)
end
end
end
-- We can't just put lua Function is passed into the open coroutine !!
--mono:StartCoroutine(fun)
-- utilize util Solutions provided in the tool table
-- If you want to put the Lua Function as C# The covariance function uses
-- Must call xlua.util Medium cs_generator(lua function )
running = mono:StartCoroutine(util.cs_generator(fun))
-- Close the coroutines
Lua call C# Generic functions of
Lua Only call constraints are supported Class With parameters c# function
Even so, there are still certain restrictions It is different under different packaging methods Be careful with
- Support Mono Pack and use
- if IL2Cpp pack , Only if the generic type is a reference type can it be used . If it's a value type , Unless C# The same generic parameter has been called ,Lua Can only be used in .
public class Test
{
public interface ITest
{
}
public class TestFather
{
}
public class TestChild : TestFather,ITest
{
}
public void TestFun1<T>(T a, T b) where T:TestFather
{
Debug.Log(" Generic methods with parameters and constraints ");
}
public void TestFun2<T>(T a)
{
Debug.Log(" Generic methods with parameter unconstrained ");
}
public void TestFun3<T>() where T:TestFather
{
Debug.Log(" Constrained parameterless generic methods ");
}
public void TestFun4<T>(T a)where T:ITest
{
Debug.Log(" There are constraints and parameters , Constraints are interfaces ");
}
}
local obj = CS.Test()
local child = CS.Lesson12.TestChild()
local father = CS.Lesson12.TestFather()
--Lua Support generic functions with constraints and parameters
obj:TestFun1(child,father)
obj:TestFun1(father,child)
--Lua Generic functions without constraints are not supported
--obj:TestFun2(child)
--Lua Generic functions with constraints and no parameters are not supported
--obj:TestFun3()
--Lua Constraints of non Class Function of
--obj:TestFun4(child)
-- summary ,Lua Only constraints of Class Functions with parameters
-- There are certain use restrictions
-- If you use Mono Packaging supports the use of
-- If it is IL2Cpp Only if the generic type is a reference type can it be used
-- If it's a value type , Unless C# The same generic parameter has been called over there ,lua Can only be used in
It can be seen that there are many inconveniences when using generics directly , but xLua
Provides the method of general function to realize the call of generic function
-- Get the general function
-- Set generic types for reuse
--xlua.get_generic_method( class ," Function name ")
local testFun2 = xlua.get_generic_method(CS.Lesson12,"TestFun2")
testFun2_R = testFun2(CS.System.Int32) -- Set generic type
-- Function call
-- Member method The first parameter is passed to the object that calls the function
-- Static methods do not need to be passed
-- The second parameter is the value of the generic
testFun2_R(obj,1)
边栏推荐
- [quick start of Digital IC Verification] 24. AHB sramc of SystemVerilog project practice (4) (AHB continues to deepen)
- Clang compile link ffmpeg FAQ
- [original] all management without assessment is nonsense!
- 【深度学习】语义分割实验:Unet网络/MSRC2数据集
- Connecting FTP server tutorial
- Webgl texture
- 【數字IC驗證快速入門】26、SystemVerilog項目實踐之AHB-SRAMC(6)(APB協議基本要點)
- 【目标检测】YOLOv5跑通VOC2007数据集
- [quick start of Digital IC Verification] 18. Basic grammar of SystemVerilog learning 5 (concurrent threads... Including practical exercises)
- Jacobo code coverage
猜你喜欢
使用cpolar建立一个商业网站(2)
【数字IC验证快速入门】26、SystemVerilog项目实践之AHB-SRAMC(6)(APB协议基本要点)
一大波开源小抄来袭
写一篇万字长文《CAS自旋锁》送杰伦的新专辑登顶热榜
全日制研究生和非全日制研究生的区别!
The rebound problem of using Scrollview in cocos Creator
Syntax of generator function (state machine)
[deep learning] semantic segmentation experiment: UNET network /msrc2 dataset
知否|两大风控最重要指标与客群好坏的关系分析
【数字IC验证快速入门】25、SystemVerilog项目实践之AHB-SRAMC(5)(AHB 重点回顾,要点提炼)
随机推荐
一大波开源小抄来袭
A need to review all the knowledge, H5 form is blocked by the keyboard, event agent, event delegation
How to build your own super signature system (yunxiaoduo)?
【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
【OBS】RTMPSockBuf_ Fill, remote host closed connection.
2.Golang基础知识
HW初级流量监控,到底该怎么做
[markdown grammar advanced] make your blog more exciting (IV: set font style and color comparison table)
Starting from 1.5, build a microservice framework link tracking traceid
避坑:Sql中 in 和not in中有null值的情况说明
The rebound problem of using Scrollview in cocos Creator
【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
Qu'est - ce qu'une violation de données
MongoDB数据库基础知识整理
连接ftp服务器教程
Webcodecs parameter settings -avc1.42e01e meaning
【数据挖掘】视觉模式挖掘:Hog特征+余弦相似度/k-means聚类
Gd32 F3 pin mapping problem SW interface cannot be burned
Tkinter after how to refresh data and cancel refreshing
MongoD管理数据库的方法介绍