abevol

unity-il2cpp-modding

by @abevol in Tools
0
0
# Install this skill:
npx skills add abevol/my-skills --skill "unity-il2cpp-modding"

Install specific skill from multi-skill repository

# Description

Unity Il2Cpp 模组开发经验总结。基于 Il2CppInterop 框架,提供 Il2Cpp 运行时交互、方法挂钩、类型访问、委托调用等核心开发知识,适用于 MelonLoader、BepInEx 等模组框架。

# SKILL.md


name: unity-il2cpp-modding
description: Unity Il2Cpp 模组开发经验总结。基于 Il2CppInterop 框架,提供 Il2Cpp 运行时交互、方法挂钩、类型访问、委托调用等核心开发知识,适用于 MelonLoader、BepInEx 等模组框架。
license: MIT


Unity Il2Cpp 模组开发

本技能总结了基于 Il2CppInterop 框架开发 Unity Il2Cpp 游戏模组的核心经验和技术要点。

核心概念

Il2Cpp 运行时环境

Il2Cpp(Intermediate Language To C++)是 Unity 的脚本后端技术,将 IL 代码编译为 C++ 代码。

关键特性:
- 运行时类型系统与原 Unity Mono 不同
- 使用 Il2CppInterop 作为桥接层
- 需要理解 Il2Cpp 的对象生命周期管理
- 内存管理遵循 Il2Cpp 的垃圾回收机制

主要模组框架支持

  • MelonLoader: 内置 Il2CppInterop 支持
  • BepInEx: 通过 Il2CppInterop 插件支持
  • 独立使用: 可以直接引用 Il2CppInterop 库

类型系统与访问

Il2Cpp 类型基础

Il2Cpp 中的类型通过 Il2CppInterop 进行桥接:

// 获取 Il2Cpp 类型
var il2cppType = Il2CppType.Of<SomeGameClass>();

// 通过名称查找类型(性能较低,避免在 Update 中频繁使用)
var typeByName = Il2CppType.From("Assembly-CSharp", "GameNamespace.GameClass");

Il2Cpp 对象创建

// 创建 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);

方法挂钩 (Hooking)

使用 Harmony 或 Il2Cpp 原生 Hook

方法补丁(Harmony 风格)

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;
    }
}

Il2Cpp 特定 Hook 技术

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 集合与数组

Il2Cpp 数组处理

// 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 列表和字典

// 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);

常用 Il2Cpp 类型

基础类型映射

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 类型

// 常用 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"));

最佳实践与注意事项

性能优化

  1. 缓存类型和方法信息
    ```csharp
    // 不好的做法:每次调用都反射
    var method = type.GetMethod("MethodName");

// 好的做法:缓存反射结果
private static readonly MethodInfo cachedMethod =
typeof(TargetClass).GetMethod("MethodName");
```

  1. 避免频繁的 Il2Cpp/Managed 边界跨越
  2. 批量处理数据而非逐个处理
  3. 缓存 Il2Cpp 对象引用

  4. 谨慎使用字符串操作

  5. Il2Cpp 字符串转换有开销
  6. 优先使用直接比较而非字符串操作

内存管理

  1. 注意 Il2Cpp 对象生命周期
    csharp // 保持对 Il2Cpp 对象的引用 private Il2CppSystem.GameObject cachedObject;

  2. 避免 Il2Cpp 对象被过早回收

  3. 在托管代码中保持强引用
  4. 使用 GC.KeepAlive() 防止优化掉引用

调试技巧

  1. 使用 Il2CppDumper 分析游戏
  2. 获取类型定义和方法签名
  3. 帮助理解游戏内部结构

  4. 日志记录
    ```csharp
    // 使用 MelonLoader 日志
    MelonLogger.Msg($"[MyMod] Value: {value}");

// 或者使用 BepInEx
Logger.LogInfo($"[MyMod] Value: {value}");
```

  1. 异常处理
    csharp try { // Il2Cpp 调用 } catch (Il2CppException ex) { // 处理 Il2Cpp 异常 MelonLogger.Error($"Il2Cpp Error: {ex.Message}"); } catch (Exception ex) { // 处理托管异常 MelonLogger.Error($"Error: {ex}"); }

常见问题与解决方案

Q: 遇到 "Method not found" 错误

A: 检查方法签名是否正确,Il2Cpp 可能进行了方法内联或剥离。使用 Il2CppDumper 验证方法是否存在。

Q: 委托回调导致崩溃

A: 确保委托的生命周期管理正确,使用 Il2CppSystem.Delegate 类型并防止过早 GC。

Q: 类型转换失败

A: 检查是否正确引用了 Il2Cpp 版本的类型。确保使用 Il2CppType.From()Il2CppType.Of<>()

Q: 游戏更新后模组失效

A: Il2Cpp 方法地址可能改变,需要重新分析游戏并更新钩子地址。考虑实现版本检测机制。

参考资源

示例模组结构

MyIl2CppMod/
├── MyMod.csproj          # 引用 Il2CppInterop 和框架
├── ModMain.cs            # 入口类
├── Patches/
│   ├── GamePatch.cs      # Harmony 补丁
│   └── UIPatch.cs
├── Utils/
│   ├── Il2CppHelper.cs   # Il2Cpp 辅助工具
│   └── ReflectionCache.cs # 反射缓存
└── Config/
    └── ModConfig.cs      # 模组配置

版本兼容性

  • Unity 2019.4+: 完整支持
  • Unity 2020.x: 完整支持
  • Unity 2021.x: 完整支持
  • Unity 2022.x+: 需要最新 Il2CppInterop 版本

注意:不同 Unity 版本的 Il2Cpp 输出可能有差异,建议针对目标游戏版本测试。

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.