本文将对Unity内非自定义的目录用途,实践进行总结

1.Assets
用于存储项目中的各种资产。这是项目的核心,几乎所有资源,如模型、纹理、脚本等都存放在此处。
2.Library (不加入版控)
此文件夹用于存储项目内部资产的数据信息。它通常占用较大的空间,主要由Unity内部使用。在合作开发或编辑器出现问题时,清理该文件夹并重新生成,可能有助于解决某些由缓存引起的问题。若无法打开Unity工程或出现错误,尝试删除Library文件夹并重新生成也是一个解决方法。
3.Temp和Logs (不加入版控):
在Unity编辑器打开项目时使用,用于存储临时数据和项目的日志信息(不包含编辑器日志)。这些内容无需代码托管,并且在关闭编辑器后,临时数据将被删除.
4.Packages
用于存储项目的包文件信息。此外,Library下的PackageCache文件夹用于缓存这些包文件。
5.Project Settings和UserSettings
包含项目的各种设置信息和用户自定义的设置信息
下面都是Assets下的目录
6.Resources
功能:为了支持在脚本中获取通过资源文件创建的对象,如类型(自定义的ScriptableObject/Font/TMP_FontAsset/Material/)。脚本获取到对象后常用于组件赋值。
为此,应将资源放在一个名为 Resources 的目录或子目录中。通过使用 Resources.Load 函数即可加载这些资源。可在 Assets 文件夹中的任何位置添加多个 Resources 文件夹。eg:
cs
using System.Collections;
using System.Collections.Generic;
using DesignPatterns.UI;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace DesignPatterns
{
public class SpeFdrDemo : MonoBehaviour
{
private TextMeshProUGUI _TMP;
public Image imgStar;
void Start()
{
_TMP = GetComponent<TextMeshProUGUI>();
//Resources.Load泛型
_TMP.font = Resources.Load<TMP_FontAsset>("Fonts & Materials/Anton SDF");
_TMP.fontSharedMaterial = Resources.Load<Material>("Fonts & Materials/Anton SDF - Drop Shadow");
//Resources.Load非泛型
imgStar.sprite = Resources.Load("WhiteStar",typeof(Sprite)) as Sprite;
//Resources.LoadAll加载目录下T类型所有资源
NavigationButtonSO[] soNB = Resources.LoadAll<NavigationButtonSO>("ButtonData/MainMenu");
Debug.Log(_TMP.font.name);
Debug.Log(_TMP.fontSharedMaterial.name);
Debug.Log(imgStar.sprite.name);
foreach(var v in soNB)
{
Debug.Log(v.name);
}
}
}
}



7.StreamingAssets
用于将目录内文件原封不动地(比如.cs和.dll不会被编译)打包到游戏中,适合存放配置文件、视频等无需Unity额外处理的资源。必须放在Assets下且只能有一个。必须通过Application.streamingAssetsPath来访问该目录,不同平台下目录不一样,它总是指向运行平台上的正确位置,eg:
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
namespace DesignPatterns
{
public class SADemo : MonoBehaviour
{
IEnumerator Start()
{
// 1. 构建文件路径:这是跨平台兼容的第一步
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "config.json");
// 2. 关键步骤:将路径转换为Uri
// 这一步至关重要!它能正确处理所有平台(尤其是Android的jar:file://)的路径格式。
string uri = new System.Uri(filePath).AbsoluteUri;
// 3. 创建UnityWebRequest
using (UnityWebRequest request = UnityWebRequest.Get(uri))
{
// 4. 发送请求并等待
yield return request.SendWebRequest();
// 5. 处理结果
#if UNITY_2020_1_OR_NEWER
if (request.result == UnityWebRequest.Result.Success)
#else
if (!request.isNetworkError && !request.isHttpError)
#endif
{
// 成功:获取文本内容
string jsonText = request.downloadHandler.text;
Debug.Log("加载成功: " + jsonText);
// 这里可以进一步解析JSON,比如使用JsonUtility
// YourConfigClass config = JsonUtility.FromJson<YourConfigClass>(jsonText);
}
else
{
// 失败:输出错误信息
Debug.LogError($"加载失败: {request.error}, URI: {uri}");
}
}
}
}
}


windows平台构建后的目录如下

8.Editor
Editor目录用于存放用于编辑器扩展的脚本和资源,可以有多个Editor目录在任意位置(和Resources目录一样)。Editor内的脚本和资源不会参与打包。
这里重点要理解的是编辑器扩展脚本开发时无论放在Editor与否都能正常执行,但是若不放在Editor内,打包时会报错。
为什么在编辑器中能运行?
Unity编辑器本身就是一个完整的开发环境,它加载了完整的Unity引擎和编辑器相关的程序集(UnityEditor.dll)。因此,无论脚本放在哪,只要在编辑器里运行,都能找到 UnityEditor 下的类,故代码能正常工作。
为什么必须放在"Editor"文件夹?
打包时 ,当尝试将项目构建为独立的应用程序(如exe、apk)时,Unity的构建系统会执行一个关键的步骤:只复制运行游戏所必需的代码和资源 。
-
打包时会发生什么?
构建系统会完全排除编辑器专属的
UnityEditor.dll程序集。此时,如果任何一个非"Editor"文件夹下的脚本中包含了对UnityEditor的引用,编译器就会因为找不到这个程序集而报错,导致打包失败 。 -
"Editor"文件夹的作用
将包含
UnityEditor的脚本放入名为"Editor"的文件夹(或其子文件夹)中,就是告诉Unity构建系统:"这是一个编辑器脚本,请将它排除在最终的游戏发布包之外。",从而使编辑器代码不会混入运行时程序集中
接下来通过一个例子对上面结论进行验证:
下面是一个编辑器扩展脚本,将其放在Editor目录下,其功能是选中一个文件
cs
using UnityEditor;
namespace DEMO.Scripts.Editor
{
public static class EditorMenu
{
[MenuItem("Sel/MazerFloor")]
public static void CTool()
{
Selection.activeObject = AssetDatabase.LoadMainAssetAtPath("Assets/UnityTechnologies/_DesignPatterns/1_Factory/Materials/MazerFloor.mat");
}
}
}
演示效果:

打包成功:

接下来把该脚本放在非Editor目录下
菜单功能还是可以正常执行,和上面一模一样这里就不放图了
打包报错,验证了上面的结论

9.Plugins
存放插件的核心目录,用于集成第三方代码,必须为Assets的子目录,该目录下的脚本会优先编译。比如下图是ToLua的插件目录,实测2019以后的Unity版本Plugins内的文件也可放到任意目录。

10.Standard Assets
该目录下的脚本会优先编译。用于Unity2017版本,之后不太常用。必须放在Assets下且只能有一个。
Unity2017导入以下Package时会将其放入Standard Assets目录,如下图所示


2019以后版本就没有这些Package了
