Пятница, 22 Ноября 2024, 12:27

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Проблема со стабилизацией после движения объекта
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).
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг