Сглаживание нервных движений в Unity PUN 2 Network Transform View

При разработке игр на Unity Photon Unity Networking (PUN) — это популярная платформа для реализации многопользовательских функций. Однако одна из распространенных проблем, возникающих при использовании представления сетевого преобразования PUN 2, — это тряское перемещение сетевых объектов. В этой статье мы рассмотрим несколько способов сгладить это нервное движение и предоставим примеры кода для демонстрации каждого подхода.

Методы сглаживания нервных движений:

  1. Интерполяция.
    Интерполяция – это метод, который сглаживает движение путем постепенного перехода от предыдущей позиции к текущей позиции. В PUN 2 вы можете включить интерполяцию для компонента Network Transform View, настроив параметр «Интерполировать движение». Вот пример фрагмента кода:
using UnityEngine;
using Photon.Pun;
public class SmoothMovement : MonoBehaviourPun, IPunObservable
{
    private Vector3 networkPosition;
    private Quaternion networkRotation;
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
        }
        else
        {
            networkPosition = (Vector3)stream.ReceiveNext();
            networkRotation = (Quaternion)stream.ReceiveNext();
        }
    }
    private void Update()
    {
        if (!photonView.IsMine)
        {
            transform.position = Vector3.Lerp(transform.position, networkPosition, Time.deltaTime * 10);
            transform.rotation = Quaternion.Lerp(transform.rotation, networkRotation, Time.deltaTime * 10);
        }
    }
}
  1. Экстраполяция.
    Экстраполяция прогнозирует будущее положение сетевого объекта на основе его предыдущих положений. Оценив следующую позицию, можно сгладить движение дальше. Вот пример фрагмента кода:
private void Update()
{
    if (!photonView.IsMine)
    {
        transform.position += (networkPosition - transform.position) * 0.1f;
        transform.rotation = Quaternion.Slerp(transform.rotation, networkRotation, Time.deltaTime * 10);
    }
}
  1. Компенсация задержки.
    Компенсация задержки помогает устранить проблемы с задержкой за счет учета задержки между отправкой и получением данных. Применяя разницу во времени к обновлениям положения и вращения, вы можете добиться более плавного движения. Вот пример фрагмента кода:
private void Update()
{
    if (!photonView.IsMine)
    {
        float lag = Mathf.Abs((float)(PhotonNetwork.Time - info.SentServerTime));
        Vector3 extrapolatedPosition = networkPosition + (transform.forward * info.GetRoundTripTime() * 0.001f);
        transform.position = Vector3.Lerp(transform.position, extrapolatedPosition, lag);
        transform.rotation = Quaternion.Slerp(transform.rotation, networkRotation, lag);
    }
}
  1. Алгоритм сглаживания.
    Реализация собственного алгоритма сглаживания может обеспечить больший контроль над поведением движения. Одним из распространенных подходов является использование средневзвешенного значения предыдущих позиций и скоростей для расчета сглаженной позиции. Вот пример фрагмента кода:
private void Update()
{
    if (!photonView.IsMine)
    {
        float smoothingFactor = 0.9f;
        transform.position = Vector3.Lerp(transform.position, networkPosition, smoothingFactor);
        transform.rotation = Quaternion.Slerp(transform.rotation, networkRotation, smoothingFactor);
    }
}