PONOS Advent Calendar 2022 18日目の記事です。
昨日は@abcdeffさんの「クラス設計に関して」でした。
Unityのコンパイラについて
UnityのコンパイラはMonoとIL2CPPの2種が用意されています。特に何も設定せずビルドをするとMonoでコンパイルが行われますが、この場合.NETの中間言語であるILで出力されます。
IL2CPPの場合はILをC++に変換するので解析が難しくなりますが、Monoの場合は各種ツールを使う事で簡単に解析・改造を行う事が可能です。
本記事では自作のゲームを用いてModを作成してみます。
本記事内でModの作成方法について触れますが改造行為を推奨する物ではありません。
行う場合はあくまで自己責任でお願いします。
dnSpyを使う
C#のデコンパイラであるdnSpyをダウンロードします。
https://github.com/dnSpy/dnSpy
Monoでビルドしたゲームのローカルファイルを見ると「(ゲーム名)_Data/Managed」
というフォルダがあります。
この中の「Assembly-CSharp.dll」
をdnSpyに入れるとデコンパイル出来ます。
・デコンパイルしたコード
見比べるとコメント文が無いなどの違いはありますが、ほぼそのままコードが復元出来ていることが分かります。
このままdnSpy上でコードを書き換えて再度コンパイルをする事も可能ですが、完全に上書きしてしまうのでModの様に再配布する形には向きません。そこで別のツールを使用します。
BepInEx
UnityのゲームにModを導入出来るフレームワークの一つにBepInExという物があります。
https://github.com/BepInEx/BepInEx
- VisualStudioでプロジェクト作成。種別はクラスライブラリ(.NET Framework)
- 参照→「参照の追加」から必要なdllを追加。
(BepInEx.dll・0Harmony.dllとManagedの中身から必要な物を探す) - 改造したい内容を記載してビルド。
- ビルドして出来たdllを
「BepInEx/plugins」
に入れれば準備完了。
先程のジャンプゲームの移動速度を3倍に、また縦にも移動出来る処理を入れてみます。
using HarmonyLib;
using UnityEngine;
namespace JumpGameMod
{
[HarmonyPatch(typeof(PlayerJump), "FixedUpdate")]
internal class FreeMove
{
public static void Postfix(Rigidbody2D ___rigidbody2d)
{
var newVec = ___rigidbody2d.velocity;
newVec.y = Input.GetAxis("Vertical") * 3.5f;
___rigidbody2d.velocity = newVec * 3f;
}
}
}
このコードをビルドして出来たdllを導入してゲームを起動すると、以下の通り記載した処理が反映されている事が確認出来ました。
まとめ
以上の通り各種ツールを用いたMod作成が出来る事を確認しました。高度な知識が必要という訳では無く、C#さえ分かればある程度のコード書き換えは出来てしまいます。
PCゲームの場合は逆にユーザーによるMod作成を推奨している作品もありますが、特に理由が無い限りはIL2CPPでのビルド及び難読化などの対策を行うことをオススメします。
明日は@tequila0725さんの記事です🍣