【自作ゲーム開発3】敵モブのモデル変更と一部アニメーション【Unity】


注意
本記事で掲載されている動作の実装方法及びプログラムのソースコードは最適な方法ではない可能性があります。
今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。

はじめに

Unityによる自作ゲーム開発進捗その3になります!

アセットストアの素材を使用したモデルの反映とアニメーションを実装します。

今回はモブのモデルとアニメーションを動作確認します。

以下にソースコードを掲載します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class CenterMobEnemy : MonoBehaviour{
    
    private GameObject[] m_pop_point = new GameObject[5];
    private GameObject[] m_end_point = new GameObject[5];

    private NavMeshAgent m_navmesh_agent;
    private Animator m_animator;

    private float m_time_count = 0.0f;

    enum STATE{
        WAIT,
        MOVE,
        DIE
    }; STATE e_state;

    private void Update(){
        switch(e_state){
            case STATE.WAIT:
                m_time_count += Time.deltaTime;

                if(m_time_count > 1.0f){
                    m_animator.SetBool("animation_move", true);
                    m_navmesh_agent.SetDestination(m_end_point[0].transform.position); // タスク1
                    e_state = STATE.MOVE;
                }
            break;

            case STATE.MOVE:

            break;

            case STATE.DIE:
                m_time_count += Time.deltaTime;

                if(m_time_count > 2.0f){
                    m_animator.SetBool("animation_die", false);
                    MobState(false);
                }
            break;
        }
    }

    private void OnTriggerEnter(Collider a_collider){
        if((e_state == STATE.WAIT) || (e_state == STATE.DIE)) return;

        if(a_collider.gameObject.tag == "Finish"){ // タスク2
            m_animator.SetBool("animation_move", false);
            m_animator.SetBool("animation_die", true);
            m_time_count = 0.0f;
            e_state = STATE.DIE;
        }
    }

    public void Initialize(){
        m_navmesh_agent = GetComponent<NavMeshAgent>();
        m_animator = GetComponent<Animator>();
        m_pop_point[0] = GameObject.Find("PopPoint"); // タスク3
        m_end_point[0] = GameObject.Find("Goal"); // タスク3
    }

    public void MobState(bool a_bool){
        if(a_bool){
            this.gameObject.transform.position = m_pop_point[0].transform.position; // タスク1
            m_navmesh_agent.enabled = true; // 補足1
            m_time_count = 0.0f;
            e_state = STATE.WAIT;
        }else{
            m_navmesh_agent.enabled = false; // 補足1
            this.gameObject.SetActive(false);
        }
    }
}

/*
    [規則]
    p_ 外部アクセス
    m_ メンバー変数
    l_ ローカル変数
    a_ 引数

    [説明]
    補足1 真だと座標移動時に障害物が干渉して初期位置にズレが発生する

    [バージョン]
    2020-12-12 プーリングとナビゲーション
    2020-01-03 アセットストアのモデル反映とアニメーション

    [タスク]
    タスク1 拠点の占拠状態で分岐が必要
    タスク2 プーリング動作確認用のため消去する
    タスク3 沸く場所全ての設定が必要
*/

アセットモデルの反映

今回からアセットストアを使用していきます。

今回使用するのは可愛い世界観のモデルを数多く出品しているSURIYUN様のモデルです。

ゲームを完成させる頃には一部のキャラクターだけでも自作物を導入したいと考えておりますが、全て自作となると挫折する可能性が高いため1作目はアセットストアのパワーを借りつつ完成を目指したいと思います。

アセットモデルの反映は現在モブとして使用している丸形のオブジェクトと同じ構成(以下リストに表示)にしてCenterMobManagerEnemy.csの外部アクセスp_mob_prefabにアタッチするだけです。

  • BoxCollider
  • Rigidbody
  • NavMeshAgent
  • CenterMobEnemy.cs

アニメーション

今回のアニメーションは以下の3つの動きを実装します。

待機(Idle)

待機のモーションでスタート地点にポップする(数秒間待機する)

移動(Move)

移動のモーションでゴール地点へ向かう

終了(Die)

終了モーションを実行してからオブジェクトを休憩させる

アニメーションのモーションはモデルに付属している物を使用。

アニメーションの切り替えはアニメーターコントローラーによるノードによる分岐を使用します。

m_animator.SetBool("animation_move", true);
m_animator.SetBool("animation_move", false);
m_animator.SetBool("animation_die", true);
m_animator.SetBool("animation_die", false);

ノードの遷移にはboolの真偽により行き来するようにします。

if((e_state == STATE.WAIT) || (e_state == STATE.DIE)) return;

OnTriggerEnter関数内の上記プログラムで沸いた瞬間や倒された後のアニメーション中は他からの干渉を受けないようにしています。

enum STATE{
    WAIT,
    MOVE,
    DIE
}; STATE e_state;

今後はアップデート関数内で列挙型を使用した分岐でキャラクターの動作を追加及び制御していきます。


今回から使用するアセット


動画


記事のリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です