Unity學(xué)習(xí)記錄/ #3 ScriptableObject
//
????本專欄為本人對(duì)ScriptableObject的學(xué)習(xí)記錄,歡迎分享學(xué)習(xí)經(jīng)驗(yàn)和指出本文的錯(cuò)誤之處。
//
????讓我們來試著想象一下,當(dāng)我們想要做一款經(jīng)典RPG模式的游戲(像勇者斗惡龍,最終幻想)的時(shí)候,我們需要在這個(gè)架空世界里加入玩家、怪物、NPC、道具、貨物、任務(wù)等等,玩家擁有各種各樣的屬性和技能(如攻擊力ATK,防御力DEF等等),而怪物我們又能細(xì)分成很多不同的種類,不同種類下又能有多種怪物,它們各有各不同的數(shù)據(jù)。在一般情況下,我們通常會(huì)使用繼承的方式來寫這些數(shù)據(jù)腳本,但這樣我們每次生成一個(gè)怪物的時(shí)候,都會(huì)實(shí)例化一次,Unity中有沒有東西是專門用來處理數(shù)據(jù)的呢。那么我們這次的主角,ScriptableObject就該登場(chǎng)了。
一、介紹
????ScriptableObject(以下簡(jiǎn)稱SO),中文翻譯為腳本化對(duì)象,它不是一種Unity組件,而是一個(gè)類。在Unity官方文檔中是這樣介紹的:“ScriptableObject 是一個(gè)可獨(dú)立于類實(shí)例來保存大量數(shù)據(jù)的數(shù)據(jù)容器。ScriptableObject 的一個(gè)主要用例是通過避免重復(fù)值來減少項(xiàng)目的內(nèi)存使用量?!迸叮∷强梢杂糜诖鎯?chǔ)數(shù)據(jù)的。

????當(dāng)我們?cè)陧?xiàng)目中可以熟練運(yùn)用SO的時(shí)候,這將對(duì)整個(gè)開發(fā)的過程是非常有幫助的。當(dāng)策劃規(guī)劃好了項(xiàng)目流程和數(shù)據(jù),美術(shù)準(zhǔn)備好了眾多精美的美術(shù)素材,想要將它們放進(jìn)游戲中,倘若他們看不懂要將數(shù)據(jù)和素材添加到哪個(gè)物體上的哪個(gè)腳本,將是非常讓人頭疼的。SO就可以完美解決這種狀況,策劃和美術(shù)只需要在游戲數(shù)據(jù)文件中添加即可(前提你所寫的SO非常清楚明了)。從某種意義上來說,SO的功能也就是一個(gè)策劃表,記錄和展現(xiàn)游戲中的數(shù)據(jù)給項(xiàng)目的每個(gè)人看。

二、我們的第一個(gè)SO!
????快來動(dòng)手寫出我們的第一個(gè)SO腳本吧,這并不是一個(gè)非常困難的事情,SO腳本其實(shí)很簡(jiǎn)單。
????首先新建一個(gè)腳本文件名為PlayerData_SO,并讓該類繼承SriptableObject類,正是因?yàn)槔^承了SO類,該腳本并不能掛載到物體上,但我們可以在其中寫入數(shù)據(jù),Unity編輯器會(huì)將其寫入硬盤中持久化數(shù)據(jù)。


????為了能夠在該SO腳本中編輯數(shù)據(jù),我們需要給它添加一個(gè)CreateAssetMenu屬性。

????這個(gè)CreateAssetMenu屬性允許我們?cè)贏sset菜單的 Data/?PlayerData_SO下,新建一個(gè)SO文件默認(rèn)名為“PlayerData_SO”,你可以看到因?yàn)槲覀冊(cè)赟O腳本中什么都還沒寫,所以該文件創(chuàng)建后是空的內(nèi)容。

????????讓我們來為這個(gè)玩家角色寫入數(shù)據(jù)。新建一個(gè)角色,他可能需要名字、年齡、性別、攻擊力、防御力、甚至是立繪等等屬性。SO腳本中可以存儲(chǔ)非常多種的數(shù)據(jù)類型,此外可以是GameObject、Vector、Audioclip、List、甚至是你所創(chuàng)建的類等等,非常的人性化。

????值得注意的是,當(dāng)我們使用創(chuàng)建新類的數(shù)據(jù)時(shí),要給新的類加上System.Serializable屬性,也就是序列化(關(guān)于序列化就不過多介紹),這樣子我們才能在項(xiàng)目面板上它的內(nèi)容。

????重新打開我們新建的數(shù)據(jù)文件,在右側(cè)面板中就可以看見具體的內(nèi)容,并對(duì)其進(jìn)行修改。

三、使用我們的SO數(shù)據(jù)
????在我們創(chuàng)建好了一個(gè)玩家應(yīng)有的數(shù)據(jù)之后,我們就可以在具體的PlayerControl腳本(也就是玩家控制腳本)中使用它了。具體的做法是,在PlayerControl腳本中聲明一個(gè)PlayerData_SO變量,訪問類型是public,將腳本掛載到玩家對(duì)象身上后,將所需的數(shù)據(jù)文件拖給它,這樣我們的玩家控制腳本就能訪問到策劃和美術(shù)所設(shè)置的玩家數(shù)據(jù),也不會(huì)出現(xiàn)混亂和意外修改。


????并且,SO文件的數(shù)據(jù)是持久化的,也就是我們對(duì)數(shù)據(jù)所做出的修改是會(huì)被保存下來并存進(jìn)硬盤中的。優(yōu)秀的設(shè)計(jì)模式會(huì)將數(shù)據(jù)分為不可變數(shù)據(jù)和可變數(shù)據(jù),前者主要用于配置數(shù)據(jù),也就是我們所說的策劃表,例如存儲(chǔ)人物的名字、物品的名字等等;后者則是玩家自己的數(shù)據(jù),它會(huì)隨著玩家對(duì)游戲進(jìn)度的推進(jìn)而改變,如等級(jí)、攻擊力、防御力等等。這兩者獨(dú)立開來進(jìn)行編寫,就可以防止出錯(cuò)。
四、強(qiáng)大的SO!
????SO只有上面所展現(xiàn)的這些作用嗎?當(dāng)然永不止這點(diǎn)!正如最開始所說的SO的功能非常強(qiáng)大,它可以幫助到我們非常多,保存玩家設(shè)置偏好、游戲場(chǎng)景加載、腳本繪制場(chǎng)景等等。甚至有大佬利用SO來替代單例模式,避免了單例模式的使用(單例模式是一種編程設(shè)計(jì)模式,有用但并不提倡頻繁使用)。所以在你學(xué)習(xí)Unity的過程中,SO是必不可少的工具,掌握并熟練使用它可以讓你受益很多!我推薦你認(rèn)真學(xué)習(xí)好SO,并將它用到你的項(xiàng)目中去。
本期推薦學(xué)習(xí)教程:
1、https://www.bilibili.com/video/BV1X84y1F7aY?share_source=copy_web
(依舊是麥扣老師的強(qiáng)大系列教程?。?/p>
2、https://www.bilibili.com/video/BV1k54y1r78X?share_source=copy_web
(咖喱飯老師的很多視頻都有用到SO)
3、https://www.bilibili.com/video/BV1GY41137m8?share_source=copy_web
(SO與有限狀態(tài)機(jī)的結(jié)合,我猜你會(huì)感興趣的)