如博文无法正常显示,请访问原文地址: https://blog.csdn.net/ChinarCSDN/article/details/83044148

tolua 教程大全


本文提供全流程,中文翻译。

Chinar 坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)

Chinar —— 心分享、心创新!

助力快速了解 tolua 热更新框架的具体使用、细节

为新手节省宝贵的时间,避免采坑!

Chinar 教程效果:


文章目录

  • 1
    • tolua —— 热更新方案
  • 2
    • DoString —— c#字符串书写lua代码,并调用
  • 3
    • ScriptsFromFile —— C#通过文件执行lua脚本
  • 4
    • CallLuaFunction —— C#调用lua函数
  • 5
    • AccessingLuaVariables —— C#访问lua变量
  • 6
    • Lua-Coroutine —— Lua中使用协程
  • 7
    • Lua-Array —— Lua中使用数组
  • 8
    • Lua-Dictionary —— Lua中使用字典
  • 9
    • Lua-Enum —— Lua中使用枚举类型
  • 5
    • Project —— 项目文件
  • 支持
    • May Be —— 搞开发,总有一天要做的事!

全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

tolua —— 热更新方案

Wait —— 敬请期待

正在整理中。。。。 Chinar 教程简单易懂,但整理资料,写起来并不容易,感谢大家的关注与理解


2

DoString —— c#字符串书写lua代码,并调用

DoString() —— 该函数:可直接调用指定的 C# 脚本中的指定字符串 lua 代码

注意:

这对于初学者是一个老生常谈的问题了

Lua 中调用C#函数用“:”,字段用“.”

: —— map:GetEnumerator()/iter:MoveNext()

. ——iter.Current.name /map.Keys

