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

Unity3D使用XLua实现简单热更新

[复制链接]
发表于 2023-2-28 17:27 | 显示全部楼层 |阅读模式
使用XLua热更新

简单的XLua热更Demo 1.首先第一步,是下载xlua插件,可以直接在GitHub下载:xlua插件地址 2.按照热更新设置:在Project Setting 的Player的Scripting Define Symbols添加HOTFIX_ENABLE,这样在编辑器上会看到XLua,然后有Generate Code和HotFix Inject In Editor,在C#脚本有改动的时候就要Generate Code一下(会提示finish) 3.要热更的地方需要标识[Hotfix]特性,在类声明的位置标识的时候在打包的时候会热更不成功,解决方案:
public static class HotFixConfig
{
    [Hotfix]
    public static List<Type> by_field = new List<Type>()
    {
        typeof(Load),
        typeof(Cube)
    };
}
4.要执行lua,开启一个lua虚拟机
private void Awake()
    {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(MyLoader);
        luaEnv.DoString("require 'Test'");
    }
    private byte[] MyLoader(ref string filePath)
    {
        string absPath = @"E:\Unity3d\HotFix\XluaTest\" + filePath + ".lua.txt";
        return  System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
    }
5.lua那边要调用的C#函数要标识为[LuaCallCSharp] 这里只实现了简单的下载单个资源,具体需要再去细写
[LuaCallCSharp]
    public void LoadResource(string resName,string filePath)
    {
        StartCoroutine(Load(resName, filePath));
    }

    IEnumerator Load(string resName,string filePath)
    {
        AssetBundle assetBundle=null;
        if (!bundleDic.ContainsKey(filePath))
        {
            UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(@"path" + filePath);
            yield return request.SendWebRequest();
            Debug.Log(request);
            bundleDic.Add(filePath, DownloadHandlerAssetBundle.GetContent(request));
        }
        yield return bundleDic[filePath];
        assetBundle = bundleDic[filePath];
        //.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        Debug.Log(assetBundle);
        //WWW wWW = new WWW(@"path" + filePath);
        //yield return wWW;
        //AssetBundle assetBundle = wWW.assetBundle;
        //Debug.Log(assetBundle);
        GameObject obj = assetBundle.LoadAsset<GameObject>(resName);

        if (!objDic.ContainsKey(resName))
        {
            objDic.Add(resName, obj);
        }
    }

    [LuaCallCSharp]
    public GameObject GetPrefab(string resName)
    {
        return objDic[resName];
    }
这里打包AssetBundle用的是官方的插件,也是可以在GitHub下载的:AssetBundle插件地址 附:导入方式:Window-》Package Manager-》右上角的加号-》选择第一个(Add package from disk)->找到下载的这个文件的package.json文件
6.开启了lua虚拟机,当然也要销毁
private void OnDestroy()
    {
        luaEnv.Dispose();
    }
7.
private void OnDisable()
    {
       luaEnv.DoString("require 'LuaDispose'");
    }
    //LuaDispose.lua.txt内容
    xlua.hotfix(CS.Cube,"Update",nil)
    xlua.hotfix(CS.Load,"Start",nil)
    xlua.hotfix(CS.Load,"Update",nil)
8.其他脚本
public class Load : MonoBehaviour
{
    public HotFixScript hotFix;

    private void Awake()
    {
        if (!hotFix)
        {
            hotFix = GetComponent<HotFixScript>();
        }
    }
    [LuaCallCSharp]
    public void Start()
    {

    }

    [LuaCallCSharp]
    public void Update()
    {

    }
}

public class Cube : MonoBehaviour
{
    public Rigidbody rigidbody1;
    // Start is called before the first frame update
    void Start()
    {
        rigidbody1 = gameObject.GetComponent<Rigidbody>();
    }

    [LuaCallCSharp]
    // Update is called once per frame
    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            rigidbody1.AddForce(Vector3.up*300);
        }
    }
}
9.lua热更内容
local UnityEngine=CS.UnityEngine

xlua.hotfix(CS.Cube,'Update',function (self)
    if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.G))  then
        self.rigidbody1:AddForce(UnityEngine.Vector3.up*300)
    end
end)

xlua.hotfix(CS.Load,'Start',function (self)
    self.hotFix:LoadResource('Sphere','gameobject.unity3d')
end)

xlua.hotfix(CS.Load,'Update',function(self)
    if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.T))  then
       local obj= UnityEngine.GameObject.Instantiate(self.hotFix:GetPrefab('Sphere'))
       obj.transform.position=UnityEngine.Vector3.right
    end
end)10.在Loading场景加载那两个lua文件
public class LoadScene : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(LoadLuaTxt());
    }

    IEnumerator LoadLuaTxt()
    {
        UnityWebRequest request = UnityWebRequest.Get(@"path/Test.lua.txt");
        yield return request.SendWebRequest();
        string str = request.downloadHandler.text;
        File.WriteAllText(@"E:\Unity3d\HotFix\XluaTest\"+"Test.lua.txt",str);
        UnityWebRequest request1 = UnityWebRequest.Get(@"path/LuaDispose.lua.txt");
        yield return request1.SendWebRequest();
        string str1 = request1.downloadHandler.text;
        File.WriteAllText(@"E:\Unity3d\HotFix\XluaTest\" + "LuaDispose.lua.txt", str1);
        SceneManager.LoadSceneAsync("SampleScene");
    }

}
附:path都是指的服务器地址,之前有需求用了腾讯云的对象存储,所以博主这里都是放在腾讯云里的
11.其他:从服务器下载图片资源方法
IEnumerator LoadImage()
    {
        UnityWebRequest request = UnityWebRequestTexture.GetTexture(@"path/AssetBundles/PC/1.jpg" );
        yield return request.SendWebRequest();
        if (request.error != null)
        {
            Debug.Log(request.error);
        }
        Texture2D texture2D = DownloadHandlerTexture.GetContent(request);
        image.sprite = Sprite.Create(texture2D, new Rect(0,0,texture2D.width,texture2D.height),Vector2.zero);
    }
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-12-22 10:04 , Processed in 0.088667 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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