dreamquest吧 关注:699贴子:3,118
  • 5回复贴,共1

【经验分享】BepInEx在DreamQuest中的使用

只看楼主收藏回复

目前在DreamQuest中成功做到了2件事情:
1.使用Unity4.6打包AssetBundle,并在DreamQuest中读取使用(仅一个Canvas【左上角那个 上世,这个 DreamQuest本体的文件我没有做过任何改动】):

2.手动进行Patch,可以输出一些日志,并成功检测和替换了 开始游戏(“Play!”)按钮的文字;


在本贴和大家分享一下我是怎么做的。


IP属地:福建1楼2024-11-17 18:17回复
    基础的部分可以看这个专栏:https://www.bilibili.com/opus/997803503691759640
    我主要讲讲在1和2中遇到的问题,及如何避免。
    首先是1,直接用 宵夜97视频中的方法是不适合Unity4.6这个版本的。
    最终查询了一下Unity4.6的手册,以及 参考了这个链接:https://discussions.unity.com/t/solved-unity-4-system-save-load-assetbundle/578879 ,选定如下的载入方法
    public string url;
    public int version;
    public IEnumerator LoadBundle()
    {
    using (WWW www = http://WWW.LoadFromCacheOrDownload(url, version))
    {
    Logger.LogInfo("尝试从 www 载入 " +url +"} {" + version + "}");
    yield return www;
    if (System.IO.File.Exists(url)) Logger.LogInfo("文件存在AssetBundle:myAssetBundle.unity3d !");
    AssetBundle assetBundle = http://www.assetBundle;
    Logger.LogInfo("成功载入AssetBundle:myAssetBundle.unity3d !");
    if (assetBundle == null)//此处为空
    {
    Logger.LogInfo("AssetBundle 为空!");
    }
    else
    {
    if(assetBundle.mainAsset != null)
    {
    //成功载入后的操作
    GameObject gameObject = assetBundle.mainAsset as GameObject;
    Instantiate(gameObject);
    assetBundle.Unload(false);
    GameObject gobj = GameObject.Find("TestUI");
    if (gobj != null) {
    loadFont = gobj.GetComponentInChildren<Text>().font;
    isLoadedFont = true;
    //重新设置字体
    for (int i = 0; i < recordMesh.Count; i++)
    {
    SetFontSizeOverride(recordMesh[i], recordFontSize[i]);
    }
    recordMesh.Clear();
    recordFontSize.Clear();
    }
    }
    else
    {
    Logger.LogInfo("AssetBundle:myAssetBundle.unity3d assetBundle.mainAsset 为空!");
    }
    }
    }
    }
    在你需要的地方,使用StartCoroutine(LoadBundle());来开启这个载入线程。


    IP属地:福建2楼2024-11-17 18:22
    收起回复
      重点讲一下 Patch。在Unity4.6的版本中,使用[HarmonyPostfix][ HarmonyPatch]这样的标签,好像没法正确生效,我目前实验成功的方法是手动进行patch,如下:
      private void PatchTargetPostfix(MethodInfo tm, MethodInfo pm)
      {
      if (tm == null)
      {
      Logger.LogError("Target method not found in SDB." + tm.ToString());
      return;
      }
      if (pm == null)
      {
      Logger.LogError("Postfix method not found in HelloMod." + pm.ToString());
      return;
      }
      var info = harmony.Patch(tm, postfix: new HarmonyMethod(pm));
      Logger.LogInfo("Patch result: " + info);
      }
      private void PatchTargetPrefix(MethodInfo tm, MethodInfo pm)
      {
      Logger.LogInfo(tm.ToString() + "|||" + pm.ToString());
      if (tm == null)
      {
      Logger.LogError("Target method not found in SDB." + tm.ToString());
      return;
      }
      if (pm == null)
      {
      Logger.LogError("Postfix method not found in HelloMod." + pm.ToString());
      return;
      }
      var info = harmony.Patch(tm, prefix: new HarmonyMethod(pm));
      Logger.LogInfo("Patch result: " + info);
      }
      调用代码如下:
      try
      {
      PatchTargetPrefix(
      typeof(FontManager).GetMethod("SetFontSize", new Type[] { typeof(TextMesh), typeof(int) }),
      typeof(HelloMod).GetMethod("SetFontSizeOverride", new Type[] { typeof(TextMesh), typeof(int) }));
      }
      catch (Exception ex)
      {
      Logger.LogError("Error while applying patch: " + ex.ToString());
      }
      建议使用try{}catch{}是因为如果不这样做,很可能会出现“没有任何反应和报错的情况”。


      IP属地:福建3楼2024-11-17 18:30
      回复
        目前在替换完字体之后,会出现 渲染层级的问题?(我不确定,就是开始游戏,等字符错误的显示在这个窗口层级之上了)

        如果想到解决办法,以后更换字体会方便非常多:
        只需要使用Unity4.6打包unity3d的资源包,然后读取就可以。
        也有可能暂时搁置这个问题。
        以上是目前的进度。


        IP属地:福建4楼2024-11-17 18:32
        回复