xLua笔记(1)—Lua启动类
前言
本笔记是为了学习用xlua写unity游戏而制作的笔记,作为自己加深对于知识的理解和记忆有感而发。如果错误,恳请各位大神回复纠正,谢谢
本教程是基于xLua的,至于xLua的教程这里我就不多说了,你可以上去xlua官网的github去下载。
根据xLua教程的建议,整个程序就一个DoString(“require ‘main’”),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。本着这个原则,我设计了一个启动lua主脚本的类。
后面还会介绍怎么去在这个主lua类里去加载其他的lua代码。
lua启动类
1、lua启动代码
这个代码将会作为整个lua代码的启动类,加载其他脚本都通过这里(将来我会继续介绍怎么在这里加载其他lua脚本)
我把代码放在了Asset/LuaScripts文件夹下
--LuaGameEntry.lua
-- 定义为全局模块,整个lua程序的入口类
LuaGameEntry={};
local function EnterGame()
print('enter game')
end
local function Start()
print('start game')
EnterGame()
end
LuaGameEntry.Start=Start;
LuaGameEntry.EnterGame=EnterGame;
return LuaGameEntry;
2、接着就到我们的xLua代码管理类
这个代码主要用来加载我们的启动lua脚本
using FileUtility;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class XLuaManager : MonoSingleton<XLuaManager>
{
//放置LuaScripts代码的文件夹名字
public const string luaScriptsFolder = "LuaScripts";
//lua代码的文件名
const string luaGameEntryScript = "LuaGameEntry";
private LuaEnv luaEnv = null;
// Start is called before the first frame update
void Start(){}
protected override void Init()
{
base.Init();
InitLuaEnv();
}
private void InitLuaEnv()
{
luaEnv = new LuaEnv();
if (luaEnv != null)
{
luaEnv.AddLoader(CustomLoader);
}
}
/// <summary>
/// 回调中可以根据这个参数去加载指定文件
/// 如果需要支持调试,需要把filepath修改为真实路径传出。
/// 该回调返回值是一个byte数组,如果为空表示该loader找不到,否则则为lua文件的内容
/// </summary>
/// <param name="_filePath"></param>
/// <returns></returns>
public static byte[] CustomLoader(ref string _filePath)
{
string _scriptPath = string.Empty;
_filePath = _filePath.Replace(".", "/") + ".lua";
if (Application.platform == RuntimePlatform.WindowsEditor)
{
_scriptPath = Path.Combine(Application.dataPath, luaScriptsFolder);
_scriptPath = Path.Combine(_scriptPath, _filePath);
byte[] _bytes = FileManager.SafeReadAllBytes(_scriptPath);
return _bytes;
}
return null;
}
/// <summary>
/// lua脚本启动入口
/// </summary>
public void OnEntry()
{
if (luaEnv != null)
{
loadScript(luaGameEntryScript);
DoString("LuaGameEntry.Start()");
}
}
// Update is called once per frame
void Update() { }
private void loadScript(string _scriptName)
{
DoString(string.Format("require('{0}')", _scriptName));
}
/// <summary>
/// 加载lua代码块
/// </summary>
/// <param name="_luaScript"></param>
public void DoString(string _luaScript)
{
if (luaEnv != null)
{
try
{
luaEnv.DoString(_luaScript);
}
catch (System.Exception ex)
{
Debug.Log(ex.Message);
}
}
}
}
1.InitEnv: 创建一个LuaEnv用于执行代码块,init方法在单例类里被调用了。(后面会贴上单例类)
2.CustomLoader: 这里会负责更改传进来的文件名,给文件名添加路径,加载正确的路径,从而通过C#加载lua文件里的内容。(当然,这里只是针对Unity编译器环境下的运行lua代码,后面还会有移动端的加载lua代码)
好了,到这里我们的代码基本就完成了。下面我们在unity下去调用,我们创建一个新C#脚本,首先调用StartUp()方法,让程序先创建好LuaEnv,然后再调用lua代码OnEntry。
OnEntry-loadScript-LuaGameEntry.Start()
我们就可以看到unity控制器里有我们在lua代码打印的信息了
PS:好久没写过笔记了,有点生疏,希望以后能加强一下自己的写作能力。
最后附上相关的其他代码
读取lua文件内容代码:
public static byte[] SafeReadAllBytes(string inFile)
{
try
{
if (string.IsNullOrEmpty(inFile))
{
return null;
}
if (!File.Exists(inFile))
{
return null;
}
File.SetAttributes(inFile, FileAttributes.Normal);
return File.ReadAllBytes(inFile);
}
catch (System.Exception ex)
{
return null;
}
}
单例类
using UnityEngine;
using System.Collections;
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
protected static T Instance = null;
public static T GetInstance()
{
if (Instance == null)
{
Instance = FindObjectOfType<T>();
if (FindObjectsOfType<T>().Length > 1)
{
return Instance;
}
if (Instance == null)
{
string instanceName = typeof(T).Name;
GameObject instanceGameObject = GameObject.Find(instanceName);
if (instanceGameObject == null)
instanceGameObject = new GameObject(instanceName);
Instance = instanceGameObject.AddComponent<T>();
DontDestroyOnLoad(instanceGameObject);
}
}
return Instance;
}
private void Awake()
{
if(Instance==null)
{
Instance = this as T;
}
DontDestroyOnLoad(gameObject);
Init();
}
/// <summary>
/// 无实现函数,用于保证MonoSingleton在使用前已创建
/// </summary>
public void StartUp()
{
Debug.Log(string.Format("{0} is start up...", gameObject.name));
}
protected virtual void Init()
{
}
protected virtual void OnDestroy()
{
Instance = null;
}
}