ET框架插件开发:Unity Package本地链接实战指南

📅 2026/8/8 6:28:48
ET框架插件开发:Unity Package本地链接实战指南
1. 项目概述为什么本地链接是ET插件开发的命门如果你正在用ET框架做游戏开发尤其是涉及到需要频繁修改和测试的自定义插件或模块那你一定对“打包-发布-导入-测试”这个循环深恶痛绝。每次改几行代码都要经历一遍完整的打包发布流程效率低得令人发指。而Unity Package的本地链接Local Linking技术就是打破这个效率瓶颈的“金钥匙”。它允许你将一个正在开发的Package像引用本地文件夹一样直接链接到你的主项目中实现代码的实时同步和即时编译。对于ET框架这种强调热更新、模块化开发的架构来说掌握本地链接技巧就意味着你的插件开发效率能提升一个数量级。ET框架本身就是一个由大量Package如cn.etetet.corecn.etetet.hotfix等构成的生态系统。无论是为ET开发一个通用的网络协议包、一个UI组件库还是一个特定的游戏逻辑模块最终都会以Package的形式存在。本文将从一线开发者的实战角度彻底拆解在ET框架生态下进行Unity Package本地链接的完整流程、核心配置、高级技巧以及那些官方文档里不会写的“坑”。我们的目标很简单让你能像开发普通Unity脚本一样流畅地开发ET插件。2. 核心原理ET Package与本地链接的本质在深入实操之前我们必须先理解两个核心概念ET Package的构成和本地链接的工作原理。这能帮你从根本上避开配置错误。2.1 ET Package的“基因”它不只是个文件夹一个标准的ET Package远不止是几个C#脚本的集合。它是一个严格遵循ET框架模块化与热更新设计理念的完整单元。首先从命名上就有严格规范。ET Package采用类似Java包名的反向域名格式cn.etetet. 你的包名。例如你开发一个任务系统插件包名可能就是cn.etetet.quest。这种命名确保了在全球范围内的唯一性避免了与Unity官方或其他第三方包冲突。其次它的目录结构是功能导向的。一个典型的ET Package核心目录如下cn.etetet.yourpackage/ ├── package.json // 包的元数据与依赖声明 ├── packagegit.json // **ET特有**用于管理Git依赖和代码引用 ├── Runtime/ // 存放AOT预先编译代码如核心系统接口、数据结构 │ └── ET.YourPackage.asmdef ├── Scripts/ // **核心区域**存放热更新相关代码 │ ├── Model/ // 服务端模型层代码双端均可执行 │ ├── Hotfix/ // 客户端热更新层代码仅客户端热更 │ ├── ModelView/ // 客户端模型层代码视图相关双端 │ └── HotfixView/ // 客户端热更新视图层代码仅客户端热更 │ ├── Client/ // 纯客户端代码 │ ├── Server/ // 纯服务端代码 │ └── Share/ // 客户端与服务端共享代码 ├── Editor/ // 编辑器扩展脚本 │ └── ET.YourPackage.Editor.asmdef └── Tests/ // 单元测试可选关键在于Scripts目录下的划分这直接对应了ET框架的Model、Hotfix、ModelView、HotfixView四大程序集。本地链接时Unity和ET的工具链需要正确识别这些目录并将代码关联到正确的程序集。2.2 本地链接的“魔法”file协议与符号链接当我们说“本地链接”时在Unity的语境下主要指的是在项目的Packages/manifest.json文件中使用file:协议来声明对一个本地路径的依赖。{ dependencies: { com.unity.collab-proxy: 2.0.4, cn.etetet.core: file:../../../ET-Packages/cn.etetet.core, cn.etetet.yourplugin: file:../MyETPlugins/yourplugin } }这行配置告诉Unity Package Manager (UPM)”别去Registry服务器上找cn.etetet.yourplugin这个包直接去我本地../MyETPlugins/yourplugin这个文件夹里读取。“在这个过程中Unity实际上会在项目的Library/PackageCache目录下为该包创建一个符号链接Symbolic Link或直接引用。这意味着你在本地Package目录下的任何修改添加、删除、修改脚本都会实时反映到主项目中触发Unity的重新编译。这才是实现高效迭代的核心。注意file:后面的路径是相对于manifest.json文件所在位置即项目根目录下的Packages文件夹的路径。使用相对路径比绝对路径更安全便于团队协作和项目迁移。3. 实战第一步搭建你的本地ET Package开发环境理论懂了现在开始动手。假设我们要为一个ET项目开发一个名为cn.etetet.achievement的成就系统插件。3.1 创建标准的ET Package目录骨架首先在你喜欢的位置比如与你的ET主项目同级目录创建插件开发文件夹。创建根文件夹ET-AchievementPlugin。创建Package核心文件夹在ET-AchievementPlugin内创建cn.etetet.achievement文件夹。这个文件夹的名字必须与将来在manifest.json中声明的包名完全一致。填充标准目录在cn.etetet.achievement内创建Runtime、Scripts、Editor目录并在Scripts下创建Model、Hotfix、ModelView、HotfixView及其子目录Client、Server、Share。你的初始结构应该像这样ET-AchievementPlugin/ └── cn.etetet.achievement/ ├── Runtime/ ├── Scripts/ │ ├── Model/ │ ├── Hotfix/ │ ├── ModelView/ │ └── HotfixView/ │ ├── Client/ │ ├── Server/ │ └── Share/ └── Editor/3.2 编写核心配置文件package.json与packagegit.json这是最容易出错也是最关键的一步。两个文件各司其职。1. package.json定义包的元数据和UPM依赖在cn.etetet.achievement根目录创建package.json。{ name: cn.etetet.achievement, displayName: ET Achievement System, version: 1.0.0, unity: 2022.3, description: A complete achievement system plugin for ET Framework., dependencies: { cn.etetet.core: file:../../../ET-Packages/cn.etetet.core }, publishConfig: { registry: https://npm.pkg.github.com/ET-Packages } }name必须与文件夹名完全一致。dependencies声明此插件依赖的其他ET包。这里使用file:协议链接到本地的cn.etetet.core包。请务必根据你的实际路径调整。publishConfig这是为将来发布到GitHub Packages准备的在本地开发阶段不影响使用但最好保持一致。2. packagegit.jsonET框架的“灵魂”配置文件这是ET框架特有的文件用于管理代码到特定程序集的引用关系。在cn.etetet.achievement根目录创建packagegit.json。{ Id: cn.etetet.achievement, Name: 成就系统, GitDependencies: { cn.etetet.core: https://github.com/ET-Packages/cn.etetet.core.git } }Id包的标识通常与name相同。GitDependencies这里定义的Git依赖在运行ET的Refresh命令时会被用来建立代码引用。注意本地开发时即使你通过file:链接了本地包这里最好也填写该包的Git仓库地址如果存在以保证工具链能正确理解依赖关系。3.3 创建程序集定义文件.asmdef为了让Unity正确编译和隔离代码每个需要独立编译的模块都需要一个.asmdef文件。Runtime程序集在Runtime/文件夹内右键创建Assembly Definition命名为ET.Achievement。这个程序集将包含你的成就系统核心接口、数据结构和AOT代码。Editor程序集在Editor/文件夹内创建Assembly Definition命名为ET.Achievement.Editor。在它的Inspector面板中在Assembly Definition References里添加对ET.Achievement的引用并在Platforms中取消勾选Any Platform只保留Editor。这确保了编辑器代码只在Unity编辑器中运行。Scripts下的“占位”程序集在Scripts/文件夹内创建一个名为Ignore的.asmdef文件。这是一个ET框架的惯例目的是让该Package默认不被包含到任何程序集中防止代码错误引用。真正的引用关系由packagegit.json和ET的Refresh命令来动态管理。4. 实现本地链接将你的插件“挂载”到主项目环境搭建好了现在要把这个正在开发的插件链接到你的ET游戏主项目中。4.1 修改主项目的manifest.json打开你的ET游戏主项目找到Packages/manifest.json文件。在dependencies区块中添加你的本地包路径。{ dependencies: { cn.etetet.core: file:../../ET-Packages/cn.etetet.core, cn.etetet.hotfix: file:../../ET-Packages/cn.etetet.hotfix, cn.etetet.achievement: file:../../ET-AchievementPlugin/cn.etetet.achievement, com.unity.textmeshpro: 3.0.6 } }保存manifest.json文件。切换回Unity编辑器Unity会自动检测到manifest.json的变更并开始导入新添加的本地包。你可以在Package Manager窗口中切换到“My Registries”或“In Project”视图看到你的cn.etetet.achievement包其来源会显示为Local。4.2 关键一步配置Unity外部工具很多开发者链接成功后发现IDE如Rider、VS无法识别新包里的类无法跳转和自动补全。问题往往出在这里。进入Edit - Preferences - External Tools。 在Generate .csproj files for:选项下确保Local packages被勾选。 这个设置告诉Unity在为IDE生成解决方案.sln和项目文件.csproj时需要将本地链接的包也包含进去。如果不勾选IDE就“看不见”你的本地包代码。实操心得修改此设置后通常需要手动触发一次项目文件生成。可以关闭Unity删除项目根目录下的*.sln文件和所有*.csproj文件然后重新打开Unity它会自动重新生成包含本地包在内的所有项目文件。或者在Unity中点击Assets - Open C# Project强制刷新。4.3 运行ET工具链命令建立代码引用本地包被成功链接并导入后你的成就系统代码还处于“孤立”状态没有被关联到ET框架的Model、Hotfix等核心程序集中。在Unity编辑器中找到ET框架的菜单栏ET - Refresh。点击运行。这个命令会读取所有包包括本地链接的包中的packagegit.json文件分析依赖关系并将Scripts目录下的代码自动关联到你的主项目Demo中对应的Model、Hotfix、ModelView、HotfixView这四个程序集定义.asmdef上。完成这一步后你的AchievementComponent或其他脚本才能被ET的实体系统正确识别和调用。5. 高级技巧与深度避坑指南基本的链接跑通了但想用得顺手还得掌握下面这些进阶技巧和避坑方法。5.1 处理“INITED”宏与Demo包初始化如果你开发的插件包含Demo示例代码通常放在Scripts/Demo目录你会遇到一个特殊问题这些Demo代码在项目初次打开或包初次下载时可能会因为依赖的程序集尚未准备好而编译报错。ET框架的解决方案是使用INITED条件编译宏。找到主项目中Model、Hotfix、ModelView、HotfixView这四个核心.asmdef文件。在它们的Scripting Define Symbols中添加INITED宏。在你的Demo代码中将所有类用#if INITED和#endif包裹起来。#if INITED namespace ET.Achievement.Demo { public class AchievementDemoSystem { // 你的演示代码 } } #endif这样只有当你通过ET - Init菜单初始化项目后INITED宏才会被定义Demo代码才会被编译。避免了初始状态下的编译错误。5.2 多包依赖与循环引用陷阱你的成就系统插件cn.etetet.achievement可能依赖于另一个本地开发的cn.etetet.analytics数据分析插件。在achievement的package.json中声明依赖dependencies: { cn.etetet.core: file:../../../ET-Packages/cn.etetet.core, cn.etetet.analytics: file:../../ET-AnalyticsPlugin/cn.etetet.analytics }在achievement的packagegit.json中也声明Git依赖指向analytics的Git仓库。在主项目的manifest.json中需要同时链接这两个包。避坑提示循环引用。绝对禁止包A依赖包B同时包B又依赖包A。这会导致Unity依赖解析失败编译错误。设计模块时要确保依赖关系是单向的、有层次的。公共基础功能应下沉到更底层的包如core。5.3 本地调试与热更新联调本地链接最大的优势就是联调。实时修改在achievement包的Hotfix/Client目录下修改一个处理成就弹出的UI系统。保存后Unity主项目几乎立刻开始重新编译包含这部分改动的程序集。断点调试由于本地包被包含在IDE的项目文件中你可以在achievement的代码里直接下断点。在Unity中运行游戏触发成就逻辑IDE会正常命中断点和调试项目内代码毫无二致。热更新测试ET框架的热更新机制依赖于将Hotfix和HotfixView程序集动态加载到游戏里。当你修改了这些程序集里的代码并编译后可以通过ET的热更新流程如使用ILRuntime或HybridCLR直接加载新的DLL在不停服的情况下测试插件功能。本地链接让“编码-编译-热更测试”这个循环变得极其快速。5.4 版本管理与团队协作策略本地链接用的是file:协议路径是写死的。这在单人开发时没问题但在团队中每个人的项目路径可能不同。解决方案使用file:协议配合相对路径的公约或创建符号链接。公约法团队约定将所有本地开发的ET包都放在一个与主项目同级或固定相对位置的LocalPackages目录中。这样每个人的manifest.json都可以使用相同的相对路径如file:../../LocalPackages/cn.etetet.achievement。符号链接法更灵活在项目的Packages目录下为你开发的包创建一个符号链接。Windows (CMD管理员):mklink /J cn.etetet.achievement D:\YourPath\ET-AchievementPlugin\cn.etetet.achievementmacOS/Linux:ln -s /path/to/your/ET-AchievementPlugin/cn.etetet.achievement ./Packages/cn.etetet.achievement然后在manifest.json中就可以使用file:协议指向这个符号链接或者甚至可以直接使用包名如果UPM能识别符号链接。这种方法路径更简洁。6. 从本地开发到正式发布的工作流本地开发测试完成后你需要将插件发布出去供其他项目使用。ET框架的包通常发布到GitHub Packages。6.1 准备发布配置确保你的package.json中的publishConfig.registry指向正确的地址如ET官方的是https://npm.pkg.github.com/ET-Packages。你需要在本地配置npm或yarn的认证以便有权限发布到该私有仓库。6.2 使用GitHub Actions自动化发布ET-Packages仓库提供了标准的发布工作流模板。这是最高效的方式。在你的插件包仓库根目录创建.github/workflows/release-package.yml文件。内容可以直接从已有的ET包如cn.etetet.yiui中复制。这个工作流通常会在你向仓库打上版本标签如v1.0.0时自动触发。它会运行npm pack打包然后将生成的.tgz文件发布到配置的GitHub Packages Registry。6.3 更新主项目依赖发布成功后其他项目就可以通过Git URL或配置Scoped Registry来引用你发布的包了。你需要将主项目manifest.json中的依赖从本地链接改为版本号或Git引用。// 从本地链接 cn.etetet.achievement: file:../../ET-AchievementPlugin/cn.etetet.achievement // 改为发布后的版本引用需配置Scoped Registry cn.etetet.achievement: 1.0.0 // 或直接使用Git URL特定commit或tag cn.etetet.achievement: https://github.com/YourName/cn.etetet.achievement.git#v1.0.07. 常见问题排查与解决方案实录即使按照指南操作也难免会遇到问题。这里记录了几个最常见的问题和解决方法。问题1Unity Package Manager里看不到我的本地包或者显示为灰色。检查manifest.json中的file:路径是否正确。路径是相对于Packages文件夹的。检查本地包根目录是否有正确且有效的package.json文件。name字段必须与文件夹名匹配。解决尝试关闭Unity删除项目下的Library和Packages文件夹manifest.json保留然后重新打开Unity。这会强制UPM重新解析所有依赖。问题2IDERider/VS无法识别本地包中的类没有代码提示和跳转。检查Edit - Preferences - External Tools中Local packages是否已勾选。检查是否在修改设置后重新生成了项目文件删除.sln和.csproj后重启Unity。解决在IDE中尝试“重新加载项目”或“清理解决方案”。有时IDE的缓存会导致问题。问题3运行ET - Refresh后我的插件代码没有被关联到程序集。检查packagegit.json文件格式是否正确Id和GitDependencies是否填写无误。检查插件包的Scripts目录结构是否符合ET规范Model, Hotfix等子目录。解决查看Unity Console是否有相关错误日志。确保主项目的几个核心程序集Model, Hotfix等存在且名称正确。问题4编译错误提示找不到依赖的包中的类型。检查依赖包的.asmdef文件是否已经正确创建并且其程序集名称是否被正确引用。检查在依赖包的.asmdef设置中是否在Assembly Definition References里添加了被依赖的程序集。解决确保所有相关包都已成功链接并导入。有时需要手动点击Package Manager中对应包的“Update”或“Reinstall”。掌握Unity Package的本地链接本质上是掌握了ET框架插件开发的“呼吸节奏”。它让开发过程从笨重的“批处理”变成了轻盈的“实时交互”。当你能够随心所欲地在本地编写、调试、验证你的ET插件并丝滑地将其集成到主项目甚至发布到团队仓库时你才能真正体会到模块化开发带来的自由与高效。这套流程初期配置略显繁琐但一旦跑通它将为你的后续开发节省海量时间。记住关键点在于路径配置、packagegit.json的理解以及ET工具链命令的恰当使用。多踩几次坑这些配置就会变成你的肌肉记忆。