Paper 2D 入門 (8) キャラクター ブループリント 4 (アニメーション ステート マシン)

ビデオの内容紹介 
まず、ジャンプのフリップブックを作ります (ビデオでは実際に作って見せてはいないのですが、この「UE4 の学び部屋」では復習の意味を込めて実際に作っていきます)。
さらに、キャラクターの動きに応じて Idle、Run、Jump のアニメーション (フリップブック) を選択するための簡単なステート マシン (状態に応じて適切なアニメーションを選択する機能) を作ります。(本格的なステートマシンについては、UE4 のドキュメンテーションである『ステートマシン』などを参考にしてください。)

なお、Zak 先生によると、今回で基本が終わったとのことです。(次回は少し細かい内容になります。)

原題 Introduction to Paper2D: Character Blueprint 4 – Animation State Machine

[1] ジャンプのフリップブックを作成する
フリップブックの作り方は、すでにPaper 2D 入門 (4) フリップブックを作るで学んでいるので、ここは復習になります。分からない考え方や用語があれば、そのページに戻ってみてください。詳しく説明されていますよ。

① まずメインエディタのコンテンツ ブラウザで Texture フォルダを開き、CharacterJumping というテクスチャがあることを確認します。
8001
ちなみに、このテクスチャをダブルクリックしてエディタを開いてみると次のようにキャラクターが一体だけしかありません (Idle と Run のテクスチャは複数のキャラクターが描かれていました)。
8008
これからスプライトを抽出するのですが、出来上がるスプライトは 1 枚だけになるはずです (Idle と Run のスプライトは複数枚出来ました)。

② この CharacterJumping を右クリックして、Extract Sprites (スプライトを抽出する) をクリックします。
8002

③ すると次のように 2 枚のスプライトができてしまいました。
8003
CharacterJumping_Sprite2 の方は不要です。エディタで開いてみてもキャラクターは含まれていません。なぜこのようなものが出来たのかは不明ですが、恐らくPaper 2D 入門 (4) フリップブックを作るで見たように、アルファの値を基にして自動的にスプライトが作成されているので、何らかの読み取り間違いがあったのかもしれません。

④ 必要な方の CharacterJumping_Sprite をつかんで Textures フォルダにドラッグアンドドロップします。
8004
その際、表示されるメニューから Move Here (ここに移動する) を選択します。
8005

⑤ Sprites フォルダを開いて、作成された CharacterJumping_Sprite の名前を分かりやすくするために Jump_1 に変更します。
8006

⑥ Jump_1 をダブルクリックしてエディタを開き、Details パネルの Pixels per unit を 1.28 にして、他のスプライトと大きさが同じになるようにします (他のスプライトも 1.28 にしてありました)。
8007

⑦ メインエディタの コンテンツ ブラウザで Flipbooks フォルダを開き、スペースで右クリックして、Animation を選択して、さらに Sprite Flipbook を選択します。
8009
8010

⑧ 新たなファイルができるので、JumpFlipbook という名前を付けます。
8011

⑨ この JumpFlipbook をダブルクリックしてエディタを開いておき、一方でコンテンツ ブラウザで Sprites フォルダを開いて Jump_1 をつかみ Sprite の欄にドラッグアンドドロップします。
8012

⑩ 以上でフリップブック作成は完了なのですが、上手く機能するか確かめてみます。前回作成したフリップブック選択のためのブループリントで、次のように RunFlipbook の代わりに JumpFlipbook を選択してみます (コンパイルを忘れずに)。
8013
プレイして A などのキーを押してみると、上手く行きました。(実際にはジャンプさせていないのですが、A キーなどで動きをもたせるとジャンプのフリップブックを選ぶようになっています。)
8014
ブループリントは元に戻しておきます。

[2] フリップブック選択のためのステートマシンを作る
前回もフリップブック (アニメーション) をキャラクターの状態に応じて選択するブループリントを作りましたが、今回は、さらに拡張性が高いステートマシンという考え方を使って同様のことをします。(ついでに、ジャンプのフリップブックも加えます。)

作業が幾分長くなるので、まず全体像から。

完成図 A
8015

完成図 B
8016

完成図 C
(完成図 B の内訳)
8017

完成図 A の意味
プレイヤーが動き関係の入力 (例: S キーを押す) をすると、UpdateAnimation というカスタムのイベントが発動します。それによって、Set IsMoving ノードが発動します。

IsMoving の Set は、作成した IsMoving (動いているか) という bool 型変数に値をセットします。その値は、GetVelocity ノード~>ノードで決まります。つまり、GetVelocity ノードで Target (この場合キャラクター自身) の速度 (Velocity、毎秒何センチ) を返します (渡します、Return します)。その速度を長さにして (Vector Length ノード)、さらにそれが 0.0 よりも大きいかどうかを判定します。大きい場合は true という値が IsMoving にセットされます (入れられます)。そうでない場合は false という値がセットされます。(このあたりのことは、Paper 2D 入門 (7) キャラクター ブループリント 3 (基本的なアニメーション操作)に詳しく説明していますので、ご参照ください。

Set IsMoving の処理が終わると、Set IsFalling ノードが発動します。これは、作成した IsFalling (落ちているか) という bool 型変数に値をセットするものです。その値は、IsFalling という関数によって決まります。この関数は、キャラクターが落下 (falling) しているかどうかを判定します。Target には、キャラクターの動きのモード全般に関わる CharacterMovement という変数が必要となります (self ではエラーになります)。また、IsFalling という関数は、キャラクターが空中にあるか否かで判断します。だからキャラクターがジャンプした直後の上昇している状態にあっても true を返します。

繰り返しになりますが、この段階で IsFalling という変数と IsMoving という変数に true か false のどちらかの値がセットされていることになります。

2 つの変数へのセットが終わると、別途作ってある Animation State Machine という関数 (後ほど触れます) を呼び出します。この入力ピンには IsFalling と IsMoving の 2 つが用意されています (自分で用意する)。それぞれに、値を供給します。そのためには、先ほど値をセットした IsFalling という変数と IsMoving という変数をつなげます。

Animation State Machine という関数は、IsFalling と IsMoving というピンに入ってくる値に基づいてそのキャラクターがどのような状態 (ステート) にあるか判断して、それに見合ったフリップブックを返すように設計されています。

Animation State Machine という関数はSet Flipbook という関数を呼び出します。SetFlipbook 関数は実際にそのフリップブックを Target にセットしますが、そのフリップブックは、Animation State Machine 関数から供給されます。この時点で、フリップブックが再生されることになります。

次に、 Animation State Machine という関数が何をするか見てみます。そのためには、完成図 C を見てください。

完成図 C の意味
(再掲 完成図 C)
8017
Animation State Machine という自作の関数が呼び出されると、まず Set IsFallingLocal が発動します。つまり、IsFallingLocal という変数に値がセットされます。その値は、先ほど見てきた完成図 A の Animation State Machine 関数の呼び出しで供給さる IsFalling 変数と IsMoving 変数の値です。それがこの Animation State Machine 関数で再度、別の変数 (IsFallingLocal という変数で、この関数内だけで有効なローカル変数) に入れられています。わざわざこのようにする必要はないのですが、さまざまな処理をこの関数の中で行う場合に IsFalling 変数をそのまま変更すると (そのようなことがあるとして)、他のブループリントでもこの変数が使われていれば、値が変更されることによって支障が出るためです。

IsFallingLocal に IsFalling の値がセットされると、次に IsMovingLocal に IsMoving の値がセットされます。

それらが終わると、いよいよキャラクターの状態 (ステート) を判定していきます (チュートリアルでは test と言っています)。まず、Branch ノードで IsFallingLocal の値が true か false かを判定します。(Branch ノードについては下の実験で詳しく調べてみます)。

sFallingLocal の値が仮に true であったとします。すると、作っておいた列挙型 (Enum) のローカル変数 AnimationState に Jumping がセットされます。

セットが終わると、ReturnNode (値を返すためのノード) が発動します。つまり、値を、呼び出し元のピン (完成図 A の Animation State Machine の呼び出しノードの OutputFlipbook ピン) に返します。値は、OutputFlipbook に接続されている Select ノードから供給されます。

Select ノードでは、Index に供給される値に応じて、その上のピンに供給されているものが Return Value となって Return Node に供給されます。つまり、この場合では、Animation State の値 (Idle、Running、Jumping) に応じて、それに対応するピン (Idle ピン、Running ピン、Jumping ピン) に接続されている変数 IdleFlipbook、RunFlipbook、JumpFlipbook) に入っている値 (フリップブックの実体である IdleFlipbook、RunFlipbook、JumpFlipbook への参照) が Return Value となって Return Node に送られます。

作成上の注意点
(1) 完成図 A の注意点
(再掲 完成図 A)
8015
前回チュートリアルと重複している部分は割愛します。
① 変数 Character Movement を表示するには、My Blueprint パネルで show inherited variables (継承されている変数を表示) にチェックを入れます。
② 変数 IsMoving は、> ノードの出力ピンを右クリックして Promote to Variable (変数に昇格させる) を選択すると、> ノードの出力ピンから出る値 (この場合 true か false) が自動的に変数にセットされるようになります。その時にできる変数に IsMoving という名前を付けます。
8022
同じように、変数 IsFalling は、IsFalling 関数の Return Value を昇格したものです。

③ 関数 Animation State Machine を作成するには、My Blueprint パネルで +f のマークをクリックします。すると自動的に Animation State Machine ウィンドウが開かれるので、そこで関数の具体的な処理を組みます。

(2) 完成図 C の注意点
(再掲 完成図 C)
8017
① 関数 Animation State Machine の IsFalling ピンと IsMoving ピンは、Details パネルの Inputs セクションで New をクリックして作ります。それぞれ bool 型にします。
8023
② 関数 Animation State Machine が返す値は、OutputFlipbook ピンから出るようにするために、Details パネルの Outputs セクションで New を押して OutputFlipbook を入れます。型は、PaperFlipbook を選択します。これによって、ReturnNode が自動的に作成されます。
8024
③ 変数 IdleFlipbook、RunFlipbook、JumpFlipbook は、My Blueprint の +V マークから作りますが、型 (Variable Type) は PaperFlipbook です。
8026
また、変数 IdleFlipbook を作る時に、Category で Animations とタイプして新たなカテゴリを作ります。RunFlipbook、JumpFlipbook も同様に Animations カテゴリを選択します。また、それぞれに Default Value (デフォルト値) を設定するために、まず Compile をクリックしてから、Details パネルの Default Value セクションで、それぞれの変数のデフォルト値にドロップダウンメニューを使って IdleFlipbook、RunFlipbook、JumpFlipbook を割り当てます。
8025
④ 変数 AnimationState の型となる Enumeration (列挙型) を作成しておきます。まず、メインエディタに戻り、コンテンツ ブラウザで Game フォルダを開き、新たなフォルダとして Data フォルダを作ります。その Data フォルダをダブルクリックして開き、右クリック メニューから Blueprint を選択、さらに Enumeration を選択します。
8027
出来たファイルに Animation State という名前を付けます。
8028
このファイルをダブルクリックして、Enumeration エディタを開きます。
8029
さらに、New をクリックして、次のように Idle、Running、Jumping とタイプしていきます。
8030
Save をクリックしてこのエディタを閉じます。(なお、列挙型については、ブループリントの基本的な構成要素⑤ 列挙型変数で詳しく紹介されていますので、ご参照ください。)

⑤ 変数 AnimationState はローカル変数なので、Local Variable のプラスマークを使って作ります。型 (Variable Type) は④で作った AnimationState 型を選択します。
8031
⑥ Select ノードを右クリックメニューから選択して、変数 AnimationState を Index につなげると、ピンの名前が AnimationState の列挙型のエントリが自動的に Select ノードの入力ピンとなって表示されます。
8032
⑦ 変数 IsFallingLocal と IsMovingLocal も、ローカル変数なので My Blueprint パネルの Local Variable のプラスマークをクリックして作成します。
⑧ AnimationState という列挙型を Set するには、通常通り、My Blueprint パネルから AnimationState をドラッグアンドドロップして、Set を選ぶだけで、自動的にその列挙型に含まれているエントリがドロップダウンメニューに登録されます。
8033
8034

⑨ 完成図 C から完成図 B にするには、次の赤枠と青枠の部分をそれぞれまとめます。(このようにすることによって、状態の数が増えた時に見やすく、分かりやすくなります。)
8035
そのためには、赤枠の部分を選択して、右クリックし、Collapse Nodes (ノードを折り畳む) をクリックします。
8036
すると次のように折り畳まれます。
8037
元に戻すには、Expand Nodes (ノードを展開する) を選択します。
8038
後は前回やったように範囲選択して C キーでコメントを付けます。

実験 Branch ノードの働き
次のようなブループリントを作ってみました。
8018 -2
これはジャンプすると (スペースキーを押すと) 3>1 が正しければ (true であれば) Good!!!、正しくなければ (false であれば) Wrong!!! という文字列を表示します。当然 3>1 は正しいので Good!!! が表示されることになります。
8019
次のように 1>3 にすると、
8020 - 2
Wrong!!! が表示されます。
8021
つまり、Branch は Condition (条件) ピンに接続したものが true なのか false なのかを判定して、true であるならば、true のピンに接続されていることが実行され、false なら false のピンに接続されていることが実行されます。本編では、Condition ピンに接続されているのが、IsFallingLocal などでした。これの値は true か false でしたので、そのまま Condition に接続することができました。

今回はこれでお終いです。お疲れ様でした!



シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. 匿名 より:

    英語が6~7割しかわからない私には最高の講座です
    ありがとう

    • なつのや より:

      お読みいただいて、ありがとうございます!大変励みになります。英語6-7割でしたら、もうすぐじゃないですか。勉強の仕方をちょっと工夫すれば(お薦めは学習用英英辞典の活用とアンリアル・エンジン 4 の英語サイトの読み込みです!)、技術系の英語はスラスラいけるようになると思いますよ。お互い、頑張りましょうね。