2015-08-26 2 views
1

Итак, я пытаюсь создать скрипт для «последователя», который начнет следовать за игроком, столкнувшись с ним. Проблема в том, что я хочу, чтобы последователь дождался определенного времени, прежде чем двигаться к игроку после каждого разговора игрока.Проблемы с WaitForSeconds

Это работает, когда игрок сталкивается с ним. Он перемещается к игроку по истечении заданного времени, но когда игрок останавливается и движется снова, последователь палочки с игроком, а не ждет, пока данное время не закончится. Вот сценарий:

void Update() { 
    //running is a triggered true on colliding with player. 
    if(running == true){ 
     StopCoroutine(Move()); 
     StartCoroutine(Move()); 
    } 
} 
IEnumerator Move(){ 
    yield return new WaitForSeconds (0.5f); 
    Vector2 pos = transform.position; 
    Vector2 playerpos = player.transform.position; 
    playerpos.y = pos.y; 
    transform.position = Vector2.MoveTowards(pos, playerpos, 1f * Time.deltaTime); 
} 

Есть ли что-то, что я делаю неправильно?

Также есть еще одна проблема, последователь движется быстрее, чем заданная скорость.

Функция для движения игрока.

void Move(float horizontalinput){ 
    Vector3 pos = transform.position; 
    pos.x += horizontalinput * maxSpeed * Time.deltaTime; 
    transform.position = pos; 
} 

Я очень благодарен за помощь.

+0

Если я правильно понимаю, что если игрок перестает двигаться, то последователь будет продолжать следить, пока он не окажется в положении игрока. На этом этапе последователь сталкивается с игроком, снова заставляя Move запускаться еще раз. Но теперь последователь больше не будет сталкиваться с игроком, потому что он должен сначала выйти из игрового коллайдера. Думаю, вам стоит рассмотреть вопрос о том, движется ли игрок, а не проверять, столкнулся ли игрок с последователем. – Saaru

+0

Я просто добавил еще одно условие в инструкции if для проверки того, движется игрок или нет, и это помогло с синхронизацией, но есть еще одна проблема, которая все еще существует, что-то заставляет последователя двигаться быстрее, чем заданная скорость, «1f», и из-за этого последователь прилип к игроку, пока он движется. Я хочу, чтобы последователь следовал за игроком, и когда игрок останавливается, он должен переместиться в позицию игрока. – Stephen

+0

Хм .. это странно. Как вы можете сказать, что он движется быстрее, чем вы ожидаете? Вы уверены, что больше ничего не движет последователь? – Saaru

ответ

0

Вы можете попробовать:

Создайте переменную с именем _canMove и установить его на false. Тогда ваш Update будет:

private void Update() 
{ 
    if(_canMove) 
    { 
     Move(); 
    } 
} 

Ваш метод Move будет такой же, как в настоящее время, но минус WaitForSeconds линии. Затем, когда останавливается игрок запустить следующую строку, которая будет препятствовать методу Update от вызова Move метода:

_canMove = false 

Когда игрок начинает двигаться снова запустить следующее:

StartCoroutine(ResetCanMove); 

Это будет вызывать ResetCanMove который будет ждать х секунд перед установкой _canMove в true и, в свою очередь, вызовет Update, чтобы снова вызвать Move.

Вот ResetCanMove метод

private IEnumerator ResetCanMove() 
{ 
    yield return new WaitForSeconds(0.5f); 
    _canMove = true; 
} 
+0

Это действительно решило проблему! Благодарю. – Stephen

+0

Но остается еще одна проблема, когда игрок меняет направление без остановки, он снова начинает играть с игроком, а не ждет этого количества времени. Есть ли что-то, что я могу сделать, чтобы этого избежать? – Stephen

+0

Вы можете отслеживать текущее вращение игрока, а затем, когда изменения поворота вызывают «StartRoutine» так же, как когда игрок начинает двигаться. Я, вероятно, не сделал бы этого для каждого изменения вращения, потому что вращение могло быть небольшим. Вместо этого, возможно, проверьте, изменилось ли вращение на 5 градусов, затем вызовите 'StartCoroutine (ResetCanMove)'. – MotoSV

1

StopCoroutine(Move()); останавливает новый экземпляр сопрограммы, а не тот, который в настоящее время работает.

либо сделать:

StopCoroutine("Move"); 
StartCoroutine("Move"); 

или это:

private IEnumerator coroutine; 

void Update() { 
    //running is a triggered true on colliding with player. 
    if(running == true){ 
     StopCoroutine(coroutine); 

     if(coroutine != null) 
      coroutine = Move(); 

     StartCoroutine(coroutine); 
    } 
} 
0

В своем коде вы не правильно используя StopCoroutine ..

Вы можете сделать что-то вроде этого:

private Coroutine myCoroutine; 

void Update() 
{ 
    //running is a triggered true on colliding with player. 
    if(running == true) 
    { 
     if(myCoroutine != null) 
     { 
      StopCoroutine(myCoroutine); 
     } 

     myCoroutine = StartCoroutine(Move()); 
    } 
} 

Другим вариантом является использование Start и Stop coroutines с именем элемента, но вы будете использовать отражение, и это может повлиять на производительность вашей игры.

+0

Я исправил его уже, но это была не основная проблема, но спасибо! – Stephen