GodotEngineを使った3Dゲームの作り方メモです
・Blockbenchからキャラをインポート・ワールド作成の記事はこちら
・キャラ移動とカメラ操作の記事はこちら
今回は追加したキャラクターのモーションを再生する方法をやります
動画での解説はこちら
ここまでで作った3Dキャラクターの移動やジャンプ
がはいったプロジェクトはこちらからDLできます。
インポートした時に、自動でAnimationPlayerがついてきます。
AnimationPlayerをクリックすると
アニメーションプレイヤーが開きます。

アニメーションプレイヤーの左上にある▶マークを押すと
選択中のアニメーションが再生されます。
「A」で逆再生「D」で再生
「S」でストップ、もう一度「S」で先頭に戻る
などのショートカットでも再生できます。

モーションの一覧から、歩くモーションや待機モーションなどの
ループしてほしいアニメーションを選びましょう。
アニメーションプレイヤーの右上にある
マークをクリックすると再生モードを変更することができます。
ループが必要なアニメーションはすべて、「ループあり」にしておきましょう。

Playerノードに、「AnimationTree」を追加しましょう。

あたらしくAnimationTreeが追加できたら
インスペクターの「AnimPlayer」の項目に
PlayerのAnimationPlayerをドラッグして割り当てましょう。

これでAnimationTreeで、プレイヤーが持っているアニメーションを
使う準備ができました。
インスペクターの「TreeRoot<空>」をクリックし
新規AnimationNodeStateMachineをえらびましょう

これはUnityのアニメーションステートマシンと同じカンジですね
おそらく自動で開いていると思いますが
下の「アニメーションツリー」をクリックすると編集画面が出てきます。
インスペクターの「Active」もオンにしておきましょう。

AnimationTreeの空白部分を
「右クリック」して「BlendSpace2D」を追加します。

ブレンドスペースは
複数のアニメーションをいい感じにブレンドしてくれるものです
後で使いやすいように名前を変更しておきましょう。
ここでは「IW」(Idle・Walk)という名前にしました。

鉛筆マークをクリックして編集画面に入ります。
グラフのような画面がでてきました。
左上の鉛筆アイコンをクリックし
中心の「x0,y0」の位置をクリックしましょう。
「アニメーションの追加」から「idle」のアニメーションを選びます。

グラフの中心は移動していないときのアニメーション、ということですね
つぎに、前進と後退のアニメーションを登録しましょう。
「x0,y1」の位置にwalkのアニメーションを登録
「x0,y-1」の位置にも同じくwalkを登録します。

今回は用意していないので前進も後退も同じアニメーションですが
用意してあれば別々に指定してあげてください。
今度は左右のアニメーションも登録しましょう。
「x1,y0」の位置にRwalkのアニメーションを登録
「x-1,y0」の位置にも同じくLwalkを登録します。

全部登録できると、ひし形のような図形ができました。
まだアニメーションされませんね
左上の「ルート」をクリックして元の画面に戻りましょう。

矢印アイコンをクリックし、
「Start」から「IW」にドラッグで矢印をつけましょう。
スタートするとIWで登録したアニメーションが動くようになりました。

idleのアニメーションがついていれば成功!

グラフの画面から、ブレンド具合を確認することができます

カーソルがX0に近づくと、手足の動きも小さく
Xが1や-1に近づくと、手足の動きが大きくなることがわかりますね。
値に応じたアニメーションをさせましょう。
Playerのスクリプトを開き、メンバ変数を用意します。
@onready var anim_tree = $AnimationTree

シーンが始まると_ready関数が呼ばれて
そこで変数にオブジェクトを入れるのが普通なんですが
var anim_tree
func _ready:
anim_tree = $AnimationTree
↑ こう書くかわりに
@onready var anim_tree = $AnimationTree
これで同じ処理を行えるということです。
お手軽ですね。
オブジェクトの代入以外は@onreadyがなくてもOKです
onreadyがいるときといらないときのちがい
さらにAnimationTreeの場所を指定している
$AnimationTree の部分ですが
ノードツリーからドラッグすることでも入力でき
深い階層にあるノードを指定する時に便利です

