Помогите разобраться со временем и интерполяцией ... - Форум Игроделов
Чт, 30 Май 2024, 20:31 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Помогите разобраться со временем и интерполяцией ...
dostalitionДата: Пн, 06 Янв 2014, 15:27 | Сообщение # 1
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Поковырялся в справках и форумах, но так толком и не понял что конкретно такое и где применять Time.time и Time.deltaTime, а , так же, как с их помощью и Mathf.Lerp делать интерполяцию. Можете нормально разжевать эти темы или , хотя бы, скинуть ссылки на русском. Стал уже пробовать на самых примитивных примерах ... Есть объект, перемещаю его так
Код
function Update () { transform.position = Vector3(-75, Mathf.Lerp(75, 90, Time.time), 21); }
и он, как и нужно, плавно сменяет позицию ... Но , если добавляю к этому условие на нажатие клавиши
Код
function Update () {
if (Input.GetKeyDown(KeyCode.V)) transform.position = Vector3(-75, Mathf.Lerp(75, 90, Time.time), 21);  
  }
, то объект мгновенно перескакивает ... В чём тут проблема ?
 
СообщениеПоковырялся в справках и форумах, но так толком и не понял что конкретно такое и где применять Time.time и Time.deltaTime, а , так же, как с их помощью и Mathf.Lerp делать интерполяцию. Можете нормально разжевать эти темы или , хотя бы, скинуть ссылки на русском. Стал уже пробовать на самых примитивных примерах ... Есть объект, перемещаю его так
Код
function Update () { transform.position = Vector3(-75, Mathf.Lerp(75, 90, Time.time), 21); }
и он, как и нужно, плавно сменяет позицию ... Но , если добавляю к этому условие на нажатие клавиши
Код
function Update () {
if (Input.GetKeyDown(KeyCode.V)) transform.position = Vector3(-75, Mathf.Lerp(75, 90, Time.time), 21);  
  }
, то объект мгновенно перескакивает ... В чём тут проблема ?

Автор - dostalition
Дата добавления - 06 Янв 2014 в 15:27
ЛевшаДата: Пн, 06 Янв 2014, 16:24 | Сообщение # 2
Черный Волк
 
Сообщений: 7257
Награды: 30
Репутация: 3313
Статус: Offline
Цитата dostalition ()
В чём тут проблема ?

Параметр Time.time, он будет правильно работать только в одиночных интереполяциях при старте игры.
Параметр Time.time - это время прошедшее с начала игры.
Используй для повторяющихся интерполяций параметр - Time.deltaTime (время прошедшее с прошлого кадра).

Кроме того - интерполяция под условием GetKeyDown или GetKeyUp работать не будет, ей необходимо множество циклов Update.
Используй условие GetKey


X.cor.R (Prologue)
 
Сообщение
Цитата dostalition ()
В чём тут проблема ?

Параметр Time.time, он будет правильно работать только в одиночных интереполяциях при старте игры.
Параметр Time.time - это время прошедшее с начала игры.
Используй для повторяющихся интерполяций параметр - Time.deltaTime (время прошедшее с прошлого кадра).

Кроме того - интерполяция под условием GetKeyDown или GetKeyUp работать не будет, ей необходимо множество циклов Update.
Используй условие GetKey

Автор - Левша
Дата добавления - 06 Янв 2014 в 16:24
ilyakosДата: Пн, 06 Янв 2014, 16:34 | Сообщение # 3
 
Сообщений: 171
Награды: 0
Репутация: 8
Статус: Offline
На java не умею, но там как-то вроде по координатам плавно перемещать так:
к примеру:
Код
var b:Transform;
var speed: float = 2f;

function Update(){
if(Input.GetKey(KeyCode.V)){
transform.position.x = Mathf.Lerp(transform.position.x,b.position.x, Time.deltaTime*speed);
}
}

И так же по другим координатам, если я не о том, извините smile
 
СообщениеНа java не умею, но там как-то вроде по координатам плавно перемещать так:
к примеру:
Код
var b:Transform;
var speed: float = 2f;

function Update(){
if(Input.GetKey(KeyCode.V)){
transform.position.x = Mathf.Lerp(transform.position.x,b.position.x, Time.deltaTime*speed);
}
}

И так же по другим координатам, если я не о том, извините smile

