首先为什么我们需要一个Lua解析器管理器?
因为每次创建一个新的C#调用lua类时,我们都需要创建一个lua解析器,步骤重复,且难以保证解析器唯一性。因此创建一个lua解析器管理类,来保证LuaEnv唯一性,并提供它。
首先创建一个单例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//1.C#中 泛型的知识
//2.设计模式中 单例模式的知识
public class BaseManager<T> where T:new()
{
private static T instance;
public static T GetInstance()
{
if (instance == null)
instance = new T();
return instance;
}
}
这个单例类的GetInstance()方法可以保证只有一个instance(对象实例)。
然后创建Lua解析器管理器继承它。
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
/// <summary>
/// Lua管理器
/// 提供lua解析器
/// 保证解析器唯一性
/// </summary>
public class LuaManager :BaseManager<LuaManager>
{
//执行Lua语言的函数
//释放垃圾
//销毁
//重定向
private LuaEnv luaEnv;
}
我们除了需要lua管理器去生成LuaEnv,还需要它干嘛呢?
当然还要它去执行其他的东西拉。我们需要重写4个接口:执行lua语言、释放垃圾、销毁解析器、执行lua脚本等
/// <summary>
/// 传入lua文件名
/// </summary>
/// <param name="fileName"></param>
public void DoluaFile(string fileName)
{
string str = string.Format("require('{0}')", fileName);
Dostring(str);
}
//重新写四个方法,相当于给外面的接口让他们调用
/// <summary>
/// 执行lua语言
/// </summary>
/// <param name="str"></param>
public void Dostring(string str)
{
if(luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.DoString(str);
}
/// <summary>
/// 释放垃圾
/// </summary>
public void Tick()
{
if (luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.Tick();
}
/// <summary>
/// 销毁解析器
/// </summary>
public void Dispose()
{
if (luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.Dispose();
luaEnv = null;
}
在此之前我们已经完成了文件路径重定向:
private byte[] MyCustomLoader(ref string filePath)
{
//拼接一个lua文件所在路径
string path = Application.dataPath + "/Lua/" + filePath + ".lua";
Debug.Log(path);
//有路径 就去加载文件
//File 知识点 C#提供的文件读写的类
//判断文件是否存在
if (File.Exists(path))
{
return File.ReadAllBytes(path);
}
else
{
Debug.Log("重定向失败,文件名为" + filePath);
}
//通过函数中的逻辑去加载lua文件
return null;
}
但是最终的文件是在AB包中的,我们要创建一个加载AB包文件的函数:
//lua脚本会放在AB包中
//最早我们会通过加载AB包再加载其中的Lua脚本资源来执行它
//AB包中如果要加载文本 后缀还是有一定的限制 .lua不能被识别
//打包时 要把lua文件后缀改为txt
private byte[] MyCustomABloader(ref string filePath)
{
//Debug.Log("进入AB包加载 重定向函数");
从AB包中加载lua文件
加载AB包
//string path = Application.streamingAssetsPath + "/lua";
//AssetBundle ab = AssetBundle.LoadFromFile(path);
加载Lua文件 返回,u3d里的文本配置都是TextAsset,TextAsset只能加载指定路径文本文件
我们给Lua文件加了.txt所以.lua也是命名的一部分,别忘记加
//TextAsset tx = ab.LoadAsset<TextAsset>(filePath + ".lua");
加载除了Lua文件 byte数组
//return tx.bytes;
加载lua文件 返回
//return null;
//通过我们的AB包管理器 加载的lua脚本资源
TextAsset lua = ABManager.GetInstance().LoadRes<TextAsset>("lua", filePath + ".lua");
if (lua != null)
return lua.bytes;
else
Debug.Log("MyCustomABloader重新定向失败,文件名为:"+filePath);
return null;
}
ABmanager就是重写了上述注释的内容。
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
/// <summary>
/// Lua管理器
/// 提供lua解析器
/// 保证解析器唯一性
/// </summary>
public class LuaManager :BaseManager<LuaManager>
{
//执行Lua语言的函数
//释放垃圾
//销毁
//重定向
private LuaEnv luaEnv;
/// <summary>
/// 得到Lua中的_G
/// </summary>
public LuaTable Global
{
get
{
return luaEnv.Global;
}
}
public void Init()
{
//已经初始化了 别初始化 直接返回
if (luaEnv != null)
return;
//初始化
luaEnv = new LuaEnv();
//加载lua脚本 重定向
luaEnv.AddLoader(MyCustomLoader);
luaEnv.AddLoader(MyCustomABloader);
}
private byte[] MyCustomLoader(ref string filePath)
{
//拼接一个lua文件所在路径
string path = Application.dataPath + "/Lua/" + filePath + ".lua";
Debug.Log(path);
//有路径 就去加载文件
//File 知识点 C#提供的文件读写的类
//判断文件是否存在
if (File.Exists(path))
{
return File.ReadAllBytes(path);
}
else
{
Debug.Log("重定向失败,文件名为" + filePath);
}
//通过函数中的逻辑去加载lua文件
return null;
}
//lua脚本会放在AB包中
//最早我们会通过加载AB包再加载其中的Lua脚本资源来执行它
//AB包中如果要加载文本 后缀还是有一定的限制 .lua不能被识别
//打包时 要把lua文件后缀改为txt
private byte[] MyCustomABloader(ref string filePath)
{
//Debug.Log("进入AB包加载 重定向函数");
从AB包中加载lua文件
加载AB包
//string path = Application.streamingAssetsPath + "/lua";
//AssetBundle ab = AssetBundle.LoadFromFile(path);
加载Lua文件 返回,u3d里的文本配置都是TextAsset,TextAsset只能加载指定路径文本文件
我们给Lua文件加了.txt所以.lua也是命名的一部分,别忘记加
//TextAsset tx = ab.LoadAsset<TextAsset>(filePath + ".lua");
加载除了Lua文件 byte数组
//return tx.bytes;
加载lua文件 返回
//return null;
//通过我们的AB包管理器 加载的lua脚本资源
TextAsset lua = ABManager.GetInstance().LoadRes<TextAsset>("lua", filePath + ".lua");
if (lua != null)
return lua.bytes;
else
Debug.Log("MyCustomABloader重新定向失败,文件名为:"+filePath);
return null;
}
/// <summary>
/// 传入lua文件名
/// </summary>
/// <param name="fileName"></param>
public void DoluaFile(string fileName)
{
string str = string.Format("require('{0}')", fileName);
Dostring(str);
}
//重新写四个方法,相当于给外面的接口让他们调用
/// <summary>
/// 执行lua语言
/// </summary>
/// <param name="str"></param>
public void Dostring(string str)
{
if(luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.DoString(str);
}
/// <summary>
/// 释放垃圾
/// </summary>
public void Tick()
{
if (luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.Tick();
}
/// <summary>
/// 销毁解析器
/// </summary>
public void Dispose()
{
if (luaEnv == null)
{
Debug.Log("解析器为空");
return;
}
luaEnv.Dispose();
luaEnv = null;
}
}