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; }
    }
  }

То есть после движения на одном клиенте происходит движение в нём и отправляется координаты всем остальным.
Теперь о неполадках - в клиенте в котором происходит движение все гладко, в клиентах приёмниках движение происходит рывками, то есть движется плавно но с разной скоростью.
Вопрос как в данной ситуации добиться того чтобы на всех клиентах объект двигался с равной скоростью?
  • Вопрос задан
  • 609 просмотров
Решения вопроса 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. без относительно фреймворка, передавай не позицию объекта, а его управление (команды на изменение поведения, повтороты, изменения скорости и т.п., и соответственно считай его новые координаты на удаленном клиенте точно так же как на сервере, но жестко привязывая к тикам времени, кодить такое сложнее но зато скроет лаги очень хорошо (пока взаимодействие не начнется само собой)
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы