0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

static class でコルーチンを実行する邪悪なコード

Last updated at Posted at 2025-04-28

一種のネタコードとして、
static class でコルーチンを実行する方法を紹介してみたいと思います。


紹介するコード

static class でコルーチンを実行する邪悪なコード
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

public static class CommonScript
{
    private static CommonScriptBootstrapper coroutineRunner;

    public class CommonScriptBootstrapper : MonoBehaviour
    {
        void Awake()
        {
            CommonScript.SetRunner(this);

            // シーンアンロードイベント登録
            SceneManager.sceneUnloaded += OnSceneUnloaded;
        }

        void OnDestroy()
        {
            // イベント解除(メモリリーク防止)
            SceneManager.sceneUnloaded -= OnSceneUnloaded;
        }

        private void OnSceneUnloaded(Scene scene)
        {
            // シーンがアンロードされたら、実行中のコルーチンを停止
            StopAllCoroutines();
        }
    }

    static CommonScript()
    {
        SceneManager.sceneLoaded += (scene, mode) =>
        {
            SetupBootstrapper();
        };
        SetupBootstrapper();
    }

    private static void SetupBootstrapper()
    {
        GameObject go = GameObject.Find("CommonScriptBootstrapper");
        if (go == null)
        {
            go = new GameObject("CommonScriptBootstrapper");
            go.AddComponent<CommonScriptBootstrapper>();
            GameObject.DontDestroyOnLoad(go);
        }
    }

    public static void SetRunner(CommonScriptBootstrapper runner)
    {
        coroutineRunner = runner;
    }

    //以下に static メソッドを記述
    //coroutineRunner?.StartCoroutine でコルーチンを実行可能

    public static void ExecCoroutine()
    {
        coroutineRunner?.StartCoroutine(CoroutineMethod());
    }

    private static IEnumerator CoroutineMethod()
    {
        Debug.Log("time: " + 1);
        yield return new WaitForSeconds(5);
        Debug.Log("time: " + 2);
        yield return new WaitForSeconds(5);
        Debug.Log("time: " + 3);
        yield return new WaitForSeconds(5);
        Debug.Log("time: " + 4);
    }

    //実行元が MonoBehaviour で
    //実行元と一蓮托生の場合はこの方法でコルーチンを生成するべきである。
    public static void ExecCoroutineDefailt(MonoBehaviour rootMono)
    {
        rootMono.StartCoroutine(CoroutineMethod());
    }
}

コードの解説

  • GameObjectの生成
    CommonScriptBootstrapper という名前の GameObject を動的に生成し、
    MonoBehaviour を継承した CommonScriptBootstrapper をアタッチしています。

  • コルーチン実行用ランナーの確保
    作成したオブジェクトによって、static なスコープでもコルーチン (StartCoroutine) の呼び出しが可能になります。

  • クラス分割について
    コメントで区切るだけでなく、CommonScriptBootstrapper を別ファイルに切り出すのも良いでしょう。
    責任の分離が明確になります。


注意点

本来、コルーチンは MonoBehaviour を継承したインスタンスから実行するのが自然です。
この手法はあくまで邪悪な裏技であり、
本番運用する際は十分注意が必要です。

どうしても static class からコルーチンを実行したい場合に、
参考程度にしていただければと思います。


最後に

この記事が皆さんにとって
ちょっとしたネタやアイデアの種になれば幸いです。

ご覧いただき、ありがとうございました!


追記

文章を作成した後に
ChatGPT で文章を添削しています。

文章の添削に生成 AI を使用する事が
苦手な方は、申し訳ありませんがご容赦頂けるよう
よろしくお願いします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?