本投稿は2024年9月時点の内容になります。アップデートにより変更となる場合があります。また環境によって違いがあると思いますのであくまで参考として、ご了承ください。
様々な書籍、ブログや動画を参考にさせていただきました。多すぎて一つ一つは紹介できませんが感謝です。
初心者の自分がUnity ソフトウエアでゲームを作ってみました。とりあえずシンプルなものということでモグラたたきに挑戦です。ゲーム作ってみるかという感じになったときに、いいタイミングで某ゲームのイベントシナリオ内ミニゲームにモグラたたきが実装されていたのでUIとかエフェクトとか、諸々の仕様をぱくって参考にして作ってみましたよ。様々なHowToの中の選択肢のひとつとして、同じ初心者さんの参考になればよいです。
\ チェック /
目次
アニメーションイベントでメソッドを実行してみる
今回は、前回の「11.簡単なバトルシステムを作ってみる」の続きです。
アニメーションイベントを使ってメソッドを実行していきます。
本記事のポイント
- アニメーションイベントの解説
- アニメーションイベントにメッソドが出てこないときのチェック
前回の確認
まずは前回まとめたバトルの仕様で出来ている部分と未完成の部分を確認します。
バトルの仕様
- 敵キャラの状態がPositiveの時はプレーヤーターンの攻撃
- 敵キャラの状態がAngerの時はエネミーターンの攻撃
- バトルのタイミング①クリックされたとき
- バトルのタイミング②クリックされずにしゃがんだとき
- クリックされたときEnemyタイプの敵は状態がPositiveに
- クリックされたときJammerタイプの敵は状態がAngerに
- クリックされなかったときEnemyタイプの敵は状態がAngerに
- クリックされなかったときJammerタイプの敵は状態がPositiveに
- しゃがみ状態になったときはタイプに限らず状態Runawayを付加する
今回は残りの4、7、8、9を実装していきます。あと1、2、3、5、6に関しても何度も叩けてしまうという問題点がありましたね。これを踏まえてスクリプトの準備をしていきます。
アニメーションイベントに使うメソッドをEnemyControllerクラスに追加する
まずは必要なメソッドを「EnemyController」クラスに追加していきます。
public class EnemyController : MonoBehaviour, IPointerDownHandler//インターフェースを実装したクラスであると宣言
{
//省略
//IPointerDownHandlerインターフェースの関数
//マウスが押されたメッセージを受け取り実行される
public void OnPointerDown(PointerEventData eventData)
{
//変更
//ここではアニメーショントリガーに関するコードのみにする
//アニメーターにトリガーを渡す
enemyMove.SetTrigger("HasClicked");
}
//アニメーションClickReactionの最初に呼び出す
public void ClickedEnemyAction()
{
EnemyStatus _enemy=enemy.EnemyStatus;
switch (_enemy.UnitType)
{
case UnitType.enemy:
//enemyタイプなら状態Positiveを加える
_enemy.AddStatus(Statuses.Positive);
break;
case UnitType.jammer:
//jammerタイプなら状態Angerを加える
_enemy.AddStatus(Statuses.Anger);
break;
default:
Debug.Log("enemyタイプエラー");
break;
}
//戦闘開始
battleManager.Battle(enemy);
}
//アニメーションUnClickReactionの最後に呼び出す(もしくはCrouchの最初?)
public void UnclickedEnemyAction()
{
EnemyStatus _enemy = enemy.EnemyStatus;
switch (_enemy.UnitType)
{
case UnitType.enemy:
//enemyタイプなら状態Angerを加える
_enemy.AddStatus(Statuses.Anger);
break;
case UnitType.jammer:
//jammerタイプなら状態Positiveを加える
_enemy.AddStatus(Statuses.Positive);
break;
default:
Debug.Log("enemyタイプエラー");
break;
}
//戦闘開始
battleManager.Battle(enemy);
}
//アニメーションCrouch,CrouchAfterClickの最初に呼び出す
public void Runaway()
{
//バトルの仕様9 状態Runawayを加える
enemy.EnemyStatus.AddStatus(Statuses.Runaway);
}
//アニメーションCrouch,CrouchAfterClickの最後に呼び出す
public void AfterCrouchingAction()
{
battleManager.EndBattles(enemy);
}
//省略
}
スクリプトざっくり解説
- (16-35)前回で書いたクリックされたときのアクション
- (43-67)クリックされなかった時のアクション
- (49-51)バトルの仕様7
- (54-57)バトルの仕様8
- (55-59)バトルの仕様9
- (71-74)下記のバトル終了のメソッドを呼び出してます。
「BattleManager」クラスにも一つメソッドを追加します。
//バトルの終了を指示するメソッド
public void EndBattles(Enemy enemy)
{
//確認用のログ
Debug.Log(enemy.EnemyStatus.Status);
//対象のゲームオブジェクトを破棄します
Destroy(enemy.gameObject);
}
メソッドの準備ができたのでアニメーションイベントを設定していきます。
アニメーションイベントの実装
前回問題のあったクリックイベントをアニメーションイベントで実装してみます
まずは前回クリックイベントで実行したメソッドをアニメーションイベントを使って実行してみましょう。
アニメーションイベントの使い方
- ヒエラルキー(シーン)で対象となるゲームオブジェクトを選択します。
- 上部のメニューから「ウィンドウ」>「アニメーション」>「アニメーション」をクリック。
- アニメーションウィンドウが開きます。
- アニメーションウィンドウの左上、レコードボタンなどが並んでいる下のドロップダウンをクリック。
- 使われているアニメーションクリップのリストが出てくるのでアニメーションイベントを付加したいクリップを選択(今回は「ClickReaction」)。
- クリップ上のフレーム位置を表す白いラインを動かしてアニメーションイベントを付加したいフレームに合わせます。
- クリップ名表示の右側にある「イベントを追加」を表すボタンをクリック
- アニメーションのフレームタイムラインに青い印が付きます。
- インスペクターを確認すると「Function」の項目が表示されていると思います。
- そこから実行したいメソッドを選択します(今回は「Enemy」>「Methods」>「ClickedEnemyAction」を選択しました)
ゲーム再生してUnitychanをクリック。コンソールを確認。
実行確認
- UnitychanのUnitTypeが「Enemy」でも
- 「Jammer」でも仕様通りか確認する。
前回は何度も叩けてしまうという問題がありました。今回は何度クリックしても一回しか処理が行われないと思います。
今回のアニメーションの遷移分岐の仕方と一方通行なところを活かしたことで、シンプルなコードのまま仕様通りに実装できました。このようにアニメーションイベントはうまく使うと非常に便利です。
残りのアニメーションイベントも追加していきます
残りのアニメーションイベント
- アニメーション「UnClickReaction」の最後に「UnClickedEnemyAction」を追加
- アニメーション「Crouch」の最初に「Runaway」を追加
- アニメーション「Crouch」の最後に「AfterCrouchingAction」を追加
- アニメーション「CrouchAfterClick」の最初に「Runaway」を追加
- アニメーション「CrouchAfterClick」の最後に「AfterCrouchingAction」を追加
再度ゲーム再生してコンソールを確認。仕様通りの結果ならOKです。
アニメーションイベントにメソッドが出てこないときの原因とチェックポイント
これマケイヌ的Unity プロジェクトの四大初心者泣かせのひとつ。
アニメーションイベントにメソッドが出てこない理由は主に2つあります。
原因その1 アニメーションウィンドウの表示時に、対象のゲームオブジェクトが選択されてない
アニメーションウィンドウにアニメーションイベントを追加した際に「Functions」にドロップダウンが出る時と空欄のフォームが出る場合があります。この空欄フォームのパターンは「プロジェクトのアセットから直接アニメーションクリップを選択した」時によく起きます。
実際は空欄のフォームにメッソドを入力してもいいのですが、入力ミスなどで実行できないことがあるのでドロップダウンから選べた方が確実ですよね。
このドロップダウンが出る時と出ないときの違いは「対象のゲームオブジェクトが選択されているかどうか」です。アセット上のアニメーションクリップはどこで使われているか保証がないので、よく考えたら当たり前なんですよね。でも初心者だとわからないのです。
原因その1の対処法 アニメーションウィンドウ表示の仕方をチェック
- ヒエラルキー上で対象のゲームオブジェクトを選択したのち、アニメーションウィンドウを開く
- アセット上のクリップからアニメーションウィンドウを開いた場合は、その後対象のゲームオブジェクトをヒエラルキー上で選択する
上記のように対応すればアニメーションイベントにメソッドがドロップダウンで出てきます。
原因その2 アニメーションイベントは、そのクリップを含んだアニメーターを持ったゲームオブジェクトに付いているスクリプトのメソッドしか呼ぶことができない
ちょっと長いですね。アニメーターを持っているゲームオブジェクト自身にアタッチしてるスクリプトのメソッドしか呼べないって感じです。まだ長い。。。メソッドがイベントの対象オブジェクトの外にあるのが原因です。
これはメッソドが実行されないときの原因でもあるので注意が必要です。
やってしまいがちなのが対象のゲームオブジェクトAを別のxxxManagerオブジェクトで管理してるときに、AのアニメーションイベントでxxxManagerの持つメソッドを呼んでしまうことです。これ何も起きません。
原因その2の対処法 対象のゲームオブジェクトにアタッチされているかチェック
- アニメーターがアタッチされているオブジェクトのスクリプトのメソッドか確認する。
- そもそも、原因その1もふまえて「Functions」のドロップダウンから選択するようにすれば良い。
アニメーションイベントが実行されないときの原因とチェック
アニメーションイベントをしっかり設定しても実行されないときは、原因がアニメーションの遷移に関わっていることが多いですので。
アニメーションイベントが実行されないときの原因の例
- クリップの一番最後にイベントを設定しているのにアニメーション終了時間が1より小さい
- アニメーションが遷移中にイベントを設定されている
- Debug.Logを使ってメソッドを通過しているか確認するのが簡単な確認方法です。これで実行そのものが行われていないのか、メソッドの記述に問題があるのかがわかります。
まとめ
まとめ
- アニメーションイベントを使い、分岐や実行のタイミングをうまく利用するとシンプルなコードで実装できることがあるので適材適所でつかえるようにしたい。
- アニメーションイベントでメソッドが出てこないときは、対象のゲームオブジェクトを選択しているか、スクリプトがアタッチされているかを確認する
- アニメーションイベントが実行されないときはアニメーションの終了時間や遷移を確認してみる
\ Unityのスクリプトを書くのに役立ちます /
もっと早く教えてほしかった!Unity C#入門
MARU
おすすめ記事
Unity ソフトウエアでゲーム制作#1モグラたたき編(28.ゲームに効果音…
Unity ソフトウエアでゲーム制作#1モグラたたき編(27.エフェクト2パ…
Unity ソフトウエアでゲーム制作#1モグラたたき編(26.エフェクトその1)
Unity ソフトウエアでゲーム制作#1モグラたたき編(25.プレハブバリア…
Unity ソフトウエアでゲーム制作#1モグラたたき編(24.Buttonで…
Unity ソフトウエアでゲーム制作#1モグラたたき編(23.シンプルなアニ…