当前位置:网站首页>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)
边栏推荐
- Cut ffmpeg as needed, and use emscripten to compile and run
- Iterator and for of.. loop
- Getting started with webgl (1)
- Zhongang Mining: Fluorite continues to lead the growth of new energy market
- 【原创】一切不谈考核的管理都是扯淡!
- postman生成时间戳,未来时间戳
- Pit avoidance: description of null values in in and not in SQL
- leetcode 241. Different ways to add parentheses design priority for operational expressions (medium)
- Database exception resolution caused by large table delete data deletion
- 【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
猜你喜欢
webgl_ Graphic transformation (rotation, translation, zoom)
知否|两大风控最重要指标与客群好坏的关系分析
Implementation of crawling web pages and saving them to MySQL using the scrapy framework
一大波开源小抄来袭
Streaming end, server end, player end
Configure mongodb database in window environment
2022全开源企业发卡网修复短网址等BUG_2022企业级多商户发卡平台源码
如何在opensea批量发布NFT(Rinkeby测试网)
Cocos creator collision and collision callback do not take effect
Wechat applet 01
随机推荐
[quick start of Digital IC Verification] 20. Basic grammar of SystemVerilog learning 7 (coverage driven... Including practical exercises)
Annexb and avcc are two methods of data segmentation in decoding
最安全的证券交易app都有哪些
Using eating in cocos Creator
Create lib Library in keil and use lib Library
The "go to definition" in VS2010 does not respond or prompts the solution of "symbol not found"
[quick start of Digital IC Verification] 22. Ahb-sramc of SystemVerilog project practice (2) (Introduction to AMBA bus)
Async and await
【數字IC驗證快速入門】26、SystemVerilog項目實踐之AHB-SRAMC(6)(APB協議基本要點)
Whether runnable can be interrupted
Do you know the relationship between the most important indicators of two strong wind control and the quality of the customer base
Runnable是否可以中断
[original] all management without assessment is nonsense!
The significance of XOR in embedded C language
[server data recovery] a case of RAID data recovery of a brand StorageWorks server
使用cpolar建立一个商业网站(2)
【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
[make a boat diary] [shapr3d STL format to gcode]
Excerpted words
Syntax of generator function (state machine)