tolua全教程-Chinar

如博文无法正常显示,请访问原文地址: 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 教程简单易懂,但整理资料,写起来并不容易,感谢大家的关注与理解

New举例子黑白88


2

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



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

注意:

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

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

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

. ——iter.Current.name /map.Keys
New举例子黑白88

using UnityEngine;
using LuaInterface;


/// 
/// Chinar解释-tolua官方测试案例1
/// 
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 脚本
New举例子黑白88

using UnityEngine;
using LuaInterface;


/// 
/// Chinar解释 —— tolua官方测试案例 2
/// 展示 searchpath 使用,require 与 dofile 区别
/// 
public class ScriptsFromFile : MonoBehaviour
{
    LuaState       lua    = null;
    private string strLog = "";


    void Start()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += Log;
#else
        Application.RegisterLogCallback(Log);
#endif
        lua = 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();  //收集GC
        lua.CheckTop(); //检验
    }


    /// 
    /// 程序退出时
    /// 
    void OnApplicationQuit()
    {
        lua.Dispose(); //释放
        lua = null;    //质空
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= Log;
#else
        Application.RegisterLogCallback(null);
#endif
    }
}

4

CallLuaFunction —— C#调用lua函数


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

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

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

Require() —— 该函数:执行 引用 ScriptsFromFile lua 脚本
New举例子黑白88

using UnityEngine;
using LuaInterface;
using System;


/// 
/// Chinar解释 —— tolua官方测试案例 3
/// C#调用lua函数
/// 
public class CallLuaFunction : MonoBehaviour
{
    private string script =
        @"  function luaFunc(num)                        
                return num + 1
            end

            test = {}
            test.luaFunc = luaFunc
			
			function ChinarTest()
                print('通过lua对象获取函数')
            end
        ";

    LuaFunction luaFunc = null;
    LuaState    lua     = null;
    string      tips    = null;


    void Start()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        new LuaResLoader();
        lua = new LuaState();
        lua.Start();
        DelegateFactory.Init();
        lua.DoString(script);
        luaFunc = lua.GetFunction("test.luaFunc"); //获取test中的luaFunc函数

        if (luaFunc != null)
        {
            //第一种方法 —— luaFunc.Invoke
            int 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.Invoke
            num = 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_GC
    void OnGUI()
    {
        GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips);
    }
#endif


    void OnDestroy()
    {
        if (luaFunc != null)
        {
            luaFunc.Dispose();
            luaFunc = null;
        }

        lua.Dispose();
        lua = null;

#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.RegisterLogCallback(null);
#endif
    }
}

5

AccessingLuaVariables —— C#访问lua变量


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

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

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

New举例子黑白88

using UnityEngine;
using LuaInterface;


/// 
/// Chinar解释 —— tolua官方测试案例 4
/// C#访问lua中的变量
/// 
public class AccessingLuaVariables : MonoBehaviour
{
    private string script =
        @"
            print('Objs2Spawn is: '..Objs2Spawn)
            var2read = 42
            varTable = {1,2,3,4,5}
            varTable.default = 1
            varTable.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_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        new LuaResLoader();
        LuaState lua = new LuaState();
        lua.Start();
        lua["Objs2Spawn"] = 5; //对lua脚本中 Objs2Spawn 赋值 5
        lua.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"]); //1

        LuaFunction 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 字符串只能是key
        Debugger.Log("Modify varTable name: {0}", table["map.name"]); //打印 new

        table.AddTable("newmap"); //表中添加 newmap                   
        //这里 table["newmap"] 是Object类型,所以需要强转为 LuaTable类型
        LuaTable table1 = (LuaTable) table["newmap"];
        table1["name"]  = "table1";
        Debugger.Log("varTable.newmap name: {0}", table1["name"]); //打印table1
        table1.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_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.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请求

此种写法官方推荐,另一种虽然书写简单,但大量使用时执行效率低,这里都不做介绍
New举例子黑白88
C# 脚本

using UnityEngine;
using LuaInterface;


/// 
/// Chinar解释 —— tolua官方案例 5
/// 例子5和6展示的两套协程系统勿交叉使用,此为推荐方案
/// 
public class TestCoroutine : MonoBehaviour
{
    public  TextAsset luaFile = null;
    private LuaState  lua     = null;
    private LuaLooper looper  = null;


    void Awake()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        new 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 对象,赋值f
        f.Call();                                           //调用,协程在lua脚本中 启动
        f.Dispose();
        f = null;
    }


    void OnApplicationQuit()
    {
        looper.Destroy();
        lua.Dispose();
        lua = null;
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.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)
end

local coDelay = nil

------------------------每隔1秒打印一次输出------------------
function Delay()
	local c = 1

	while true do
		coroutine.wait(1) 
		print("Count: "..c)
		c = c + 1
	end
end

----------------------------开启协程------------------------
function StartDelay()
	coDelay=coroutine.start(Delay)
end

----------------------------停止协程------------------------
function StopDelay()
	coroutine.stop(coDelay)
end

----------------------------每隔0.1秒计算一次------------------------
function fib(n)
    local a, b = 0, 1
    while n > 0 do
        a, b = b, a + b
        n = n - 1
    end

