【Unity】何かが終了したときにイベントを実行する

投稿者: | 2020-12-05

アニメーションが終了したときに毎回イベントを呼ぶようにして、中身のメソッドを変えてみました。

キャラクターにはアニメーターとスクリプトが付いています。アニメーターコントローラーでは、何も無いステートから、トリガーによってモーションのアタッチされたステートへ即遷移するようにしています。

スクリプトでは、モーションの付いたステートが終了するときに、進行管理するスクリプトの終了イベントを呼ぶようにしています。進行管理のスクリプトはタグと名前で探すようにしてみました。

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

public class Actor : MonoBehaviour
{
    [SerializeField] string motionName;
    Animator animator;

    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName(motionName) && animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.98f)
        {
            foreach (GameObject obj in GameObject.FindGameObjectsWithTag("Manager"))
            {
                if (obj.name == "ProgressManager")
                {
                    obj.GetComponent<ProgressManager>().EndEvent(this.gameObject);// 終了イベントを実行
                }
            }
            
        }
    }
}

進行管理では、キー入力でキャラクターのトリガーをセットして、イベントにメソッドを設定するようにしています。そのメソッドでは、キャラクターの胸辺りのボーンの位置にCubeをおいて、キャラクターを削除し、イベントの中身を空にしています。

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

public class ProgressManager : MonoBehaviour
{
    [SerializeField] GameObject actor;
    [SerializeField] GameObject cube;
    [SerializeField] MeshRenderer planeMeshRenderer;

    delegate void EndEventHandler(GameObject sender);
    event EndEventHandler endEventHandler;

    public void EndEvent(GameObject sender)
    {
        if (endEventHandler != null) endEventHandler(sender);
    }

    void EndEvent1(GameObject sender)
    {
        // Cubeと置き換える
        Transform bone = sender.transform.GetChild(0).GetChild(0).GetChild(2).GetChild(0).GetChild(0);
        Instantiate(cube, bone.position, cube.transform.rotation);
        Destroy(sender);

        endEventHandler = null;
    }

    void EndEvent2(GameObject sender)
    {
        // 床を赤くする
        planeMeshRenderer.material.SetColor("_BaseColor",Color.red);

        endEventHandler = null;
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            actor.GetComponent<Animator>().SetTrigger("Walk"); // トリガーをセット
            endEventHandler = EndEvent1; // 終了イベントを設定
            //endEventHandler = EndEvent2;
        }
    }
}

これで冒頭のGifのように、アニメーションが終わるとキャラクターがCubeと置き換わるようになりました。

イベントに入れるメソッドを変えれば、キャラクターのスクリプトの内容を変えなくても、終了時の処理を変えられます。

イベントがnullのままだと何もしません。

コメントを残す

メールアドレスが公開されることはありません。