Zefirot
@Zefirot

Как сделать плавное равномерное передвижение?

У меня движение осуществляется в мультиплеере, движение происходит так
// приём в клиенте движения
private void FixedUpdate(){
  Vector3 pos = Obj.transform.position; // объект который двигаем и при этом его позиция передаётся по сети
  if(InputUp){ pos.z += Speed * Time.deltaTime; }
  if(InputDown){ pos.z -= Speed * Time.deltaTime; }
  if(InputLeft){ pos.x -= Speed * Time.deltaTime; }
  if(InputRight){ pos.x += Speed * Time.deltaTime; }
  if(transform.position != pos){
    NetworkSendData(pos); // посылается всем клиентам (кроме этого) требуемая позиция
    }
  Obj.PositionRequired = pos; // задаётся требуемая позиция объекту который двигаем
  }

// контроль объекта на всех клиентах
// PositionRequired - приходит по сети
private void FixedUpdate(){
  if(transform.position != PositionRequired){
    transform.position = Vector3.Lerp(transform.position, PositionRequired, Speed * Time.deltaTime);
    if(Vector3.Distance(transform.position, PositionRequired) < 0.002f){ transform.position = PositionRequired; }
    }
  }

То есть после движения на одном клиенте происходит движение в нём и отправляется координаты всем остальным.
Теперь о неполадках - в клиенте в котором происходит движение все гладко, в клиентах приёмниках движение происходит рывками, то есть движется плавно но с разной скоростью.
Вопрос как в данной ситуации добиться того чтобы на всех клиентах объект двигался с равной скоростью?
  • Вопрос задан
  • 462 просмотра
Решения вопроса 1
freeExec
@freeExec
Участник OpenStreetMap
Очень похоже на копипасту и не знание главного цикла Юнити.

Предположим игра показывает 1 FPS, т.е. 1 кард в секунду. Следовательно deltaTime = 1.
Физика, чтобы не быть ущербной выдерживает 5 циклов в секунду.
Соответственной за 1 кадр ваш FixedUpdate отработает 5 раз и при скорость 1 юнит подвинет объект на 5 юнитов.

Если мы проагрейдим видюху и игра заработает с 2 FPS, то deltaTime = 0.5
Значит физика за 1 секунду подвинет объект на 2.5 юнита.

В итоге самые нищеброды будут в вашей игре двигаться быстрее ПК-бояр.

ПС. Действительно как пишут в комментариях, юнити подхачивает, и при вызове FixedUpdate, deltaTime = fixedDeltaTime
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@rPman
Ты используешь Vector3.Lerp который считает расположение точки между двумя указанными позициями (у тебя это текущая позиция и та что пришла по сети), третий параметр должен быть при значении 0 и 1 соответственно первой позиции и второй, при значениях больше - позиция будет интерполирована дальше линейно, у тебя же там speed*Time.deltaTime что это значит я полагаю ты сам не понимаешь.

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

Ты пробовал просто позицию полученную по сети подставлять без интерполяции?

p.s. без относительно фреймворка, передавай не позицию объекта, а его управление (команды на изменение поведения, повтороты, изменения скорости и т.п., и соответственно считай его новые координаты на удаленном клиенте точно так же как на сервере, но жестко привязывая к тикам времени, кодить такое сложнее но зато скроет лаги очень хорошо (пока взаимодействие не начнется само собой)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы