使用XLua实现简单热更新

使用XLua实现简单热更新,第1张

使用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();
    }
    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(@"http://www.kaotop.com/file/tupian/20220630/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);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/563646.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存