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.Wandering
和 Input.Nothing
是什么? ...您能否编辑您提供的代码以将其变成一个最小的可复制示例?
@Chestera,我试过这个(以及不同形式的这个),不幸的是,它没有帮助
@derHugo、Input.Wandering
和 Input.Nothing
与此处无关。 StateMachine.NextState
致电StateTransition.Execute
。
可以填写do something块吗?
【参考方案1】:
好的,我想通了。
我将我的 action
类型从 IEnumerator
更改为 System.Func<IEnumerator>
并且......它成功了!
现在我的代码如下所示:
////////////////////////////////////////////////////////////////////////////
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,协程无法启动的主要内容,如果未能解决你的问题,请参考以下文章