Vector2.MoveTowards в корутине
Суть: 2D бесконечный раннер, игрок не успел среагировать, препятствие "отодвинуло" персонажа. И дабы всю игру персонаж не бежал где-то сбоку, через время возвращать его назад на середину экран, тобеж на нулевую координату по X. У препятствий тег "Barrier". По коду, приведенному ниже, ничего не происходит. Сама корутина запускается (проверено посредством Debug.Log), а MoveTowards не срабатывает. Скрипт висит на персонаже.
public float returnSpeed;
[SerializeField] private Transform target;
public void Start()
{
target = transform;
target.position = new Vector2(0f, 0f);
}
public void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.CompareTag("Barrier") && (transform.position.x < 0))
{
StartCoroutine("ReturnPositionToZero");
}
}
private IEnumerator ReturnPositionToZero()
{
yield return new WaitForSeconds(3);
var step = returnSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, target.position, step);
}
Ответы (1 шт):
Автор решения: Valera Kvip
→ Ссылка
- returnSpeed Нигде не инициализирован и равен нулю, а значит и step == 0.
- ReturnPositionToZero Выполнится всего один раз через 3 секунды и движение может быть незаметно(зависит от returnSpeed).
Нужно примерно так:
returnSpeed = 5;// подбери нужное число
private IEnumerator ReturnPositionToZero()
{
yield return new WaitForSeconds(3);//хз зачем
int iteration = 0;// просто что бы случайно не уйти в бесконечный
цикл(тогда редактор просто зависнет, а игра упадет)
float delta = 0.1f;// или любая дельта
while (Vector2.Distance(transform.position,target.position) > delta && iteration < 100)
{
iteration++;
var step = returnSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, target.position, step);
yield return new WaitForEndOfFrame();//ждем конца кадра
}
}
Немного ссылок:
https://docs.unity3d.com/ScriptReference/WaitForEndOfFrame.html
https://docs.unity3d.com/ScriptReference/Vector2.Distance.html