☰
Unity 特殊文件夹完全指南:Editor、Resources、StreamingAssets 等 6 类目录的手游开发实战(Unity3DTraining 仓库视角)
2026/9/25 11:58:07 网站建设 项目流程
  • 示例工程

【免费下载链接】Unity3DTraining

【Unity杂货铺】unity大杂烩~

项目地址:https://gitcode.com/gh_mirrors/un/Unity3DTraining
点击查看免费下载

本文基于仓库 Doc/Unity手游开发中所有特殊的文件夹.md 整理而成,系统讲解 Unity 手游开发中六类特殊文件夹——Editor、Editor Default Resources、Gizmos、Plugins、Resources、StreamingAssets 的作用、打包行为、加载 API 与适用场景,并结合本仓库 HotUpdate 下的 AssetBundle 工程源码,展示 StreamingAssets 在资源热更新中的真实落地方式。读完本文,你将能够正确规划 Unity 工程的目录结构,判断哪类资源该放哪个特殊文件夹,并掌握Resources.Load、AssetDatabase、Application.streamingAssetsPath等 API 的精确使用边界。


1. Editor 文件夹:只属于编辑器、绝不进包的代码与资源

特性总结:

  • 位置灵活:Editor文件夹既可以放在工程根目录(Assets/Editor),也可以放在任意子目录(如Assets/xxx/Editor、Assets/Scripts/Editor),只要文件夹名字叫Editor即可,多个Editor文件夹可以共存,效果等同。
  • 不进发布包:Editor文件夹下放置的所有资源文件与脚本文件都不会被打进最终的发布包(.apk / .ipa / 可执行文件)。
  • 仅编辑期可用:其中的脚本只能在编辑器环境下运行,不能作为运行时逻辑使用。

典型用途:把工具类脚本、编辑器扩展代码、编辑期使用的 DLL 放在这里。典型场景如技能编辑器——编辑器核心代码放Editor目录,运行时只消费编辑器生成出来的配置/数据文件,而不需要携带编辑器本体代码。

