Godot キャラコン 18 「dae の import とanimation あれこれ」 4/6
だんだんメンドクサくなってきたが、今回は「AnimationPlayer」ノードを利用したdaeアニメーションを実施する。[ゲーム再生]で、アイドルアニメーションがループ再生され、キーを押している間はウォークアニメーションになる。キーを離すとまたアイドルアニメに戻る。こんな単純な仕組みを作る。
シーンを2つ用意
[1]
daeボディー("BodyF02.dae")を [New Inherited] で開いて新規シーンを作成し、適当な名前で保存する。(やり方を忘れてたらキャラコンの15参照。)
[2]
メインシーンを作る。「Node」ノードをルートにし、「Camera」ノードと [1] で作ったシーンを追加。メインシーン([ゲーム再生] で最初に映る画面)として設定しておく。ま、しなくてもいいけど、間違ってdaeの方のシーンを選択したまま [シーン再生] すると、「あれっ?」ってなるかなら。
それから、シーンを追加した時に出てくるノードの「タイプと名前」は、 [1] のシーンで使っている「ルートノードのタイプと名前」。
スクリプト
メインシーンのルートノードである「Node」ノードに貼る。
L3
- daeシーンが持ってる「AnimationPlayer」ノードにアクセスできるように変数に代入。
- 「AnimationPlayer」ノードは、daeをシーンとして扱う時に自動で追加してくれている。・・・ハズ。
_ready():
関数内でやるのはメンドかったので、ここでonready var
した。get_node()
のカッコ内のストリングは、daeシーンの方のルートノード名を変えてたら変えないといけないので注意。- ただ、追加したシーンの中のノードにもこうやって入って行けるのはすごいと思う。しかも、入力支援もしてくれるし。
L4
- 現在playされているアニメの名前を入れる変数。
L5
- playして欲しいアニメの名前を入れる変数。
- [ゲーム再生] で最初からplayするのはアイドルアニメなので、"idle01"としてある。
- 今使っているdaeボディー("BodyF02.dae")は"idle01"と"walk01"のアニメが付いてるからね。(キャラコンの17)
L8~11
- デフォでマッピングしてある"ui_up"を利用した。矢印キーの上キー。
- 押してたら、再生してほしいアニメを"walk01"に、押してなかったら"idle01"にする。
L13
- 現在playされているアニメの名前を変数に入れる。
current_animation
はAnimationPlayer
クラスで定義されている変数。
- 何もplayしてない時は「空」になるというところが結構重要で、この性質を利用して同一のアニメを上手くループさせている。(L14~15)
L14~15
- "!=": "if A == B:"は「AとBが同じなら」、"if A != B:"は「AとBが同じでないなら」。"!"はNOTの意。
- 「現在playしてるアニメ」と「playして欲しいアニメ」が違ったら「playして欲しいアニメ」をplayしろって事。
- daeにつけたアニメはdaeシーン内の「AnimationPlayer」ノードで管理されている。そのアニメを再生するのが、
play()
関数。もち、これもAnimationPlayer
クラスで定義。指定したアニメを1回再生するもの。 - もし、L13~14の処理をしないと、L15で、毎フレームアニメを最初から再生してしまうので、アニメが最初のフレームから進まなくなってしまう。見た目、止まって見えてしまう。
- 上矢印キーを押してなければ、毎フレーム"anime_to_play"には"idle01"が入って来るが、"anime_current"も"idle01"であれば、"anime_to_play == anime_current"なのでアニメが最初のフレームにセットされず、先に進む事が出来る。
- 現在playしているアニメが終わった時"anime_current"が「空」になる。この瞬間に"anime_to_play != anime_current"になるので、あらたに"anime_to_play"が再生され始める事になる。簡易的ループアニメが実現している。(なかなかすごいねYouTubeの人。)
※====
先ずは、current_animation
変数と、play()
関数、これを確実に覚えよう。
それから、L13~14は変数に代入せずに、
if node_anime.current_animation != anime_to_play:
と、直接比べてもいい。
====※
確認
では、[ゲーム再生] だ。
歩く時と止まる時の切り替えが瞬間なので、スムーズではない。次回はこれを「AnimationTreePlayer」を利用する事で解決する。
コード
extends Node onready var node_anime = get_node("Scene Root/AnimationPlayer") var anime_current var anime_to_play = "idle01" func _process(delta): if Input.is_action_pressed("ui_up"): anime_to_play = "walk01" else: anime_to_play = "idle01" anime_current = node_anime.current_animation if anime_current != anime_to_play: node_anime.play(anime_to_play)