首页 > 解决方案 > 使用 C# 从 Unity 中的静态方法调用 IEnumerator 的最佳方法

问题描述

编辑器:Unity - C#

你能给我一些信息和提示我如何从静态方法启动 IEnumerator。到目前为止,我所知道的是以下选项:

A):使调用 IEnumerator 的方法 (METHOD_1) 成为非静态的,然后像这样搜索脚本

FindObjectOfType<Scriptname>().METHOD_1();

B):使用 MonoBehaviour 启动协程

Scriptname.METHOD_1(this);

public static void METHOD_1(MonoBehaviour StartThisStatic)
{
    StartThisStatic.StartCoroutine(Test());
}
public static IEnumerator Test()
{
    yield return new WaitForSeconds(2f);
}

C):在唤醒/启动中使用实例

就性能和稳定性而言,最佳选择是什么?可以简单的给我解释一点背景知识吗?

非常感谢!

标签: c#unity3d

解决方案


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoroutineController : MonoBehaviour
{

    static CoroutineController _singleton;
    static Dictionary<string,IEnumerator> _routines = new Dictionary<string,IEnumerator>(100);

    [RuntimeInitializeOnLoadMethod( RuntimeInitializeLoadType.BeforeSceneLoad )]
    static void InitializeType ()
    {
        _singleton = new GameObject($"#{nameof(CoroutineController)}").AddComponent<CoroutineController>();
        DontDestroyOnLoad( _singleton );
    }

    public static Coroutine Start ( IEnumerator routine ) => _singleton.StartCoroutine( routine );
    public static Coroutine Start ( IEnumerator routine , string id )
    {
        var coroutine = _singleton.StartCoroutine( routine );
        if( !_routines.ContainsKey(id) ) _routines.Add( id , routine );
        else
        {
            _singleton.StopCoroutine( _routines[id] );
            _routines[id] = routine;
        }
        return coroutine;
    }
    public static void Stop ( IEnumerator routine ) => _singleton.StopCoroutine( routine );
    public static void Stop ( string id )
    {
        if( _routines.TryGetValue(id,out var routine) )
        {
            _singleton.StopCoroutine( routine );
            _routines.Remove( id );
        }
        else Debug.LogWarning($"coroutine '{id}' not found");
    }
    public static void StopAll () => _singleton.StopAllCoroutines();
    
}

然后:

CoroutineController.Start( Test() );

您还可以通过给它们标签来停止特定的协程:

CoroutineController.Start( Test() , "just a test" );

// <few moments later, meme>

CoroutineController.Stop( "just a test" );

推荐阅读