using UnityEngine;
using LuaInterface;/// <summary>
/// Chinar解释-tolua官方测试案例1
/// </summary>
public class HelloWorld : MonoBehaviour
{void Awake(){LuaState lua = new LuaState();lua.Start();string hello = //字符串书写 lua 代码@"                print('hello tolua#')                                  ";lua.DoString(hello, "HelloWorld.cs"); //执行C#脚本: HelloWorld 中的 hello字符串lua.CheckTop();                       //检验lua.Dispose();                        //释放lua = null;                           //质空}
}

运行结果:

hello tolua

3

ScriptsFromFile —— C#通过文件执行lua脚本

AddSearchPath() —— 该函数:添加搜索路径,将 lua 与 .Cs 脚本的路径,添加至搜索范围

注意: 只有先添加了AddSearchPath()搜索路径,才可以保证以下2个函数的正常调用

DoFile() —— 该函数:执行 ScriptsFromFile.lua 脚本

Require() —— 该函数:执行 引用 ScriptsFromFile lua 脚本

using UnityEngine;
using LuaInterface;/// <summary>
/// Chinar解释 —— tolua官方测试案例 2
/// 展示 searchpath 使用,require 与 dofile 区别
/// </summary>
public class ScriptsFromFile : MonoBehaviour
{LuaState       lua    = null;private string strLog = "";void Start(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += Log;
#elseApplication.RegisterLogCallback(Log);
#endiflua = new LuaState();lua.Start();//如果移动了ToLua目录,自己手动修复吧,只是例子就不做配置了//string fullPath = Application.dataPath + "\\ToLua/Examples/02_ScriptsFromFile"; //这是官方默认路径,需要自己修改为自己的string fullPath = Application.dataPath + "\\LuaFramework/ToLua/Examples/02_ScriptsFromFile";lua.AddSearchPath(fullPath); //添加搜索路径,将lua与.Cs脚本的搜索路径,添加至搜索范围}void Log(string msg, string stackTrace, LogType type){strLog += msg;strLog += "\r\n";}void OnGUI(){GUI.Label(new Rect(100, Screen.height / 2 - 100, 600, 400), strLog);if (GUI.Button(new Rect(50, 50, 120, 45), "DoFile")) //点击 DoFile 按钮{strLog = "";lua.DoFile("ScriptsFromFile.lua"); //执行 ScriptsFromFile.lua 脚本}else if (GUI.Button(new Rect(50, 150, 120, 45), "Require")) //点击 Requre 按钮{strLog = "";lua.Require("ScriptsFromFile"); //执行 引用 ScriptsFromFile 脚本}lua.Collect();  //收集GClua.CheckTop(); //检验}/// <summary>/// 程序退出时/// </summary>void OnApplicationQuit(){lua.Dispose(); //释放lua = null;    //质空
#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= Log;
#elseApplication.RegisterLogCallback(null);
#endif}
}

4

CallLuaFunction —— C#调用lua函数

GetFunction() —— 该函数:获取lua中指定test类的luaFunc函数

注意: 只有先添加了AddSearchPath()搜索路径,才可以保证以下2个函数的正常调用

DoFile() —— 该函数:执行 ScriptsFromFile.lua 脚本

Require() —— 该函数:执行 引用 ScriptsFromFile lua 脚本

using UnityEngine;
using LuaInterface;
using System;/// <summary>
/// Chinar解释 —— tolua官方测试案例 3
/// C#调用lua函数
/// </summary>
public class CallLuaFunction : MonoBehaviour
{private string script =@"  function luaFunc(num)                        return num + 1endtest = {}test.luaFunc = luaFuncfunction ChinarTest()print('通过lua对象获取函数')end";LuaFunction luaFunc = null;LuaState    lua     = null;string      tips    = null;void Start(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();lua = new LuaState();lua.Start();DelegateFactory.Init();lua.DoString(script);luaFunc = lua.GetFunction("test.luaFunc"); //获取test中的luaFunc函数if (luaFunc != null){//第一种方法 —— luaFunc.Invokeint num = luaFunc.Invoke<int, int>(123456);    //调用函数返回int值Debugger.Log("generic call return: {0}", num); //123457//第二种方法luaFunc.BeginPCall();luaFunc.Push(123456);luaFunc.PCall();num = (int) luaFunc.CheckNumber();luaFunc.EndPCall();Debugger.Log("expansion call return: {0}", num); //123457//第三种方法 —— 委托调用Func<int, int> Func = luaFunc.ToDelegate<Func<int, int>>();num                 = Func(123456);Debugger.Log("Delegate call return: {0}", num); //123457//第四种方法 —— lua.Invokenum = lua.Invoke<int, int>("test.luaFunc", 123456, true);Debugger.Log("luastate call return: {0}", num); //123457//第五种方法 —— LuaFunction . Call()LuaFunction func = lua["ChinarTest"] as LuaFunction; //lua对象 转 lua函数func.Call();                                       //调用lua TestFunc 函数func.Dispose();}lua.CheckTop();}void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}#if !TEST_GCvoid OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips);}
#endifvoid OnDestroy(){if (luaFunc != null){luaFunc.Dispose();luaFunc = null;}lua.Dispose();lua = null;#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endif}
}

5

AccessingLuaVariables —— C#访问lua变量

注意: lua["变量名"] —— 通过这种方式对 lua 中的变量进行访问

lua["TestFunc"] as LuaFunction —— LuaState 对象 转 LuaFunction,调用 lua 中 TestFunc 函数

lua.GetTable("lua 中的表名") —— 获取 lua 中的表,返回类型为LuaTable

using UnityEngine;
using LuaInterface;/// <summary>
/// Chinar解释 —— tolua官方测试案例 4
/// C#访问lua中的变量
/// </summary>
public class AccessingLuaVariables : MonoBehaviour
{private string script =@"print('Objs2Spawn is: '..Objs2Spawn)var2read = 42varTable = {1,2,3,4,5}varTable.default = 1varTable.map = {}varTable.map.name = 'map'print(varTable.map.name)meta = {name = 'meta'}setmetatable(varTable, meta)function TestFunc(strs)print('get func by variable')end"; //lua脚本void Start(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();LuaState lua = new LuaState();lua.Start();lua["Objs2Spawn"] = 5; //对lua脚本中 Objs2Spawn 赋值 5lua.DoString(script);//通过LuaState访问 —— 从lua中读取 var2read 的值Debugger.Log("Read var from lua: {0}", lua["var2read"]); //42//LuaState 拆串式table,读取lua表中的值Debugger.Log("Read table var from lua: {0}", lua["varTable.default"]); //1LuaFunction func = lua["TestFunc"] as LuaFunction; //lua对象 转 lua函数func.Call();                                       //调用lua TestFunc 函数func.Dispose();//cache成LuaTable进行访问LuaTable table = lua.GetTable("varTable");Debugger.Log("Read varTable from lua, default: {0} name: {1}", table["default"], table["map.name"]);//1 和 无table["map.name"] = "new";                                    //table 字符串只能是keyDebugger.Log("Modify varTable name: {0}", table["map.name"]); //打印 newtable.AddTable("newmap"); //表中添加 newmap                   //这里 table["newmap"] 是Object类型,所以需要强转为 LuaTable类型LuaTable table1 = (LuaTable) table["newmap"];table1["name"]  = "table1";Debugger.Log("varTable.newmap name: {0}", table1["name"]); //打印table1table1.Dispose();table1 = table.GetMetaTable(); //获取元表,并赋值if (table1 != null){Debugger.Log("varTable metatable name: {0}", table1["name"]);}object[] list = table.ToArray();for (int i = 0; i < list.Length; i++){Debugger.Log("varTable[{0}], is {1}", i, list[i]);}table.Dispose(); //释放表lua.CheckTop();  //检验lua.Dispose();   //释放}private void OnApplicationQuit(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endif}string tips = null;void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);}
}

6

Lua-Coroutine —— Lua中使用协程

coroutine.start(函数名) —— 在 lua 中开启协程

coroutine.stop(函数名) —— 停止协程

coroutine.step() —— 等待一帧

coroutine.www(UnityEngine.WWW("http://www.baidu.com")) —— 开启www请求

此种写法官方推荐,另一种虽然书写简单,但大量使用时执行效率低,这里都不做介绍

C# 脚本

using UnityEngine;
using LuaInterface;/// <summary>
/// Chinar解释 —— tolua官方案例 5
/// 例子5和6展示的两套协程系统勿交叉使用,此为推荐方案
/// </summary>
public class TestCoroutine : MonoBehaviour
{public  TextAsset luaFile = null;private LuaState  lua     = null;private LuaLooper looper  = null;void Awake(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();lua = new LuaState();lua.Start();LuaBinder.Bind(lua);                                    //绑定lua对象DelegateFactory.Init();                                 //委托工厂初始化looper          = gameObject.AddComponent<LuaLooper>(); //使用协程必须添加looper.luaState = lua;                                  //指定对象lua.DoString(luaFile.text, "TestLuaCoroutine.lua"); //读指定Asset中的资源文本,tolua会自动完成读取,指定文件名LuaFunction f = lua.GetFunction("TestCortinue");    //获取 lua 脚本中 TestCortinue 对象,赋值ff.Call();                                           //调用,协程在lua脚本中 启动f.Dispose();f = null;}void OnApplicationQuit(){looper.Destroy();lua.Dispose();lua = null;
#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endif}string tips = null;void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);if (GUI.Button(new Rect(50, 50, 120, 45), "Start Counter"))//开启协程{tips             = null;LuaFunction func = lua.GetFunction("StartDelay");func.Call();func.Dispose();}else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter"))//停止协程{LuaFunction func = lua.GetFunction("StopDelay");func.Call();func.Dispose();}else if (GUI.Button(new Rect(50, 250, 120, 45), "GC"))//回收{lua.DoString("collectgarbage('collect')", "TestCoroutine.cs");Resources.UnloadUnusedAssets();}}
}

Lua 脚本

-------tolua官方案例:初始化时,C#调用此函数开启协程----------
function TestCortinue() coroutine.start(CoFunc)
endlocal coDelay = nil------------------------每隔1秒打印一次输出------------------
function Delay()local c = 1while true docoroutine.wait(1) print("Count: "..c)c = c + 1end
end----------------------------开启协程------------------------
function StartDelay()coDelay=coroutine.start(Delay)
end----------------------------停止协程------------------------
function StopDelay()coroutine.stop(coDelay)
end----------------------------每隔0.1秒计算一次------------------------
function fib(n)local a, b = 0, 1while n > 0 doa, b = b, a + bn = n - 1endreturn a
end----------------------------协程运行函数------------------------
function CoFunc()print('Coroutine started')    for i = 0, 10, 1 doprint(fib(i))                    coroutine.wait(0.1)--等待0.1秒                       end print("current frameCount: "..Time.frameCount)coroutine.step()--等待一帧print("yield frameCount: "..Time.frameCount)local www = UnityEngine.WWW("http://www.baidu.com")coroutine.www(www)--开启www请求local s = tolua.tolstring(www.bytes)print(s:sub(1, 128))print('Coroutine ended')
end

7

Lua-Array —— Lua中使用数组

func.Push(arrayInts) —— 将 数组 arrayInts 传至 Lua 中

func.CheckNumber() —— 得到 Lua 对应函数返回值中的:值类型

func.CheckString() —— 得到 Lua 对应函数返回值中的:字符串类型

func.CheckBoolean() —— 得到 Lua 对应函数返回值中的:布尔类型

注意: 书写顺序应该是与函数返回值先后顺序保持一致,否则会报错

C# 脚本

// ========================================================
// 描述:测试数组的调用
// 作者:Chinar
// 创建时间:2018-10-21 14:31:37
// 版 本:1.0
// ========================================================
using LuaInterface;
using UnityEngine;/// <summary>
/// Chinar解释 —— tolua官方案例8
/// </summary>
public class ChinarTestArray : MonoBehaviour
{private string script =@"function TestArray(array)----------------------------获取数组长度------------------------local len = array.Length----------------------------遍历数组输出------------------------for i = 0, len - 1 doprint('数组: '..tostring(array[i]))end----------------------------获取枚举器--------------------------local iter = array:GetEnumerator()----------------------调用数组函数MoveNext()--------------------while iter:MoveNext() do print('依次取: '..iter.Current)end----------------------数组转表----------------------------------local t = array:ToTable()for i = 1, #t doprint('转表: ' .. tostring(t[i]))end----------------------调用数组函数BinarySearch(3)---------------local pos = array:BinarySearch(3)print('数组二进制 BinarySearch: 下标是: '..pos..' 值: '..array[pos])----------------------调用数组函数IndexOf(4)--------------------pos = array:IndexOf(4)print('数组 indexof 4 下标是: '..pos)----------------------返回值参数--------------------------------return 5, 'Chinar', trueend";LuaState    lua  = null;LuaFunction func = null;string      tips = null;void Start(){#if UNITY_2017||UNITY_2018||UNITY_5                 //对应版本Application.logMessageReceived += ShowTips; //监听输出信息函数
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();tips = "";lua = new LuaState();lua.Start();lua.DoString(script, "ChinarTestArray.cs"); //运行 script 字符串中的lua脚本,指定C#脚本路径int[] arrayInts = {1, 2, 3, 4, 5};func            = lua.GetFunction("TestArray"); //取得 lua script 脚本中的 TestArray 函数func.BeginPCall();#region 第一种写法func.Push(arrayInts);func.PCall();//  接受返回值时顺序要一一对应。 顺序写错,会报错//  另外 int string float 这些会自动完成转换,不会报错//  如: 10.3 ——  func.CheckValua<int>(); 这里会自动 返回 int//  如: 1 ——  func.CheckNumber();//  如: `123` ——  func.CheckString();//  如: true ——  func.CheckBoolean();double arg1 = func.CheckNumber();string arg2 = func.CheckString();bool   arg3 = func.CheckBoolean();Debugger.Log("返回值:{0}|{1}|{2}", arg1, arg2, arg3);//-------------------------------------------func.EndPCall();#endregion#region 第二种通用写法//调用通用函数需要转换一下类型,避免可变参数拆成多个参数传递//func.LazyCall((object) arrayInts);//相当于 ↓↓//func.Push(arrayInts);//func.PCall();object[] objects = func.LazyCall((object) arrayInts);if (objects != null){Debugger.Log("return is {0} {1} {2}", objects[0], objects[1], objects[2]);}func.EndPCall();lua.CheckTop(); //检查返回值#endregion}void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 300, 600, 600), tips);}/// <summary>/// 显示输出提示/// </summary>private void ShowTips(string msg, string stacktrace, LogType type){tips += msg;    //信息tips += "\r\n"; //换行}private void OnApplicationQuit(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endiffunc.Dispose();lua.Dispose();}
}

输出结果:


8

Lua-Dictionary —— Lua中使用字典

map.Add(1, new TestAccount(1, "水水", 0)); —— 字典中添加元素:利用构造函数,新建测试账号对象时,在对象中直接完成赋值

注意:

这对于初学者是一个老生常谈的问题了

Lua 中调用C#函数用“:”,字段用“.”

: —— map:GetEnumerator()/iter:MoveNext()

. ——iter.Current.name /map.Keys

C# 脚本

using UnityEngine;
using System.Collections.Generic;
using LuaInterface;/// <summary>
/// Chinar解释 —— tolua官方案例9
/// Lua中使用字典
/// </summary>
public sealed class TestAccount
{public int    id;public string name;public int    sex;/// <summary>/// 构造函数/// </summary>public TestAccount(int id, string name, int sex){this.id   = id;this.name = name;this.sex  = sex;}
}public class UseDictionary : MonoBehaviour
{private Dictionary<int, TestAccount> map = new Dictionary<int, TestAccount>();string script =@"              function TestDict(map)------------调用字典函数GetEnumerator()---------------local iter = map:GetEnumerator()-------------调用字典函数MoveNext()-------------------while iter:MoveNext() dolocal v = iter.Current.Valueprint('id: '..v.id .. ' name: '..v.name..' sex: '..v.sex)end-------------调用字典函数TryGetValue()-----------------local flag, account = map:TryGetValue(1, nil)if flag thenprint('TryGetValue 返回结果正确时: '..account.name)end--------------------获取字典中的键---------------------local keys = map.Keysiter = keys:GetEnumerator()print('------------打印输出字典中的键---------------')while iter:MoveNext() doprint(iter.Current)endprint('----------------------over----------------------')local values = map.Valuesiter = values:GetEnumerator()print('------------打印输出字典中的值---------------')while iter:MoveNext() doprint(iter.Current.name)endprint('----------------------over----------------------')-----------获取字典中2键对应的name值---------------------print('kick '..map[2].name)-----------移除map中下标2对应的元素---------------------map:Remove(2)iter = map:GetEnumerator()-----------重新输出---------------------while iter:MoveNext() dolocal v = iter.Current.Valueprint('id: '..v.id .. ' name: '..v.name..' sex: '..v.sex)endend";void Awake(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();map.Add(1, new TestAccount(1, "水水", 0));map.Add(2, new TestAccount(2, "王伟", 1));map.Add(3, new TestAccount(3, "王芳", 0));LuaState luaState = new LuaState();luaState.Start();BindMap(luaState);luaState.DoString(script, "UseDictionary.cs");LuaFunction func = luaState.GetFunction("TestDict");func.BeginPCall();func.Push(map);func.PCall();func.EndPCall();func.Dispose();func = null;luaState.CheckTop();luaState.Dispose();luaState = null;}void OnApplicationQuit(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endif}string tips = "";void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);}//示例方式,方便删除,正常导出无需手写下面代码//Chinar:这里不用管,这是tolua作者为方便我们删除示例预留的代码//为了保证删除示例是,不影响我们的整体工程的其他 wrap 文件void BindMap(LuaState L){L.BeginModule(null);TestAccountWrap.Register(L);L.BeginModule("System");L.BeginModule("Collections");L.BeginModule("Generic");System_Collections_Generic_Dictionary_int_TestAccountWrap.Register(L);System_Collections_Generic_KeyValuePair_int_TestAccountWrap.Register(L);L.BeginModule("Dictionary");System_Collections_Generic_Dictionary_int_TestAccount_KeyCollectionWrap.Register(L);System_Collections_Generic_Dictionary_int_TestAccount_ValueCollectionWrap.Register(L);L.EndModule();L.EndModule();L.EndModule();L.EndModule();L.EndModule();}
}

输出结果:


9

Lua-Enum —— Lua中使用枚举类型

LuaBinder.Bind(lua); —— 首先这一步不能少

lua["space"] = Space.World; —— Lua 脚本中的 space 变量,进行枚举类型赋值

C# 脚本

using UnityEngine;
using LuaInterface;/// <summary>
/// Chinar解释 —— tolua官方案例 10
/// Lua中使用Unity枚举类型
/// </summary>
public class AccessingEnum : MonoBehaviour
{string script =@"space = nilfunction TestEnum(e)print('枚举是:'..tostring(e))----------------枚举类型转int----------------if space:ToInt() == 0 thenprint('枚举转Int成功')end-------------枚举类型int与0比较--------------if not space:Equals(0) thenprint('枚举类型(与int型)比较成功')end-------------枚举类型直接比较----------------if space == e thenprint('枚举类型比较成功')end-------调用Unity中的Space枚举值转枚举--------local s = UnityEngine.Space.IntToEnum(0)if space == s thenprint('int转枚举,比较成功')endend----------------改变Unity光照类型---------------function ChangeLightType(light, type)print('改变光照类型为: '..tostring(type))light.type = typeend";LuaState state = null;string   tips  = "";int      count = 1;/// <summary>/// 格式化打印输出/// </summary>void ShowTips(string msg, string stackTrace, LogType type){tips += msg;tips += "\r\n";}/// <summary>/// 初始化函数/// </summary>void Start(){#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived += ShowTips;
#elseApplication.RegisterLogCallback(ShowTips);
#endifnew LuaResLoader();state = new LuaState();state.Start();LuaBinder.Bind(state); //绑定,必须要写state.DoString(script);state["space"] = Space.World;  //Lua脚本中的space变量,进行枚举类型赋值LuaFunction func = state.GetFunction("TestEnum");func.BeginPCall();func.Push(Space.World);func.PCall();func.EndPCall();func.Dispose();func = null;}/// <summary>/// 绘制函数/// </summary>void OnGUI(){GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);if (GUI.Button(new Rect(0, 60, 120, 50), "ChangeType")){Light       light = GameObject.Find("/Light").GetComponent<Light>(); //获取层次列表中对象的Light组件LuaFunction func  = state.GetFunction("ChangeLightType");func.BeginPCall();func.Push(light);                           //将light传入ChangeLightType函数LightType type = (LightType) (count++ % 4); //简单计算得到类型func.Push(type);                            //将type类型传入ChangeLightType函数func.PCall();                               //调用ChangeLightType函数func.EndPCall();func.Dispose();}}/// <summary>/// 应用退出时执行函数/// </summary>void OnApplicationQuit(){state.CheckTop();state.Dispose();state = null;#if UNITY_5 || UNITY_2017 || UNITY_2018Application.logMessageReceived -= ShowTips;
#elseApplication.RegisterLogCallback(null);
#endif}
}

输出:


5

Project —— 项目文件

项目文件为 unitypackage 文件包:

下载导入 Unity 即可使用

点击下载 —— 项目资源 (积分支持)

点击下载 —— 项目资源 (Chinar免费)


支持

May Be —— 搞开发,总有一天要做的事!

拥有自己的服务器,无需再找攻略!

Chinar 提供一站式教程,闭眼式创建!

为新手节省宝贵时间,避免采坑!

先点击领取 —— 阿里全产品优惠券 (享受最低优惠)

1 —— 云服务器超全购买流程 (新手必备!)

2 —— 阿里ECS云服务器自定义配置 - 购买教程(新手必备!)

3—— Windows 服务器配置、运行、建站一条龙 !

4 —— Linux 服务器配置、运行、建站一条龙 !


技术交流群:806091680 ! Chinar 欢迎你的加入


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

tolua全教程-Chinar相关推荐

