【问题标题】:Universal type for any yield type任何产量类型的通用类型
【发布时间】:2021-06-12 12:33:35
【问题描述】:

试图让系统能够存储任何类型的屈服指令

YieldInstruction m_yield;

void SetInstruction()
{
    switch(condition)
    {
        case UseWait:
            m_yield = new WaitForSeconds(1f);
            break;
        case UseWaitUntil:
            m_yield = new WaitUntil(() => flag == true); // Cannot cast here
    }
}

将类型更改为 IEnumerator 会将问题放在第一个问题上。 CustomeYieldInstruction 也不做。

我无法确定 YieldInstruction 和 CustomYieldInstruction 之间的关系。尽管有名字,一个是它自己的基类型,而后者是 IEnumerator。

我也很困惑,因为这两种方法可以在 IEnumerator 方法中产生,但如果按照我的尝试完成则不会强制转换。

public sealed class WaitForSeconds : YieldInstruction{ /* ** */ }
public class YieldInstruction { }

public sealed class WaitUntil : CustomYieldInstruction { /* ** */}
public abstract class CustomYieldInstruction : IEnumerator { /* ** */ }

我可以做到:

public IEnumerator Sequence()
{
     yield return new WaitForSeconds(1f),
     yield return new WaitUntil(()=> condition == true);
}

【问题讨论】:

    标签: c# unity3d coroutine yield


    【解决方案1】:

    除了Menyus' answer

    我想说使用object 对我来说有点太脏了。

    但是您可以简单地为那些自己不实现它的类型构建一个包装器IEnumerator(就像任何基于内部时间的东西):

    private IEnumerator WaitForYieldInstruction(YieldInstruction instruction)
    {
        yield return instruction;
    }
    

    然后使用

    IEnumerator m_yield;
    
    void SetInstruction()
    {
        switch(condition)
        {
            case UseWait:
                m_yield = WaitForYieldInstruction(new WaitForSeconds(1f));
                break;
            case UseWaitUntil:
                m_yield = new WaitUntil(() => flag); 
                break;
        }
    }
    

    【讨论】:

    • 确实我会说避免Object。优雅的解决方案。我目前正在为 YieldInstructions 编写一个包装类,但我更喜欢这个我可能不会发布它。
    • 我们确实有一些我们自己的称为 Yield 的“丑陋”包装器,我希望避免使用它。我宁愿拥有那个,因为它不会创建新类型。谢谢。
    【解决方案2】:

    YieldInstruction 得到 Unity 内部系统的特殊处理。如果你只看WaitUntil,它不需要内部引擎(C/C++)的特殊处理,因为它只需要一个 C# 谓词。另一方面,WaitForSecondsWaitForEndOfFrame ofc 需要一些特殊处理。前者需要内部定时器,后者需要协程调度器在帧结束时产生特殊中断,这对于托管脚本来说是不可能的。

    也不要忘记你可以产生任何东西! null 也没有实现IEnumeratorstring 等。

    当您调用StartCoroutine(MyCoroutine); 时,您基本上是将方法注册到 Unity 的协程调度程序中,并且它是用 C/C++ 实现的。

    回到你原来的问题。幸运的是,在 C# 中,每个类都继承自 System.Object,因此它们可以拥有一个基类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-15
      • 2022-01-21
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多