xLua 学习
xLua https://github.com/Tencent/xLua
文档 https://tencent.github.io/xLua/public/v1/guide/index.html
FAQ https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/faq.md
Features https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/features.md
教程 https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/XLua%E6%95%99%E7%A8%8B.md
Tutorial
using UnityEngine;
using System.Collections;
using XLua; namespace Tutorial
{
public class ByString : MonoBehaviour
{
LuaEnv luaenv = null;
// Use this for initialization
void Start()
{
luaenv = new LuaEnv();
luaenv.DoString("print('hello world')");
} // Update is called once per frame
void Update()
{
if (luaenv != null)
{
luaenv.Tick();
}
} void OnDestroy()
{
luaenv.Dispose();
}
}
}
LoadLuaScriptByString
Resources/byfile.lua.txt namespace Tutorial
{
public class ByFile : MonoBehaviour
{
LuaEnv luaenv = null;
// Use this for initialization
void Start()
{
luaenv = new LuaEnv();
luaenv.DoString("require 'byfile'");
} // Update is called once per frame
void Update()
{
if (luaenv != null)
{
luaenv.Tick();
}
} void OnDestroy()
{
luaenv.Dispose();
}
}
}
LoadLuaScriptByFile
using UnityEngine;
using System.Collections;
using XLua; namespace Tutorial
{
public class CustomLoader : MonoBehaviour
{
LuaEnv luaenv = null;
// Use this for initialization
void Start()
{
luaenv = new LuaEnv();
luaenv.AddLoader((ref string filename) =>
{
if (filename == "InMemory")
{
string script = "return {ccc = 9999}";
return System.Text.Encoding.UTF8.GetBytes(script);
}
return null;
});
luaenv.DoString("print('InMemory.ccc=', require('InMemory').ccc)");
} // Update is called once per frame
void Update()
{
if (luaenv != null)
{
luaenv.Tick();
}
} void OnDestroy()
{
luaenv.Dispose();
}
}
}
LoadLuaScriptLoader
using UnityEngine;
using System.Collections.Generic;
using System;
using XLua; public class CSCallLua: MonoBehaviour { LuaEnv luaEnv = null; string script = @"
a = 1
b = 'hello world'
c = true d = {
f1 = 12,
f2 = 34,
1,2,3,
add = function(self, a, b)
print('d.add called')
return a + b
end
} function e()
print('i am e')
end function f(a, b)
print('a', a, 'b', b)
return 1, { f1 = 1024 }
end function ret_e()
print('ret_e called')
return e
end
"; public class DClass {
public int f1;
public int f2;
} [CSharpCallLua]
public interface ItfD {
int f1 { get; set; }
int f2 { get; set; }
int add(int a, int b);
} [CSharpCallLua]
public delegate int FDelegate(int a, string b, out DClass c); [CSharpCallLua]
public delegate Action GetE(); void Start() {
luaEnv = new LuaEnv();
luaEnv.DoString(script); Debug.Log("_G.a = " + luaEnv.Global.Get<int>("a"));
Debug.Log("_G.b = " + luaEnv.Global.Get<string>("b"));
Debug.Log("_G.c = " + luaEnv.Global.Get<bool>("c")); DClass d = luaEnv.Global.Get<DClass>("d"); // 映射到有对应字段的class, by value
Debug.Log("_G.d = { f1 = " + d.f1 + ", f2 = " + d.f2 + " }"); Dictionary<string, double> d1 = luaEnv.Global.Get<Dictionary<string, double>>("d"); // 映射到Dictionary<string, double>, by value
Debug.Log("_G.d = { f1 = " + d1["f1"] + ", f2 = " + d1["f2"] + "}, d.Count = " + d1.Count); List<double> d2 = luaEnv.Global.Get<List<double>>("d"); // 映射到List<double>, by value
Debug.Log("_G.d.len = " + d2.Count); ItfD d3 = luaEnv.Global.Get<ItfD>("d"); // 映射到interface实例,by ref, 这个要求interface加到生成列表,否则会返回null,建议用法
d3.f2 = ;
Debug.Log("_G.d= { f1 = " + d3.f1 + ", f2 = " + d3.f2 + "}");
Debug.Log("_G.d:add(1, 2) = " + d3.add(, )); LuaTable d4 = luaEnv.Global.Get<LuaTable>("d"); // 映射到一个delegate, 要求delegate加到生成列表,否则返回null,建议用法
Debug.Log("_G.d = { f1 = " + d4.Get<int>("f1") + ", f2 = " + d4.Get<int>("f2") + "}"); Action e = luaEnv.Global.Get<Action>("e"); // 映射到一个delegate,要求delegate加到生成列表,否则返回null, 建议用法
e(); FDelegate f = luaEnv.Global.Get<FDelegate>("f");
DClass d_ret;
int f_ret = f(, "john", out d_ret); // lua的多返回值映射: 从左往右映射到c#的输出参数,输出参数包括返回值,out参数,ref参数
Debug.Log("ret.d = { f1 = " + d_ret.f1 + ", f2 = " + d_ret.f2 + "}, ret = " + f_ret); GetE ret_e = luaEnv.Global.Get<GetE>("ret_e"); // delegate可以返回更复杂的类型,甚至是另外一个delegate
e = ret_e();
e(); LuaFunction d_e = luaEnv.Global.Get<LuaFunction>("e");
d_e.Call();
} void Update() {
if (luaEnv != null) {
luaEnv.Tick();
}
} void OnDestroy() {
luaEnv.Dispose();
}
}
CSharpCallLua
using UnityEngine;
using System;
using XLua; [LuaCallCSharp]
public class BaseClass { public static int BSF = ; public int BMF { get; set; } public static void BSFunc() {
Debug.Log("Derived Static Func, BSF = " + BSF);
} public void BMFunc() {
Debug.Log("Derived Member Func, BMF = " + BMF);
}
} public struct Param1 {
public int x;
public string y;
} [LuaCallCSharp]
public enum TestEnum {
E1,
E2
} [LuaCallCSharp]
public class DerivedClass: BaseClass { [LuaCallCSharp]
public enum TestEnumInner {
E3,
E4
} public void DMFunc() {
Debug.Log("Derived Member Func, DMF = " + DMF);
} public int DMF { get; set; } public double ComplexFunc(Param1 p1, ref int p2, out string p3, Action luafunc, out Action csfunc) {
Debug.Log("P1 = { x = " + p1.x + ", y = " + p1.y + "},p2 = " + p2); luafunc();
p2 = p2 * p1.x;
p3 = "hello " + p1.y; csfunc = () => {
Debug.Log("csharp callback invoked!");
}; return 1.23;
} public void TestFunc(int i) {
Debug.Log("TestFunc(int i)");
} public void TestFunc(string i) {
Debug.Log("TestFunc(string i)");
} public static DerivedClass operator+(DerivedClass a, DerivedClass b) {
DerivedClass ret = new DerivedClass();
ret.DMF = a.DMF + b.DMF;
return ret;
} public void DefaultValueFunc(int a = , string b = "cccc", string c = null) {
UnityEngine.Debug.Log("DefaultValueFunc: a = " + a + ", b = " + b + ", c = " + c);
} public void VariableParamsFunc(int a, params string[] strs) {
UnityEngine.Debug.Log("VariableParamsFunc: a = " + a);
foreach (var str in strs) {
UnityEngine.Debug.Log("str:" + str);
}
} public TestEnum EnumTestFunc(TestEnum e) {
Debug.Log("EnumTestFunc: e = " + e);
return TestEnum.E2;
} public Action<string> TestDelegate = (param) => {
Debug.Log("TestDelegate in C#:" + param);
}; public event Action TestEvent; public void CallEvent() {
TestEvent();
} public ulong TestLong(long n) {
return (ulong)(n + );
} class InnerCalc: ICalc {
public int add(int a, int b) {
return a + b;
} public int id = ;
} public ICalc GetCalc() {
return new InnerCalc();
} public void GenericMethod<T>() {
Debug.Log("GenericMethod<" + typeof(T) +">");
}
} [LuaCallCSharp]
public interface ICalc {
int add(int a, int b);
} [LuaCallCSharp]
public static class DerivedClassExtensions {
public static int GetSomeData(this DerivedClass obj) {
Debug.Log("GetSomeData ret = " + obj.DMF);
return obj.DMF;
} public static int GetSomeBaseData(this BaseClass obj) {
Debug.Log("GetSomeBaseData ret = " + obj.BMF);
return obj.BMF;
} public static void GenericMethodOfString(this DerivedClass obj) {
obj.GenericMethod<string>();
}
} public class LuaCallCs1 : MonoBehaviour { LuaEnv luaEnv = null;
string script = @"
function demo()
--new C#对象
local newGameObj = CS.UnityEngine.GameObject()
local newGameObj2 = CS.UnityEngine.GameObject('helloworld')
print(newGameObj, newGameObj2) --访问静态属性,方法
local GameObject = CS.UnityEngine.GameObject
print('UnityEngine.Time.deltaTime:', CS.UnityEngine.Time.deltaTime) --读静态属性
CS.UnityEngine.Time.timeScale = 0.5 --写静态属性
print('helloworld', GameObject.Find('helloworld')) --静态方法调用 --访问成员属性,方法
local DerivedClass = CS.DerivedClass
local testobj = DerivedClass()
testobj.DMF = 1024--设置成员属性
print(testobj.DMF)--读取成员属性
testobj:DMFunc()--成员方法 --基类属性,方法
print(DerivedClass.BSF)--读基类静态属性
DerivedClass.BSF = 2048--写基类静态属性
DerivedClass.BSFunc();--基类静态方法
print(testobj.BMF)--读基类成员属性
testobj.BMF = 4096--写基类成员属性
testobj:BMFunc()--基类方法调用 --复杂方法调用
local ret, p2, p3, csfunc = testobj:ComplexFunc({x=3, y = 'john'}, 100, function()
print('i am lua callback')
end)
print('ComplexFunc ret:', ret, p2, p3, csfunc)
csfunc() --重载方法调用
testobj:TestFunc(100)
testobj:TestFunc('hello') --操作符
local testobj2 = DerivedClass()
testobj2.DMF = 2048
print('(testobj + testobj2).DMF = ', (testobj + testobj2).DMF) --默认值
testobj:DefaultValueFunc(1)
testobj:DefaultValueFunc(3, 'hello', 'john') --可变参数
testobj:VariableParamsFunc(5, 'hello', 'john') --Extension methods
print(testobj:GetSomeData())
print(testobj:GetSomeBaseData()) --访问基类的Extension methods
testobj:GenericMethodOfString() --通过Extension methods实现访问泛化方法 --枚举类型
local e = testobj:EnumTestFunc(CS.TestEnum.E1)
print(e, e == CS.TestEnum.E2)
print(CS.TestEnum.__CastFrom(1), CS.TestEnum.__CastFrom('E1'))
print(CS.DerivedClass.TestEnumInner.E3)
assert(CS.BaseClass.TestEnumInner == nil) --Delegate
testobj.TestDelegate('hello') --直接调用
local function lua_delegate(str)
print('TestDelegate in lua:', str)
end
testobj.TestDelegate = lua_delegate + testobj.TestDelegate --combine,这里演示的是C#delegate作为右值,左值也支持
testobj.TestDelegate('hello')
testobj.TestDelegate = testobj.TestDelegate - lua_delegate --remove
testobj.TestDelegate('hello') --事件
local function lua_event_callback1() print('lua_event_callback1') end
local function lua_event_callback2() print('lua_event_callback2') end
testobj:TestEvent('+', lua_event_callback1)
testobj:CallEvent()
testobj:TestEvent('+', lua_event_callback2)
testobj:CallEvent()
testobj:TestEvent('-', lua_event_callback1)
testobj:CallEvent()
testobj:TestEvent('-', lua_event_callback2) --64位支持
local l = testobj:TestLong(11)
print(type(l), l, l + 100, 10000 + l) --typeof
newGameObj:AddComponent(typeof(CS.UnityEngine.ParticleSystem)) --cast
local calc = testobj:GetCalc()
print('assess instance of InnerCalc via reflection', calc:add(1, 2))
assert(calc.id == 100)
cast(calc, typeof(CS.ICalc))
print('cast to interface ICalc', calc:add(1, 2))
assert(calc.id == nil)
end demo() --协程下使用
local co = coroutine.create(function()
print('------------------------------------------------------')
demo()
end)
assert(coroutine.resume(co))
"; void Start() {
luaEnv = new LuaEnv();
luaEnv.DoString(script);
} void Update() {
if (luaEnv != null) {
luaEnv.Tick();
}
} void OnDestroy() {
luaEnv.Dispose();
}
}
LuaCallCs
Examples
using UnityEngine;
using XLua; public class Helloworld : MonoBehaviour
{
// Use this for initialization
void Start()
{
LuaEnv luaenv = new LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
} // Update is called once per frame
void Update()
{ }
}
01_HelloWorld 快速入门的例子
LuaTestScript.lua.txt local speed =
local lightCpnt = nil function start()
print("lua start...")
print("injected object", lightObject)
lightCpnt = lightObject:GetComponent(typeof(CS.UnityEngine.Light))
end function update()
local r = CS.UnityEngine.Vector3.up * CS.UnityEngine.Time.deltaTime * speed
self.transform:Rotate(r)
lightCpnt.color = CS.UnityEngine.Color(CS.UnityEngine.Mathf.Sin(CS.UnityEngine.Time.time) / + 0.5, , , )
end function ondestroy()
print("lua destory")
end LuaBehaviour.cs using UnityEngine;
using XLua;
using System; [System.Serializable]
public class Injection {
public string name;
public GameObject value;
} [LuaCallCSharp]
public class LuaBehaviour : MonoBehaviour { public TextAsset luaScript;
public Injection[] injections; internal static LuaEnv luaEnv = new LuaEnv(); // all lua behaviour shared one luaenv only!
internal static float lastGCTime = ;
internal const float GCInterval = ; //1 second private Action luaStart;
private Action luaUpdate;
private Action luaOnDestroy; private LuaTable scriptEnv; void Awake() {
scriptEnv = luaEnv.NewTable(); // 为每个脚本设置一个独立的环境,可一定程度上防止脚本间全局变量,函数冲突
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
scriptEnv.SetMetaTable(meta);
meta.Dispose(); scriptEnv.Set("self", this);
foreach (var injection in injections) {
scriptEnv.Set(injection.name, injection.value);
} luaEnv.DoString(luaScript.text, "LuaTestScript", scriptEnv); Action luaAwake = scriptEnv.Get<Action>("awake");
scriptEnv.Get("start", out luaStart);
scriptEnv.Get("update", out luaUpdate);
scriptEnv.Get("ondestroy", out luaOnDestroy); if (luaAwake != null) {
luaAwake();
}
} void Start() {
if (luaStart != null) {
luaStart();
}
} void Update() {
if (luaUpdate != null) {
luaUpdate();
} if (Time.time - LuaBehaviour.lastGCTime > GCInterval) {
luaEnv.Tick();
LuaBehaviour.lastGCTime = Time.time;
} } void OnDestroy() {
if (luaOnDestroy != null) {
luaOnDestroy();
} luaOnDestroy = null;
luaUpdate = null;
luaStart = null;
scriptEnv.Dispose();
injections = null;
}
}
02_U3DScripting 怎么用lua来写MonoBehaviour
ButtonInteraction.lua.txt function start()
print("lua start...") self:GetComponent("Button").onClick:AddListener(function()
print("clicked, you input is '" ..input:GetComponent("InputField").text .."'")
end)
end LuaBehaviour.cs using UnityEngine;
using XLua;
using System; [System.Serializable]
public class Injection
{
public string name;
public GameObject value;
} [LuaCallCSharp]
public class LuaBehaviour : MonoBehaviour
{
public TextAsset luaScript;
public Injection[] injections; internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
internal static float lastGCTime = ;
internal const float GCInterval = ;//1 second private Action luaStart;
private Action luaUpdate;
private Action luaOnDestroy; private LuaTable scriptEnv; void Awake()
{
scriptEnv = luaEnv.NewTable(); // 为每个脚本设置一个独立的环境,可一定程度上防止脚本间全局变量、函数冲突
LuaTable meta = luaEnv.NewTable();
meta.Set("__index", luaEnv.Global);
scriptEnv.SetMetaTable(meta);
meta.Dispose(); scriptEnv.Set("self", this);
foreach (var injection in injections)
{
scriptEnv.Set(injection.name, injection.value);
} luaEnv.DoString(luaScript.text, "LuaTestScript", scriptEnv); Action luaAwake = scriptEnv.Get<Action>("awake");
scriptEnv.Get("start", out luaStart);
scriptEnv.Get("update", out luaUpdate);
scriptEnv.Get("ondestroy", out luaOnDestroy); if (luaAwake != null)
{
luaAwake();
}
} // Use this for initialization
void Start()
{
if (luaStart != null)
{
luaStart();
}
} // Update is called once per frame
void Update()
{
if (luaUpdate != null)
{
luaUpdate();
}
if (Time.time - LuaBehaviour.lastGCTime > GCInterval)
{
luaEnv.Tick();
LuaBehaviour.lastGCTime = Time.time;
}
} void OnDestroy()
{
if (luaOnDestroy != null)
{
luaOnDestroy();
}
luaOnDestroy = null;
luaUpdate = null;
luaStart = null;
scriptEnv.Dispose();
injections = null;
}
}
03_UIEvent 怎么用UI来写UI逻辑
/*
* Tencent is pleased to support the open source community by making xLua available.
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/ using System;
using UnityEngine;
using XLua; namespace XLuaTest
{
public class PropertyChangedEventArgs : EventArgs
{
public string name;
public object value;
} public class InvokeLua : MonoBehaviour
{
[CSharpCallLua]
public interface ICalc
{
event EventHandler<PropertyChangedEventArgs> PropertyChanged; int Add(int a, int b);
int Mult { get; set; } object this[int index] { get; set; }
} [CSharpCallLua]
public delegate ICalc CalcNew(int mult, params string[] args); private string script = @"
local calc_mt = {
__index = {
Add = function(self, a, b)
return (a + b) * self.Mult
end, get_Item = function(self, index)
return self.list[index + 1]
end, set_Item = function(self, index, value)
self.list[index + 1] = value
self:notify({name = index, value = value})
end, add_PropertyChanged = function(self, delegate)
if self.notifylist == nil then
self.notifylist = {}
end
table.insert(self.notifylist, delegate)
print('add',delegate)
end, remove_PropertyChanged = function(self, delegate)
for i=1, #self.notifylist do
if CS.System.Object.Equals(self.notifylist[i], delegate) then
table.remove(self.notifylist, i)
break
end
end
print('remove', delegate)
end, notify = function(self, evt)
if self.notifylist ~= nil then
for i=1, #self.notifylist do
self.notifylist[i](self, evt)
end
end
end,
}
} Calc = {
New = function (mult, ...)
print(...)
return setmetatable({Mult = mult, list = {'aaaa','bbbb','cccc'}}, calc_mt)
end
}
";
// Use this for initialization
void Start()
{
LuaEnv luaenv = new LuaEnv();
Test(luaenv);//调用了带可变参数的delegate,函数结束都不会释放delegate,即使置空并调用GC
luaenv.Dispose();
} void Test(LuaEnv luaenv)
{
luaenv.DoString(script);
CalcNew calc_new = luaenv.Global.GetInPath<CalcNew>("Calc.New");
ICalc calc = calc_new(, "hi", "john"); //constructor
Debug.Log("sum(*10) =" + calc.Add(, ));
calc.Mult = ;
Debug.Log("sum(*100)=" + calc.Add(, )); Debug.Log("list[0]=" + calc[]);
Debug.Log("list[1]=" + calc[]); calc.PropertyChanged += Notify;
calc[] = "dddd";
Debug.Log("list[1]=" + calc[]); calc.PropertyChanged -= Notify; calc[] = "eeee";
Debug.Log("list[1]=" + calc[]);
} void Notify(object sender, PropertyChangedEventArgs e)
{
Debug.Log(string.Format("{0} has property changed {1}={2}", sender, e.name, e.value));
} // Update is called once per frame
void Update()
{ }
}
}
04_LuaObjectOrented: lua面向对象和C#的配合
using UnityEngine;
using System;
using XLua; namespace XLuaTest
{
[GCOptimize]
[LuaCallCSharp]
public struct Pedding
{
public byte c;
} [GCOptimize]
[LuaCallCSharp]
public struct MyStruct
{
public MyStruct(int p1, int p2)
{
a = p1;
b = p2;
c = p2;
e.c = (byte)p1;
}
public int a;
public int b;
public decimal c;
public Pedding e;
} [LuaCallCSharp]
public enum MyEnum
{
E1,
E2
} [CSharpCallLua]
public delegate int IntParam(int p); [CSharpCallLua]
public delegate Vector3 Vector3Param(Vector3 p); [CSharpCallLua]
public delegate MyStruct CustomValueTypeParam(MyStruct p); [CSharpCallLua]
public delegate MyEnum EnumParam(MyEnum p); [CSharpCallLua]
public delegate decimal DecimalParam(decimal p); [CSharpCallLua]
public delegate void ArrayAccess(Array arr); [CSharpCallLua]
public interface IExchanger
{
void exchange(Array arr);
} [LuaCallCSharp]
public class NoGc : MonoBehaviour
{
LuaEnv luaenv = new LuaEnv(); IntParam f1;
Vector3Param f2;
CustomValueTypeParam f3;
EnumParam f4;
DecimalParam f5; ArrayAccess farr;
Action flua;
IExchanger ie;
LuaFunction add; [NonSerialized]
public double[] a1 = new double[] { , };
[NonSerialized]
public Vector3[] a2 = new Vector3[] { new Vector3(, , ), new Vector3(, , ) };
[NonSerialized]
public MyStruct[] a3 = new MyStruct[] { new MyStruct(, ), new MyStruct(, ) };
[NonSerialized]
public MyEnum[] a4 = new MyEnum[] { MyEnum.E1, MyEnum.E2 };
[NonSerialized]
public decimal[] a5 = new decimal[] { 1.00001M, 2.00002M }; public float FloatParamMethod(float p)
{
return p;
} public Vector3 Vector3ParamMethod(Vector3 p)
{
return p;
} public MyStruct StructParamMethod(MyStruct p)
{
return p;
} public MyEnum EnumParamMethod(MyEnum p)
{
return p;
} public decimal DecimalParamMethod(decimal p)
{
return p;
} // Use this for initialization
void Start()
{
luaenv.DoString(@"
function id(...)
return ...
end function add(a, b) return a + b end function array_exchange(arr)
arr[0], arr[1] = arr[1], arr[0]
end local v3 = CS.UnityEngine.Vector3(7, 8, 9)
local vt = CS.XLuaTest.MyStruct(5, 6) function lua_access_csharp()
monoBehaviour:FloatParamMethod(123) --primitive
monoBehaviour:Vector3ParamMethod(v3) --vector3
local rnd = math.random(1, 100)
local r = monoBehaviour:Vector3ParamMethod({x = 1, y = 2, z = rnd}) --vector3
assert(r.x == 1 and r.y == 2 and r.z == rnd)
monoBehaviour:StructParamMethod(vt) --custom struct
r = monoBehaviour:StructParamMethod({a = 1, b = rnd, e = {c = rnd}})
assert(r.b == rnd and r.e.c == rnd)
monoBehaviour:EnumParamMethod(CS.XLuaTest.MyEnum.E2) --enum
monoBehaviour:DecimalParamMethod(monoBehaviour.a5[0])
monoBehaviour.a1[0], monoBehaviour.a1[1] = monoBehaviour.a1[1], monoBehaviour.a1[0] -- field
end exchanger = {
exchange = function(self, arr)
array_exchange(arr)
end
} A = { B = { C = 789}}
GDATA = 1234;
"); luaenv.Global.Set("monoBehaviour", this); luaenv.Global.Get("id", out f1);
luaenv.Global.Get("id", out f2);
luaenv.Global.Get("id", out f3);
luaenv.Global.Get("id", out f4);
luaenv.Global.Get("id", out f5); luaenv.Global.Get("array_exchange", out farr);
luaenv.Global.Get("lua_access_csharp", out flua);
luaenv.Global.Get("exchanger", out ie);
luaenv.Global.Get("add", out add); luaenv.Global.Set("g_int", );
luaenv.Global.Set(, );
int i;
luaenv.Global.Get("g_int", out i);
Debug.Log("g_int:" + i);
luaenv.Global.Get(, out i);
Debug.Log("123:" + i);
} // Update is called once per frame
void Update()
{
// c# call lua function with value type but no gc (using delegate)
f1(); // primitive type
f2(new Vector3(, , )); // vector3
MyStruct mystruct1 = new MyStruct(, );
f3(mystruct1); // custom complex value type
f4(MyEnum.E1); //enum
decimal dec1 = -32132143143100109.00010001010M;
f5(dec1); //decimal // using LuaFunction.Func<T1, T2, TResult>
add.Func<int, int, int>(, ); // LuaFunction.Func<T1, T2, TResult> // lua access c# value type array no gc
farr(a1); //primitive value type array
farr(a2); //vector3 array
farr(a3); //custom struct array
farr(a4); //enum arry
farr(a5); //decimal arry // lua call c# no gc with value type
flua(); //c# call lua using interface
ie.exchange(a2); //no gc LuaTable use
luaenv.Global.Set("g_int", );
int i;
luaenv.Global.Get("g_int", out i); luaenv.Global.Set(123.0001, mystruct1);
MyStruct mystruct2;
luaenv.Global.Get(123.0001, out mystruct2); decimal dec2 = 0.0000001M;
luaenv.Global.Set((byte), dec1);
luaenv.Global.Get((byte), out dec2); int gdata = luaenv.Global.Get<int>("GDATA");
luaenv.Global.SetInPath("GDATA", gdata + ); int abc = luaenv.Global.GetInPath<int>("A.B.C");
luaenv.Global.SetInPath("A.B.C", abc + ); luaenv.Tick();
} void OnDestroy()
{
f1 = null;
f2 = null;
f3 = null;
f4 = null;
f5 = null;
farr = null;
flua = null;
ie = null;
add = null;
luaenv.Dispose();
}
}
}
05_NoGc: 怎么去避免值类型的GC
CoroutineTest.cs using UnityEngine;
using XLua; namespace XLuaTest
{
public class CoroutineTest : MonoBehaviour
{
LuaEnv luaenv = null;
// Use this for initialization
void Start()
{
luaenv = new LuaEnv();
luaenv.DoString("require 'coruntine_test'");
} // Update is called once per frame
void Update()
{
if (luaenv != null)
{
luaenv.Tick();
}
} void OnDestroy()
{
luaenv.Dispose();
}
}
} coruntine_test.lua local cs_coroutine = (require 'cs_coroutine') local a = cs_coroutine.start(function()
print('coroutine a started') coroutine.yield(cs_coroutine.start(function()
print('coroutine b stated inside cotoutine a')
coroutine.yield(CS.UnityEngine.WaitForSeconds())
print('i am coroutine b')
end))
print('coroutine b finish') while true do
coroutine.yield(CS.UnityEngine.WaitForSeconds())
print('i am coroutine a')
end
end) cs_coroutine.start(function()
print('stop coroutine a after 5 seconds')
coroutine.yield(CS.UnityEngine.WaitForSeconds())
cs_coroutine.stop(a)
print('coroutine a stoped')
end) cs_coroutine.lua local util = require 'xlua.util' local gameobject = CS.UnityEngine.GameObject('Coroutine_Runner')
CS.UnityEngine.Object.DontDestroyOnLoad(gameobject)
local cs_coroutine_runner = gameobject:AddComponent(typeof(CS.XLuaTest.Coroutine_Runner)) return {
start = function(...)
return cs_coroutine_runner:StartCoroutine(util.cs_generator(...))
end; stop = function(coroutine)
cs_coroutine_runner:StopCoroutine(coroutine)
end
} Coroutine_Runner.cs using UnityEngine;
using XLua;
using System.Collections.Generic;
using System.Collections;
using System; namespace XLuaTest
{
public class Coroutine_Runner : MonoBehaviour
{
} public static class CoroutineConfig
{
[LuaCallCSharp]
public static List<Type> LuaCallCSharp
{
get
{
return new List<Type>()
{
typeof(WaitForSeconds),
typeof(WWW)
};
}
}
}
}
06_Coroutine: lua协程怎么和Unity协程相配合
相关文章
xLua 学习的更多相关文章
- 热更新解决方案--xlua学习笔记
一.热更新方案简介 在Unity游戏工程中,C#代码(编译型语言)资源和Resources文件夹下的资源打包后都不可以更改,因此这部分内容不能进行热更新,而lua代码(解释型语言)逻辑不需要进行预编译 ...
- XLua系统学习
官方网站:https://github.com/Tencent/xLua 学习手册:http://manual.luaer.cn/ 技术博客: http://blog.csdn.net/column/ ...
- 热更新应用--热补丁Hotfix学习笔记
一.热补丁简介 热补丁主要是用于将纯C#工程在不重做的情况下通过打补丁的形式改造成具备lua热更新功能工程,主要是让原来脚本中Start函数和Update函数等函数代码块重定向到lua代码. 二.第一 ...
- Unity3D学习笔记(三十二):Xlua(2)
Xlua支持通过子类对象访问父类的变量属性和方法 对于C#的ref,out参数的方法 当调用的时候:out类型的参数是不需要传递实参的,普通的参数和ref参数需要传递实参. out,ref传出值通 ...
- Unity3D学习笔记(三十一):Xlua(1)
Xlua:腾讯研发,开源免费 配置:文件解压,拷贝到Unity项目里 注意:Xlua文件夹不许移动,不许重命名 运行Xlua: 1.引用命名空间 2.创建虚拟机 3.运行lua语句 4.不需要 ...
- Unity XLua 官方教程学习
一.Lua 文件加载 1. 执行字符串 using UnityEngine; using XLua; public class ByString : MonoBehaviour { LuaEnv lu ...
- Unity XLua 官方案例学习
1. Helloworld using UnityEngine; using XLua; public class Helloworld : MonoBehaviour { // Use this f ...
- Unity的学习笔记(XLua的初学用法并在lua中使用unity周期函数)
自己最近也在研究怎么用lua控制UI,然后看着网上介绍,决定选用XLua,毕竟TX爸爸出的,有人维护,自己琢磨着怎么用,于是弄出来一个能用的作为记录. 当然,XLua主要是用于热更新,我自己是拿来尝试 ...
- 基于xlua和mvvm的unity框架
1.框架简介 这两天在Github上发现了xlua的作者车雄生前辈开源的一个框架—XUUI,于是下载下来学习了一下.XUUI基于xlua,又借鉴了mvvm的设计概念.xlua是目前很火的unity热更 ...
随机推荐
- .NET Core 中读取 Request.Headers 的姿势
Request.Headers 的类型是 IHeaderDictionary 接口,对应的实现类是 HeaderDictionary ,C# 实现源码见 HeaderDictionary.cs . H ...
- php处理curl的返回结果
最简单的方式: json_decode($res,true): 结果都是:
- spring cloud 2.x版本 Gateway路由网关教程
前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...
- 用sticky.js实现头部导航栏固定
在页面中,如果页面长度过大,滑动页面时,头部导航栏则会跟着划走. 我的头部导航栏代码为: <div class="headbar"> <center class= ...
- 使用vue组件需要注意的4个细节
细节1:table(表格)中直接引用自定义组件出现的bug 如上图,tr本应在tbody中面,现在却是同级.造成的原因是h5规定table里必须有tbody,tbody中必须有tr, 当tbody中引 ...
- 数据库——SQL-SERVER练习(6) 数据库安全性
一.实验准备 (1)运行SQL-SERVER服务管理器, 启动服务(2)运行查询分析器, 以DBA身份登录数据库服务器: 用户名sa, 密码123456(3)打开CREATE-TABLE ...
- idea设置类注释和方法注释
类注释 1.file-->setting-->editor-->file and code templates-->includes--> file header 2.在 ...
- Elasticsearch 6.x版本全文检索学习之Search API
Elasticsearch 6.x版本全文检索学习之Search API. 1).Search API,实现对es中存储的数据进行查询分析,endpoind为_search,如下所示. 方式一.GET ...
- VS2019安装好后,经常打不开软件没反应解决方法
原文地址:https://blog.csdn.net/FL1623863129/article/details/89013137 VS2019于昨日正式发布,博主立马下载一个专业版尝尝鲜,但是发现项目 ...
- 如何使用npm的部分用法以及npm被墙的解决方法
我们要明白我们使用的npm就是node中自带的包(模块)管理工具:借助NPM可以帮助我们快速安和管理依赖包,使Node与第三方模块之间形成了一个良好的生态系统. 我们可以直接输入npm,查看帮助引导: ...