Unityに関連する記事です

 プレイヤー用のゲームオブジェクトの移動と停止の動作に合わせて、アニメーションの同期制御を行います。
プレイヤーが移動している場合には移動のアニメーションをループ再生し、停止している場合には待機のアニメーションをループ再生させます。


<実装動画 
動画ファイルへのリンク


<実装動画◆
動画ファイルへのリンク



 以下の内容で順番に実装を進めていきます。

手順10 ー移動処理と移動アニメーションの同期ー
1.キャラクターのアニメーション遷移用のスクリプトの作成
2.移動の処理と移動のアニメーションを同期させる
3.enum によるアニメーションの状態設定



1.キャラクターのアニメーション遷移用のスクリプトの作成

1.設計


 プレイヤー用のキャラクターのアニメーション遷移を制御するクラスを作成します。
汎用的なクラスを作成することを目的として設計することで、例えば、プレイヤー用のキャラだけではなく、
敵キャラのアニメーションの制御にも利用することが可能です。

 そのため、各キャラクターの制御用のクラス(PlayerMove など)にはアニメーション制御の処理は記述せず、
新しい専用のクラスを作成して、色々なキャラクターに対応できるような設計を行います。


2.PlayerAnimation スクリプトを作成する


 アニメーションの制御は Animator コンポーネントと、Animator コンポーネントにアサインされている
AnimatorController ファイルを通じて行います。
 
 今回は Animator コンポーネントを活用した処理を1つのクラス内にまとめて記載しておき、アニメーションの遷移制御の専用クラスとして作成します。
このように役割を決めてクラスを作成しておくと利用方法や活用方法も明確になります。


PlayerAnimation.cs

 ← クリックすると開きます


 スクリプトを作成したらセーブします。

 以前作成した PlayerMove スクリプトにおいて利用した RequireComponent 属性や TryGetComponet メソッドが再度登場しています。
処理の内容を振り返り、どのような機能であるのかを復習を行って理解を深めてください。


3.<Animator.SetFloat() メソッド>


 Unity のアニメーションは、Animator クラスによって、AnimatorController に登録している様々なアニメーションの制御が行えます。

Unity公式スクリプトリファレンス
Animator




 今回はアニメーションの遷移のために SetFloat メソッドを利用し、遷移の条件をこのメソッドの引数に指定してアニメーションの遷移を行っています。

 各メソッドの引数にはそれぞれ型の指定が異なりますが、いずれも第1引数は string 型です。この部分には、パラメータで設定した文字列を指定します。
文字列ですので大文字小文字は区別されます。パラメータに登録した文字列をこの第1引数に指定することでパラメータのもつ情報を変更することが出来ます。
そして、パラメータの値を変更する内容を第2引数に指定します。

 例えば、SetFloat メソッドであれば、第1引数に Float 型のパラメータである Speed の文字列を指定し、第2引数に浮動小数点の値を指定します。

  // 待機状態のアニメと移動状態のアニメの再生の制御(アニメーションの遷移)を行う
  anim.SetFloat("Speed", magnitude);

 第2引数の浮動小数点の値は固定値ではなく、変数を指定しています。
このようにしておくことにより、Speed の値を固定値ではなく、変数で操作することが出来ます。

 この Speed の値をステート間のトランジションの Conditions の条件として設定しておくことで、
値を判断してアニメーションの遷移を行うことが出来ます。

 例えば、待機アニメのステートから移動アニメのステートへのトランジションには、下記のように条件を設定しています。


待機アニメのステート → 移動アニメのステート



トランジションの Conditions


 この条件の場合、SetFloat メソッドの第1引数で Parameters の Speed を指定し、
かつ、第2引数で指定する値が 0.1 よりも大きい値であれば、ステートの遷移が発生します。

 以上のような手順により、AnimatorController のパラメータの値をスクリプトから書き換えることができます。
その結果として、条件が合致したアニメーションに遷移することが出来ます。



パラメータとSet〜メソッドの関連性



