откуда вообще берется интерполяция позиции?
Выжимка из моей документации -
transform.position = Vector3.Lerp(A, B, fraction);
Если нам нужно пройти путь от точки А до точки Б в размере 10 точек то надо fraction = 1/10 =0.1f
fraction = fraction + 0.1f;
transform.position = Vector3.Lerp(new Vector2(0,0), new Vector2(5, 5), fraction);
transform.position от нуля передвигается в 0.5f,0.5f - 1,1 – 1.5f,1.5f…..5,5. Десятая доля отрезка в размере пяти единиц равна 0.5f.(получаем путь из десяти точек между двумя точками(0,0 и 5,5))
Теперь объясню зачем нам рисовать точки движения между двумя точками:
Есть проблема в передачи движения по сети. Стабильная игра = 60 фпс. Это значит 60 точек позиций в секунду. Мы не можем передавать 60 позиций через сеть. Это очень больше затраты передачи трафика в секунду. Для экономии трафика по дефолту передают 10 позиций в секунду. OnPhotonSerializeView вызывается 10 раз в секунду. Если будем передавать движение 10 позиций в секунду .Получаем паузу между этими позициями которая равна шести кадрам(60/10). Эти отрезки между позициями в размере времени шести кадров должны сглаживаться. С помощью интерполяции мы создаем новые точки позиций в этом отрезке. Нужно создать минимум шесть точек. Нам нужно брать 1/6 долю отрезка. Это примерно Time.deltaTime * 10 . Почему разработчики фотона взяли Time.deltaTime * 9 ? Мы не должны никогда полностью догонять конец отрезка лерпа ,тогда в этом случае мы будем стоять 1-2 кадра в конце отрезка лерпа ожидая новую позицию по сети. И поэтому желательней двигаться медленней Time.deltaTime * 10.
Всегда должна быть только экстрополяция
Нет. и это подтверждает например случай который показан здесь. Тут проблема которая часто возникает, когда пытаются в быструю интерполяцию(путь от точки А до точки Б передвигается очень быстро(рисуется очень мало точек в отрезке лерпа)) добавить не медленную экстраполяцию. В итоге она обгоняет отрезки которые рисует интерполяция.
Хотя если автор поста уравновесит экстраполяцию то я полностью поменяю свою риторику)) и пересмотрю многое)). Но пока на видео я вижу другое.
Вот собственно пример быстрой интерполяции от разработчиков фотон клауда
Синтаксис:
Используется csharp
using UnityEngine;
[RequireComponent(typeof (PhotonView))]
public class CubeLerp : Photon.MonoBehaviour, IPunObservable
{
private Vector3 latestCorrectPos;
private Vector3 onUpdatePos;
private float fraction;
public void Start()
{
latestCorrectPos = transform.position;
onUpdatePos = transform.position;
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
stream.SendNext(transform.position);
else
{
Vector3 pos = Vector3.zero;
pos = (Vector3)stream.ReceiveNext();
latestCorrectPos = pos;
onUpdatePos = transform.position;
fraction = 0;
}
}
public void Update()
{
if (photonView.isMine) return;
fraction = fraction + Time.deltaTime * 9;
transform.position = Vector3.Lerp(onUpdatePos, latestCorrectPos, fraction);
}
}
[RequireComponent(typeof (PhotonView))]
public class CubeLerp : Photon.MonoBehaviour, IPunObservable
{
private Vector3 latestCorrectPos;
private Vector3 onUpdatePos;
private float fraction;
public void Start()
{
latestCorrectPos = transform.position;
onUpdatePos = transform.position;
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
stream.SendNext(transform.position);
else
{
Vector3 pos = Vector3.zero;
pos = (Vector3)stream.ReceiveNext();
latestCorrectPos = pos;
onUpdatePos = transform.position;
fraction = 0;
}
}
public void Update()
{
if (photonView.isMine) return;
fraction = fraction + Time.deltaTime * 9;
transform.position = Vector3.Lerp(onUpdatePos, latestCorrectPos, fraction);
}
}
Если мы в этот пример добавим велосити в районе 10 единиц и выше то получаем примерно предсказание потому что изменение направления велосити у нас же будет с задержкой в районе шести кадров
-----
про скрипт в начале поста:
Даже при том что у него в скрипте якобы отделен лерп от велосити
у него иф - лерп, елсе - трансформ позишин + велосити. Все равно когда он переходит в елсе у него иф лерп до конца отрезка то не дошел и получается мешанина из двух движений - Лерпа и добавления велосити и это все очень не просто нормализовать без обгонов.
По поводу задержки в шесть кадров это я говорю про фотонклауд) хотя сомневаюсь что в Unet позиции передаются по сети 60 раз в секунду)) наверно тоже 10 примерно