前往
大廳
主題

【Godot 筆記】FINITE STATE MACHINE IN GODOT

Muryan | 2023-04-29 22:00:11 | 巴幣 0 | 人氣 276

學習後的一點小紀錄,希望留下些東西在腦子。
未來回來也能當作複習。

另外這篇範例是以 Godot 為主。


Finite State Machine 是什麼?
這裡首先就要從我們遇到的問題開始。

想像我們在製作一款平台跳躍遊戲,例如《瑪利歐》。
玩家操控的角色基本上的動作有移動( Run )和跳躍( Jump ),還有可能會被忽略的待機( Idle )。

示意圖

因為很簡單,我們就把程式碼都塞在 _physics_process( ) 裡面。
現在這樣看起來還不算太複雜。



接著團隊討論後,為了內容豐富一點想要加入在空中滑翔的動作。
在空中掉落速度會比較慢,而且不能馬上轉向。
滑翔途中按跳躍可以取消。

那再來看一下程式碼會變成怎麼樣。
可以看到內容變得更複雜了。



未來或許還想要增加衝刺、攀爬等動作的時候,
這樣正面硬上除了有閱讀上的困難,也容易漏掉東西造成 BUG。


State Variable

比較簡單的改進方法。
設狀態 ( State ) 變數,裡面裝了 { ON_GROUND, IN_AIR, GLIDING }
方便我們追蹤角色的狀態,閱讀上會比較輕鬆。

範例在參考來源裡面,就不另外截圖了。


State Pattern

目的是要把每個狀態分成單獨的物件。
然後利用 state machine 追蹤角色現在的狀態,以及決定轉移到哪個狀態。
就像控制中心一樣。

因為每個狀態都變獨立物件了,
  • 所以只讀取自己需要的變數,減少不小心動到其他狀態變數的機率。
  • debug 的時候比較方便。
現在又回到上面的例子,這時候我們最主要需要兩樣東西。
  • StateMachine :處理切換狀態的控制中心。
  • State :狀態的範本

例子

在我們開始設計 State 前,可以先把可能的情況做分類。

例如:
Idle -> Run:從停止狀態開始移動
Run -> Air:從移動狀態離開地板到空中,例如跳躍或是落下
Air -> Run:落地時在移動
Air -> Idle:落地後什麼動作都沒有

接著就是實際運用的範例了。

State

可以看到 function 裡面都是空白沒內容,之後讓每個 State 覆蓋利用的。
像是填空題一樣,這個題目你希望現在的 State 怎麼動作。


StateMachine

簡單紀錄我可能忘的地方
yield( owner, "ready" )
等到 StateMachine 底下的 child 都執行完 _ready( ) 後再繼續跑下去。
func _process( ) 和 _physics_process( )
執行現在 State 的內容
state.exit( )
離開現在的 State
state = get_node(target_state_name)
設定新的 State
state.enter(msg)
進入新的 State


原文章裡有 IdleRunAir State的範例。
這裡簡單放了 Idle 的。


可以看到在 update( ) 裡面寫了判斷什麼時候用 transition_to( )。
  • 角色不在地板上就轉到 Air State。
  • 有按左右鍵移動就轉到 Run State。
因為拆成單個單個的 Script,
程式碼長度相較原版都放一起就能比較短,閱讀上可以比較輕鬆。

最後提供他放在 GitHub 寫好的範例
需要用 Godot 執行。

創作回應

追蹤 創作集

作者相關創作

相關創作

更多創作