【经验分享】BepInEx在DreamQuest中的使用
dreamquest吧
全部回复
仅看楼主
level 9
多啦A户 楼主
目前在DreamQuest中成功做到了2件事情:
1.使用Unity4.6打包AssetBundle,并在DreamQuest中读取使用(仅一个Canvas【左上角那个 上世,这个 DreamQuest本体的文件我没有做过任何改动】):
2.手动进行Patch,可以输出一些日志,并成功检测和替换了 开始游戏(“Play!”)按钮的文字;
在本贴和大家分享一下我是怎么做的。
2024年11月17日 10点11分 1
level 9
多啦A户 楼主
基础的部分可以看这个专栏: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());来开启这个载入线程。
2024年11月17日 10点11分 2
在贴吧代码看起来很差,稍后我可能会重新编辑后发在博客园
2024年11月17日 10点11分
在贴吧查看代码很不方便,后续涉及代码的我都会在博客园发:https://www.cnblogs.com/blackgames2017/p/18550943
2024年11月17日 11点11分
level 9
多啦A户 楼主
重点讲一下 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{}是因为如果不这样做,很可能会出现“没有任何反应和报错的情况”。
2024年11月17日 10点11分 3
level 9
多啦A户 楼主
目前在替换完字体之后,会出现 渲染层级的问题?(我不确定,就是开始游戏,等字符错误的显示在这个窗口层级之上了)
如果想到解决办法,以后更换字体会方便非常多:
只需要使用Unity4.6打包unity3d的资源包,然后读取就可以。
也有可能暂时搁置这个问题。
以上是目前的进度。
2024年11月17日 10点11分 4
1