赞
踩
插件在GITHUB上进行下载。
下载后的文件目录结构
Assets
文件夹将Plugins
和XLua
这两个文件夹Copy到Unity人更新项目中的Assets文件夹中。在Unity的IDE出现XLua选项
设置完成后会在出现
Generate Code
。Hotfix Inject In Editor
,进行Lua注入。using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System.IO; namespace XLuaProject { [Hotfix] public class HotfixTest : MonoBehaviour { public LuaEnv luaEnv; // Start is called before the first frame update void Start() { luaEnv = new LuaEnv(); luaEnv.DoString("CS.UnityEngine.Debug.Log('hello world')"); luaEnv.Dispose(); } } }
6. 运行Generate Code
。
7. 执行Hotfix Inject In Editor
,进行Lua注入。
8. 运行结果,lua虚拟环境搭建完毕。
插件在GITHUB上进行下载。
1. 将插件下载下来后一定注意放入Unity的目录结构。在Unity的项目目录中装件Editor文件夹。
2.将AssetBundles-Browser解压后的Editor文件夹Copy到Unity的项目中。目录结构如下图所示。
3.在Unity的IDE导航条中的Window就会出现AssetBundles-Browser。
未更新前运行后值2s后创建一个sun物体并自转,更新后先创建earth物体并自转2s后创建sun并自转,sun出现后earth围绕sun进行公转。
Rotation
,公转脚本Revolution
。并将自转脚本挂载到上述两个预制体上。using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; namespace XLuaProject { public class Rotation : MonoBehaviour { public static int speed = -50; // Start is called before the first frame update [LuaCallCSharp] void Start() { } // Update is called once per frame void Update() { transform.Rotate(0, speed * Time.deltaTime, 0, Space.Self); } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace XLuaProject { public class Revolution : MonoBehaviour { public GameObject Axis;//轴,用于选择围绕中心 public float RotateSpeed = 10;//旋转速度// Use this for initialization void Start() { } void Update() { this.transform.RotateAround(Axis.transform.position, Vector3.up, RotateSpeed); } } }
sun
,同样的操作将earth预制体打包命名为earth
后缀命名为ab
Build
,设置Build Target 及Output Path(输出目录)。using System.Collections; using System.Collections.Generic; using UnityEngine; namespace XLuaProject { public class LoadAB : MonoBehaviour { public static Dictionary<string, GameObject> prefabDict = new Dictionary<string, GameObject>(); // Start is called before the first frame update void Start() { } /// <summary> /// 加载AB资源 /// </summary> /// <param name="resName">字典对象名</param> /// <param name="filePath">资源名</param> public void LoadResource(string resName, string filePath) { string path = Application.dataPath + "/AssetBundles/StandaloneWindows/" + filePath; AssetBundle ab = AssetBundle.LoadFromFile(path); GameObject gameObject = ab.LoadAsset<GameObject>(resName); prefabDict.Add(resName, gameObject); } public GameObject GetGameObject(string objName) { return prefabDict[objName]; } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; namespace XLuaProject { public class CreateObj : MonoBehaviour { LoadAB loadAB; private void Awake() { loadAB = GetComponent<LoadAB>(); } // Start is called before the first frame update void Start() { Invoke("CreateSun", 2); } void CreateSun() { loadAB.LoadResource("sun", "sun.ab"); GameObject gameObject = loadAB.GetGameObject("sun"); var tempObj = Instantiate(gameObject); tempObj.name = "sun"; tempObj.transform.position = new Vector3(0f, 0, 0); } } }
由于引入xLua的关系,每次我们修改加上热更新标识的脚本代码都需要执行一遍 ,运行
Generate Code
在执行Hotfix Inject In Editor
,进行Lua注入。否则运行报错。
官方建议方式二。
和其它配置一样,有两种方式
方式一:直接在类里头打Hotfix标签(不建议,示例只是为了方便演示采取这种方式);
!!注意,方式一在高版本unity不支持
方式二:在一个static类的static字段或者属性里头配置一个列表。属性可以用于实现的比较复杂的配置,比如根据Namespace做白名单。
!!注意,高版本Unity需要把配置文件放Editor目录下
静态类
静态类
静态类 HotficCfg
*XLuaProject
。using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using UnityEngine; using XLua; public static class HotficCfg { [Hotfix] public static List<Type> by_property { get { //从程序集中获取全部类信息 var allTypes = Assembly.Load("Assembly-CSharp").GetTypes(); var nameSpace = new List<string>(); //遍历所有类筛选符合规则的命名空间 foreach (var t in allTypes) { if (t.Namespace != null && (t.Namespace.StartsWith("XLuaProject", StringComparison.CurrentCulture))) { if (!nameSpace.Contains(t.Namespace)) { nameSpace.Add(t.Namespace); } } } var retList = new List<Type>(); var sb = new StringBuilder(); //遍历所有类筛选所有包含该命名空间的Type对象 foreach (var t in allTypes) { if (nameSpace.Contains(t.Namespace)) { retList.Add(t); sb.AppendLine(t.FullName); } } //输出所有Type信息到项目根目录HotTypes.txt文本中 File.WriteAllText(Path.Combine(Application.dataPath, "../HotTypes.txt"), sb.ToString()); return retList; } } }
每次我们在执行Generate Code
都会在项目根目录也就是和Assets平级目录下生成一个可以热更新的类的白名单。
在Resources创建lua文件夹保存lua脚本,unity中加载lua文件要以.lua.txt
结尾。
创建LuaEnv 脚本管理LuaManager
,自定义加载器MyLoader,lua文件命名以.lua.txt
结尾。
using System.IO; using UnityEngine; using XLua; public class LuaManager : MonoBehaviour { public static LuaManager _instance; public static LuaManager Instance { get { return _instance; } } [CSharpCallLua] public delegate void LuaDelegate(string paras); /// <summary> /// 定义一个Delegate,Lua结果将传参回调给该Delegate /// </summary> public static LuaDelegate LuaFunc; /// <summary> /// 定义一个Lua虚拟机,建议全局唯一 /// </summary> public static LuaEnv luaEnv; void Awake() { _instance = this; LuaEnvInit(); } public void LuaEnvInit() { luaEnv = new LuaEnv(); luaEnv.AddLoader(MyLoader); ///lua脚本的主入口 luaEnv.DoString(@"require 'updateInfo'"); //获取Lua中全局function,然后映射到delegate luaEnv.Global.Get("LuaFunc", out LuaFunc); } private byte[] MyLoader(ref string filepath) { string abspath = Application.dataPath + "/Resources/lua/" + filepath + ".lua.txt"; return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(abspath)); } }
在Unity编写xLua脚本的注意事项。
运行Generate Code
在执行Hotfix Inject In Editor
就OK了。
先来个Hello Word!在lua文件夹中创建名为hello.lua.txt
xlua.hotfix(CS.XLuaProject.CreateObj,'Start',function(self)
CS.UnityEngine.Debug.Log("Hello word!")
end)
lua脚本更新CreateObj脚本中的Start
方法输出"Hello word!"
运行之后不再创建sun的脚本而是输出Hello Word!
xlua.hotfix(CS.XLuaProject.Rotation,'Start',function(self)
ChangeCode()
end)
function ChangeCode()
CS.XLuaProject.Rotation.speed=100
CS.UnityEngine.Debug.Log(CS.XLuaProject.Rotation.speed)
end
local util=require 'util'
local util=require 'util'
util.hotfix_ex(CS.XLuaProject.CreateObj,'Start',function(self)
self.Start(self)
-- lua 函数更新创建地球预制体
CreateEarth(self)
end)
function CreateEarth(self)
self.loadAB:LoadResource("earth", "earth.ab")
local gameObject=self.loadAB:GetGameObject("earth")
local tempObj=CS.UnityEngine.GameObject.Instantiate(gameObject)
tempObj.name="earth"
tempObj.transform.position = CS.UnityEngine.Vector3(-1.7, 0, 0)
end
xlua.private_accessible(CS.XLuaProject.CreateObj)
local util=require 'util' util.hotfix_ex(CS.XLuaProject.CreateObj,'Start',function(self) self.Start(self) CreateEarth(self) end) util.hotfix_ex(CS.XLuaProject.CreateObj,'CreateSun',function(self) self.CreateSun(self) local earth=CS.UnityEngine.GameObject.Find("earth") local sun=CS.UnityEngine.GameObject.Find("sun") local dd=earth:AddComponent(typeof(CS.XLuaProject.Revolution)) dd.Axis =sun dd.RotateSpeed = 3 end) function CreateEarth(self) self.loadAB:LoadResource("earth", "earth.ab") local gameObject=self.loadAB:GetGameObject("earth") local tempObj=CS.UnityEngine.GameObject.Instantiate(gameObject) tempObj.name="earth" tempObj.transform.position = CS.UnityEngine.Vector3(-1.7, 0, 0) end xlua.hotfix(CS.XLuaProject.Rotation,'Start',function(self) ChangeCode() end) function ChangeCode() CS.XLuaProject.Rotation.speed=100 CS.UnityEngine.Debug.Log(CS.XLuaProject.Rotation.speed) end
1.xLua所有的配置都支持三种方式:打标签;静态列表;动态列表。此项目使用的是动态列表方式,
因此方法无需在打[LuaCallCSharp]的标签。
2.关于AssetBundle打包本篇侧重点在热更新,因此忽略了AssetBundle打包的原则。
3.由于项目开发时间较长开发过程中解决一些坑未及时记录,如果您按照本篇文章做下来出现问题欢迎留言讨论。
4.最后以此文终结2020,终结疫情。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。