    return a
end

----------------------------协程运行函数------------------------
function CoFunc()
    print('Coroutine started')    
    for i = 0, 10, 1 do
        print(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 对应函数返回值中的:布尔类型

注意: 书写顺序应该是与函数返回值先后顺序保持一致,否则会报错
New举例子黑白88
C# 脚本

// ========================================================
// 描述:测试数组的调用
// 作者:Chinar 
// 创建时间:2018-10-21 14:31:37
// 版 本:1.0
// ========================================================
using LuaInterface;
using UnityEngine;

/// 
/// Chinar解释 —— tolua官方案例8
/// 
public class ChinarTestArray : MonoBehaviour
{
    private string script =
        @"
            function TestArray(array)
            ----------------------------获取数组长度------------------------
                local len = array.Length
            ----------------------------遍历数组输出------------------------
                for i = 0, len - 1 do
                    print('数组: '..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 do
                    print('转表: ' .. 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', true
            end
        ";

    LuaState    lua  = null;
    LuaFunction func = null;
    string      tips = null;


    void Start()
    {
#if UNITY_2017||UNITY_2018||UNITY_5                 //对应版本
        Application.logMessageReceived += ShowTips; //监听输出信息函数
#else
        Application.RegisterLogCallback(ShowTips);
#endif

        new 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
        //  如: 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);
    }


    /// 
    /// 显示输出提示
    /// 
    private void ShowTips(string msg, string stacktrace, LogType type)
    {
        tips += msg;    //信息
        tips += "\r\n"; //换行
    }


    private void OnApplicationQuit()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.RegisterLogCallback(null);
#endif
        func.Dispose();
        lua.Dispose();
    }
}

输出结果:
tolua全教程-Chinar_第1张图片


8

Lua-Dictionary —— Lua中使用字典


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

注意:

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

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

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

. ——iter.Current.name /map.Keys
New举例子黑白88
C# 脚本

using UnityEngine;
using System.Collections.Generic;
using LuaInterface;


/// 
/// Chinar解释 —— tolua官方案例9
/// Lua中使用字典
/// 
public sealed class TestAccount
{
    public int    id;
    public string name;
    public int    sex;


    /// 
    /// 构造函数
    /// 
    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() do
                local v = iter.Current.Value
                print('id: '..v.id .. ' name: '..v.name..' sex: '..v.sex)
            end
        -------------调用字典函数TryGetValue()-----------------
            local flag, account = map:TryGetValue(1, nil)
    
            if flag then
                print('TryGetValue 返回结果正确时: '..account.name)
            end

        --------------------获取字典中的键---------------------
            local keys = map.Keys
            iter = keys:GetEnumerator()
            print('------------打印输出字典中的键---------------')
            while iter:MoveNext() do
                print(iter.Current)
            end
            print('----------------------over----------------------')
    
            local values = map.Values
            iter = values:GetEnumerator()
            print('------------打印输出字典中的值---------------')
            while iter:MoveNext() do
                print(iter.Current.name)
            end
            print('----------------------over----------------------')

        -----------获取字典中2键对应的name值---------------------
            print('kick '..map[2].name)

        -----------移除map中下标2对应的元素---------------------
            map:Remove(2)
            iter = map:GetEnumerator()
    
        -----------重新输出---------------------
            while iter:MoveNext() do
                local v = iter.Current.Value
                print('id: '..v.id .. ' name: '..v.name..' sex: '..v.sex)
            end
        end
                        
        ";


    void Awake()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        new 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_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.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();
    }
}

输出结果:
tolua全教程-Chinar_第2张图片


9

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


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

lua["space"] = Space.World; —— Lua 脚本中的 space 变量,进行枚举类型赋值
New举例子黑白88
C# 脚本

using UnityEngine;
using LuaInterface;

/// 
/// Chinar解释 —— tolua官方案例 10
/// Lua中使用Unity枚举类型
/// 
public class AccessingEnum : MonoBehaviour
{
    string script =
        @"
            space = nil

            function TestEnum(e)
                print('枚举是:'..tostring(e))
                ----------------枚举类型转int----------------
                if space:ToInt() == 0 then
                    print('枚举转Int成功')
                end
    
                -------------枚举类型int0比较--------------
                if not space:Equals(0) then
                    print('枚举类型(与int型)比较成功')
                end
    
                -------------枚举类型直接比较----------------
                if space == e then
                    print('枚举类型比较成功')
                end
 
                -------调用Unity中的Space枚举值转枚举--------
                local s = UnityEngine.Space.IntToEnum(0)
    
                if space == s then
                    print('int转枚举,比较成功')
                end
            end
 
            ----------------改变Unity光照类型---------------
            function ChangeLightType(light, type)
                print('改变光照类型为: '..tostring(type))
                light.type = type
            end
        ";

    LuaState state = null;
    string   tips  = "";
    int      count = 1;


    /// 
    /// 格式化打印输出
    /// 
    void ShowTips(string msg, string stackTrace, LogType type)
    {
        tips += msg;
        tips += "\r\n";
    }


    /// 
    /// 初始化函数
    /// 
    void Start()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
        new 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;
    }


    /// 
    /// 绘制函数
    /// 
    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();
        }
    }


    /// 
    /// 应用退出时执行函数
    /// 
    void OnApplicationQuit()
    {
        state.CheckTop();
        state.Dispose();
        state = null;

#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.RegisterLogCallback(null);
#endif
    }
}

输出:


5

Project —— 项目文件



项目文件为 unitypackage 文件包:

下载导入 Unity 即可使用

New举例子黑白88

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

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


支持

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


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

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

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

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



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


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


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


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


tolua全教程-Chinar_第3张图片

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


END

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

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

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

你可能感兴趣的:(lua,Unity,3D,Unity3D初级入门必学)