小屋創作

日誌2020-12-30 17:11

【專案】ACG Baha2021 - 技術總結

作者:樂小呈


這是ACG Baha2021 project專案紀錄第100篇
整理了一些專案裡程式用到的技術,分享一下自己的作法
不會像教學一樣解釋到那麼細,只是提供一個思路而已

> 玩家角色腳本的分工結構
事件系統觀察者模式,讓程式的連接變單向的
這樣核心腳本就不需要知道有哪些次要腳本在運作,而且就算關閉次要的腳本,核心還是可以正常運作

分工主要分成四種部分
核心腳本 角色動作 PlayerCharater
        使用狀態機的結構執行動作,並在狀態執行和狀態切換時調用事件
        public Action<CharaterState, CharaterState> OnStateChangeEvent;
        public Action<CharaterState, float> OnStateEvent;
    玩家狀態 PlayerStatus
        玩家的狀態資訊,並在角色動作觸發擊中事件的時候輸出傷害
    角色動畫 CharaterAnimation
        根據角色動作觸發事件時傳遞的資料,判斷要撥放的是哪個動畫
        因為我們使用Spine動畫,所以沒有用到Unity Animator
    角色特效 CharaterVisualEffect
        根據角色動作觸發事件時傳遞的資料,判斷要使用甚麼特效

一開始專案的時後全部都寫進一個腳本,稍微動到一點就容易連帶到其他地方出錯
如果功能開始多了就應該拆成不同腳本,分工清楚的話個別的功能要修改就會變得更容易


> 玩家動作 PlayerCharater
為了讓玩家動起來流暢,也花了不少時間研究
玩家的動作是透過狀態機控制的,大概有六種State
(Launching, Falling, Charging, Diving, Failing, Rising)
動作是根據當前狀態的持續時間(t)和上下範圍,用Lerp計算的,有稍微加一點ease(t)

但就算有緩動,整體移動看起來還是很機械
所以我用 lerp(current, next) 讓移動更流暢,然後再加了不少緩衝和過度的State
整體感覺舒服多了,對比一下差距真的很大
但缺點就是實際的速度變不好控制,但應該不會有太大誤差


> 裝備系統的條件效果 EquipConditionAction
條件效果 Condition & Action
把條件和效果分開來寫,就不需要重複寫一樣的效果或判斷,用組合的編輯起來也比較輕鬆
條件: 當玩家攻擊敵人、當玩家觸發晶片
效果: 觸發爆炸、獲得速度、啟用護盾

組合條件和效果的方式是在遊戲一開始時會讀取資料
先把效果包進一個Action裡,再把它傳進條件判斷,當條件達成時就直接Invoke效果事件

第一次這樣嘗試,花了一些時間研究出的作法
但是一個等級只能有一種效果,而且一些改動數值的效果也做不到,所以捨棄了一些設計


> 裝備系統的數據傳遞 GamePlayValuer
第一次嘗試處理那麼多的數值運算,我的作法是再遊戲開始時先把所有數值傳進一個腳本裡
每個特定的值都有一個自己的計算器,記錄所有傳進去的計算資料 (加減、比例、指定)
最後根據基礎值完成計算再發出給需要的對象使用

缺點蠻明顯的,就是只能計算一次,之後有需要要再研究不同做法


> 敵人資料的儲存方式 EnemyData
第一次使用 ScriptalbeObject儲存資料
然後把敵人行為模組化,移動、行動、死亡,這樣就可以讓同種類的敵人共用相同的行為
雖然沒有寫得很好,但也比每個敵人重新設置一次輕鬆的多

我花最多時間搞的是移動路徑,因為計算是寫在ScriptableObject裡的,所以數值儲存和傳遞是一大難題,也不能用全域變量存,因為參考是共用的
最後的解決方法是回傳移動值,用ref 傳其他參考資料
不過這種作法也只適合簡單的移動模式,比較複雜的菁英怪就不能用了,又是一大難題
     
然後還搞了自訂編輯器


> 粒子系統的物件池 VisualEffectObjectPools
之前在想怎麼做粒子系統的物件池,但是Particle沒辦法像我其他地方一樣只改數據共用物件
所以我換了作法,透過 ScriptalboObject 儲存物件池資料,但實體是在遊戲一開始就生好的
生的時候讓在資料夾裡的 ScriptableObject 儲存物件池的Index,這樣運作時要取出粒子就不需要把整個池掃一次

然後我用了一種特殊的寫法,讓物件池調用比較容易,一行就能指定好所有數值
VisualEffectObjectPools.EnableVisualEffect(particle).SetPosition(position).SetDirction(dirction);
其實就只需要return this 而已,這種寫法好像有名子...但我忘了
誰記得的麻煩告訴我一下 :P

這東西再調整一下就可以輸出給其他專案用ㄌ


> 實作介面 Interface
也是第一次用C#的介面功能,蠻方便的,主要是希望對像有特定功能的時候可以用
IHealthStatus、IHealthSystem、IPushinderation
直接參考我之前的筆記八,使用 Interface 實作血量系統
https://home.gamer.com.tw/creationDetail.php?sn=4939998


第一次把專案做到這麼大
一堆功能都是第一次做,每個都改了又改,重構再重購
沒用到什麼插件,幾乎所有功能都自己寫的,所以也學到很多
專案也快進入尾聲了,接下來也繼續加油吧~


25

11

LINE 分享

相關創作

20240504 遊戲製作進度 「我現在要幹嘛?」

《Pintaris》 自製遊戲介紹

肥宅的C#學習紀錄:第一個沒解決成功也沒能解決的BUG

留言

開啟 APP

face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】