前回はアニメーション自体を制作しました。今回は作ったアニメーションを制御していきたいと思います。↑の動画でも解説しています。わからない、うまくいかない事があったら質問される前に、一回、動画の方で手順を確認してください
この記事は本のように順を追って解説しています。この記事は途中のページになります。
この記事を見ていて、現在の状況がわからない場合や忘れてしまった事などが出てきたら↓のリンクから目次ページへ飛べますので立ち戻って見てください。
<現状について>
前回はアニメーションをAnimation Controllerから作成しました。
・立ち
・走り
・ジャンプ(上昇)
・ジャンプ(下降)
・クリア
・ダウン
これらのアニメーションを作成してある状態です。
<アニメーターコントローラー>
前回Animator Controllerという物を作りましたが、この中身を見ていこうと思います。
↑の中身を見ていきます。
上部メニューのWindow>Animation>Animatorをクリックしてください
↓のようなウィンドウが開いたかと思います。
この状態で前回作成したキャラクターのゲームオブジェクトを選択してください。
すると↓のように、選択したゲームオブジェクトに付いているAnimatorのコンポーネントの中身を表示してくれます。
マウスのホイールで拡大縮小する事ができます。
ちなみに出てきたAnimationと↑のAnimatorは似ていて混同しやすいので注意してください。
アニメーションと言ったら、アニメーションファイルそのものの事をさします。
アニメーターと言ったらアニメーションファイルを制御する為のコンポーネントを指します。
<遷移を矢印で繋げよう>
AnimatorにAnimationを入れる
さて、アニメーションを状況によって切り替える下準備をしたいと思います。その前に、アニメーターウィンドウに、もし無いアニメーションがあるならドラッグ&ドロップで追加する事もできます。
自分は立ち、走り、ジャンプ(上昇)、ジャンプ(下降)、やられモーション、クリアーモーションを用意しています。皆さんにとって必要なアニメーションが揃っているかどうか確認してください。
確認できたら、このままではなんか編集しづらいので綺麗に整えましょうか。中の四角はドラッグで動かす事ができます。
とりあえず、見やすい位置においたら、デフォルトのアニメーションを選択します。今回の場合、デフォルトで「立ちモーション」をして欲しいです。ですが、すでに立ちモーションがデフォルトになっています。オレンジ色になっているやつがデフォルトのモーションになっています。
デフォルトのモーションを変更したいときは、デフォルトにしたいアニメーションを選択して右クリック>Set as Layer Default Stateを押せばそこがオレンジ色になります。
アニメーション遷移を描こう
それではアニメーションの制御をしていこうと思います。
今回場合、例えば、何もしていない時立ちモーションで左ボタンか右ボタンを押されたら走って、上ボタンを押されたらジャンプ(上昇)、ジャンプの最高点に達したらジャンプ(下降)、敵に攻撃されたらやられモーション、クリアーしたらクリアーモーションみたいな感じですね。
左ボタンか右ボタンが押されたら走るとした場合、押される前は立ちモーションで、押されたら走りモーションにしたいので「立ち」と「走り」を繋ぎます。
立ちモーションを選択して、右クリック>Make Transitionを選択します。
そしたら、何やら矢印のようなものが出てくると思いますが、そのまま走りモーションをクリックしてください。
↑のように矢印が引かれたと思います。
間違えて違うところに矢印を引いてしまった人は、矢印をクリックして、WindowsならDeleteキー。MacならBackSpaceキー+commandキーで削除できます。
矢印をちゃんと引けたら、矢印をクリックしてください。矢印をクリックするとインスペクターが↓のようになります。
この時、Has Exit Timeのチェックを外してください。Has Exit Timeというのは、アニメーションが全て再生し終わったら次のアニメーションに遷移するという意味です。
今回は左ボタンか右ボタンが押されたら即座に反応して欲しいのでHas Exit Timeを切ります。
自分の場合は立ちアニメーションが1コマなので、Has Exit Timeをつけていても特に変わりは無いのですが、立ちアニメーションを数コマで作った人は、左ボタンか右ボタンを押されても、立ちアニメーションが終わるまで走りモーションに移行しなくなります。
次にSettingとなっているところの▶︎をクリックして展開してください。
何やら色々出てきましたが、この部分はアニメーションとアニメーションを合成する項目です。合成ってなんだよって話ですが、これは3Dのアニメーションを作成した時に使用する項目で、2Dアニメーションでは合成をして欲しくありません。
ちなみに、2Dアニメーションでもボーンを使用するタイプの2Dアニメーションの場合は合成を使用します。
パラパラ漫画で合成というのは基本しない行為なので(絵と絵がフェードするという意味ではありません)合成を行わないようにします。
Transition Durationを0にしましょう。これで合成しなくなります。
下の方に警告文が出ていますが、「遷移が有効になるには、少なくとも1つの条件または終了時間が必要です。それ以外の場合は無視されます。」と言っています。矢印を通る条件がありませんよという事です。
と、いうわけで矢印を通る条件を入れましょう。
左上のParametersをクリックします。
上の方に出てきた「+」をクリックしましょう
これで何のパラメータを追加するのかを聞いてきます。今回の場合、ボタンを押している間走って、ボタンを離している間止まって欲しいので、これが表現できるBool型を選択します。
Bool型は真か偽の2種類を表す型でした。trueなら走る。falseなら止まる。という風に2種類あれば表現することができます。
Float型は浮動小数でしたね。例えばスピードが一定値以上達したらとかそういった表現で使用されることが多いです。
Int型は整数でした。例えばアニメーションが何パターンか存在して、割り振った番号で制御したい時などで使用されます。
Trigger型というものは実はありません。これはプログラムの「型」ではなく、しばしばUnityの機能上で表現される単語です。○○が起こったらという意味で使われることが多いです。アニメーターの場合、Triggerがオンだったら矢印へ進み、矢印へ進み終わったら自動でオフになります。一方通行なアニメーション遷移を表す際によく使われます。
何だかよくわからないよとか、忘れてしまったよという人は↓の記事を参考にしてください。
とりあえず、立ち→走るの遷移はBool型で表現したいと思います。
一応他の型でも可能ですが、Bool型が一番ぴったりなのでこれを使用します
とりあえずBool型でParametersを追加して、runと名前をつけました。
次に矢印をクリックして、インスペクターをみてください。Conditionsのところの「+」をクリックしてください。
↓のようになったかと思います。
左側にパラメータ名、右側に値が何だったら条件に当てはまるかが表示されています。変更したければそこをクリックすれば変更ができます。
今回は、パラメータ「run」が「true」になったら立ちモーションから走りモーションに遷移するようにしたいと思います。
つまり、左ボタンか右ボタンを押されたらパラメータ「run」をtrueにすれば走ります。逆に離したら止まりたいので反対も作成しましょう。
今度は走りモーションから立ちモーションへ矢印を引きます。
新しく引かれた矢印をクリックして、同じようにHas Exit Timeのチェックを外して、Transition Durationを0にしましょう。
その後Conditionsの+を押してパラメータを追加します。
↑のようになったかと思うので、今度は反対に条件をfalseにします。
これで、左ボタンか右ボタンを押されたらパラメータ「run」をtrueにし、キーを離したらfalseにするようにすれば走る表現をすることができます。
<スクリプトで制御しよう>
スクリプトを作ってAnimatorを取得
それではスクリプトから左ボタンか右ボタンを押されたらパラメータ「run」をtrueにし、キーを離したらfalseにするようにしたいと思います。
とりあえず、スクリプトを作成し、Animatorを貼り付けたゲームオブジェクトにアタッチします。自分は適当にスクリプト名を「Player」にしました。
アタッチが完了したら、スクリプトを書き始めましょう。
スクリプトの書き方がわからないとか、忘れてしまった人は↓の記事を参考にしてください。
private Animator anim = null;
void Start()
{
anim = GetComponent<Animator>();
}
まずは同じゲームオブジェクトに設定されたAnimatorのインスタンスを取得し、変数に突っ込みます。
現在のキー入力の設定を見てみよう
次にキー入力をみましょう。上部メニューのEdit>Project Settingをクリック。
次に出てきたウィンドウの左メニューのInputをクリックしてください。
すると↑のようになったかと思います。展開してない場合は▶︎をクリックして展開してください。
このHorizontalというのが水平方向の入力を表します。Negative Buttonがleft、Positive Buttonがrightとなっているのがわかるでしょうか。これは、水平方向のマイナス方向のボタンは「left」とし、プラス方向のボタンは「right」とするという意味になります。
leftは「←」キー、rightは「→」キーです。
Input Managerについての詳しい説明は↓の記事で解説しています。まだ詳しく知る必要はありませんので、興味のある方はのぞいてみてください。
ちなみにキーの対応は以下の文字列になっています。
通常キー: “a”, “b”, “c” …
数字キー: “1”, “2”, “3”, …
矢印キー: “up”, “down”, “left”, “right”
キーパッド キー: “[1]”, “[2]”, “[3]”, “[+]”, “[equals]”
修飾キー: “right shift”, “left shift”, “right ctrl”, “left ctrl”, “right alt”, “left alt”, “right cmd”, “left cmd”
マウスボタン: “mouse 0”, “mouse 1”, “mouse 2”, …
(任意の)ジョイスティックボタン: “joystick button 0”, “joystick button 1”, “joystick button 2”, …
(特定の)ジョイスティックボタン: “joystick 1 button 0”, “joystick 1 button 1”, “joystick 2 button 0”, …
特殊キー: “backspace”, “tab”, “return”, “escape”, “space”, “delete”, “enter”, “insert”, “home”, “end”, “page up”, “page down”
Functionキー: “f1”, “f2”, “f3”, …
https://docs.unity3d.com/jp/460/Manual/ConventionalGameInput.html
プログラムにキー入力を書いてみよう
これが確認できたら今度はUpdateにプログラムを書いていきます。
Updateは「毎フレーム処理を行う」ので、この場所に「もし左ボタンか右ボタンを押したら」と記述します。そうすることで、毎フレーム、ボタンを押したかどうか監視することができます。
private Animator anim = null; void Start() { anim = GetComponent<Animator>(); } void Update() { float horizontalKey = Input.GetAxis("Horizontal"); if (horizontalKey > 0) { anim.SetBool("run", true); } else if (horizontalKey < 0) { anim.SetBool("run", true); } else { anim.SetBool("run", false); } }
↑のように真似してみてください。
float horizontalKey = Input.GetAxis("Horizontal");
これは、↑のInput Managerの「Horizontal」と書いてあったところを表します。水平方向のマイナス方向のボタンに設定したキーを押されると、マイナスになり、プラス方向のボタンに設定したキーを押されるとプラスになります。
それを変数に入れているわけです。
else if (horizontalKey < 0) { anim.SetBool("run", true); }
これの「horizontalKey < 0」は「もしマイナスならば」という意味ですので、マイナス方向のボタンを押した事になります。
初期設定ではマイナス方向のボタンは”left”という奴になっているはずです。これは「←」キーを表すので、「もし←キーを入力すると」という意味になります。↓のNegative Buttonというやつですね。
本当は、直接「←」「→」キーを押されたらと書くこともできます。
その場合は、
if (Input.GetKey("left"))
{
}
else if (Input.GetKey("right"))
{
}
と書く事で、直接キー入力を見る事ができますが、ちょっと汎用性に欠けてしまいます。
GetAxisで汎用化しよう
さて、一見するとInput.GetKey(“○○”)と書いた方が楽なような気がしますが、それはそのキーしか見る事ができません。
GetAxisというのはInput Managerの中に書いてある内容を見る事ができます。
↑のInput Managerを介す事で、キーの設定を簡単に変更する事ができるようになります。
途中でキー変更したくなったとか、そういう事があれば、Input Managerの中に入っているキー設定を変えればスクリプトを変更しなくてもいつでも変更が可能になります。
変更が可能になるというのは結構便利なもので、例えば、PCだったら「←」「→」というキーがありますが、他のプラットフォームに移植したくなったりした時にいちいち全部のスクリプトを変更していてはしんどいです。
また、今回はちょっとしかキー入力を書いていませんが、たくさん書く事があるようだと全部のスクリプトを変更するのは大変です。
Input Managerを使用すれば、ここの入力を変更するだけで全部の変更ができるようになります。とても便利なので覚えておきましょう。
スマホのタッチに変更したりもできます。
アニメーターのパラメータを変更しよう
さて、キー入力を判別できるようになったらアニメーターのパラメータを変更しましょう。
anim.SetBool("run", true);
というのはAnimatorのコンポーネントのインスタンス(実態)にアクセスしてBool型のパラメータの値を変更するという意味になります。
引数に(“run”,true)としているのは先ほど自分で作ったパラメータ「run」をtrueにするという意味になります。↓のこれですね。
つまり、スクリプトの↓の部分は、
float horizontalKey = Input.GetAxis("Horizontal"); if (horizontalKey > 0) { anim.SetBool("run", true); } else if (horizontalKey < 0) { anim.SetBool("run", true); } else { anim.SetBool("run", false); }
もし右ボタンが押されたらアニメーターのrunをtrueに、左ボタンを押されてもアニメーターのrunをtrueに、右ボタンも左ボタンも押されていなければrunはfalseにしています。
この状態で再生すると
右か左ボタンを押した時、runがtureになって、走りだすようになりました。
しかし、これでは右ボタンと左ボタンのどっちを押しても右側に走っていってしまいます。そのため、左ボタンを押された時は左右反転をするようにします。
float horizontalKey = Input.GetAxis("Horizontal"); if (horizontalKey > 0) { transform.localScale = new Vector3(1, 1, 1); anim.SetBool("run", true); } else if (horizontalKey < 0) { transform.localScale = new Vector3(-1, 1, 1); anim.SetBool("run", true); } else { anim.SetBool("run", false); }
実は、Transformの大きさをマイナスにすると反転します。
今回は左右反転させたいので、xをマイナスにします。大きさを変更するにはtransform.localScaleで大きさを変更できます。
transform.localScale = new Vector3(-1, 1, 1);
↑は↓と一緒です。
プログラムから値をこの値を触っているわけですね。
今は自分達はインスペクターから値を触れますが、当然ゲームを遊ぶプレイヤーは触れないので、プログラムからキー入力で値を触れるようにしてあげないといけません。
また、左を向きっぱなしになっても困るので右ボタンを押したら右に向きなおしてもらうため、
if (horizontalKey > 0) { transform.localScale = new Vector3(1, 1, 1); anim.SetBool("run", true); }
としています。
この状態で再生してみましょう。
はい、これで走れるようになりました。アニメーションの制御に関してはだいたいこんな感じです。
全体のソースコードは↓のようになっています。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { private Animator anim = null; void Start() { anim = GetComponent<Animator>(); } void Update() { float horizontalKey = Input.GetAxis("Horizontal"); if (horizontalKey > 0) { transform.localScale = new Vector3(1, 1, 1); anim.SetBool("run", true); } else if (horizontalKey < 0) { transform.localScale = new Vector3(-1, 1, 1); anim.SetBool("run", true); } else { anim.SetBool("run", false); } } }
他のモーションについては、またその時になったら解説したいと思います。
何かうまくいかない事があった場合は↓の記事を参考にしてみてください
最低限↓の動画の要件を満たしていない質問は受けかねるので、ご理解ください。
また、筆者も間違えることはありますので、何か間違っている点などありましたら、動画コメント欄にでも書いていただけるとありがたいです。
次はいよいよステージを作成していきたいと思いますのでよろしくお願いします。