Автор - ilyakos
Дата добавления - 06 Янв 2014 в 16:34
dostalitionДата: Пн, 06 Янв 2014, 17:35 | Сообщение # 4
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Ну, вот, в примере ilyakos-а , как Я уже пробовал, получается, что объект перемещается постоянно, пока нажата клавиша, а Мне нужно, чтобы это произошло однократно ... И что значит "время, прошедшее с прошлого кадра" ??? Я уже встречал это определение, но так и не понял ... Сколько может пройти времени с прошлого кадра ?
 
СообщениеНу, вот, в примере ilyakos-а , как Я уже пробовал, получается, что объект перемещается постоянно, пока нажата клавиша, а Мне нужно, чтобы это произошло однократно ... И что значит "время, прошедшее с прошлого кадра" ??? Я уже встречал это определение, но так и не понял ... Сколько может пройти времени с прошлого кадра ?

Автор - dostalition
Дата добавления - 06 Янв 2014 в 17:35
ilyakosДата: Пн, 06 Янв 2014, 17:37 | Сообщение # 5
 
Сообщений: 171
Награды: 0
Репутация: 8
Статус: Offline
А ты введи булевую переменную и при нажатии клавиши делай ее true, и когда она true - меняй координаты...

Сообщение отредактировал ilyakos - Пн, 06 Янв 2014, 17:39
 
СообщениеА ты введи булевую переменную и при нажатии клавиши делай ее true, и когда она true - меняй координаты...

Автор - ilyakos
Дата добавления - 06 Янв 2014 в 17:37
dostalitionДата: Пн, 06 Янв 2014, 19:47 | Сообщение # 6
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Пробовал - тоже самое получается ...
 
СообщениеПробовал - тоже самое получается ...

Автор - dostalition
Дата добавления - 06 Янв 2014 в 19:47
seamanДата: Пн, 06 Янв 2014, 20:36 | Сообщение # 7
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
А где мой пост? Блин не сохранил, что ли?
Цитата
И что значит "время, прошедшее с прошлого кадра" ???

Я вот не понимаю - как это можно не понять? "Время, прошедшее с прошлого кадра" именно это и означает. Именно то, что написано! Может непонятно почему это нужно знать? А вот посмотрите - у каждого своя видеокарта. У каждого своя скорость отрисовки. Следовательно один кадр -вся сцена может рисоваться разное время! Чтобы не зависеть от железа пользователя и нужно знать - сколько времени прощло с отрисовки предыдущего кадра!
А! блин! Я понял, я не тут писал! Вот почему нет моего поста! Цитирую:
Цитата
Проверяйте клавишу и устанавливайте флаг. При установленном флаге двигайте и проверяйте достигли ли места. Когда достигли - сбрасывайте флаг. И используйте не прямо time, а разницу с временем начала движения.
Вообще нужно Вам изучать не время, а Lerp.
http://poqxert.ru/page/matematika-unity3d-urok-9-mathf-interpoljacii
http://poqxert.ru/page/matematika-unity3d-urok-13-vector-interpoljacii
 
СообщениеА где мой пост? Блин не сохранил, что ли?
Цитата
И что значит "время, прошедшее с прошлого кадра" ???

Я вот не понимаю - как это можно не понять? "Время, прошедшее с прошлого кадра" именно это и означает. Именно то, что написано! Может непонятно почему это нужно знать? А вот посмотрите - у каждого своя видеокарта. У каждого своя скорость отрисовки. Следовательно один кадр -вся сцена может рисоваться разное время! Чтобы не зависеть от железа пользователя и нужно знать - сколько времени прощло с отрисовки предыдущего кадра!
А! блин! Я понял, я не тут писал! Вот почему нет моего поста! Цитирую:
Цитата
Проверяйте клавишу и устанавливайте флаг. При установленном флаге двигайте и проверяйте достигли ли места. Когда достигли - сбрасывайте флаг. И используйте не прямо time, а разницу с временем начала движения.
Вообще нужно Вам изучать не время, а Lerp.
http://poqxert.ru/page/matematika-unity3d-urok-9-mathf-interpoljacii
http://poqxert.ru/page/matematika-unity3d-urok-13-vector-interpoljacii

Автор - seaman
Дата добавления - 06 Янв 2014 в 20:36
ilyakosДата: Вт, 07 Янв 2014, 11:25 | Сообщение # 8
 
Сообщений: 171
Награды: 0
Репутация: 8
Статус: Offline
Цитата ilyakos ()
Пробовал - тоже самое получается ...

Да быть такого не может...