キャラクターを動かすタイミングで
キャラがどの方向に進んだかをIWに渡します。
40~43行目を追加
これで前進・後退・左右のアニメーションが
切り替わるのが確認できると思います。


AnimationTreeをクリックして編集画面を開き
空白部分を右クリック → アニメーションを追加で
ジャンプのアニメーションを選びます。

名前をクリックして、分かりやすい名前に変更しておきましょう。
ここでは「JUMP」という名前にしました。
IWからJUMPに遷移できるようにしましょう。
矢印マークをクリックして、IWからJUMPに矢印を伸ばします。

矢印を伸ばすと、インスペクターに矢印の設定が表示されますので
「XFadeTimeを0.1」に
「Advance」の「ModeをEnabled」にします。
XFadeTimeが0だと、モーションがブレンドなしに切り替わるので
かなり不自然な動きになります。
(手をおろした状態からいきなりバンザイの状態になる)
AdvanceのModeがAutoのままだと
かってにジャンプアニメーションに遷移してしまいます。
JUMPからIWへの矢印も追加しましょう。
反対向きの矢印も同じように
「XFadeTimeを0.1」に
「Advance」の「ModeをEnabled」にします。

プレイヤーのスクリプトに戻りましょう。
プログラムの8行目でステートマシンを使えるようにしています
@onready var state_machine = $AnimationTree.get("parameters/playback")
つぎにこのstate_machineのtravelを使って
アニメーションを切り替えたいところで名前を指定します
state_machine.travel("JUMP")
再生してみると
スペースキーでジャンプしたときに、ジャンプのアニメーション
地面についた時にIWのアニメーションに戻りました

これでいちおうアニメーションは完成です!
アニメーションはほかの動きと組み合わせてブレンドしたりと
奥が深いのですが、基本的にはtravelでなんとかなるかな!と思います
・Blockbenchからキャラをインポート・ワールド作成の記事はこちら
・キャラ移動とカメラ操作の記事はこちら
今回は追加したキャラクターのモーションを再生する方法をやります
動画での解説はこちら
ここまでで作った3Dキャラクターの移動やジャンプ
がはいったプロジェクトはこちらからDLできます。
アニメーションをループさせよう
ブロックベンチであらかじめアニメーションを作っておけばインポートした時に、自動でAnimationPlayerがついてきます。
AnimationPlayerをクリックすると
アニメーションプレイヤーが開きます。

アニメーションプレイヤーの左上にある▶マークを押すと
選択中のアニメーションが再生されます。
「A」で逆再生「D」で再生
「S」でストップ、もう一度「S」で先頭に戻る
などのショートカットでも再生できます。

モーションの一覧から、歩くモーションや待機モーションなどの
ループしてほしいアニメーションを選びましょう。
アニメーションプレイヤーの右上にある
ループが必要なアニメーションはすべて、「ループあり」にしておきましょう。

アニメーションツリーを作ろう
アニメーションは登録されているだけでは再生できません。Playerノードに、「AnimationTree」を追加しましょう。

あたらしくAnimationTreeが追加できたら
インスペクターの「AnimPlayer」の項目に
PlayerのAnimationPlayerをドラッグして割り当てましょう。

これでAnimationTreeで、プレイヤーが持っているアニメーションを
使う準備ができました。
インスペクターの「TreeRoot<空>」をクリックし
新規AnimationNodeStateMachineをえらびましょう

これはUnityのアニメーションステートマシンと同じカンジですね
おそらく自動で開いていると思いますが
下の「アニメーションツリー」をクリックすると編集画面が出てきます。
インスペクターの「Active」もオンにしておきましょう。

AnimationTreeの空白部分を
「右クリック」して「BlendSpace2D」を追加します。

ブレンドスペースは
複数のアニメーションをいい感じにブレンドしてくれるものです
後で使いやすいように名前を変更しておきましょう。
ここでは「IW」(Idle・Walk)という名前にしました。

