【问题标题】:Wait at waypoint for amount of time in unity C#在统一C#中等待航路点的时间量
【发布时间】:2020-01-26 13:12:55
【问题描述】:

我在 Unity 2D 项目中有一个航点系统,其中游戏对象将按顺序跟随每个航点,然后重复该过程,我希望游戏对象在每个点停止一段固定的时间,我认为我可以实现这使用协程但不完全确定如何实现这一点,到目前为止我所做的是创建一个名为 WaitAtPoint 的协程,然后在每个航路点移动时调用它但无济于事,不确定我做错了什么。

public class BrainBoss : MonoBehaviour {
[SerializeField]
Transform[] waypoints;

[SerializeField]
float moveSpeed = 2f;

int waypointIndex = 0;


// Start is called before the first frame update
void Start()
{
    transform.position = waypoints[waypointIndex].transform.position;
}

// Update is called once per frame
void Update()
{
    Move();
}

void Move()
{
    transform.position = Vector2.MoveTowards(transform.position, 
        waypoints[waypointIndex].transform.position, moveSpeed * Time.deltaTime);

    if(transform.position == waypoints[waypointIndex].transform.position)
    {
        StartCoroutine(WaitAtPoint());
        waypointIndex += 1;
    }

    if(waypointIndex == waypoints.Length)
    {
        waypointIndex = 1;
    }
}

IEnumerator WaitAtPoint()
{
    yield return new WaitForSeconds(3f);
}

}

【问题讨论】:

    标签: c# unity3d coroutine


    【解决方案1】:

    您在每次更新时都调用 Move,并且您也可能多次调用 StartCoroutine,所以我建议使用变量来查看是否应该更新运动

    public class BrainBoss : MonoBehaviour
    {
    [SerializeField]
    Transform[] waypoints;
    
    [SerializeField]
    float moveSpeed = 2f;
    
    int waypointIndex = 0;
    private bool shouldMove = true;
    
    
    // Start is called before the first frame update
    void Start() {
        transform.position = waypoints[waypointIndex].transform.position;
    }
    
    // Update is called once per frame
    void Update() {
        if (this.shouldMove) {
            Move();
        }
    }
    
    void Move() {
        transform.position = Vector2.MoveTowards(transform.position,
            waypoints[waypointIndex].transform.position, moveSpeed * Time.deltaTime);
    
        if (transform.position == waypoints[waypointIndex].transform.position) {
            StartCoroutine(WaitAtPoint(3));
            waypointIndex += 1;
        }
    
        if (waypointIndex == waypoints.Length) {
            waypointIndex = 1;
        }
    }
    
    IEnumerator WaitAtPoint(int seconds) {
        this.shouldMove = false;
        int counter = seconds;
        while (counter > 0) {
            yield return new WaitForSeconds(1);
            counter--;
        }
    
        this.shouldMove = true;
    }
    

    }

    【讨论】:

    • 完美,现在使用变量检查是否应该移动是有意义的,它直接在我的脑海中浮现,从没想过用计数器循环,或者我喜欢这个设置它运作良好,非常感谢跨度>
    【解决方案2】:

    您可以使用一个简单的布尔标志来知道您是否应该移动。在移动(或更新)中,检查该布尔值以了解您是否应该移动。

    在 WaitAtPoint 中,将 bool(如 shouldWait)设置为 true,然后在 WaitForSecond 之后返回 false!

    【讨论】:

      【解决方案3】:

      嗯,您的 WaitAtPoint 目前并没有做很多事情。这是因为它在 IEnumerator 内部等待,而不是在您调用它的位置。

      有多种方法可以解决这个问题,但我建议在等待时间后执行的 IEnumerator 上使用 callback

      像这样:

      private bool isWaiting;
      
      void Update() {
          if (!isWaiting) {
              Move();
          }
      }
      
      void Move()
      {
          transform.position = Vector2.MoveTowards(transform.position, 
              waypoints[waypointIndex].transform.position, moveSpeed * Time.deltaTime);
      
          if(transform.position == waypoints[waypointIndex].transform.position)
          {
              StartCoroutine(WaitAtPoint(() => 
              {
                  // All code that should be executed after waiting here.
                  waypointIndex += 1;
              }));
      
          }
      
          if(waypointIndex == waypoints.Length)
          {
              waypointIndex = 1;
          }
      }
      
      IEnumerator WaitAtPoint(Action callback)
      {
          isWaiting = true;
          yield return new WaitForSeconds(3f);
          callback.Invoke();
          isWaiting = false;
      }
      

      【讨论】:

      • 我喜欢这个概念,但如果你像 OP 一样在 Update 中启动它,你不会启动大量协程吗?不像 OP 那样无论如何都不会这样做,但是......
      • 是的,你是对的,我错过了。所以我想无论如何你在当前结构中都需要一个布尔标志。更新了答案
      猜你喜欢
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多