Сообщение отредактировал ilyakos - Вт, 07 Янв 2014, 11:25
 
Сообщение
Цитата ilyakos ()
Пробовал - тоже самое получается ...

Да быть такого не может...

Автор - ilyakos
Дата добавления - 07 Янв 2014 в 11:25
dostalitionДата: Вт, 07 Янв 2014, 13:45 | Сообщение # 9
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
Цитата ilyakos ()
Да быть такого не может...
Пишу такой код
Код
var go = false;
var speed = 0.5f;

function Update () {
   if(go)transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);
   if (Input.GetKeyDown(KeyCode.V)) go =true;
   }
и объект, при нажатии клавиши, плавно, но без остановки, движется вверх ! ...
 
Сообщение
Цитата ilyakos ()
Да быть такого не может...
Пишу такой код
Код
var go = false;
var speed = 0.5f;

function Update () {
   if(go)transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);
   if (Input.GetKeyDown(KeyCode.V)) go =true;
   }
и объект, при нажатии клавиши, плавно, но без остановки, движется вверх ! ...

Автор - dostalition
Дата добавления - 07 Янв 2014 в 13:45
ЛевшаДата: Вт, 07 Янв 2014, 18:10 | Сообщение # 10
Черный Волк
 
Сообщений: 7257
Награды: 30
Репутация: 3313
Статус: Offline
Цитата
плавно, но без остановки, движется вверх

Именно это в твоем коде и написано...
Позиция каждый кадр увеличивается и каждый кадр к ней плюсуется + 5...
Конца процессу не будет.


X.cor.R (Prologue)
 
Сообщение
Цитата
плавно, но без остановки, движется вверх

Именно это в твоем коде и написано...
Позиция каждый кадр увеличивается и каждый кадр к ней плюсуется + 5...
Конца процессу не будет.

Автор - Левша
Дата добавления - 07 Янв 2014 в 18:10
ilyakosДата: Вт, 07 Янв 2014, 18:15 | Сообщение # 11
 
Сообщений: 171
Награды: 0
Репутация: 8
Статус: Offline
Код
var timeout: float;

if(timeout>0){
go = true;
timeout -= Time.deltaTime;
}else{
if(timeout<=0){
go = false;
}
   if(go) {
transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);   
     if (Input.GetKeyDown(KeyCode.V))  
timeout = 2.0f;
     }


Сообщение отредактировал ilyakos - Вт, 07 Янв 2014, 18:16
 
Сообщение
Код
var timeout: float;

if(timeout>0){
go = true;
timeout -= Time.deltaTime;
}else{
if(timeout<=0){
go = false;
}
   if(go) {
transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);   
     if (Input.GetKeyDown(KeyCode.V))  
timeout = 2.0f;
     }

Автор - ilyakos
Дата добавления - 07 Янв 2014 в 18:15
dostalitionДата: Вт, 07 Янв 2014, 20:41 | Сообщение # 12
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
smile Благодарю ! Пришлось , правда, привести твой скрипт в работоспособный вид
Код
var timeout: float;  
var speed = 0.5;

function Update(){

  if(timeout>0){  
  go = true;  
  timeout -= Time.deltaTime;  
  }
  else if(timeout<=0) go = false;   
  if(go) transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);    
  if (Input.GetKeyDown(KeyCode.V)) timeout = 2.0f;      
  }
Но , в итоге, работает , как надо, жаль только , что так замудрённо, Я бы сам не додумался ... smile Сейчас попробую прилепить что-то подобное к своему скрипту приседания ... smile

Добавлено (07 Янв 2014, 20:41)
---------------------------------------------
Странно только , что , когда увеличиваю speed - меняется не скорость, с которой объект поднимается от y до y+5, а само расстояние, т.е. он с той же скоростью поднимается выше ....

 
Сообщениеsmile Благодарю ! Пришлось , правда, привести твой скрипт в работоспособный вид
Код
var timeout: float;  
var speed = 0.5;

function Update(){

  if(timeout>0){  
  go = true;  
  timeout -= Time.deltaTime;  
  }
  else if(timeout<=0) go = false;   
  if(go) transform.position.y = Mathf.Lerp(transform.position.y,transform.position.y + 5, Time.deltaTime*speed);    
  if (Input.GetKeyDown(KeyCode.V)) timeout = 2.0f;      
  }
Но , в итоге, работает , как надо, жаль только , что так замудрённо, Я бы сам не додумался ... smile Сейчас попробую прилепить что-то подобное к своему скрипту приседания ... smile

Добавлено (07 Янв 2014, 20:41)
---------------------------------------------
Странно только , что , когда увеличиваю speed - меняется не скорость, с которой объект поднимается от y до y+5, а само расстояние, т.е. он с той же скоростью поднимается выше ....


Автор - dostalition
Дата добавления - 07 Янв 2014 в 20:41
игнатДата: Вт, 07 Янв 2014, 20:49 | Сообщение # 13
 
Сообщений: 706
Награды: 0
Репутация: 107
Статус: Offline
А справку открыть нельзя? Третий параметр - скорость.


Правила форума · участник GCC
 
СообщениеА справку открыть нельзя? Третий параметр - скорость.

Автор - игнат
Дата добавления - 07 Янв 2014 в 20:49
dostalitionДата: Вт, 07 Янв 2014, 21:14 | Сообщение # 14
 
Сообщений: 155
Награды: 0
Репутация: 9
Статус: Offline
В справке написано "// Move the object 10 meters per second! var translation : float = Time.deltaTime * 10;" Т.е. скорость = 10метров в секунду ... Так ? Тогда, изменяя значение 10 можно изменить скорость, но не расстояние, которое нужно пройти с такой скоростью ... А расстояние - это дистанция от y до y+5... Я так понимаю ...

Сообщение отредактировал dostalition - Вт, 07 Янв 2014, 21:15
 
СообщениеВ справке написано "// Move the object 10 meters per second! var translation : float = Time.deltaTime * 10;" Т.е. скорость = 10метров в секунду ... Так ? Тогда, изменяя значение 10 можно изменить скорость, но не расстояние, которое нужно пройти с такой скоростью ... А расстояние - это дистанция от y до y+5... Я так понимаю ...

Автор - dostalition
Дата добавления - 07 Янв 2014 в 21:14
seamanДата: Вт, 07 Янв 2014, 21:29 | Сообщение # 15
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
Жуть. Жалко тут нет смайлика "Полная Ж..."
Вы почитали уроки от PoqXert? Я думал, что там не понять что такое Lerp просто невозможно. Оказывается возможно.
Что делает Lerp? Он ПРОСТО выдает среднее между первым и вторым параметрами. Какое среднее - определяет третий параметр. ВСЕ.
Формула расчета этого среднего a + (b-a) * t
Никакой магии нет.
Вам нужно постепенно из одного места перейти в другое. Как это сделать. Указать в Lerp первым параметром первое место, вторым параметром - второе место. И плавно менять третий параметр. Тогда Lerp будет выдавать нечто среднее между первой позицией и второй позицией. Как будет меняться это среднее положение зависит от того как Вы будете менять третий параметр.
Ну и какой вывод?
1. При старте движения запоминаем позицию - это будет первый параметр. Тут же прибавляем к позиции необходимое смещение (+5) и запоминаем эту вторую позицию - это будет второй параметр Лерпа. Сохраняем время начала движения. Ставим флаг - начали движение.
Для упрощения пересчитываем скорость во время за которое пройдем смещение при данной скорости.
Код
Vector3 startPosition;
Vector3 endPosition;
float startTime;
bool moving;
float deltaTime;

public Vector3 shiftPosition; //Это устанавливаем в инспекторе - смещение
public float speed; //Это устанавливаем в инспекторе - скорость движения

void StartMoving()
{
      startPosition = transform.position;
      endPosition = startPosition + shiftPosition;
      startTime = Time.time;
      deltaTime = shiftPosition.magnitude / speed;
      moving = true;
}

Ну и в Update, если флаг движения установлен - смещаем позицию. Проверяем достигли ли конечной точки. Если достигли - сбрасываем флаг движения.
Код
void Update()
{
      if(moving)    
      {
          transform.position = Mathf.Lerp(startPosition, endPosition, (Time.time - startTime) / deltaTime);
          if(Time.time >= startTime + deltaTime) moving = false;
      }
}

Сложно? Это так нужно только если Вам нужно двигаться с постоянной скоростью. Если можно постепенно замедляться можно сделать проще.
Можно в каждый момент времени в качестве начальной позиции брать текущее положение. Тогда не нужно ничего о старте запоминать, а в качестве третьего параметра использовать время, прошедшее с предыдущего кадра.
Код
Vector3 endPosition;
bool moving;

public Vector3 shiftPosition; //Это устанавливаем в инспекторе - смещение
public float speed; //Это устанавливаем в инспекторе - скорость движения

void StartMoving()
{
      endPosition = startPosition + shiftPosition;
      moving = true;
}

Ну и в Update, если флаг движения установлен - смещаем позицию. Проверяем достигли ли конечной точки. Если достигли - сбрасываем флаг движения.
Код
void Update()
{
      if(moving)    
      {
          transform.position = Mathf.Lerp(transform.position, endPosition, Time.deltaTime * speed);
          if((endPosition - transform.position).sqrMagnitude < 0.001f) moving = false;
      }
}


PS: Да, забыл написать, вдруг непонятно будет. Чтобы начать движение - нужно вызвать функцию StartMoving. Как и когда ее вызывать - Вам виднее. Например в том же Update по нажатию клавиши. Можно не выносить в отдельную функцию, а все делать в месте принятия решения о движении.
 
СообщениеЖуть. Жалко тут нет смайлика "Полная Ж..."
Вы почитали уроки от PoqXert? Я думал, что там не понять что такое Lerp просто невозможно. Оказывается возможно.
Что делает Lerp? Он ПРОСТО выдает среднее между первым и вторым параметрами. Какое среднее - определяет третий параметр. ВСЕ.
Формула расчета этого среднего a + (b-a) * t
Никакой магии нет.
Вам нужно постепенно из одного места перейти в другое. Как это сделать. Указать в Lerp первым параметром первое место, вторым параметром - второе место. И плавно менять третий параметр. Тогда Lerp будет выдавать нечто среднее между первой позицией и второй позицией. Как будет меняться это среднее положение зависит от того как Вы будете менять третий параметр.
Ну и какой вывод?
1. При старте движения запоминаем позицию - это будет первый параметр. Тут же прибавляем к позиции необходимое смещение (+5) и запоминаем эту вторую позицию - это будет второй параметр Лерпа. Сохраняем время начала движения. Ставим флаг - начали движение.
Для упрощения пересчитываем скорость во время за которое пройдем смещение при данной скорости.
Код
Vector3 startPosition;
Vector3 endPosition;
float startTime;
bool moving;
float deltaTime;

public Vector3 shiftPosition; //Это устанавливаем в инспекторе - смещение
public float speed; //Это устанавливаем в инспекторе - скорость движения

void StartMoving()
{
      startPosition = transform.position;
      endPosition = startPosition + shiftPosition;
      startTime = Time.time;
      deltaTime = shiftPosition.magnitude / speed;
      moving = true;
}

Ну и в Update, если флаг движения установлен - смещаем позицию. Проверяем достигли ли конечной точки. Если достигли - сбрасываем флаг движения.
Код
void Update()
{
      if(moving)    
      {
          transform.position = Mathf.Lerp(startPosition, endPosition, (Time.time - startTime) / deltaTime);
          if(Time.time >= startTime + deltaTime) moving = false;
      }
}

Сложно? Это так нужно только если Вам нужно двигаться с постоянной скоростью. Если можно постепенно замедляться можно сделать проще.
Можно в каждый момент времени в качестве начальной позиции брать текущее положение. Тогда не нужно ничего о старте запоминать, а в качестве третьего параметра использовать время, прошедшее с предыдущего кадра.
Код
Vector3 endPosition;
bool moving;

public Vector3 shiftPosition; //Это устанавливаем в инспекторе - смещение
public float speed; //Это устанавливаем в инспекторе - скорость движения

void StartMoving()
{
      endPosition = startPosition + shiftPosition;
      moving = true;
}

Ну и в Update, если флаг движения установлен - смещаем позицию. Проверяем достигли ли конечной точки. Если достигли - сбрасываем флаг движения.
Код
void Update()
{
      if(moving)    
      {
          transform.position = Mathf.Lerp(transform.position, endPosition, Time.deltaTime * speed);
          if((endPosition - transform.position).sqrMagnitude < 0.001f) moving = false;
      }
}


PS: Да, забыл написать, вдруг непонятно будет. Чтобы начать движение - нужно вызвать функцию StartMoving. Как и когда ее вызывать - Вам виднее. Например в том же Update по нажатию клавиши. Можно не выносить в отдельную функцию, а все делать в месте принятия решения о движении.

Автор - seaman
Дата добавления - 07 Янв 2014 в 21:29
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2024