使用BepInEx与Harmony实现游戏逻辑重写:以攻击冷却修改为例

首先找一个Unity游戏,本文使用Hollow knight(空洞骑士)作为案例,
第一步老样子先分析Assembly-CSharp.dll
 

Dnspy

搜索attack查看关键词可以找到

右键分析一下在哪被赋值和使用

首先一个if判断了是否装备了叫什么快速劈砍的护符,装备了就用ATTACK_COOLDOWN_TIME_CH的值,没装就是ATTACK_COOLDOWN_TIME;所以我们这里改ATTACK_COOLDOWN_TIME或者直接attack_cooldown都是可以的;下面那些就是攻击的方向逻辑了

BepinEx

在github下载BepinEx [Releases · BepInEx/BepInEx] 安装到游戏以加载我们写的dll

下载后打开将winhttp.dll,doorstop_config.ini,BepInEx两个文件加一个文件夹解压缩到游戏根目录

打开游戏BepinEx目录下出现LogOutput.log即加载成功

Visual Studio

打开Visual Studio创建一个类库项目,
先添加引用,将游戏Hollow Knight\hollow_knight_Data\Managed目录下的Assmbly-Csharp和一些UnityEngine库都加上,然后再加上Hollow Knight\BepInEx\core的dll

using BepInEx;
using GlobalEnums;
using HarmonyLib;
using UnityEngine;

[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
public class AttackMod : BaseUnityPlugin
{
    private const string pluginGuid = "com.attack.test";
    private const string pluginName = "AttackMod";
    private const string pluginVersion = "1.0.0";

    private readonly Harmony _harmony = new Harmony(pluginGuid);

    private void Awake()
    {
        _harmony.PatchAll();
        Logger.LogInfo("攻击Mod加载成功!");
    }

}

[HarmonyPatch(typeof(HeroController))]
class HeroControllerPatches
{
    [HarmonyPatch("DoAttack")]
    [HarmonyPostfix]
    static void DoAttackPostfix(HeroController __instance)
    {
        var traverse = Traverse.Create(__instance);
        traverse.Field("ATTACK_COOLDOWN_TIME").SetValue(0.1f);
        traverse.Field("ATTACK_COOLDOWN_TIME_CH").SetValue(0.01f);
    }

    [HarmonyPatch("CanAttack")]
    [HarmonyPostfix]
    static void CanAttackPostfix(HeroController __instance, ref bool __result)
    {
        var traverse = Traverse.Create(__instance);
        float attackCooldown = traverse.Field("attack_cooldown").GetValue<float>();

        __result = attackCooldown <= 0f
            && !__instance.cState.dead
            && !__instance.cState.hazardDeath
            && !__instance.cState.hazardRespawning
            && !__instance.controlReqlinquished
            && __instance.hero_state != ActorStates.no_input
            && __instance.hero_state != ActorStates.hard_landing
            && __instance.hero_state != ActorStates.dash_landing;
    }
}

语法这里就不多讲了,可以看看harmonylib的文档,如果目标是private就要使用traverse来访问资源,比如private void DoAttack,所以用traverse,我这里修改了ATTACK_COOLDOWN_TIME发现没生效

然后发现是这个方法限制了,所以我这里还重写了CanAttack方法,将attacking和dashing的判断删除了

Ctrl+B编译,将dll拖进BepinEx的plugin目录查看log显示加载成功,修改生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值