Проблема со стабилизацией после движения объекта
| |
urbemAngeli | Дата: Воскресенье, 04 Сентября 2016, 20:45 | Сообщение # 1 |
частый гость
Сейчас нет на сайте
| Всем добрый вечер! Пытаюсь реализовать движение из точки А в точку Б с плавным затуханием скорости. Вроде бы все просто - брать метод Lerp(текущая позиция, цель, время) и далее двигать объект, но такой подход меня не совсем устраивает. Проблема в том, что за весь период движения объекта к цели(по оси y из -15 к 0), объект достигает цели примерно за 60-70 процентов от этого периода, остальное время идет какое-то хаотическое изменение transform переменных по той оси, которую изменяем(6, 2, -0.001, -1, 4, 3 и т.д). Визуально эти скачки никак не проявляются. Больше понравился метод SmoothStep, однако там тоже присутствует такой эффект. Меня такое явление совсем не устраивает, так как после достижения к цели необходимо сразу объект двигать к следующей цели, а для этого нужно знать окончание предыдущего, и у меня получается что объект у цели а из за "скачков" переменных он вроде еще как движется. Подскажите что это за скачки и как их устранить?
Код public float speed; float endPos = 0; float y;
void Update() { //y = Mathf.Lerp(transform.position.y, _endPos, Time.time * speed); y = Mathf.SmoothStep(transform.position.y, endPos, Time.time / speed);
if (transform.position.y != 0) // Движемся пока не будем у цели { transform.position = new Vector3(transform.position.x, y, transform.position.z); } }
Сообщение отредактировал urbemAngeli - Воскресенье, 04 Сентября 2016, 21:02 |
|
| |
SkorpyX | Дата: Воскресенье, 04 Сентября 2016, 21:05 | Сообщение # 2 |
участник
Сейчас нет на сайте
| Это же float, точно 0 никогда не будет
|
|
| |
Lertmind | Дата: Воскресенье, 04 Сентября 2016, 21:08 | Сообщение # 3 |
заслуженный участник
Сейчас нет на сайте
| Для сравнения float используй Mathf.Approximately.
Цитата SkorpyX ( ) а почему у вас Time.time, а не Time.deltaTime? Потому что туда передаются значения от 0 до 1 с линейным характером. UPD: Даже пример из документации это предполагает https://docs.unity3d.com/ScriptReference/Mathf.SmoothStep.html, только у него без startTime и speed некорректно назван, потому что это переменная определяет промежуток времени, а не скорость.
Сообщение отредактировал Lertmind - Воскресенье, 04 Сентября 2016, 21:13 |
|
| |
SkorpyX | Дата: Воскресенье, 04 Сентября 2016, 21:15 | Сообщение # 4 |
участник
Сейчас нет на сайте
| Цитата Lertmind ( ) Потому что туда передаются значения от 0 до 1 с линейным характером. Time.time - это время с запуска игры в секундах
|
|
| |
Lertmind | Дата: Воскресенье, 04 Сентября 2016, 21:23 | Сообщение # 5 |
заслуженный участник
Сейчас нет на сайте
| SkorpyX, ага, пример смотрел из документации? Ещё раз на пальцах:
Код using UnityEngine; using System.Collections;
public class ExampleClass : MonoBehaviour { public float minimum = 10.0F; public float maximum = 20.0F; public float duration = 5.0F; private float startTime; void Start() { startTime = Time.time; // Время когда объект создался } void Update() { float t = (Time.time - startTime) / duration; // После создания объекта t = 0, потом t = 1 // когда прошедшее время от создания объекта равно продолжительности анимации, // после равно больше 1, но это не важно, так как будет ограничено maximum transform.position = new Vector3( Mathf.SmoothStep(minimum, maximum, t), 0, 0); // SmoothStep принимает t линейно относительно времени, // но возвращает значение с замедлением от minimum до maximum } }
Сообщение отредактировал Lertmind - Воскресенье, 04 Сентября 2016, 21:24 |
|
| |
Tymonr | Дата: Воскресенье, 04 Сентября 2016, 21:31 | Сообщение # 6 |
With OpenSource forever♥
Сейчас нет на сайте
| Блин, я когда-то давно использовал офигенную формулу для смазывания движения до цели, буквально вот вчера пытался ее найти/вспомнить, но так и не смог
Если вы решили обратиться к нам за помощью, не становитесь в позицию неудачника. И не ведите себя как неудачник. Лучший способ получить быстрый и чуткий ответ, - спрашивать как победитель — спрашивать как человек умный, уверенный в себе и знающий, которому просто понадобилась помощь при решении одной конкретной проблемы. Как правильно задавать вопросы в технических форумах
|
|
| |
Lertmind | Дата: Воскресенье, 04 Сентября 2016, 21:36 | Сообщение # 7 |
заслуженный участник
Сейчас нет на сайте
| urbemAngeli, сейчас догадался, что тебе проще сравнить t:
Код float t = Time.time / speed; y = Mathf.SmoothStep(transform.position.y, endPos, t); if (t > 1) // Движемся пока не будем у цели { transform.position = new Vector3(transform.position.x, y, transform.position.z); } speed конечно надо переименовать и добавить startTime, как в документации.
|
|
| |
Tymonr | Дата: Воскресенье, 04 Сентября 2016, 21:52 | Сообщение # 8 |
With OpenSource forever♥
Сейчас нет на сайте
| Во, короче.
http://paulbourke.net/miscellaneous/interpolation/
Любая из интерполяций сойдет, линейной должно быть вполне достаточно
Код double LinearInterpolate( double y1,double y2, double mu) { return(y1*(1-mu)+y2*mu); }
param1 - целевая позиция param2 - текущая позиция mu - свой коэффициент*дельтуВремени для стабилизации
В конечном итоге очень плавненько подлетает к целевой точке
Если вы решили обратиться к нам за помощью, не становитесь в позицию неудачника. И не ведите себя как неудачник. Лучший способ получить быстрый и чуткий ответ, - спрашивать как победитель — спрашивать как человек умный, уверенный в себе и знающий, которому просто понадобилась помощь при решении одной конкретной проблемы. Как правильно задавать вопросы в технических форумах
|
|
| |
urbemAngeli | Дата: Воскресенье, 04 Сентября 2016, 22:18 | Сообщение # 9 |
частый гость
Сейчас нет на сайте
| Спасибо за ответы, завтра буду разбираться с возможным решениями
Сообщение отредактировал urbemAngeli - Воскресенье, 04 Сентября 2016, 22:25 |
|
| |
Lertmind | Дата: Воскресенье, 04 Сентября 2016, 23:28 | Сообщение # 10 |
заслуженный участник
Сейчас нет на сайте
| Tymonr, зачем ты привёл код, который соответствует Mathf.LerpUnclamped? И опечатка здесь: (1u), должно быть (1 - mu).
|
|
| |
|