  1. Docker最全教程——从理论到实战(六)

    Docker最全教程--从理论到实战(六) 原文:Docker最全教程--从理论到实战(六) 托管到腾讯云容器服务 托管到腾讯云容器服务,我们的公众号"magiccodes"已经发 ...

  2. Docker最全教程——从理论到实战(一)

    Docker最全教程--从理论到实战(一) 目录 前言 随着生产力的发展尤其是弹性架构的广泛应用(比如微服务),许多一流开发者都将应用托管到了应用容器上,比如Google.微软.亚马逊.腾讯.阿里.京 ...

  3. java开发五年多少钱,附超全教程文档

    一.分布式架构学习路线图 据统计,人的阅读时间在20分钟以内是能够达到全身心投入的,顾文章单张篇幅以后会尽量缩短,但更新会尽量相应频繁一些. 二.计算机软件发展历史 首先我们了解下计算机软件的发展历史 ...

  4. Docker最全教程——Redis容器化以及排行榜实战(十三)

    Docker最全教程--Redis容器化以及排行榜实战(十三) 原文:Docker最全教程--Redis容器化以及排行榜实战(十三) 前言 容器教程的路还很长,笔者尽量根据实践来不断地完善.由于在编写 ...

  5. 使用Reactor进行反应式编程最全教程

