找回密码
 立即注册
查看: 394|回复: 0

ToLua的案例学习笔记

[复制链接]
发表于 2021-10-15 07:26 | 显示全部楼层 |阅读模式
文章目录

    案例一:DoString的使用案例二:展示searchpath 使用,require 与 dofile 区别案例三:CS调用lua方法案例四:读写lua的全局变量的两种方式


复习lua与C#调用做的笔记,注释大部分都写在了代码里面
案例一:DoString的使用
  1. using UnityEngine;
  2. using LuaInterface;
  3. using System;
  4. public class HelloWorld : MonoBehaviour
  5. {
  6.     void Awake()
  7.     {
  8.         LuaState lua = new LuaState();//lua虚拟机
  9.         lua.Start();//启动
  10.         //lua代码
  11.         string hello =
  12.             @"               
  13.                 print('hello tolua#')                                 
  14.             ";
  15.         
  16.         lua.DoString(hello, "HelloWorld.cs");//注解(1)
  17.         lua.CheckTop();//检测堆栈是否平衡,每次都需要手动调用
  18.         lua.Dispose();注解(2)
  19.         lua = null;
  20.     }
  21. }
复制代码
注解(1)
DoString()函数:执行字符串
注解(2)
lua.CheckTop();
检测堆栈平衡

案例二:展示searchpath 使用,require 与 dofile 区别
  1. public class ScriptsFromFile : MonoBehaviour
  2. {
  3.     LuaState lua = null;//lua虚拟机
  4.     private string strLog = "";   
  5.         void Start ()
  6.     {
  7. #if UNITY_5 || UNITY_2017 || UNITY_2018               
  8.         Application.logMessageReceived += Log;
  9. #else
  10.         Application.RegisterLogCallback(Log);
  11. #endif         
  12.         lua = new LuaState();               
  13.         lua.Start();        //开启虚拟机
  14.         //如果移动了ToLua目录,自己手动修复吧,只是例子就不做配置了
  15.         string fullPath = Application.dataPath + "\\ToLua/Examples/02_ScriptsFromFile";//lua文件路径
  16.         lua.AddSearchPath(fullPath);     //搜索此路径   
  17.     }
  18.     void Log(string msg, string stackTrace, LogType type)
  19.     {
  20.         strLog += msg;
  21.         strLog += "\r\n";
  22.     }
  23.     void OnGUI()
  24.     {
  25.         GUI.Label(new Rect(100, Screen.height / 2 - 100, 600, 400), strLog);
  26.         if (GUI.Button(new Rect(50, 50, 120, 45), "DoFile"))
  27.         {
  28.             strLog = "";
  29.             lua.DoFile("ScriptsFromFile.lua");       //DoFile                 
  30.         }
  31.         else if (GUI.Button(new Rect(50, 150, 120, 45), "Require"))
  32.         {
  33.             strLog = "";            
  34.             lua.Require("ScriptsFromFile");            //require
  35.         }
  36.         lua.Collect();
  37.         lua.CheckTop();
  38.     }
  39.     void OnApplicationQuit()
  40.     {
  41.         lua.Dispose();
  42.         lua = null;
  43. #if UNITY_5 || UNITY_2017 || UNITY_2018       
  44.         Application.logMessageReceived -= Log;
  45. #else
  46.         Application.RegisterLogCallback(null);
  47. #endif
  48.     }
  49. }
复制代码
  1. lua代码:(ScriptsFromFile)
  2. print("This is a script from a utf8 file")
  3. print("tolua: 你好! こんにちは! ?????!")
复制代码
DoFile和Require的区别
(1):经过运行发现每次调用DoFile都会输出,但是Require只会在第一次调用的时候输出。由此说明:DoFile在每次调用的时候都会对lua代码进行重新的加载。查看源码也是如此:


但是Reuire是在执行的时候先检测模块是否存在,如果不存在则加载,存在直接return,源码奉上:


(2)DoFile的参数需要带上.lua后缀,Require不需要后缀,直接名字就可。

案例三:CS调用lua方法
  1. public class CallLuaFunction : MonoBehaviour
  2. {
  3.     private string script =
  4.         @"  function luaFunc(num)                        
  5.                 return num + 1
  6.             end
  7.             test = {}
  8.             test.luaFunc = luaFunc
  9.         ";
  10.     LuaFunction luaFunc = null;
  11.     LuaState lua = null;
  12.     string tips = null;
  13.        
  14.         void Start ()
  15.     {
  16. #if UNITY_5 || UNITY_2017 || UNITY_2018
  17.         Application.logMessageReceived += ShowTips;
  18. #else
  19.         Application.RegisterLogCallback(ShowTips);
  20. #endif
  21.         new LuaResLoader();//注解(1)
  22.         lua = new LuaState();//定义虚拟机
  23.         lua.Start();//开启虚拟机
  24.         DelegateFactory.Init();  //注解(2)      
  25.         lua.DoString(script);
  26.         //Get the function object
  27.         luaFunc = lua.GetFunction("test.luaFunc");//加载test表中的luaFunc
  28.         if (luaFunc != null)
  29.         {
  30.             int num = luaFunc.Invoke<int, int>(123456);//注解(3)
  31.             Debugger.Log("generic call return: {0}", num);
  32.             luaFunc.BeginPCall();               
  33.             luaFunc.Push(123456);
  34.             luaFunc.PCall();        
  35.             num = (int)luaFunc.CheckNumber();
  36.             luaFunc.EndPCall();
  37.             Debugger.Log("expansion call return: {0}", num);//注解(4)
  38.             Func<int, int> Func = luaFunc.ToDelegate<Func<int, int>>();//注解(5)
  39.             num = Func(123456);
  40.             Debugger.Log("Delegate call return: {0}", num);
  41.             
  42.             num = lua.Invoke<int, int>("test.luaFunc", 123456, true);//注解6
  43.             Debugger.Log("luastate call return: {0}", num);
  44.         }
  45.         lua.CheckTop();
  46.         }
  47.     void ShowTips(string msg, string stackTrace, LogType type)
  48.     {
  49.         tips += msg;
  50.         tips += "\r\n";
  51.     }
  52. #if !TEST_GC
  53.     void OnGUI()
  54.     {
  55.         GUI.Label(new Rect(Screen.width / 2 - 200, Screen.height / 2 - 150, 400, 300), tips);
  56.     }
  57. #endif
  58.     void OnDestroy()
  59.     {
  60.         if (luaFunc != null)
  61.         {
  62.             luaFunc.Dispose();
  63.             luaFunc = null;
  64.         }
  65.         lua.Dispose();
  66.         lua = null;
  67. #if UNITY_5 || UNITY_2017 || UNITY_2018
  68.         Application.logMessageReceived -= ShowTips;
  69. #else
  70.         Application.RegisterLogCallback(null);
  71. #endif
  72.     }
  73. }
