上一节说到了将lua语法的字符串转为类方法去调用,但是字符串在类的内部写法达不到动态读取更新的效果,现在进一步说一下读取外部路径的.lua文件去执行文本里面的类方法。
我们打开ToLua/Examples/02_ScriptsFromFile下的ScriptsFromFile场景,运行一下,可以看到一系列的内容打印。
点击DoFile按钮,打印出[ScriptsFromFile.lua:2]:tolua: 你好! こんにちは! 안녕하세요!;一直点击一直打印,一直打印一直爽。再点击Require按钮,发现没有任何反应和打印;在重新启动编译器后,点击Require按钮,此时可以打印了,但是再次点击,发现没反应了。由此我们得出了两个结果,点击DoFile按钮,可以一直打印字符串,点击Require按钮,只能打印一次。
接下来我们就看看其原理,看看怎么加载外部文件打印,DoFile与Require的调用区别。
using UnityEngine;
using System.Collections;
using LuaInterface;
using System;
using System.IO;
//展示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";
//添加lua文件路径
lua.AddSearchPath(fullPath);
}
//日志打印事件方法
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"); //执行路径中的lua文件中方法
}
else if (GUI.Button(new Rect(50, 150, 120, 45), "Require"))//Require按钮
{
strLog = "";
lua.Require("ScriptsFromFile");//执行路径中的lua文件中方法
}
lua.Collect();//lua内存回收
lua.CheckTop();//检查lua方法内容
}
void OnApplicationQuit()
{
//lua资源回收
lua.Dispose();
lua = null;
#if UNITY_5 || UNITY_2017 || UNITY_2018
Application.logMessageReceived -= Log;//回收消息事件
#else
Application.RegisterLogCallback(null);
#endif
}
}
总结:
lua.AddSearchPath(fullPath); 方法可以将lua文件夹加载进来;
lua.DoFile(“ScriptsFromFile.lua”); 方法可以加载文件夹中的ScriptsFromFile.lua文件并执行里面的内容;
lua.Require(“ScriptsFromFile”); 方法可以自动加载ScriptsFromFile.lua文件并执行里面的内容;
可以看出DoFile每启动一次就加载一次ScriptsFromFile.lua,并执行里面的内容;Require方法会自动加载ScriptsFromFile,但是没有手动指定加载的lua文件,且只要内存中有就只会加载一次。