鉛筆マークをクリックして編集画面に入ります。
グラフのような画面がでてきました。
左上の鉛筆アイコンをクリックし
中心の「x0,y0」の位置をクリックしましょう。
「アニメーションの追加」から「idle」のアニメーションを選びます。

グラフの中心は移動していないときのアニメーション、ということですね
つぎに、前進と後退のアニメーションを登録しましょう。
「x0,y1」の位置にwalkのアニメーションを登録
「x0,y-1」の位置にも同じくwalkを登録します。

今回は用意していないので前進も後退も同じアニメーションですが
用意してあれば別々に指定してあげてください。
今度は左右のアニメーションも登録しましょう。
「x1,y0」の位置にRwalkのアニメーションを登録
「x-1,y0」の位置にも同じくLwalkを登録します。

全部登録できると、ひし形のような図形ができました。
まだアニメーションされませんね
左上の「ルート」をクリックして元の画面に戻りましょう。

矢印アイコンをクリックし、
「Start」から「IW」にドラッグで矢印をつけましょう。
スタートするとIWで登録したアニメーションが動くようになりました。

idleのアニメーションがついていれば成功!

グラフの画面から、ブレンド具合を確認することができます

カーソルがX0に近づくと、手足の動きも小さく
Xが1や-1に近づくと、手足の動きが大きくなることがわかりますね。
プログラムからスピードに応じたアニメーションをさせよう
今のままではidleのアニメーションのままなので値に応じたアニメーションをさせましょう。
Playerのスクリプトを開き、メンバ変数を用意します。
@onready var anim_tree = $AnimationTree

シーンが始まると_ready関数が呼ばれて
そこで変数にオブジェクトを入れるのが普通なんですが
var anim_tree
func _ready:
anim_tree = $AnimationTree
↑ こう書くかわりに
@onready var anim_tree = $AnimationTree
これで同じ処理を行えるということです。
お手軽ですね。
オブジェクトの代入以外は@onreadyがなくてもOKです
onreadyがいるときといらないときのちがい
さらにAnimationTreeの場所を指定している
$AnimationTree の部分ですが
ノードツリーからドラッグすることでも入力でき
深い階層にあるノードを指定する時に便利です

キャラクターを動かすタイミングで
キャラがどの方向に進んだかをIWに渡します。
40~43行目を追加
これで前進・後退・左右のアニメーションが
切り替わるのが確認できると思います。


ジャンプのアニメーションを追加しよう
ジャンプモーション入れるために、ステートマシンに戻りましょう。AnimationTreeをクリックして編集画面を開き
空白部分を右クリック → アニメーションを追加で
ジャンプのアニメーションを選びます。

名前をクリックして、分かりやすい名前に変更しておきましょう。
ここでは「JUMP」という名前にしました。
IWからJUMPに遷移できるようにしましょう。
矢印マークをクリックして、IWからJUMPに矢印を伸ばします。

矢印を伸ばすと、インスペクターに矢印の設定が表示されますので
「XFadeTimeを0.1」に
「Advance」の「ModeをEnabled」にします。
XFadeTimeが0だと、モーションがブレンドなしに切り替わるので
かなり不自然な動きになります。
(手をおろした状態からいきなりバンザイの状態になる)
AdvanceのModeがAutoのままだと
かってにジャンプアニメーションに遷移してしまいます。
JUMPからIWへの矢印も追加しましょう。
反対向きの矢印も同じように
「XFadeTimeを0.1」に
「Advance」の「ModeをEnabled」にします。

プレイヤーのスクリプトに戻りましょう。
プログラムの8行目でステートマシンを使えるようにしています
@onready var state_machine = $AnimationTree.get("parameters/playback")
つぎにこのstate_machineのtravelを使って
アニメーションを切り替えたいところで名前を指定します
state_machine.travel("JUMP")
再生してみると
スペースキーでジャンプしたときに、ジャンプのアニメーション
地面についた時にIWのアニメーションに戻りました

これでいちおうアニメーションは完成です!
アニメーションはほかの動きと組み合わせてブレンドしたりと
奥が深いのですが、基本的にはtravelでなんとかなるかな!と思います
コメント