Unity,协程无法启动

Posted

技术标签:

【中文标题】Unity,协程无法启动【英文标题】:Unity, Coroutine Won't Start 【发布时间】:2020-07-15 17:00:37 【问题描述】:

我有一个由我编写的简单有限状态机。我有过渡和状态。这是StateTransition 从内部看的样子:

////////////////////////////////////////////////////////////////////////////

public delegate void ActionCaller(IEnumerator action); // Take note of this delegate

private readonly ActionCaller caller;
private readonly IEnumerator action; // This is my State action

////////////////////////////////////////////////////////////////////////////

public void Execute()

    caller.Invoke(action); // Here I call my `action` through `caller`


////////////////////////////////////////////////////////////////////////////

这是我的MonoBehaviour 代码,它创建了这个状态:

////////////////////////////////////////////////////////////////////////////
private void Start()

    // Here I initialize my states and pass a method which will be called in `StateTransition.Execute` to execute passed method and `CallAction` to start Coroutine in my `MonoBehaviour` class
    States = new Dictionary<State, StateTransition>()
    
         State.Idling, new StateTransition(State.Idling, DoNothing(), CallAction) ,
         State.WanderingAround, new StateTransition(State.WanderingAround, WanderAround(), CallAction) 
    ;

    StateMachine = new FiniteStateMachine(new List<Transition>()
    
        new Transition(States[State.Idling], States[State.WanderingAround], Input.Wandering),
        new Transition(States[State.WanderingAround], States[State.Idling], Input.Nothing)
    );

    StateMachine.NextState(Input.Wandering);


////////////////////////////////////////////////////////////////////////////

private void CallAction(IEnumerator routine)

    if (currentActionCoroutine != null)
    
        StopCoroutine(currentActionCoroutine);
    

    currentActionCoroutine = StartCoroutine(routine); // This code right here starts my passed `routine`


////////////////////////////////////////////////////////////////////////////

这就是问题所在,当我调用我的第一个NextState 时,它调用WanderAround,然后调用DoNothing,之后它应该再次调用WanderAround 就好了,但问题是它根本不称它为。没有发生任何错误。协程只是不想启动。但是,如果我打电话,比如说,DoNothing StartCoroutine(WanderAround()) - 它有效!但不是通过我奇怪的StateTransition/Action/Execute 关系。

////////////////////////////////////////////////////////////////////////////

private IEnumerator DoNothing()

    Debug.Log("DoNothing:Enter");

    do
    
        yield return new WaitForSeconds(2.5f);
     while (CurrentState == State.Dead);

    Debug.Log("DoNothing:Exit");

    StateMachine.NextState(Input.Wandering); // Calls `StateTransition.Execute`


private IEnumerator WanderAround()

    Debug.Log("WanderAround:Enter");

    Vector2 randomPosition = new Vector2(Random.Range(-5f, 5f), Random.Range(-5f, 5f));

    movementController.RotateAndMoveTo(randomPosition, Genes[Gene.MovementSpeed], Genes[Gene.TurnSpeed]);

    while (movementController.IsMoving || movementController.IsRotating)
    
        yield return new WaitForSeconds(Time.deltaTime);
    

    Debug.Log("WanderAround:Exit");

    StateMachine.NextState(Input.Nothing); // Calls `StateTransition.Execute`


////////////////////////////////////////////////////////////////////////////

我该怎么办?谢谢!

P.S.真的很抱歉,如果这对你没有任何意义,我只是不知道如何更清楚地解释它。

【问题讨论】:

我不确定,但在第一行将 void 更改为协程。我的意思是公共委托 Coroutine ActionCaller(IEnumerator action); StateMachine.NextState 是做什么的? Input.WanderingInput.Nothing 是什么? ...您能否编辑您提供的代码以将其变成一个最小的可复制示例? @Chestera,我试过这个(以及不同形式的这个),不幸的是,它没有帮助 @derHugo、Input.WanderingInput.Nothing 与此处无关。 StateMachine.NextState 致电StateTransition.Execute 可以填写do something块吗? 【参考方案1】:

好的,我想通了。

我将我的 action 类型从 IEnumerator 更改为 System.Func&lt;IEnumerator&gt; 并且......它成功了!

现在我的代码如下所示:

////////////////////////////////////////////////////////////////////////////

public delegate void ActionCaller(IEnumerator action); // Take note of this delegate

private readonly ActionCaller caller;
private readonly System.Func<IEnumerator> action; // This is my State action

////////////////////////////////////////////////////////////////////////////

public void Execute()

    caller(action()); // Here I call my `action` through `caller`


////////////////////////////////////////////////////////////////////////////

StateTransition 构造函数中,我通过SomeFunc 而不是SomeFunc()

干杯!

【讨论】:

以上是关于Unity,协程无法启动的主要内容,如果未能解决你的问题,请参考以下文章

无法启动协程,因为游戏对象处于非活动状态

Discord Bot 错误:无法向刚启动的协程发送非无值

TypeError:无法向刚启动的协程发送非无值

Unity自己实现协程

无法在 Unity 中启动外部进程

unity游戏启动如何调出