Неверная синхронизация игроков Photon

Неверная синхронизация игроков Photon

Сообщение slavut-17 13 июн 2013, 20:13

Мне говорили что нужно использовать в photon Lerp для сглаживания движений игроков (чтобы другие игроки видели что другой клиент не дёргаеться)

Пишу вот так
Синтаксис:
Используется csharp
  private Vector3 correctPlayerPos = Vector3.zero; //We lerp towards this
    private Quaternion correctPlayerRot = Quaternion.identity; //We lerp towards this

    void Update()
    {
        if (!photonView.isMine)
        {
            //Update remote player (smooth this, this looks good, at the cost of some accuracy)
            transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * 5);
            transform.rotation = Quaternion.Lerp(transform.rotation, correctPlayerRot, Time.deltaTime * 5);

Но при входе в игру клиенты видят других клиентов что они моргают...
В чём может быть проблема?
http://vk.com/video92118245_165917626
slavut-17
UNITрон
 
Сообщения: 176
Зарегистрирован: 23 сен 2011, 16:37

Re: Неверная синхронизация игроков Photon

Сообщение ximael 13 июн 2013, 21:39

Не так надо.
Вот пример с сайта юнити. Новую позицию помещает в массив, а уже между позициями из массива сглаживание итп, в зависимости от статического лага. Адаптировать под нужды фотона несложно.
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class NetworkInterpolatedTransform : MonoBehaviour {
       
        public double interpolationBackTime = 0.1;
       
        internal struct  State
        {
                internal double timestamp;
                internal Vector3 pos;
                internal Quaternion rot;
        }

        // We store twenty states with "playback" information
        State[] m_BufferedState = new State[20];
        // Keep track of what slots are used
        int m_TimestampCount;
       
        void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
        {
                // Always send transform (depending on reliability of the network view)
                if (stream.isWriting)
                {
                        Vector3 pos = transform.localPosition;
                        Quaternion rot = transform.localRotation;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref rot);
                }
                // When receiving, buffer the information
                else
                {
                        // Receive latest state information
                        Vector3 pos = Vector3.zero;
                        Quaternion rot = Quaternion.identity;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref rot);
                       
                        // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
                        for (int i=m_BufferedState.Length-1;i>=1;i--)
                        {
                                m_BufferedState[i] = m_BufferedState[i-1];
                        }
                       
                        // Save currect received state as 0 in the buffer, safe to overwrite after shifting
                        State state;
                        state.timestamp = info.timestamp;
                        state.pos = pos;
                        state.rot = rot;
                        m_BufferedState[0] = state;
                       
                        // Increment state count but never exceed buffer size
                        m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);

                        // Check integrity, lowest numbered state in the buffer is newest and so on
                        for (int i=0;i<m_TimestampCount-1;i++)
                        {
                                if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
                                        Debug.Log("State inconsistent");
                        }
                       
                        //Debug.Log("stamp: " + info.timestamp + "my time: " + Network.time + "delta: " + (Network.time - info.timestamp));
                }
        }
       
        // This only runs where the component is enabled, which is only on remote peers (server/clients)
        void Update () {
                double currentTime = Network.time;
                double interpolationTime = currentTime - interpolationBackTime;
                // We have a window of interpolationBackTime where we basically play
                // By having interpolationBackTime the average ping, you will usually use interpolation.
                // And only if no more data arrives we will use extrapolation
               
                // Use interpolation
                // Check if latest state exceeds interpolation time, if this is the case then
                // it is too old and extrapolation should be used
                if (m_BufferedState[0].timestamp > interpolationTime)
                {
                        for (int i=0;i<m_TimestampCount;i++)
                        {
                                // Find the state which matches the interpolation time (time+0.1) or use last state
                                if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
                                {
                                        // The state one slot newer (<100ms) than the best playback state
                                        State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
                                        // The best playback state (closest to 100 ms old (default time))
                                        State lhs = m_BufferedState[i];
                                       
                                        // Use the time between the two slots to determine if interpolation is necessary
                                        double length = rhs.timestamp - lhs.timestamp;
                                        float t = 0.0F;
                                        // As the time difference gets closer to 100 ms t gets closer to 1 in
                                        // which case rhs is only used
                                        if (length > 0.0001)
                                                t = (float)((interpolationTime - lhs.timestamp) / length);
                                       
                                        // if t=0 => lhs is used directly
                                        transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
                                        transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
                                        return;
                                }
                        }
                }
                // Use extrapolation. Here we do something really simple and just repeat the last
                // received state. You can do clever stuff with predicting what should happen.
                else
                {
                        State latest = m_BufferedState[0];
                       
                        transform.localPosition = latest.pos;
                        transform.localRotation = latest.rot;
                }
        }
}
 
Музыка и звуковой дизайн для игр
Bomb Heroes - Бомбермен онлайн
ximael
UNец
 
Сообщения: 36
Зарегистрирован: 20 апр 2013, 00:23

Re: Неверная синхронизация игроков Photon

Сообщение slavut-17 13 июн 2013, 22:09

Почему-то всёровно виснит,
Заменил на photon
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class Networkplayer : Photon.MonoBehaviour {
       
        public double interpolationBackTime = 0.1;
       
        internal struct  State
        {
                internal double timestamp;
                internal Vector3 pos;
                internal Quaternion rot;
        }

        // We store twenty states with "playback" information
        State[] m_BufferedState = new State[20];
        // Keep track of what slots are used
        int m_TimestampCount;
       
        void OnSerializePhotonView(BitStream stream, PhotonMessageInfo info)
        {
                // Always send transform (depending on reliability of the network view)
                if (stream.isWriting)
                {
                        Vector3 pos = transform.localPosition;
                        Quaternion rot = transform.localRotation;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref rot);
                }
                // When receiving, buffer the information
                else
                {
                        // Receive latest state information
                        Vector3 pos = Vector3.zero;
                        Quaternion rot = Quaternion.identity;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref rot);
                       
                        // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
                        for (int i=m_BufferedState.Length-1;i>=1;i--)
                        {
                                m_BufferedState[i] = m_BufferedState[i-1];
                        }
                       
                        // Save currect received state as 0 in the buffer, safe to overwrite after shifting
                        State state;
                        state.timestamp = info.timestamp;
                        state.pos = pos;
                        state.rot = rot;
                        m_BufferedState[0] = state;
                       
                        // Increment state count but never exceed buffer size
                        m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);

                        // Check integrity, lowest numbered state in the buffer is newest and so on
                        for (int i=0;i<m_TimestampCount-1;i++)
                        {
                                if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
                                        Debug.Log("State inconsistent");
                        }
                       
                        //Debug.Log("stamp: " + info.timestamp + "my time: " + Network.time + "delta: " + (Network.time - info.timestamp));
                }
        }
       
        // This only runs where the component is enabled, which is only on remote peers (server/clients)
        void Update () {
                double currentTime = Network.time;
                double interpolationTime = currentTime - interpolationBackTime;
                // We have a window of interpolationBackTime where we basically play
                // By having interpolationBackTime the average ping, you will usually use interpolation.
                // And only if no more data arrives we will use extrapolation
               
                // Use interpolation
                // Check if latest state exceeds interpolation time, if this is the case then
                // it is too old and extrapolation should be used
                if (m_BufferedState[0].timestamp > interpolationTime)
                {
                        for (int i=0;i<m_TimestampCount;i++)
                        {
                                // Find the state which matches the interpolation time (time+0.1) or use last state
                                if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
                                {
                                        // The state one slot newer (<100ms) than the best playback state
                                        State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
                                        // The best playback state (closest to 100 ms old (default time))
                                        State lhs = m_BufferedState[i];
                                       
                                        // Use the time between the two slots to determine if interpolation is necessary
                                        double length = rhs.timestamp - lhs.timestamp;
                                        float t = 0.0F;
                                        // As the time difference gets closer to 100 ms t gets closer to 1 in
                                        // which case rhs is only used
                                        if (length > 0.0001)
                                                t = (float)((interpolationTime - lhs.timestamp) / length);
                                       
                                        // if t=0 => lhs is used directly
                                        transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
                                        transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
                                        return;
                                }
                        }
                }
                // Use extrapolation. Here we do something really simple and just repeat the last
                // received state. You can do clever stuff with predicting what should happen.
                else
                {
                        State latest = m_BufferedState[0];
                       
                        transform.localPosition = latest.pos;
                        transform.localRotation = latest.rot;
                }
        }
}

Не могу разобраться с этой строкой
68. double currentTime = Network.time;
slavut-17
UNITрон
 
Сообщения: 176
Зарегистрирован: 23 сен 2011, 16:37

Re: Неверная синхронизация игроков Photon

Сообщение slavut-17 14 июн 2013, 20:13

Вот нашел скрипт, вроде бы подходит, но почемуто игроки теперь респауняться на 0,0,0 кординатах

Синтаксис:
Используется csharp
    using UnityEngine;
    using System.Collections;
     
    public class NetworkCar : Photon.MonoBehaviour {
     
    public double interpolationBackTime = 0.1;
     
    internal struct State
    {
    internal double timestamp;
    internal Vector3 pos;
    internal Quaternion rot;
    }
     
    // We store twenty states with "playback" information
    State[] m_BufferedState = new State[20];
     
    // Keep track of what slots are used
    int m_TimestampCount;
     
    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
    // Always send transform (depending on reliability of the network view)
    if (stream.isWriting)
    {
    Vector3 pos = transform.localPosition;
    Quaternion rot = transform.localRotation;
    stream.Serialize(ref pos);
    stream.Serialize(ref rot);
    }
    // When receiving, buffer the information
    else
    {
    // Receive latest state information
    Vector3 pos = transform.position;
    Quaternion rot = Quaternion.identity;
    stream.Serialize(ref pos);
    stream.Serialize(ref rot);
     
    // Shift buffer contents, oldest data erased, 18 becomes 19, ... , 0 becomes 1
    for (int i = m_BufferedState.Length-1; i >= 1; i--)
    {
    m_BufferedState[i] = m_BufferedState[i-1];
    }
     
    // Save currect received state as 0 in the buffer, safe to overwrite after shifting
    State state;
    state.timestamp = info.timestamp;
    state.pos = pos;
    state.rot = rot;
    m_BufferedState[0] = state;
     
    // Increment state count but never exceed buffer size
    m_TimestampCount = Mathf.Min(m_TimestampCount + 1, m_BufferedState.Length);
     
    // Check integrity, lowest numbered state in the buffer is newest and so on
    for (int i = 0; i < m_TimestampCount-1; i++)
    {
    if (m_BufferedState[i].timestamp < m_BufferedState[i+1].timestamp)
    Debug.Log("State inconsistent");
    }
     
    //Debug.Log("stamp: " + info.timestamp + "my time: " + PhotonNetwork.time + "delta: " + (PhotonNetwork.time - info.timestamp));
    }
    }
     
    // This only runs where the component is enabled, which is only on remote peers (server/clients)
    void Update ()
    {
    double currentTime = PhotonNetwork.time;
    double interpolationTime = currentTime - interpolationBackTime;
    // We have a window of interpolationBackTime where we basically play
    // By having interpolationBackTime the average ping, you will usually use interpolation.
    // And only if no more data arrives we will use extrapolation
     
    // Use interpolation
    // Check if latest state exceeds interpolation time, if this is the case then
    // it is too old and extrapolation should be used
    if (m_BufferedState[0].timestamp > interpolationTime)
    {
    for (int i = 0; i < m_TimestampCount; i++)
    {
    // Find the state which matches the interpolation time (time+0.1) or use last state
    if (m_BufferedState[i].timestamp <= interpolationTime || i == m_TimestampCount-1)
    {
    // The state one slot newer (<100ms) than the best playback state
    State rhs = m_BufferedState[Mathf.Max(i-1, 0)];
     
    // The best playback state (closest to 100 ms old (default time))
    State lhs = m_BufferedState[i];
     
    // Use the time between the two slots to determine if interpolation is necessary
    double length = rhs.timestamp - lhs.timestamp;
    float t = 0.0F;
    // As the time difference gets closer to 100 ms t gets closer to 1 in
    // which case rhs is only used
    if (length > 0.0001)
    t = (float)((interpolationTime - lhs.timestamp) / length);
     
    // if t=0 => lhs is used directly
    transform.localPosition = Vector3.Lerp(lhs.pos, rhs.pos, t);
    transform.localRotation = Quaternion.Slerp(lhs.rot, rhs.rot, t);
    return;
    }
    }
    }
    // Use extrapolation. Here we do something really simple and just repeat the last
    // received state. You can do clever stuff with predicting what should happen.
    else
    {
    State latest = m_BufferedState[0];
    transform.localPosition = latest.pos;
    transform.localRotation = latest.rot;
    }
    }
    }
slavut-17
UNITрон
 
Сообщения: 176
Зарегистрирован: 23 сен 2011, 16:37


Вернуться в Photon

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3