序言
知乎上看篇文章,講學(xué)一樣的東西有兩種入門(mén)方式,一種方式是從簡(jiǎn)單的學(xué)起,另一種方式是基礎(chǔ)的學(xué)起。所謂不管簡(jiǎn)單還是基礎(chǔ),兩個(gè)都要同樣的學(xué)。
這篇內(nèi)容介紹博主自己學(xué)到的Unity工程的目錄結(jié)構(gòu)相關(guān)內(nèi)容,最終還是以Unity的官方文檔為準(zhǔn)。當(dāng)然網(wǎng)上各類(lèi)分享很多,博主就是拋磚引玉,如果有問(wèn)題請(qǐng)隨時(shí)指正。
Unity工程的目錄介紹
這里用的Unity版本是2022.3.3f1c1,其他版本可能會(huì)稍有不同,但大體一致
首先我們創(chuàng)建一個(gè)空工程,那我們就把工程起名叫做Dummy_2022_3_3f1c1吧,創(chuàng)建完目錄下
這里Unity自動(dòng)創(chuàng)建好了需要的文件,可以觀察出工程是C#工程
.sln和.csproj是C#的項(xiàng)目配置文件,相關(guān)文檔?程序集定義 - Unity 手冊(cè)
其他目錄都是Unity約定并提前創(chuàng)建好的,相關(guān)文檔?特殊文件夾和腳本編譯順序 - Unity 手冊(cè)
在閱讀和理解這些目錄和文件的用途時(shí),請(qǐng)牢記,Unity工程中默認(rèn)情況下多數(shù)文件都是文本格式,能打開(kāi)看其中的內(nèi)容,保持對(duì)這些文件內(nèi)容的好奇心很重要。
Assets目錄
Assets目錄里放項(xiàng)目要用的資源,通常會(huì)有兩類(lèi)
- 外部創(chuàng)建好放進(jìn)來(lái)能被Unity識(shí)別的文件,比如代碼(.cs文件),比如貼圖(.png/.jpg等等),比如模型(.fbx等等)等等。
- Unity內(nèi)會(huì)創(chuàng)建的文件,比如材質(zhì)(.mat),比如配置(ScriptableObject,后綴是.asset),比如預(yù)制體(.prefab),比如場(chǎng)景(.unity)
所有在Assets下的文件和文件夾,都會(huì)由Unity生成對(duì)應(yīng)帶有meta后綴的文件,比如有個(gè)GameObject.prefab,那么Unity就會(huì)創(chuàng)建一個(gè)GameObject.prefab.meta文件,這個(gè)meta文件里存放了這個(gè)資源的全局唯一id,這個(gè)id被用于資源之間記錄引用關(guān)系。所以在Unity編輯器外,手工處理移動(dòng)文件時(shí),要確保文件和meta文件一起移動(dòng),否則資源之間的引用關(guān)系會(huì)丟失。
在Assets目錄下,還有些Unity特殊約定的目錄
Editor目錄
Unity - Manual: Special folders and script compilation order (unity3d.com)
簡(jiǎn)言之,只用在Unity編輯器的代碼要放到Editor目錄下,這些代碼在構(gòu)建游戲包時(shí)會(huì)被剔除掉,因?yàn)閁nity提供的編輯器功能只在編輯器環(huán)境用,如果一起隨著代碼構(gòu)建進(jìn)游戲包里,構(gòu)建時(shí)就直接報(bào)錯(cuò)了。
由于Editor目錄和Plugins目錄涉及程序集的概念,這里合并一起說(shuō)下
Unity會(huì)自動(dòng)把不是自定義程序集的代碼合并到最頂層的4個(gè)特殊程序集中,即
Assembly-CSharp-Editor-firstpass:處于Assets/Plugins/Editor目錄下的代碼
Assembly-CSharp-firstpass:處于Assets/Plugins,但不在Assets/Plugins/Editor下的代碼
Assembly-CSharp-Editor:處于**/Editor,但在不Assets/Plugins/下的代碼
Assembly-CSharp:上邊程序集剩下的代碼
另:上面這張圖使用Rider IDE選擇solution模式查看的結(jié)果,VSCode也是有相似的功能能看solution劃分的
工程里寫(xiě)的C#代碼當(dāng)然不是直接運(yùn)行的源代碼,而是執(zhí)行源代碼編譯后的dll
Unity的每個(gè)程序集對(duì)應(yīng)一個(gè)csproj,每個(gè)csproj對(duì)應(yīng)一個(gè)dll(動(dòng)態(tài)鏈接庫(kù))文件
編輯器環(huán)境使用的dll會(huì)生成到Library/ScriptAssemblies下,下面的截圖可以看出,左邊4個(gè)csproj,在右邊Library里都有對(duì)應(yīng)dll
Unity的4個(gè)特殊程序集Assembly-CSharp-*是Unity維護(hù)的會(huì)默認(rèn)引用其他相關(guān)程序集,同時(shí)注意用戶自定義的asmdef程序集沒(méi)法引用這4個(gè)程序集中的代碼。通常寫(xiě)代碼可以按照Unity規(guī)則不自行劃分程序集,但是隨著項(xiàng)目規(guī)模變大,不劃分程序集可能帶來(lái)諸多坑點(diǎn),舉幾個(gè)例子,代碼熱更新方案,現(xiàn)在流行的方案 介紹 | HybridCLR (code-philosophy.com)?這個(gè)方案就需要指定熱更哪些程序集,更細(xì)粒度的劃分對(duì)更可控一些。
對(duì)于自定義程序集,Unity提供了Assembly?definition功能,可以創(chuàng)建一個(gè).asmdef文件,所有.asmdef文件所在目錄文件、文件夾都會(huì)歸屬到這個(gè)asmdef中
舉個(gè)例子,先創(chuàng)建一個(gè)MyAsm.cs,看程序集劃分到了Assembly-CSharp下
那么此時(shí)在MyAsm目錄下右鍵菜單,Create=>Assmebly Definition 創(chuàng)建一個(gè)asmdef文件
這樣我們?cè)賹?duì)比看程序集之間的變化,現(xiàn)在MyAsm從Assembly-CSharp被移動(dòng)到NewAssembly中了
同時(shí)csproj也多了一個(gè)NewAssembly.csproj,dll也多了NewAssembly.dll
這樣就完成了程序集的劃分,但是還沒(méi)完,程序集劃分也是有代價(jià)的
- 一個(gè)程序集要調(diào)用另一個(gè)程序集中代碼必須配置引用,且只能單向引用,不能雙向相互引用
- 除了Unity的4個(gè)特殊程序集會(huì)自動(dòng)引用其他程序集外,自定義程序集需要手工設(shè)置引用其他程序集和引用其他dll
- 自定義程序集需要手工設(shè)置生效平臺(tái)
這里就得看程序集配置面板了,這里選幾個(gè)重要的來(lái)介紹
Plugins目錄
插件目錄,插件目錄下可以根據(jù)平臺(tái)放置其他目錄,比如Android目錄,iOS目錄等等
Resources目錄
Resources 文件夾 - Unity 手冊(cè)
這個(gè)目錄下的資源能被Unity用Resources - Unity 腳本 API方法加載,并且在構(gòu)建游戲包的時(shí)候,Resources目錄下的資源會(huì)一起構(gòu)建進(jìn)底包。注意這里是構(gòu)建進(jìn)包,所以Resources下的資源能直接進(jìn)行加載。
注意,Unit現(xiàn)在不建議使用這個(gè)目錄放太多資源
路徑要從Resources目錄下開(kāi)始寫(xiě),不用寫(xiě)文件名后綴,舉個(gè)例子
var prefab = Resources.Load<GameObject>("TestLoad/GameObject");
StreamingAssets目錄
StreamingAssets目錄里的文件會(huì)在構(gòu)建游戲包時(shí)被放入底包,注意是放入底包而不是構(gòu)建進(jìn)底包,所以不能將資源直接放進(jìn)StreamingAssets目錄,以下就是個(gè)反例,把一個(gè)預(yù)制體Prefab拖進(jìn)StreamingAssets目錄,Unity甚至都不識(shí)別:
?Unity可以用?Application-streamingAssetsPath - Unity 腳本 API 來(lái)拼接獲取路徑
比較特殊的是Android平臺(tái)的游戲包,在Android平臺(tái)下,StreamingAssets路徑是在apk文件里,不能直接用文件IO接口讀取到(簡(jiǎn)言之,apk相當(dāng)于一個(gè)zip包,想讀zip包的文件直接讀取是不行的,當(dāng)然有其他辦法),需要用WebRequest來(lái)讀取
public IEnumerator LoadStreamingAssets()
{
var streamingAssetsFilePath = Application.streamingAssetsPath + "/TestLoad/Custom.bundle";
if (Application.platform == RuntimePlatform.Android)
{
var request = UnityWebRequest.Get(streamingAssetsFilePath);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
var bytes = request.downloadedBytes;
}
}
else
{
var bytes = File.ReadAllBytes(streamingAssetsFilePath);
}
}
為了能讀取StreamingAssets下資源,通常的做法是把資源轉(zhuǎn)換成Unity的Bundle(Bundle可以認(rèn)為是把資源進(jìn)行了封裝,Unity兩種資源轉(zhuǎn)bundle方案分別是AssetBundle和AddressableBundle,這里不做展開(kāi)),再把Bundle放到StreamingAssets,這樣就是通過(guò)讀取Bundle,再加載其中的資源,比較方便的是Unity提供的接口已經(jīng)處理了讀Android包內(nèi)資源的情況,所以直接傳路徑給Unity來(lái)讀取Bundle
var streamingAssetsFilePath = Application.streamingAssetsPath + "/TestLoad/Custom.bundle";
var bundle = AssetBundle.LoadFromFile(streamingAssetsFilePath);
var prefab = bundle.LoadAsset<GameObject>("Assets/TestLoad/GameObjec");
Library目錄
Library目錄放置了Unity導(dǎo)入后的資源,打包構(gòu)建的中間文件,還有package
首先解釋下什么叫做導(dǎo)入,比如向Unity的Assets目錄里,隨便創(chuàng)建個(gè)文件夾,然后放入一張smile.png笑臉圖,那Unity之后運(yùn)行游戲時(shí),用到這張圖時(shí)是直接用這張png圖嗎?當(dāng)然不是的,Unity要把這張png圖資源轉(zhuǎn)換成某種Unity可用的文件格式并放到Library目錄,這個(gè)轉(zhuǎn)換過(guò)程就是資源的導(dǎo)入。只有被導(dǎo)入完的資源,才是能被Unity使用的資源。并且因?yàn)樽罱K的輸出平臺(tái)(Android,iOS,Win,Macos)需要的資源導(dǎo)入設(shè)置不一樣,對(duì)圖的導(dǎo)入處理也可能有不同。
Logs目錄
Unity想這個(gè)目錄寫(xiě)入一些日志,但是注意UnityEditor.log以及很多特殊的log不在這里
更具體的可以參看?Unity - Manual: Log files (unity3d.com)
Packages目錄
包管理所在目錄,Package可以理解為是一些插件或者工具包。這是Unity使用的一套方便配置和管理的目錄,通常情況下有兩個(gè)文件manifest.json和pacakges-lock.json。這套包管理器是類(lèi)似npm的結(jié)構(gòu),其中manifest.json配置了每個(gè)package的版本號(hào)信息,packages-lock.json配置實(shí)際使用的包版本
可以看到manifest.json寫(xiě)了package名和版本號(hào),package-lock.json寫(xiě)了本地工程使用的package所在倉(cāng)庫(kù)、安裝方式、依賴等信息。這種用包倉(cāng)庫(kù)配置的package安裝后會(huì)被放置到工程的Library/PackageCache目錄。
但是注意放到Library/PackageCache的package內(nèi)容是無(wú)法修改的,如果需要修改,需要使用插件或者手工的將Library/PackageCache下將要用package復(fù)制到Packages目錄,此時(shí)再回到Unity編輯器會(huì)發(fā)現(xiàn)Unity自動(dòng)把packages-lock.json里記錄的package的source:"registry"改成了source:"embeded'配置,這樣就優(yōu)先讀取Packages目錄下自行維護(hù)修改package了
ProjectSettings目錄
工程項(xiàng)目配置路徑,Unity ProjectSettings里的配置都是寫(xiě)到這個(gè)路徑下的配置文件里的
Temp目錄
臨時(shí)路徑,Unity編輯器退出時(shí)這個(gè)目錄會(huì)被刪除掉,Unity會(huì)把一些處理的中間結(jié)果放到這個(gè)路徑下,注意目錄里有個(gè)名為UnityLockfile的文件,這個(gè)是用來(lái)標(biāo)志這個(gè)Unity工程已經(jīng)被某個(gè)Unity編輯器打開(kāi)了。如果UnityLockfile在工程打開(kāi)使用中被刪了,那么Unity編輯器是能同時(shí)多次打開(kāi)同一工程的,當(dāng)然這樣做會(huì)有各種奇怪報(bào)錯(cuò)的問(wèn)題。
UserSettings目錄
通常記錄用戶配置和界面布局,這個(gè)目錄具體內(nèi)容博主也沒(méi)細(xì)看過(guò),哈哈哈
總結(jié)
以上就是Unity工程目錄的一些介紹,內(nèi)容覆蓋不全,很多更具體的文件用處Unity官方也是沒(méi)提及的,具體用處得看自行查資料摸索,未來(lái)如果博主有新發(fā)現(xiàn)也會(huì)繼續(xù)補(bǔ)充文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-790078.html
另外分享個(gè)網(wǎng)上找到的可以參考的鏈接文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-790078.html
- The Uninomicon。分享一些Unity文檔里語(yǔ)焉不詳?shù)暮诎到锹?The Uninomicon [Uninomicon]
到了這里,關(guān)于Unity的工程中文件夾介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!