원클릭으로
unity-il2cpp-modding
Unity Il2Cpp 模组开发经验总结。基于 Il2CppInterop 框架,提供 Il2Cpp 运行时交互、方法挂钩、类型访问、委托调用等核心开发知识,适用于 MelonLoader、BepInEx 等模组框架。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Unity Il2Cpp 模组开发经验总结。基于 Il2CppInterop 框架,提供 Il2Cpp 运行时交互、方法挂钩、类型访问、委托调用等核心开发知识,适用于 MelonLoader、BepInEx 等模组框架。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
管理本地技能仓库"我的技能"的自动化工作流。当用户要求将技能放入/添加/创建/生成/提交到"我的技能"、更新/修改"我的技能"中的技能、安装 Github/本地技能或卸载技能时触发使用。
GitHub CLI (gh) 技能。用于通过命令行与 GitHub 进行无缝交互或读取内容,包括仓库管理、PR/Issue 操作、代码空间管理、发布管理、读取 GitHub 网站内容等。当用户需要与 GitHub 仓库、PR、Issue、Release、Codespace 等交互,或读取 GitHub 网站内容,或需要执行 GitHub 相关自动化任务时使用此技能。
| name | unity-il2cpp-modding |
| description | Unity Il2Cpp 模组开发经验总结。基于 Il2CppInterop 框架,提供 Il2Cpp 运行时交互、方法挂钩、类型访问、委托调用等核心开发知识,适用于 MelonLoader、BepInEx 等模组框架。 |
| license | MIT |
本技能总结了基于 Il2CppInterop 框架开发 Unity Il2Cpp 游戏模组的核心经验和技术要点。
Il2Cpp(Intermediate Language To C++)是 Unity 的脚本后端技术,将 IL 代码编译为 C++ 代码。
关键特性:
Il2Cpp 中的类型通过 Il2CppInterop 进行桥接:
// 获取 Il2Cpp 类型
var il2cppType = Il2CppType.Of<SomeGameClass>();
// 通过名称查找类型(性能较低,避免在 Update 中频繁使用)
var typeByName = Il2CppType.From("Assembly-CSharp", "GameNamespace.GameClass");
// 创建 Il2Cpp 对象实例
var gameObject = new Il2CppSystem.GameObject("MyObject");
// 使用反射创建(当构造函数有参数时)
var type = Il2CppType.From("Assembly-CSharp", "MyClass");
var instance = type.GetConstructor().Invoke(new object[] { arg1, arg2 });
// 直接访问(编译时已知类型)
var component = gameObject.GetComponent<SomeComponent>();
// 反射访问(运行时动态)
var field = type.GetField("fieldName");
var value = field.GetValue(instance);
field.SetValue(instance, newValue);
// 属性访问
var property = type.GetProperty("PropertyName");
var propValue = property.GetValue(instance);
using HarmonyLib;
[HarmonyPatch(typeof(TargetClass), "TargetMethod")]
public class MyPatch
{
// 前置补丁:在原始方法前执行
[HarmonyPrefix]
static bool Prefix(TargetClass __instance, ref int __0)
{
// __instance: 被调用方法的实例
// __0, __1, ...: 方法参数(按顺序)
// ref 参数可以修改传入值
// 返回 false 可跳过原始方法执行
return true; // 继续执行原始方法
}
// 后置补丁:在原始方法后执行
[HarmonyPostfix]
static void Postfix(TargetClass __instance, int __0, ref int __result)
{
// __result: 修改方法的返回值
__result = modifiedValue;
}
// 转置补丁:完全替代原始方法
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
// IL 代码操作,高级用法
return instructions;
}
}
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
// 获取方法指针并进行原生 Hook
var methodInfo = typeof(TargetClass).GetMethod("TargetMethod");
var methodPointer = methodInfo.MethodHandle.GetFunctionPointer();
// 使用 Detours 或 MinHook 进行底层 Hook
// 注意:需要处理 Il2Cpp 的调用约定
Il2Cpp 中的委托处理需要特别注意:
// 创建 Il2Cpp 委托
public delegate void MyCallback(IntPtr ptr);
// 转换方法为 Il2Cpp 委托
var action = (Il2CppSystem.Action)Delegate.CreateDelegate(
typeof(Il2CppSystem.Action),
target,
"MethodName"
);
// 事件订阅
someObject.OnEvent += (Il2CppSystem.Action)MyHandler;
// Il2Cpp 数组
Il2CppReferenceArray<SomeType> il2cppArray;
// 转换常规数组到 Il2Cpp 数组
var managedArray = new[] { 1, 2, 3 };
var il2cppArray = new Il2CppStructArray<int>(managedArray);
// 遍历 Il2Cpp 数组
foreach (var item in il2cppArray)
{
// 处理 item
}
// Il2Cpp List
var list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.String>();
list.Add("item1");
// Il2Cpp Dictionary
var dict = new Il2CppSystem.Collections.Generic.Dictionary<Il2CppSystem.String, Il2CppSystem.Int32>();
dict["key"] = 42;
Il2Cpp 字符串与托管字符串的转换:
// 托管字符串转 Il2Cpp 字符串
Il2CppSystem.String il2cppString = "managed string";
// Il2Cpp 字符串转托管字符串
string managedString = il2cppString.ToString();
// 直接转换
Il2CppSystem.String il2cppStr = new Il2CppSystem.String(managedStr);
| C# 类型 | Il2CppInterop 类型 |
|---|---|
string | Il2CppSystem.String |
object | Il2CppSystem.Object |
int | Il2CppSystem.Int32 |
float | Il2CppSystem.Single |
bool | Il2CppSystem.Boolean |
byte[] | Il2CppStructArray<byte> |
T[] | Il2CppReferenceArray<T> / Il2CppStructArray<T> |
// 常用 Unity 类型的 Il2Cpp 版本
Il2CppSystem.GameObject
Il2CppSystem.Transform
Il2CppSystem.Component
Il2CppSystem.Vector3
Il2CppSystem.Quaternion
// 转换示例
UnityEngine.Vector3 managed = il2cppVector3;
Il2CppUnityEngine.Vector3 il2cpp = managed;
// 查找场景中的对象
var objects = UnityEngine.Object.FindObjectsOfType<Il2CppSomeComponent>();
// 通过路径查找
var foundObject = GameObject.Find("Path/To/Object");
// 获取组件(Il2Cpp 版本)
var component = gameObject.GetComponent<Il2CppType.ComponentType>();
// 动态获取
var comp = gameObject.GetComponent(Il2CppType.From("Assembly-CSharp", "SomeComponent"));
缓存类型和方法信息
// 不好的做法:每次调用都反射
var method = type.GetMethod("MethodName");
// 好的做法:缓存反射结果
private static readonly MethodInfo cachedMethod =
typeof(TargetClass).GetMethod("MethodName");
避免频繁的 Il2Cpp/Managed 边界跨越
谨慎使用字符串操作
注意 Il2Cpp 对象生命周期
// 保持对 Il2Cpp 对象的引用
private Il2CppSystem.GameObject cachedObject;
避免 Il2Cpp 对象被过早回收
GC.KeepAlive() 防止优化掉引用使用 Il2CppDumper 分析游戏
日志记录
// 使用 MelonLoader 日志
MelonLogger.Msg($"[MyMod] Value: {value}");
// 或者使用 BepInEx
Logger.LogInfo($"[MyMod] Value: {value}");
异常处理
try
{
// Il2Cpp 调用
}
catch (Il2CppException ex)
{
// 处理 Il2Cpp 异常
MelonLogger.Error($"Il2Cpp Error: {ex.Message}");
}
catch (Exception ex)
{
// 处理托管异常
MelonLogger.Error($"Error: {ex}");
}
A: 检查方法签名是否正确,Il2Cpp 可能进行了方法内联或剥离。使用 Il2CppDumper 验证方法是否存在。
A: 确保委托的生命周期管理正确,使用 Il2CppSystem.Delegate 类型并防止过早 GC。
A: 检查是否正确引用了 Il2Cpp 版本的类型。确保使用 Il2CppType.From() 或 Il2CppType.Of<>()。
A: Il2Cpp 方法地址可能改变,需要重新分析游戏并更新钩子地址。考虑实现版本检测机制。
MyIl2CppMod/
├── MyMod.csproj # 引用 Il2CppInterop 和框架
├── ModMain.cs # 入口类
├── Patches/
│ ├── GamePatch.cs # Harmony 补丁
│ └── UIPatch.cs
├── Utils/
│ ├── Il2CppHelper.cs # Il2Cpp 辅助工具
│ └── ReflectionCache.cs # 反射缓存
└── Config/
└── ModConfig.cs # 模组配置
注意:不同 Unity 版本的 Il2Cpp 输出可能有差异,建议针对目标游戏版本测试。