Подождите в точке маршрута количество времени в единстве C # - PullRequest
2 голосов
/ 26 сентября 2019

У меня есть система путевых точек в проекте Unity 2D, где GameObject будет следовать за каждой путевой точкой по порядку, а затем повторять процесс, я хочу, чтобы GameObject останавливался в каждой точке в течение фиксированного периода времени, и я думал, что смогу достичьэто с использованием сопрограммы, но не совсем уверенный в том, как этого добиться, я до сих пор создал сопрограмму с именем 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);
}

}

Ответы [ 3 ]

2 голосов
/ 26 сентября 2019

Ну, ваш WaitAtPoint не очень много делает в данный момент.Это потому, что он ожидает внутри IEnumerator, а не там, где вы его вызываете.

Существуют различные способы решения этой проблемы, но я бы предложил использовать callback на вашем IEnumerator, который выполняется после времени ожидания.

Например:

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;
}
2 голосов
/ 26 сентября 2019

Вы вызываете 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 голосов
/ 26 сентября 2019

Вы можете использовать симметричный флаг bool, чтобы знать, следует ли вам двигаться или нет.В Move (или Update) проверьте, чтобы этот bool знал, нужно ли вам двигаться.

В WaitAtPoint установите bool (например, shouldWait) в значение true, а затем в false после WaitForSecond!

...