<参考サイト>
Unity公式スクリプトリファレンス
SetTrigger



4.PlayerAnimation スクリプトをアタッチする


 ヒエラルキーにあるプレイヤー用のゲームオブジェクトに PlayerAnimation スクリプトをドラッグアンドドロップしてアタッチします。
アタッチした際には必ずゲームオブジェクトを選択し、インスペクターを見てアタッチされていることを確認します。


インスペクター画像



 インスペクター上に設定項目がないので、アタッチの確認だけしておきましょう。


2.移動の処理と移動のアニメーションを同期させる

1.設計


 プレイヤーの移動制御に合わせて、待機と移動のアニメーションを再生させる機能を実装します。

 プレイヤーの移動が発生していない(停止している)場合には、待機のアニメーションをループ再生します。
プレイヤーの移動が発生している場合には、移動しているアニメーションをループ再生します。

 この2つのアニメーションの制御をプレイヤーの移動状態に応じて自動的に切り替える制御を作成します。


2.PlayerMove スクリプトを修正する


 先ほど作成した PlayerAnimation スクリプトを利用するための新しい変数を1つを宣言します。
同じ種類の修飾子は並べて記述するようにし、可読性を高めます

 また、Move メソッド内に処理を追加します。TODO を記述している部分に追加しますので、
どういった処理を追加すれば移動のアニメーションの制御が行えるのか、一緒に考えてみてください。


<TODO 部分の実装>
        // TODO 移動や停止のアニメーションの同期


PlayerController.cs

<= クリックすると開きます。


 スクリプトを修正したらセーブします。


3.<Summary(サマリー)機能>


 関数(メソッド)やクラスを作成し終わりましたら、必ずその関数やクラスの説明を書くように心がけましょう。書く場所は関数名、あるいはクラス名の1行上の部分です。
半角スラッシュを3個連続で記述すると説明用のコメントであるサマリー(概要)が自動的に記述されます。

 別の記事で詳しく解説していますので、そちらを確認しておいてください。


 => 知っておきたい豆知識


4.ゲームを実行して動作を確認する


 アニメーションの遷移のデバッグを行う際には、Game ビューだけではなく、Animator ビューも合わせて確認を行うようにしてください。
ステートの状態がリアルタイムで動作するため、どのステートに遷移しているのか、どのパラメータに値が代入されているのかを確認することが出来ます。


<実装動画 
動画ファイルへのリンク


<実装動画◆
動画ファイルへのリンク


 ゲーム画面、および Animator ビューの双方で確認を行い、正常に動作していれば完成です。

 最後に enum を利用した処理の実装方法を学習します。


3.enum によるアニメーションの状態設定

1.enum(列挙型)


 enum(イニューム)とは C# に用意されている構造体に分類される機能の1つです。列挙(れっきょ)型と呼ばれます。

 enum(列挙型)とは、特定の値(作成した定数)しかとらない集まりのことです。
enum はクラスと同じように、自由に名前を付けて作成することが出来ます。そしてその中に、自由に名前をつけて定数を作成しておくことが出来ます。
この時の定数の情報を列挙子といいます。

<enum の作成>
public enum EnumName { // class の部分を enum に変更することで enum を宣言出来ます。EnumName が作成した enum の名前です。任意の名前を付けられます。
    列挙子1,    // カンマで区切ることで次の列挙子を定義できます
  列挙子2,


}


 enum は様々な情報を種類ごとにまとめておくことが出来る便利な機能です。

 今回は enum を利用して、プレイヤーの起こりえるアニメーションの種類を登録しておき、参照して利用するようにします。
そうすることでアニメーションの種類の管理にも役立ちます。


