【Unity 2Dローグライク】公式チュートリアルをやってみる part.12~敵のアニメーションの管理
こんにちは!ヤギです!
Unityの2Dローグライクの
公式チュートリアルをやってみる part.12になります!
※前回(part.11)の記事はこちら
www.yagigame.com
記事概要
今回の記事では、敵のアニメーションの管理についてご説明していきます。※part.12に対応する公式チュートリアルの章は、Enemy Animator Controllerです!
unity3d.com
※この記事は、ひよこのたまご様の記事をリスペクトしています。
hiyotama.hatenablog.com
敵のアニメーションコントローラの修正
1. Enemy1のアニメーションコントローラを開きます。2. Enemy1IdleとEnemy1Attackを右クリックし、Make Transitionで矢印を結びます。
3. Animator view > Parameters > +をクリックし、アニメーションを遷移させるTriggerを新規作成します。
※名前はEnemyAttackとします。
4. Enemy1IdleからEnemy1Attackに遷移する矢印をクリックし、Inspector viewを開きます。
5. Conditionsに先ほど作成した、EnemyAttackを設定します。
6. Enemy1Idleはループして表示するため、Has Exit Timeのチェックを外し、アニメーションを即座に切り替えるため、Transition Durationを0にします。
7. Enemy1AttackからEnemyIdleにつながる矢印をクリックし、Inspector viewを開きます。
8. Enemy1Attackは一定時間表示したら、自動でEnemy1Idleに戻るため、Has Exit Timeもチェックをつけたままにします。
9. 一定時間表示する時間を設定するために、Exit Timeを1と設定します。
10. アニメーションを即座に切り替えるため、Transition Durationを0にします。
※8~10の設定後のInspector viewは以下の通りです。
※これで敵のアニメーションコントローラが完成しました!
GameManager.csの修正
GameManager.csをゲーム内のターンなどを管理できるように修正していきます。※ソース内に解説を記載いたしました。ご参照ください。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { //ここからpart.12で追加 public float turnDelay = .1f; //1ターンの時間 private List<Enemy> enemies; //複数の敵を管理 private bool enemiesMoving; //敵の移動フラグ //ここまでpart.12で追加 //クラスに属し、複数のシーンで使われる変数を宣言 //Staticにすることで、他のスクリプトからも呼び出すことができます public static GameManager instance = null; //ここから:part.10で追加 public int playerFoodPoints = 100; //プレイヤーの食料 //HideInspectorをつけることで、Inspector viewに表示されなくなる [HideInInspector] public bool playerTurn = true; //プレイヤーのターンかの判定フラグ //ここまで:part.10で追加 //BoardManager型の変数を宣言 private BoardManager boardScript; //テストとして、敵が出現するレベルの3とする private int level = 3; // AwakeはStartよりも前、最初に呼ばれる void Awake() { //GameManagerが存在しなければ、このオブジェクトを設定する if (instance == null) instance = this; else if (instance != this) //すでに存在する場合、このオブジェクトは不要なため破壊する Destroy(gameObject); //シーン遷移時に、このオブジェクトは破壊せず引き継ぐ DontDestroyOnLoad(gameObject); //ここからpart.12で追加 enemies = new List<Enemy>(); //敵を初期化 //ここまでpart.12で追加 //BoardManagerのコンポーネントを取得 boardScript = GetComponent<BoardManager>(); //ステージ生成の関数を呼ぶための、関数を呼ぶ InitGame(); } void InitGame() { //ここからpart.12で追加 enemies.Clear(); //ステージ移動時は敵をリセットする //ここまでpart.12で追加 //ステージ生成の関数を呼ぶ boardScript.SetupScene(level); } //ここまでpart.10で追加 //ここからpart.12で追加 void Update() { //プレイヤーのターンか、敵の動いている場合は、アップデートしない if (playerTurn || enemiesMoving) return; //敵の動いていない、敵のターンのみ敵を動かす StartCoroutine(MoveEnemies()); } //敵をリストに加える処理 public void AddEnemyList(Enemy script){ enemies.Add(script); } //敵を移動させる処理 IEnumerator MoveEnemies() { //エネミー移動フラグをtrueにする enemiesMoving = true; //1ターン待つ yield return new WaitForSeconds(turnDelay); //敵がいなければ if (enemies.Count == 0) { //1ターン待つ yield return new WaitForSeconds(turnDelay); } //敵の数だけ、敵を移動させる for (int i = 0; i < enemies.Count; i++) { enemies[i].MoveEnemy(); //1ターン待つ yield return new WaitForSeconds(turnDelay); } //プレイヤーのターンにする playerTurn = true; enemiesMoving = false; } //ここまでpart.12で追加 //ここかpart.10で追加 public void GameOver() { //enabledをfalseにすることで、GameManagerが無効になる enabled = false; } }
※これでGameManager.csの修正は完了です。
Enemy.csの修正
最後に、Enemy.csに敵の攻撃アニメーションの呼び出しなどを追加しましょう。※ソースの中に解説を記載しています!
using System.Collections; using System.Collections.Generic; using UnityEngine; //MovingObjectを継承する public class Enemy : MovingObject { public int playerDamage; //プレイヤーへのダメージ private Animator animator; private Transform target; //プレイヤー場所 private bool skipMove; //動くか判定 // Use this for initialization //継承クラス protected override void Start () { //ここからpart.12で追加 //敵をリストに加える GameManager.instance.AddEnemyList(this); //ここまでpart.12で追加 //Animatorコンポーネント取得 animator = GetComponent<Animator>(); //プレイヤーの場所を取得する target = GameObject.FindGameObjectWithTag("Player").transform; //MovingObjectクラスのStartを呼び出す base.Start(); } //敵のターンか判定、移動を試みる処理 protected override void AttemptMove<T>(int xDir, int yDir) { //敵のターンではない場合 if(skipMove){ //敵のターンにする skipMove = false; return; } base.AttemptMove<T>(xDir, yDir); //敵のターンを終わる skipMove = true; } //敵を移動させる処理 public void MoveEnemy(){ int xDir = 0; //左右の移動量 int yDir = 0; //上下の移動量 //敵とプレイヤーの左右の距離がほぼ0の場合 if(Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon){ //プレイヤーが上にいれば、1とし、下にいれば、-1とする yDir = target.position.y > transform.position.y ? 1 : -1; }else{ //プレイヤーが右にいれば、1とし、左にいれば、-1とする xDir = target.transform.position.x > transform.position.x ? 1 : -1; } //移動する AttemptMove<Player>(xDir, yDir); } //敵が移動できない時の処理 protected override void OnCantMove<T>(T component) { //衝突したプレイヤーを設定 Player hitPlayer = component as Player; //ここからpart.12で追加 //プレイヤーに攻撃するアニメーションを呼び出す animator.SetTrigger("EnemyAttack"); //ここまでpart.12で追加 //プレイヤーの食料を減らす hitPlayer.LoseFood(playerDamage); } }
※これでEnemy.csの修正は完了です。
Enemy Prefabの設定を修正する
作成したEnemy.csをEnemyにアタッチしましょう。1. Prefabs > Enemy1とEnemy2をシフトを押しながらクリックし、両方選択します。
2. 画面上部のConponent > Scripts > Enemyをクリックし、Enemy.csをアタッチします。
3. Enemy PrefabのInspector > Blocking Layer をblocking Layerに設定します。
4. Enemy PrefabのInspector > Player Damegeに任意の数値を設定します。
※これで、Enemy Prefabの設定も完了です!
ゲームを実行してみよう!
ここまででゲームを実行してみましょう!プレイヤーや敵がスムーズに動くことが確認できると思います!!!
次回予告
次回の記事では、画面のUIや、ステージのレベル管理について書いていきたいと思います。※次回の記事はこちら
www.yagigame.com
※Unityのチュートリアルの章としては、次回は(Adding UI & Level Transitions)となります!
読んでいただきありがとうございました!