Brief Summary of GDQuest 3D Mannequin Project w/o Camera Rig 隨手寫的讀書報告

Structure

GDQuest 的 Mannequin Project 裏,在不談 Camera Rig 的情況下,只有三個主要的 Scene。

  1. Mannequincy Scene (Skin Scene)
    • Direct Import from *.gld file
    • Playback the animation at fixed position
    • Maintain animation state machine using AnimationTree
  2. Player Scene
    • Include Mannequincy scene
    • Collision Detection
    • Change the position in the 3D world
    • Maintain state machine for
      • Change skin animation in enter func in state script
      • Get input event
      • Change position
  3. Game Scene
    • Player
    • Camera
    • Environment light
    • Level (Static Body)

Mannequincy Scene

  1. 建立 AnimationPlayer,與 AnimationTree。
  2. 從 AnimationTree 裡面可以取得 playback 物件。
  3. Script 中的 move_direction 是為了指定行走得 animation blend 數值,可以做出介於 walk & run 的動畫效果。

容易出錯的地方

  1. AnimationPlayer
    • 要把 Process Mode 改成 Physics,這樣每個 Physics Process 才都會更新。
    • 大部分的 Animation 都要改成 loop
  2. AnimationTree
    • 要把 Process Mode 改成 Physics,這樣每個 Physics Process 才都會更新。
    • 在 State Machine 視覺圖中,要設定某個 node 為 start node。
    • 使用前要將 AniationTree.active 改成 true (programatically or in node property)

Player Scene

State Machine 只是個 State 的容器,一次可以指定一個 State 與呼叫 method。轉換 State 的工作是 State 自己完成的。

第一層的 Move State 負責變換 Position,Move State 下的 Sub-state 會呼叫 Move State 並負責更改 skin animation,是繼承的概念。繼承關係是:

State (Virtual Class) – PlayerState (只是放 Skin 和 Player reference 用的) – Move State (input event, 計算與改變位置) – Air/Run/Idle Substate (呼叫 animation tree in skin)

容易出錯的地方

  1. gld 座標和 GLES 座標對 “正面” 的概念相反,記得將 Player -> Mannequincy 轉 180 度。
  2. 更改物件的位置和動畫要在 _physical_process() 內完成,而不是 _process()。
  3. dictionay 有個有趣的語法 { my_var = my_var } 和  { ‘my_var’ = my_var } 好像是一樣的?

Game Scene

Collision Layer and Mask

  1. 每個會被其他物件碰撞或是會碰撞其他物件都有自己的 Layer。
  2. 需要在其他物件碰撞到自己時,有 signal / callback / reaction 的,需要將 mask 勾選那個物件的 Layer。

Project 中,Player 是 Layer 1,地板 (Level) 和司令台是 Layer 2。為了讓 Player 不會從地板掉下去,也為了能站上/撞到司令台,Player’s collision mask 要設定為 Mask 2,也就是地板和司令台的 Layer bit。

但反之我們的地板和司令台是不動的 StaticBody,不需要知道使用者有沒有碰撞,所以完全不需要設定 mask,將不必要的 mask bit 清空,可以減少碰撞偵測總數並增加效能,是重要的好習慣。