UnityMod开发教程 07 实践(一) 大钱袋Mod

一. 前言

  玩了一天的撒币:双冠,玩法和前代基本上是一样的,不过,钱袋还是一如既往的小,装不了多少就开始撒币了,所以,我们的第一个mod,就以修改钱袋为目标来进行。

二. 观察和分析

  对于一个新接触的游戏,我们制作mod大部分的时间都会用来观察游戏逻辑,分析游戏的结构,找到我们需要修改的地方,才能进行mod制作。首先我们打开dnspy,将AC.dll拖入dnspy,观察双冠这几百个类。
  我们这次的目标是钱袋,关于钱的修改在mod和修改器里非常常见,有几个高频词语值得关注:gold money coin gem,这些都是游戏中常见的货币,我们先以此对这些词语进行搜索,果不其然,coin和gem都搜索到了大量的结果,联系到我们游戏中的两种货币,对于这次的游戏我们运气比较好,一次就找到了他们。
  对于大钱袋这个mod,其实我们并不一定真的需要让钱袋变大,在游戏中我们可以发现,硬币都是一枚一枚的扔进钱袋的,他们之间存在物理的碰撞,溢出的硬币会掉出来。所以,我们只要让硬币变小,就可以实现大钱袋的效果,这样不会变动钱袋图片的大小,不会对游戏的UI造成影响。
  所以接下来,我们就针对涉及到coin的几个类进行工作。

三. 新建项目

  关于新建项目的步骤在之前的教程中我们已经说过了,这里我们快速的创建一下。

  1. 新建.Net Framework类库程序, 平台4.5, 项目名称BigWallet
  2. 添加常用引用
  3. 修改Class1为Main
  4. 添加info.json,属性修改为较新则复制
  5. using常用命名空间
  6. 写出mod主体

这样,我们的基础部分就完成了,主类现在应该看起来是这个样子的

using System;
using Harmony12;
using UnityEngine;
using System.Linq;
using System.Text;
using System.Reflection;
using UnityModManagerNet;
using System.Collections.Generic;

namespace BigWallet
{
    public static class Main
    {
        public static UnityModManager.ModEntry mod;
        public static bool Load(UnityModManager.ModEntry modEntry)
        {
            mod = modEntry;
            HarmonyInstance.Create(mod.Info.Id).PatchAll(Assembly.GetExecutingAssembly());
            return true;
        }
    }
}

info.json

{
  "Id": "BigWallet",
  "DisplayName": "大钱袋",
  "Author": "xiaoye97",
  "Version": "1.0.0",
  "AssemblyName": "BigWallet.dll",
  "EntryMethod": "BigWallet.Main.Load"
}

四. 补丁

  根据观察,我们觉得Coin类应该就是我们要改的地方,观察类可以发现它有物理的相关函数,会参与碰撞,所以我们在Load下面写下补丁如下

[HarmonyPatch(typeof(Coin), "OnEnable")]
class CoinPatch
{
    public static void Postfix(Coin __instance)
    {
        if (mod.Enabled)
        {
            __instance.gameObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
        }
    }
}

  这样,我们就在Coin的OnEnable函数调用之后,把Coin的大小修改为0.5倍,需要注意的是,在所有的逻辑前,我们都应该判断一下mod.Enabled,这样的好处是可以在游戏内关闭Mod,如果我们不加判断,即使玩家在游戏内关闭了Mod,实际上逻辑还是在继续执行的,关于Mod什么时候执行的判断,应该是我们开发者的责任。
  接下来,我们编译Mod,添加到游戏,然后启动游戏。然而,我们可以看到,我们预想的结果并没有发生,钱袋里的硬币并没有变小,这是怎么回事呢?原来,这个Coin并不是钱袋内的硬币,这个时候如果我们进行花钱操作,就可以发现,漂浮到建筑上的硬币变成了一半大小,也就是说,Coin这个类,控制的是花钱时漂浮出来的这个硬币,我们的目标应该不是它。
  我们继续从dnspy观察有关Coin的类,很快,我们发现了真正的目标,BagCoin,这次就显而易见了,根据这个名字我们就能断定它应该就是钱袋内真正发送碰撞的那个硬币。删掉刚才的补丁,我们重新写一个。

[HarmonyPatch(typeof(BagCoin), "Show")]
class BagCoinPatch
{
    public static void Postfix(Coin __instance, bool visible)
    {
        if(mod.Enabled)
        {
            if (visible)
            {
                __instance.gameObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
            }
        }
    }
}

  BagCoin中没有OnEnable,但是有个Show方法,大致阅读代码,我们就能发现这个方法就是显示硬币的方法,我们跟在它的后面打上补丁,判断当Show传入visible为true时,改变BagCoin大小为一半。
  我们再次编译Mod进入游戏,这次,我们可以之间发现钱袋内的硬币变成了一半大小,至此,我们这个小Mod就完成了。再加上一个UI写上作者信息,整体代码如下
Main.cs

using System;
using Harmony12;
using UnityEngine;
using System.Linq;
using System.Text;
using System.Reflection;
using UnityModManagerNet;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace BigWallet
{
    public static class Main
    {
        public static UnityModManager.ModEntry mod;
        public static bool Load(UnityModManager.ModEntry modEntry)
        {
            mod = modEntry;
            HarmonyInstance.Create(mod.Info.Id).PatchAll(Assembly.GetExecutingAssembly());
            mod.OnGUI = OnGUI;
            return true;
        }

        public static void OnGUI(UnityModManager.ModEntry modEntry)
        {
            GUILayout.BeginVertical("大钱包Mod", GUI.skin.window);
            GUILayout.Label("作者: xiaoye97");
            GUILayout.EndVertical();
        }

        [HarmonyPatch(typeof(BagCoin), "Show")]
        class BagCoinPatch
        {
            public static void Postfix(Coin __instance, bool visible)
            {
                if(mod.Enabled)
                {
                    if (visible)
                    {
                        __instance.gameObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
                    }
                }
            }
        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容

  • 一. 前言   通过上面的学习,其实我们已经可以完成一部分的mod,比如点击一下按钮,获得一堆金币,点一下按钮,让...
    宵夜97阅读 7,621评论 2 0
  • 中国诗词大舞台 传承文化聚人才 外卖小哥超勤奋 一举夺冠展风采 今晚观看CCTV_1频道的《中国诗词大会》第三季冠...
    胡杨公主阅读 337评论 2 9
  • 你若三心二意,整个世界都会远离你。 你要专心致志,整个宇宙都会来帮你。 今天看到朋友圈转一段小视频,大体意思就是一...
    读力赢阅读 387评论 1 4
  • 随着高考分数的公布,各地也开始了紧张的填报志愿工作,相信大部分刚刚结束高考的孩子还对未来要选的专业存在着迷茫吧?今...
    美和易思阅读 267评论 0 1
  • 11.16刘润商学院日课感悟:SCQA架构 向上级汇报工作还是向客户介绍本公司的产品,都是需要一个吸引点来让人...
    徐猛_Merlin阅读 306评论 0 0