本仓库中有大量此类实践。例如 HotUpdate/AssetBundleDemo/Assets/Scripts/Editor/BundleHelper.cs 正是放在Assets/Scripts/Editor子目录下的打包工具脚本,它通过MenuItem暴露菜单,调用BuildPipeline.BuildAssetBundles将资源输出到Application.streamingAssetsPath(BundleHelper.cs#L25-L40)。这套打包代码只服务于开发期,运行时玩家根本不需要,正是Editor文件夹存在的意义。

从源码结构看,仓库中Assets/Editor一级目录的用法也一致,例如 HotUpdate/AssetBundleFramework/Assets/Editor/BuildeAssets.cs 同样是纯编辑期脚本。凡此类目录中的代码都不会进入最终包体。


2. Editor Default Resources:编辑器的默认资源仓库

注意:这个文件夹的名字中间是有空格的(Editor Default Resources),且必须放在 Project 视图的根目录下(即Assets/Editor Default Resources),不能放在任意子目录。

特性总结:

  • 存放编辑器用到的图片、文本等资源;
  • 与Editor文件夹一样不会被打进最终发布包,仅用于开发期;
  • 可以通过EditorGUIUtility.Load直接读取其中的资源,无需关心具体路径:
TextAsset text = EditorGUIUtility.Load("test.txt") as TextAsset; Debug.Log(text.text);

也就是说,编辑器扩展中常用的图标、模板文本等散碎资源,统一放进Editor Default Resources后,用EditorGUIUtility.Load按文件名即可取到。它与Editor文件夹的分工是:Editor放代码,Editor Default Resources放编辑器运行时需要的原始资源。


3. Gizmos:Scene 视图里的可视化辅助图标

Gizmos文件夹用于存放 Scene 视图中绘制的辅助图标所用图片。

核心用法一:Gizmos.DrawIcon绘制坐标图标

void OnDrawGizmos() { Gizmos.DrawIcon(transform.position, "0.png", true); }
  • 第一个参数是Vector3坐标,即图标要显示的 world 位置;
  • 第二个参数是图片名,图片必须放在Gizmos文件夹下;
  • 第三个参数true表示允许缩放。

核心用法二:Inspector 直接给单个对象设置图标

如果只想把图标挂在某个游戏对象上,无需写代码,直接在 Inspector 中设置即可:

核心用法三:OnDrawGizmos()的机制与典型场景

  • 只要脚本继承MonoBehaviour,在编辑模式下OnDrawGizmos()会每帧执行;
  • 发布后的游戏运行时不会执行,它只能用于在 Scene 视图中绘制辅助物件;
  • 典型场景:做摄像机轨迹预览,用Gizmos.DrawLine和Gizmos.DrawFrustum在 Scene 视图中画出轨迹线与视锥,方便美术和策划直观地调参,而这些辅助线完全不影响运行时表现。

4. Plugins:原生 SDK 与第三方库的安置处

做手机游戏时,Android 或 iOS 接入 SDK 的依赖库文件——.so(Android 原生库)、.jar(Android Java 库)、.a(iOS 静态库)等——放在Plugins文件夹下,打包时 Unity 会自动把这些文件打进安装包,并按照对应平台目录(如Plugins/Android、Plugins/iOS)正确归档。

这是接入渠道 SDK、广告 SDK、统计 SDK 的标准目录约定:原生代码不进托管层,但必须随包发布,Plugins正是 Unity 约定的"原生库随包"入口。


5. Resources:随包打进的运行时资源

特性总结:

  • 位置灵活:Resources文件夹可以放在根目录,也可以放在子目录(如/xxx/xxx/Resources),多个Resources文件夹可以共存。
  • 必进包体:Resources下的资源不管你是否使用,都会被打进 .apk 或 .ipa,因此它是一把双刃剑——用起来方便,但容易让包体膨胀。

三类加载 API 的边界(务必分清):

API使用时机真机可用路径要求
Resources.Load()编辑时与运行时均可是相对于Resources文件夹的路径
Resources.LoadAssetAtPath()编辑时 / 编辑器运行时否"Assets/xx/xx.xxx",须带文件后缀名
AssetDatabase.LoadAssetAtPath()仅编辑时否"Assets/xx/xx.xxx",须带文件后缀名

(原文档中写作Resource.Load,实为Resources.Load。)

实践建议:

  • 开发期(PC 上)尽量使用Resources.Load()或Resources.LoadAssetAtPath(),方便快捷;
  • 如果手机上选择"一部分资源打进 AssetBundle,一部分资源用Resources.Load()"的混合方案,那么在自动化打包时,可以在打包前用AssetDatabase.MoveAsset()把已经打成 AssetBundle 的原始文件从Resources文件夹下移动出去再打包,这样打出的运行包就不会包含多余文件;打包完成后再把移动出去的文件移回原位。这一招能在保留Resources便利性的同时,避免重复资源进包。

6. StreamingAssets:不压缩、只读的随包目录与热更新基石

特性总结:

  • StreamingAssets 下的资源会全部打包进 .apk / .ipa;
  • 与Resources的区别是:Resources会压缩文件,而 StreamingAssets 不压缩、原封不动地打包进去;
  • 它是一个只读目录:程序运行时只能读、不能写;
  • 各平台路径不同,统一用Application.streamingAssetsPath获取,Unity 会根据当前平台自动返回对应路径。

各平台路径对照(常见形态):

平台StreamingAssets 实际路径
Windows / macOS 编辑器项目目录/Assets/StreamingAssets
Androidjar:file://.../xxx.apk!/assets(压缩包内 assets)
iOS应用包内的Data/Raw目录

热更新标准做法(原文核心流程):

  1. 将一部分初始 AssetBundle放在StreamingAssets目录下,随安装包发布;
  2. 运行时把这些初始 AssetBundle 拷贝到Application.persistentDataPath目录下;
  3. 当有 AssetBundle 更新时,从服务器下载新包,覆盖persistentDataPath下对应的旧文件;
  4. 后续加载优先从persistentDataPath取最新版本,StreamingAssets仅作为首次安装的种子数据。

两个关键认知:

  • Application.persistentDataPath是应用程序的沙盒目录,打包之前这个目录是不存在的,直到应用在手机上安装完毕才被系统创建;
  • 由于 StreamingAssets 资源不压缩,会比较占空间。例如应用本体装在手机上占 100M,又在 StreamingAssets 放了 100M 的 AssetBundle,那么安装后整体占用约为 200M——规划包体时要把它计入成本。

7. 仓库源码佐证:StreamingAssets 在热更新工程中的真实用法

上述理论在本仓库的 HotUpdate 系列工程中有大量真实落地代码,可直接对照阅读。

7.1 路径常量的平台差异处理

HotUpdate/AssetBundleDemo/Assets/Scripts/AssetBundleMgr.cs#L12-L19 定义了三条路径常量,正是对"StreamingAssets 各平台路径不同"的工程化封装:

public static readonly string streamingAssetPath = Application.streamingAssetsPath; public static readonly string persistentDataPath = Application.persistentDataPath; public static readonly string wwwStreamingAssetPath = #if UNITY_ANDROID Application.streamingAssetsPath; // Android 上 streamingAssetsPath 本身就是可被 WWW 识别的路径 #else "file://" + Application.streamingAssetsPath; // 其他平台需要手动补 file:// 前缀 #endif

可见,即便在非 Android 平台,直接拿Application.streamingAssetsPath拼 WWW 地址也需要补协议头,这就是文档所说"各平台路径不同、务必用统一 API 获取"的实战含义。

7.2 从 StreamingAssets 与 persistentDataPath 双向加载

同一文件 AssetBundleMgr.cs#L67-L100 分别提供:

  • LoadFromStreamingAssetPath:从随包目录加载(同步);
  • LoadFromPersistantDataPath:从沙盒目录加载(同步);
  • 以及对应的两个异步版本,LoadAssetBundleAsync(Path.Combine(...))。

这正好对应上文"初始 bundle 放 StreamingAssets,更新后覆盖 persistentDataPath"的双目录设计。

7.3 打包输出直接指向 StreamingAssets

HotUpdate/AssetBundleDemo/Assets/Scripts/Editor/BundleHelper.cs#L25 中abOutputPath = Application.streamingAssetsPath,即打包脚本把 AssetBundle 直接输出到 StreamingAssets 目录,运行时再从这里读取初始资源。

7.4 Manifest 加载与依赖管理的固定写法

HotUpdate/AssetBundleFramework/Assets/Scripts/Manager/BundleManager.cs#L27-L28 将local_Path设为Application.streamingAssetsPath、deposit_DownFilePath设为persistentDataPath下的下载目录;BundleManager.cs#L63-L76 则展示了从StreamingAssets加载StreamingAssets(主 Manifest 的 bundle 名)并解析AssetBundleManifest、再递归加载依赖的完整链路——这是"初始 AssetBundle 放在 StreamingAssets"这一策略的标准读法。

仓库中 HotUpdate/AssetBundleDemo/Assets/StreamingAssets/ 目录下真实存放着main、start、uiloginpanel等 bundle 及对应的.manifest文件,可以直接打开验证目录结构与打包产物形态。


8. 结语:一张表记住六类特殊文件夹

文件夹位置要求是否进发布包关键 API / 特性
Editor根目录或任意子目录否仅编辑器代码 / 工具脚本 / 编辑期 DLL
Editor Default Resources仅 Project 根目录(注意空格)否EditorGUIUtility.Load
Gizmos根目录下约定位置否(仅编辑期图标)Gizmos.DrawIcon、OnDrawGizmos、Inspector Select Icon
Plugins按平台分子目录是(原生库随包).so/.jar/.a
Resources根目录或任意子目录是(无论用不用)Resources.Load(运行时);Resources.LoadAssetAtPath/AssetDatabase.LoadAssetAtPath(仅编辑期);打包前可用AssetDatabase.MoveAsset移出已打 bundle 的源文件
StreamingAssets根目录是(不压缩原样打包,只读)Application.streamingAssetsPath;与persistentDataPath配合做资源热更新

在 Doc/Unity手游开发中所有特殊的文件夹.md 原文基础上,本文结合仓库 HotUpdate 下的真实 AssetBundle 工程补全了路径平台差异、加载 API 边界、打包输出与 Manifest 依赖管理的源码级细节。规划包体与资源热更架构时,把这六类文件夹的边界吃透,可以避免"Resources 塞满导致包体膨胀""Editor 代码误进包""StreamingAssets 路径写死导致平台兼容崩溃"等经典坑。

  • 示例工程

【免费下载链接】Unity3DTraining

【Unity杂货铺】unity大杂烩~

项目地址:https://gitcode.com/gh_mirrors/un/Unity3DTraining
点击查看免费下载

相关推荐

上一篇:PDF补丁丁使用指南:如何免费编辑书签、合并拆分PDF文档
下一篇:Apex Legends压枪宏终极指南:如何轻松实现零后坐力射击

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询