参考サイト
MicroSoft
列挙型 (C# リファレンス)
Pasona 様
【ソースコード有】列挙型とは?C#のenumの使い方を知ろう


2.PlayerAnimationState を作成する


 enum 型の PlayerAnimationState を作成します。

PlayerAnimationState.cs

 ← クリックすると開きます



3.<enum の列挙子と機能>


 if 文において bool 型の変数を利用すると、2つの分岐パターンを作成することができます。
ですが bool 型には true/false の2つの状態しか値として持たないため、3つ以上の状態を管理することが出来ません。

 2つ以上の同じ種類の情報を1つの情報源として管理する場合や、true/false では認識しにくい場合には、
enumを作成し、その種類を登録しておくことをおすすめします''。

 enum で作成する型には任意の名前を付けることが出来ます。クラスと同じです。
宣言した enum 内には任意の名前の列挙子を作成できます。数に指定はなく、日本語でも作成できます。

<enum で作成された PlayerAnimationState 型の宣言>
/// <summary>
/// プレイヤー用のキャラクターのアニメの種類
/// </summary>
public enum PlayerAnimationState {
    Speed,
    Down,
    Damage,
    Clear

}

 今回は、プレイヤーのアニメーションの状態を表現する方法として enum によって作成された PlayerAnimationState 型を用意しました。
Speed 〜 Clear まで、4種類の列挙子を宣言しています。これは自由に名前の変更、新しい列挙子の追加・削除ができます。



 作成した PlayerAnimationState 型は情報源、つまり、設定情報であり、この情報を実際にゲーム内で利用するためには、PlayerAnimationState 型の変数の宣言を行います。


<PlayerAnimationState 型の変数の宣言>
 public PlayerAnimationState currentPlayerAnimationState;

 以上のように enum は、enum を宣言して設定を行う部分と、それを利用するための変数の宣言の2つが必要になります。
自作した enum の PlayerAnimationState 型には、PlayerAnimationState 型内に宣言した列挙子の値を1つだけ代入することが出来ます
2つ以上の状態が代入されることはあり得ない(存在しない)ため、処理を排他的に構築する際に役立ちます。

<列挙子の代入>
  // ステート管理処理を追加
  currentPlayerAnimationState  = PlayerAnimationState.Down;

 代入する場合には必ず、[enum の型名.列挙子名] で指定をします。列挙子名のみでの指定は出来ません。

 このように1つの変数内には、いずれかの列挙子の値が1つだけ代入できるため、
bool 型とは異なり、宣言した列挙子分の分岐を用意することが可能になります
よって、true なら/false なら、という分岐の形ではなく、現在の PlayerAnimationState の値が Donw なら / Damage なら / Clear なら、という風に、
列挙子の値に合わせて分岐が作成できます。これは処理の可読性を上げる上でも役立ちます。



 enum を利用する場合、その登録してある列挙子からしか情報を指定できませんので、
例えば、文字列と異なり、指定に際して打ち間違えが発生しませんので、不備の値が入ることも防ぐことが出来ます

 以上のことから、ゲームの内容に応じた enum を考えて作成して運用します
ほかには、プレイヤーの状態用(毒、混乱、痺れとか)、アイテムの種類(消耗品、武器、防具、など)、
ゲームの状態管理(ゲーム開始前、ゲーム中、ゲーム終了)など、非常に応用が利く機能です。



 enum は自分の目的に合わせて自由に作成できます。
今後も必要に応じて作成し、プログラムを読みやすく、管理をしやすいゲーム環境を作っていくようにしましょう。


4.PlayerAnimation スクリプトを修正する


 PlayerAnimation スクリプトの SetFloat メソッドの第1引数で利用している文字列の情報を enum に置き換えます。


PlayerAnimation.cs

<= クリックすると開きます。


 スクリプトを修正したらセーブします。


5.enum の列挙子のキャスト処理


 enum に登録している列挙子の値は、異なる型への型変換の機能があります。この型変換の処理のことをキャストといいます。

 enum の列挙子は文字に見えますが、情報としては列挙型になります。
文字列である string 型には、ToString メソッドを利用することでキャストが出来ます。


<enum の列挙子のキャスト enum → string 型>
 string  enumString = PlayerAnimationState.Down.ToString();



 今回変更した処理では、このキャスト処理が行われています。
SetFloat メソッドの第1引数は string 型です。そのため、enum の列挙子型をそのまま利用することは出来ませんが、
キャスト処理をすることにより、Speed 列挙子が、Speed という文字列に変換されます。

 anim.SetFloat(PlayerAnimationState.Speed.ToString(), magnitude);

 これはつまり

 anim.SetFloat("Speed", magnitude);

 このような状態として扱われます。すなわち、元々あった処理と同じ内容になります。

 この機能により、SetFloat メソッドの第1引数の条件を満たすことが出来ています。



 なお enum では各列挙子に自動的に整数の番号が与えられます一番上から 0 で連番になっています
今回の場合であれば、Speed には 0、Clear には 3 の数字が与えられています。

 この番号は見えない情報ですが、列挙子を int 型にキャストを行うことで取得して利用出来ます
下記の例の場合、enumValue には 1 が代入されます。

<enum の列挙子のキャスト◆enum → int 型>
 int  eventValue = (int)PlayerAnimationState.Down;

 また、列挙子の宣言時に数字を指定して代入することも可能です。その場合には連番ではなく、指定した数値を取得出来ます。

<数字の代入の例(今回この方式は利用しません)>
public enum PlayerAnimationState {
    Speed = 10,
    Down = 5,
  Damage = 1000,
    Clear = 15,
}

 上記のように代入されている場合には、列挙子を int 型にキャストすると、代入してある値が取得出来ます
今回は数字の代入は行っていませんので一番上の列挙子には 0 から順番に採番されています。



6.enum を利用するメリット


 PlayerAnimation スクリプト内の処理を修正していただきましたが、新しく書いた処理の内容も、元々あった処理の内容も、内部的には同じ処理です。


 anim.SetFloat(PlayerAnimationState.Speed.ToString(), magnitude);

 anim.SetFloat("Speed", magnitude);

 ではなぜ、わざわざ書き換えたのでしょうか?

 SetFloat メソッドの第1引数で利用している文字列ですが、文字列はスクリプトのコンパイル時にエラーチェックの対象になりません。
そのため文字を打ち間違えていても、それを見つけてくれる機能がありません

 また、固定値として利用する情報であっても、プログラムにはなるべく直接記述(リテラル表記)を避けた方がよいためです。
そのためには、メンバ変数で固定値の情報を用意しておくようにしたり、今回のように enum を作成し、列挙子内からのみ選択できるような状況を作ることが大切です。

 以上のようなデメリットを回避するため、今回は SetFloat メソッドの第1引数の部分を置き換えて
enum の PlayerAnimationState 型の Speed 列挙子を指定し、それを ToString メソッドを利用して string 型にキャストしています。
enum は列挙子に登録している情報しか利用できません。よって、登録されていない列挙子を書き込もうとするとエラーが表示されるようになります。

 このようにすることで、文字列の場合においては直接書き込んで打ち間違えをしてしまうというエラーの可能性を、enum を利用することで排除しています。

 特に複数人で作業をおこなう場合には極力、文字列を直接書き込むことは避けた方がよいでしょう。
またメソッドの引数を利用した実装を設計することで、変数を上手く活用した設計(変数の値によって自動的に分岐化させること)が出来ます。


7.<応用 複数のクラスの記述>


 1つのスクリプト・ファイルの中に複数のクラス・enum を合わせて作成することも出来ます。

 今回であれば、PlayerAnimation クラスと同じスクリプトの中に PlayerAnimationState を作成することも出来ます。
記述する順番に優劣はありません。


PlayerAnimation.cs

 ← クリックすると開きます


 ファイルは1つになりますが、この書き方であっても、同じ機能が利用できます。

 他にもクラス内に入れ子にした enum など、スクリプトには色々な記述の方法があります。
覚えておくといいでしょう。


8.ゲームを実行して動作を確認する


 以前と同じように移動に合わせて、移動と待機のアニメーションの遷移が実行されていれば問題ありません。



 以上でこの手順は終了です。

 => 次は 手順11 −宝石プレハブの作成− です。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます