アニメーションが終了したときに毎回イベントを呼ぶようにして、中身のメソッドを変えてみました。
キャラクターにはアニメーターとスクリプトが付いています。アニメーターコントローラーでは、何も無いステートから、トリガーによってモーションのアタッチされたステートへ即遷移するようにしています。
スクリプトでは、モーションの付いたステートが終了するときに、進行管理するスクリプトの終了イベントを呼ぶようにしています。進行管理のスクリプトはタグと名前で探すようにしてみました。
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のままだと何もしません。