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热更 ...
随机推荐
- java之位运算符
整型转二进制:Integer.toBInaryString(6) <<:左移,3<<2 = 3*2*2 = 12 >>:右移,3>>1 = 3/2 = ...
- dva+umi+antd项目从搭建到使用(没有剖验证,不知道在说i什么)
先创建一个新项目,具体步骤请参考https://www.cnblogs.com/darkbluelove/p/11338309.html 一.添加document.ejs文件(参考文档:https:/ ...
- Mybatis框架增删改查
一.recourses中核心配置文件mybatis-config.xml 二. recourse中jdbc.properties 三.entity实体类 四.ISmbmsUserDao层 五.ISmb ...
- video调用直播接口:防止缓存方案
有时候我们需要调用解析过直播接口,使用video播放,但是在暂停又开始后,直播视频不会自动刷新,而是继续从暂停之前的时间点开始播放. 下面是我的解决方案代码,弟弟们请看我的下面: <!DOCTY ...
- git分支合并创建切换
1. 场景描述 介绍下Git最新内容合并到主干.从主干创建最新分支.idea下切换最新分支,能在2分钟内完成git合并.分支创建以及在idea中完成切换,希望能帮到一些朋友. 2. 解决方案 从以下三 ...
- 洛谷 P1351 (枚举)
### 洛谷P1351 题目链接 ### 题目大意: 给你 n 个节点, n-1 条边的无向联通图.若定义(u,v)表示 u 与 v 点的最短距离,如果 (u,v)值为 2 ,则这两个点的点权之积(即 ...
- 前端开发JS——jQuery常用方法
jQuery基础(三)- 事件篇 1.jQuery鼠标事件之click与dbclick事件 click方法用于监听用户单击操作,dbclick方法用于监听用户双击操作,这两个方法用法及其类似,所以 ...
- flex弹性布局没有生效
display: -webkit-flex; /* 新版本语法: Chrome 21+ */ display: -webkit-box; /* 老版本语法: Safari, iOS, Android ...
- Android框架Volley使用:Json请求实现
首先我们在项目中导入这个框架: implementation 'com.mcxiaoke.volley:library:1.0.19' 在AndroidManifest文件当中添加网络权限: < ...
- RdKafka文档翻译
函数string rd_kafka_err2str ( integer $err ) 将rdkafka错误代码转换为字符串 integer rd_kafka_errno2err ( integer $ ...