Unity,协程无法启动
Unity, Coroutine Won't Start
我有一个自己写的简单的有限状态机。我有过渡和状态。这是 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.如果这对你没有任何意义,我真的很抱歉,我只是不知道如何解释得更清楚。
好的,我明白了。
我将我的 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()
.
干杯!
我有一个自己写的简单的有限状态机。我有过渡和状态。这是 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.如果这对你没有任何意义,我真的很抱歉,我只是不知道如何解释得更清楚。
好的,我明白了。
我将我的 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()
.
干杯!