1. 先搞清楚这件事:BepInEx到底在什么位置干活
第一次在游戏根目录看到 winhttp.dll、doorstop_config.ini、BepInEx 文件夹时,很多人会愣一下:这游戏本体明明是Unity引擎开发的,怎么根目录里多出了几个不像是Unity默认生成的文件?这正是BepInEx在“游戏启动早期”插了一脚的表现。在讲怎么装、怎么写插件之前,我建议先把这层机制弄懂,否则后面排错时会一直处于“照着教程做了但不知道为什么”的悬浮状态。
1.1 Mono与IL2CPP:先得知道游戏脚本是怎么被运行的
要理解BepInEx,绕不开Unity本身的运行机制。Unity游戏绝大多数逻辑是用C#写的,C#代码编译后不会直接变成CPU能执行的原生指令,而是先编译成一种叫中间语言(IL)的东西。IL需要一个运行时来消费,Unity目前有两条路线:
- Mono模式:游戏包内自带一套Mono运行时,IL交给Mono运行时解释执行。对应到游戏目录,你会看到
MonoBleedingEdge文件夹,并且在*_Data/Managed目录下能直接看到大量托管DLL。 - IL2CPP模式:Unity打包时会把C#代码的IL转成C++代码,再用各个平台的原生编译器把C++编译成二进制。此时游戏目录里没有可以直接阅读的托管DLL,逻辑被压进了
GameAssembly.dll这种原生库里。
这两者决定了mod制作的难度和路子完全不同。Mono模式下,你甚至可以把游戏 Managed 目录里的DLL反编译出来,直接改逻辑再放回去,很多老Unity游戏就是这么被改的。IL2CPP模式下,反编译和修改原生二进制都麻烦得多,常规手段是在“游戏加载运行时的入口”上下功夫,也就是用BepInEx这类框架在外部介入。
我见过不少新手一上来就问“为什么我反编译看不到我的目标方法”,结果一问游戏是IL2CPP的,自然看不到熟悉的C#托管DLL。先判断游戏属于哪种模式,后面的选型和做法才会顺。
1.2 BepInEx的核心工作方式:在游戏启动时抢先进场
BepInEx的底层原理,我习惯叫它“门禁式注入”。Windows平台下,Unity游戏的可执行文件启动时,需要加载一系列系统DLL。BepInEx利用 winhttp.dll 这个系统库劫持点,让游戏进程在初始化游戏逻辑之前,先把BepInEx核心程序集加载进来。
打个比方:游戏本来是一个商场,顾客是各种游戏逻辑。BepInEx是在商场门口加装的一道闸机。顾客还是那些顾客,但进门前必须先过闸机,闸机可以偷偷做自己的事——记录顾客、给顾客换券、在顾客消费离场后再补一刀。这就是BepInEx加载插件、以及配合Harmony改方法逻辑的本质。
具体到流程,游戏启动后大致是这样的:
- Windows加载器因为劫持配置,提前加载
winhttp.dll。 winhttp.dll读取doorstop_config.ini,定位并启动BepInEx的核心入口。- 核心入口初始化BepInEx环境,扫描
BepInEx/plugins目录。 - 加载每个插件程序集,执行插件里
Awake、Update等生命周期方法。 - 一切就绪后,游戏本体逻辑开始正常执行。
因为动作发生得足够早,BepInEx可以在游戏自己的初始化代码运行前就注册好补丁和Hook,从而在后续游戏逻辑里“埋伏笔”。
1.3 为什么是BepInEx,而不是其他mod框架
Unity游戏mod框架远不止BepInEx一家,MelonLoader、Unity Mod Manager、Nebula等也各自有用户群。但BepInEx有一个非常适合做mod的特性组合:
- 插件化彻底:你可以同时丢十几个插件进
plugins目录,只要不互相冲突,它们会并行加载。 - 版本策略清晰:BepInEx 5 LTS主打Mono游戏,BepInEx 6覆盖IL2CPP游戏,路线划分明确。
- 日志系统强大:每次运行都会生成
LogOutput.log,排错时这是第一手资料。 - 中文社区资料多、教程多,网上能搜到的踩坑记录也最全。
如果只是给自己的单机Unity游戏做本地功能修改,BepInEx基本是默认首选。当然,MelonLoader在某些特定游戏上也有优势,但BepInEx的通用性和成熟度决定了它更适合作为入门主线。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 版本选型:BepInEx 5 LTS和BepInEx 6到底差在哪
许多新手栽的第一个跟头,就是版本下错了。搜索引擎里那些“bepinex 5 lt
