俺に解るように説明する "Godot Engine 3.x" 入門+

ゲームエンジン Godot Engine に関すること。入門とか使い方とかチュートリアルとか、あれとかこれとか。日本語解説。

Godot キャラコン 18 「dae の import とanimation あれこれ」 4/6

だんだんメンドクサくなってきたが、今回は「AnimationPlayer」ノードを利用したdaeアニメーションを実施する。[ゲーム再生]で、アイドルアニメーションがループ再生され、キーを押している間はウォークアニメーションになる。キーを離すとまたアイドルアニメに戻る。こんな単純な仕組みを作る。

f:id:ore2wakaru:20180430082240g:plain


シーンを2つ用意

[1]

daeボディー("BodyF02.dae")を [New Inherited] で開いて新規シーンを作成し、適当な名前で保存する。(やり方を忘れてたらキャラコンの15参照。)

f:id:ore2wakaru:20180430063509p:plain

[2]

メインシーンを作る。「Node」ノードをルートにし、「Camera」ノードと [1] で作ったシーンを追加。メインシーン([ゲーム再生] で最初に映る画面)として設定しておく。ま、しなくてもいいけど、間違ってdaeの方のシーンを選択したまま [シーン再生] すると、「あれっ?」ってなるかなら。

f:id:ore2wakaru:20180430065739p:plain

それから、シーンを追加した時に出てくるノードの「タイプと名前」は、 [1] のシーンで使っている「ルートノードのタイプと名前」。


スクリプト

メインシーンのルートノードである「Node」ノードに貼る。

f:id:ore2wakaru:20180430072219p:plain

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_animationAnimationPlayerクラスで定義されている変数。
    f:id:ore2wakaru:20180430075504p:plain
  • 何も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)