【Unity】デリゲートで少し複雑な進行管理をする

投稿者: | 2020-10-04

デリゲートでゲームの進行管理をするゲームの進行条件が複数あるときの方法で、少し複雑な進行条件を作ってみました。

上の動画では、青いCubeをクリックすると赤いコライダーが出現するようになっています。次の状態に進行するには、赤いCubeのクリックと赤いコライダーの侵入の2つが無いといけません。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.IO;

public class GameScript : MonoBehaviour
{
    [SerializeField] GameObject collider; // 赤いコライダー
    [SerializeField] Text text;

    public static bool onTriggerEnter;

    float sec;
    Transform playerHead;

    delegate void Method(); // デリゲートを定義
    Method method;

    // Start is called before the first frame update
    void Start()
    {
        collider.SetActive(false);
        text.text = "";
        playerHead = Camera.main.transform;

        method += Method1;
        method += Method2;
    }

    // Update is called once per frame
    void Update()
    {

        method();

    }
  
    void Method1()
    {
        RaycastHit hit;

        // 青いCubeをクリックした時
        if(Input.GetMouseButtonDown(0) && Physics.Raycast(playerHead.position, playerHead.forward,out hit, 2f, ~(1 << 9)))
        {
            if (hit.collider.name == "Cube1")
            {

                method += Method4; // 次のメソッドを入れる
                method -= Method1; // メソッドを削除
                Destroy(hit.transform.gameObject); // Cubeを削除

                collider.SetActive(true); // 赤いコライダーを表示            
            }
        }

    }

    void Method2()
    {
        RaycastHit hit;

        // 赤いCubeをクリックした時
        if (Input.GetMouseButtonDown(0) && Physics.Raycast(playerHead.position, playerHead.forward, out hit, 2f,~(1 << 9)))
        {
            if (hit.collider.name == "Cube2")
            {
                method -= Method2; // メソッドを削除
                Destroy(hit.transform.gameObject);

                // デリゲートが空のとき
                if (method == null)
                {
                    text.text = "ゲーム終了";
                    method = Method3;
                }
            }
        }

    }

    void Method3()
    {
        sec += Time.deltaTime;

        if (sec >= 3f)
        {
            sec = 0f;
            SceneManager.LoadScene("New Scene");
        }
    }
    void Method4()
    {
        // 赤いコライダーに入ったら
        if (onTriggerEnter)
        {
            onTriggerEnter = false;
            collider.SetActive(false); // 赤いコライダーを非アクティブ

            method -= Method4; // メソッドを削除

            // デリゲートが空のとき
            if (method == null)
            {
                text.text = "ゲーム終了";
                method = Method3;
            }
        }
    }   

}

Start()でデリゲートに2つのメソッドを入れます。赤いCubeをクリアしたときは前と同じですが、青いCubeをクリックすると、別のメソッドと入れ替えて、赤いコライダーをアクティブにします。

method += Method4; // 次のメソッドを入れる
method -= Method1; // メソッドを削除
Destroy(hit.transform.gameObject); // Cubeを削除

collider.SetActive(true); // 赤いコライダーを表示    

新しいメソッドでは、コライダーに入ったときにそのメソッドをデリゲートから削除し、デリゲートが空なら最後のメソッドだけが入っている状態にします。

void Method4()
{
    // 赤いコライダーに入ったら
    if (onTriggerEnter)
    {
        onTriggerEnter = false;
        collider.SetActive(false); // 赤いコライダーを非アクティブ

        method -= Method4; // メソッドを削除

        // デリゲートが空のとき
        if (method == null)
        {
            text.text = "ゲーム終了";
            method = Method3;
        }
    }
}

コライダーに入ったかどうかは、プレイヤーのスクリプトのOnTriggerEnterでわかります。

private void OnTriggerEnter(Collider other)
{
    if (other.tag == "Collider")
    {
        GameScript.onTriggerEnter = true;
    }
}

赤いコライダーに入ったときに、赤いCubeがまだクリックされていなければ、ゲームが進行しません。どの順番でクリアしても、赤いCubeと赤いコライダーがなくならなければ、次の状態にいかないようになっています。

これで、デリゲートを使って少し複雑な進行管理ができました。

コメントを残す

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