Unity IEnumerator,等待但不再完全执行被调用的函数

时间:2015-05-09 20:29:05

标签: c# unity3d

我正在编写一个游戏,其中包含一些记录玩家行为的逻辑,然后在同一时间以相同的顺序重放它们,但以后会涉及其他影响。

到目前为止,我的代码有点工作,它完全按照我的要求记录,然后完美地播放序列,但问题是时间问题。

作为一个简单的例子。如果角色要走A - >; B - > C但要在B处等待x时间,那么代码很容易遍历路径,但在给定时间内不会在B处停止。

所以我写了一些我认为可以处理的函数,你可以在这里看到。

private IEnumerator followSequence()
{
    // Loop through each action steps in sequence.
    foreach (Action step in sequence)
    {
        //Check if the action time is less than the current clock time.
        Debug.Log("Step.tick: " + step.tick + " || Clock.tick: " + clock.getTick());
        if (clock.getTick() < step.tick)
        {
            //If so wait out the difference to resync the action.
            yield return new WaitForSeconds(step.tick - clock.getTick());                
        }

        // Carry out the step.
        play(step);
    }
    yield break;
}

private void play(Action step)
{
    Debug.Log(step.type);

    // Set up a followpath script
    FollowPath follow = (player.GetComponent<FollowPath>() ? player.GetComponent<FollowPath>() : player.AddComponent<FollowPath>());

    // Tell the follow path script that object is not a guard.
    follow.isGuard = false;

    // Create a new point object on the map
    Transform aPoint = (Transform)Instantiate(PathPoint, step.point, Quaternion.identity);
    path.points.Add(aPoint);

    // Initiate movement.
    follow.Path = path;
    follow.TravelPath();

    // Check if action is an objective.
    if (step.type == Action.Type.Action)
    {
        step.actions.OnClick();
    }        
}

现在,如果我在第一个函数中注释掉*yield return new WaitForSeconds()*部分,则代码按预期工作,并完成序列中的步骤,而不是给定时间。

当相同的代码没有被注释掉时,时间工作完美,第二个*Debug.log("step.type")*在恰当的时间被调用,但角色不再移动,I.E。 *follow.TravelPath()*似乎永远不会被执行。

我试过让第二个函数成为IEnmerator并屈服于它。我尝试过自定义wait()函数。我试过屈服于TravelPath()函数。

有没有人有更多的想法我会跟进或者我可以尝试解决这个问题?

编辑:

按要求调用followSequence()的代码:

    private void playActions()
{
    // Reset player immediately to the starting position
    player.transform.position = sequence[0].point;

    // Stop the character and freeze the scene when alarm sounds!.
    player.GetComponent<IncrementController>().freeze();
    player.GetComponent<IncrementController>().enabled = false;

    // Restart the clock and scene.
    clock.Restart();
    sceneManager.restart();

    // Activate guard and remove sphere.
    guard.SetActive(true);
    guardShere.SetActive(false);

    // Stop recording;
    recording = false;
    line.SetActive(false);

    // Start playback sequence.
    StartCoroutine(followSequence());
}

1 个答案:

答案 0 :(得分:1)

行为符合预期,在你执行的行yield return上暂停执行上下文,直到你在枚举数上执行MoveNext()(显然从未发生),返回者followSequence

但是从评论中我可以看到,你只想等待几秒钟进行重新同步,这样你根本不需要返回。在您的情况下,如果您只是想跳过一段时间,我就不会发现您可能需要WaitForSeconds的可数的原因。如果您不知道如何调用该函数以及WaitForSeconds的实现,我建议您将其返回类型更改为void

private void followSequence()
{
    // Loop through each action steps in sequence.
    foreach (Action step in sequence)
    {
        //Check if the action time is less than the current clock time.
        Debug.Log("Step.tick: " + step.tick + " || Clock.tick: " + clock.getTick());
        if (clock.getTick() < step.tick)
        {
            //If so wait out the difference to resync the action.
            new WaitForSeconds(step.tick - clock.getTick());                
        }

        // Carry out the step.
        play(step);
    }
}