    反应式编程(Reactive Programming)这种新的编程范式越来越受到开发人员的欢迎.在 Java 社区中比较流行的是 RxJava 和 RxJava 2.本文要介绍的是另外一个新的反应式编 ...

  6. Docker最全教程——数据库容器化之持久保存数据(十一)

    Docker最全教程--数据库容器化之持久保存数据(十一) 原文:Docker最全教程--数据库容器化之持久保存数据(十一) 上一节我们讲述了SQL Server容器化实践(注意,SQL Server ...

  7. Docker最全教程——从理论到实战(七)

    Docker最全教程--从理论到实战(七) 原文:Docker最全教程--从理论到实战(七) 在本系列教程中,笔者希望将必要的知识点围绕理论.流程(工作流程).方法.实践来进行讲解,而不是单纯的为讲解 ...

  8. Docker最全教程之使用 Visual Studio Code玩转Docker(二十一)

    VS Code是一个年轻的编辑器,但是确实是非常犀利.通过本篇,老司机带你使用VS Code玩转Docker--相信阅读本篇之后,无论是初学者还是老手,都可以非常方便的玩转Docker了!所谓是&qu ...

  9. Docker最全教程之使用.NET Core推送钉钉消息(二十)

    前言 上一篇我们通过实战分享了使用Go推送钉钉消息,由于技痒,笔者现在也编写了一个.NET Core的Demo,作为简单的对照和说明. 最后,由于精力有限,笔者希望有兴趣的朋友可以分享下使用CoreR ...

最新文章

  1. ACM——模拟(hard) 刷题总结
  2. 发展大数据还有三道坎要迈
  3. Combiner合并案例
  4. 华为云阳云计算外包给哪家公司的_长春作为东北中心,华为四大件已经配齐,绝了!...
  5. 【Qt】仿360安全卫士界面(自定义阴影边框类)
  6. [机器学习] --- 参数优化与模型选择
  7. VirtualBox的Linux虚拟机访问Windows7的文件
  8. 视图的数据存放在哪里_分布式 | DBLE 是如何实现视图的?
  9. 一种全新的软件界面设计方法
  10. App流量测试--使用安卓自身提供的TCP收发长度统计功能
  11. day21 java的数字类
  12. 个人使用mysql_MySql使用总结
  13. Linux的高效传输函数sendfile
  14. 给 layui upload 带每个文件的进度条, .net 后台代码
  15. android ems的作用,对话框主题活动中忽略android:minEms
  16. Sip 响应状态码 对照 详解
  17. Introduction to Computer Networking学习笔记(九):error detection 错误探查 Checksum、CRC、MAC
  18. css实现div半透明而文字不透明
  19. python找不到模块pyodbc_python安装pyodbc模块
  20. 百度竞价后台操作技巧

热门文章

  1. 学习VGG(网络讲解+代码)
  2. 控制工程实践(5)——线性控制系统的稳态误差(之二)
  3. String是基本数据类型吗?
  4. Artificial Intelligence -- Chapter 12 Intro to Machine Learning
  5. docker下安装kong和konga
  6. 解决CentOS下boost安装后不能使用的问题
  7. 这个世界,没有传奇(一)——挺住,就是一切
  8. ISO26262解析(十二)——HARA分析
  9. 关于使用PyQt5时报错This application failed to start because no Qt platform plugin could be initialized及后续问题
  10. 有机化学php,有机化学原理