BepInEx完整指南:零改动免费给Unity游戏装上Mod插件的框架
【免费下载链接】BepInExUnity / XNA game patcher and plugin framework项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx
BepInEx 是一个免费的 Unity 游戏插件框架:把插件 DLL 扔进游戏目录的 plugins 文件夹,它就能在 game 代码跑起来之前自动加载执行。你不用再自己碰注入、钩子和插件依赖排序这些底层脏活。
BepInEx帮你解决什么问题
痛点一:想给 Unity 游戏加 Mod,却没有 Mod 入口。游戏本体不带 Mod 支持,第三方 Mod 又总说"需要 BepInEx"。它正是那个入口——把整个 Mod 圈的地基统一好:插件怎么被发现、加载顺序怎么排、配置放哪、日志写哪,全部由框架兜底。你只管把 DLL 放对位置。
痛点二:自己写加载器太累。如果你是想造轮子的开发者,单独实现插件发现、版本比对、依赖拓扑排序、配置持久化和统一日志,工作量不小且容易出错。BepInEx 把这些做成了现成 API,你继承基类、加几个属性就能写出规范的插件。
它覆盖哪些游戏?按运行时分三类(注意:目前只有 Unity Mono 提供稳定版):
- Unity Mono:Windows、macOS、Linux 全平台支持,成熟度最高
- Unity IL2CPP:Windows 和 Linux 可用,macOS 不行,需使用 Bleeding Edge 测试版构建
- .NET 系(XNA、FNA、MonoGame 等):Windows 原生支持,macOS / Linux 通过 Mono 运行
拆开看:BepInEx是怎么运转的
把游戏启动想象成餐厅开餐前的备餐。厨师(游戏本体)还没进后厨,采购组(BepInEx)已经先一步进场:对着冰箱清一遍"进货单"(扫描 plugins 目录里有哪些插件),按每道菜用到的先后顺序把食材分类摆好(根据插件声明的依赖关系排加载顺序),把账本和储物柜位置定下来(配置与日志目录结构)。等这一切就绪,才把后厨钥匙交给厨师——游戏初始化才开始。
所有家当都集中在游戏根目录的BepInEx文件夹里,结构在 BepInEx.Core/Paths.cs 中定义:
BepInEx/ ├── core/ # 框架自身的 DLL ├── plugins/ # 插件 DLL 的存放地 ├── patchers/ # 预加载修补程序 ├── config/ # 各插件的 .cfg 配置 └── cache/ # 运行期缓存具体谁先谁后、哪些插件被跳过,逻辑写在 BepInEx.Core/Bootstrap/BaseChainloader.cs——它会把每个插件的 GUID、版本、依赖、进程名限制都解析成一条插件记录,再据此完成排序和筛选。游戏运行日志落在根目录的LogOutput.log。
两条上手路线,各选最短路径
路线一:普通玩家装 Mod
- 从官方发布页下载对应平台压缩包(Unity Mono 选稳定版;IL2CPP 游戏用 Bleeding Edge 版)。
- 解压后把整个
BepInEx文件夹拷到游戏根目录(即游戏 exe 所在的那一层)。 - 把拿到的插件 DLL 放进
BepInEx/plugins。 - 启动游戏,打开根目录
LogOutput.log,看到插件名即代表加载成功。
路线二:开发者自行编译
构建脚本基于 CakeBuild,硬性要求.NET 6.0 及以上。
git clone https://gitcode.com/GitHub_Trending/be/BepInEx ./build.sh --target Compile # Linux / macOS build.cmd --target Compile # Windows 命令行想直接产出可分发包就改用--target MakeDist(在bin/dist生成各平台包);Publish会在此基础上再打 zip。各目标的说明见 docs/BUILDING.md。
进阶技巧:三个最值得掌握的配置
1. 把 Unity 原生日志重定向到文件。BepInEx 接管前的报错(比如启动早期就崩的)在控制台里往往看不到。打开 Runtimes/Unity/Doorstop/doorstop_config_mono.ini,把redirect_output_log改为true,Unity 的输出日志会同步写到当前目录的output_log.txt,排查"没进游戏就死"类问题必备。
2. 崩溃现场保留:即时刷盘。核心配置在BepInEx/config/BepInEx.cfg的Logging.Disk段。把InstantFlushing设为true,每条日志立即落盘——性能有代价,但崩溃时不会丢最后几条记录,是查崩溃的利器。同一时刻开多个游戏实例调试时,再顺手调大ConcurrentFileLimit(默认 5),否则日志文件会不够用。
3. 用属性声明依赖和进程限制。写插件时在类上加[BepInDependency("某插件的GUID")],表示它必须先于你加载,缺了就拒绝启动;加[BepInProcess("GameName")]则只在指定进程名下运行。插件基类在 Runtimes/Unity/BepInEx.Unity.Mono/BaseUnityPlugin.cs,这些元数据属性的定义见 BepInEx.Core/Contract/Attributes.cs。
踩坑自救手册:五个最常见症状
症状:游戏正常启动,但一个插件都没加载。原因:Doorstop 没真正接管启动,或target_assembly路径指错了。 解法:检查doorstop_config_mono.ini中enabled = true,且target_assembly指向BepInEx\core\BepInEx.Unity.Mono.Preloader.dll。
症状:报找不到 mscorlib 或系统程序集。原因:部分游戏裁剪过Managed目录,Mono 拿不到核心库。 解法:在 doorstop 配置里设置dll_search_path_override = "BepInEx\core",让 Mono 优先从框架目录找核心库(该文件默认已带上这行,若被删可补回)。
症状:同一插件放了新旧两个版本,只生效了一个。原因:GUID 相同的插件,框架只保留版本号最高的那份。 解法:这不是 bug 是特性——删掉旧版 DLL 即可,别指望两份共存。
症状:插件在这台游戏里死活不加载,换个游戏却好好的。原因:插件声明了[BepInProcess],只认特定进程名。 解法:核对属性里的进程名与当前游戏 exe 名(不含扩展名)是否一致,不一致就是它故意不加载。
症状:IL2CPP 游戏装不上稳定版。原因:官方稳定发布只覆盖 Unity Mono,IL2CPP 走测试线。 解法:按 README 的说明改用 Bleeding Edge 构建,或等官方推进稳定版。
一句话总结与下一步
BepInEx 已经是 Unity Mod 圈事实上的基础设施,装 Mod 选它不会错;写插件选它等于白得一套成熟的配置、日志和依赖系统。
下一步建议两个入口:先读 docs/BUILDING.md 摸清全部构建目标,再翻 BepInEx.Core/ 源码,重点看Configuration/和Logging/两个目录,把配置与日志 API 吃透后,你写插件时就不会再被细节卡住。
【免费下载链接】BepInExUnity / XNA game patcher and plugin framework项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考