复制代码
注解(1):new LuaResLoader();
自定义加载lua文件,优先读取persistentDataPath/系统/Lua 目录下的文件(默认下载目录)未找到文件怎读取 Resources/Lua 目录下文件(仍没有使用LuaFileUtil读取),如果不想自定义则直接new LuaResLoader。自定义可参考:自定义加载lua文件,后面也会提到。
注解(2):DelegateFactory.Init();
目前没有很好的理解,大佬们有什么高招吗?
注解(3):int num = luaFunc.Invoke<int, int>(123456)
通用的方式(有GC、慎用)


注解(4):注释3的另一种形式(个人理解),只是对返回值进行了特殊处理。无GC,注意最后的dispose,否则造成内存泄漏。
注释(5):自行理解吧。



注解(6):调用LuaState里面的函数




案例四:读写lua的全局变量的两种方式
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using LuaInterface;
  4. public class AccessingLuaVariables : MonoBehaviour
  5. {
  6.     private string script =
  7.         @"
  8.             print('Objs2Spawn is: '..Objs2Spawn)
  9.             var2read = 42
  10.             varTable = {1,2,3,4,5}
  11.             varTable.default = 1
  12.             varTable.map = {}
  13.             varTable.map.name = 'map'
  14.             
  15.             meta = {name = 'meta'}
  16.             setmetatable(varTable, meta)
  17.             
  18.             function TestFunc(strs)
  19.                 print('get func by variable')
  20.             end
  21.         ";
  22.         void Start ()
  23.     {
  24. #if UNITY_5 || UNITY_2017 || UNITY_2018
  25.         Application.logMessageReceived += ShowTips;
  26. #else
  27.         Application.RegisterLogCallback(ShowTips);
  28. #endif
  29.         new LuaResLoader();//默认加载lua
  30.         LuaState lua = new LuaState();//虚拟机
  31.         lua.Start();//启动
  32.         lua["Objs2Spawn"] = 5;//相当于在lua文件中加入【Objs2Spawn = 5】即新增一个全局变量
  33.         lua.DoString(script);//略
  34.         //通过LuaState访问
  35.         Debugger.Log("Read var from lua: {0}", lua["var2read"]); //读取第10行的变量,看第十行
  36.         Debugger.Log("Read table var from lua: {0}", lua["varTable.default"]);  //LuaState 拆串式table,12行
  37.         LuaFunction func = lua["TestFunc"] as LuaFunction;//TestFunc方法
  38.         func.Call();//案例3的第一种方式,注意有GC,少量call可使用
  39.         func.Dispose();
  40.         //cache成LuaTable进行访问,很好理解
  41.         LuaTable table = lua.GetTable("varTable");//包装成LuaTable
  42.         Debugger.Log("Read varTable from lua, default: {0} name: {1}", table["default"], table["map.name"]);
  43.         table["map.name"] = "new";  //table 字符串只能是key
  44.         Debugger.Log("Modify varTable name: {0}", table["map.name"]);
  45.         table.AddTable("newmap");
  46.         LuaTable table1 = (LuaTable)table["newmap"];
  47.         table1["name"] = "table1";
  48.         Debugger.Log("varTable.newmap name: {0}", table1["name"]);
  49.         table1.Dispose();
  50.         table1 = table.GetMetaTable();
  51.         if (table1 != null)
  52.         {
  53.             Debugger.Log("varTable metatable name: {0}", table1["name"]);
  54.         }
  55.         object[] list = table.ToArray();
  56.         for (int i = 0; i < list.Length; i++)
  57.         {
  58.             Debugger.Log("varTable[{0}], is {1}", i, list[i]);
  59.         }
  60.         table.Dispose();                        
  61.         lua.CheckTop();
  62.         lua.Dispose();
  63.         }
  64.     private void OnApplicationQuit()
  65.     {
  66. #if UNITY_5 || UNITY_2017 || UNITY_2018
  67.         Application.logMessageReceived -= ShowTips;
  68. #else
  69.         Application.RegisterLogCallback(null);
  70. #endif
  71.     }
  72.     string tips = null;
  73.     void ShowTips(string msg, string stackTrace, LogType type)
  74.     {
  75.         tips += msg;
  76.         tips += "\r\n";
  77.     }
  78.     void OnGUI()
  79.     {
  80.         GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);
  81.     }
  82. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 20:34 , Processed in 0.063870 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表