[Unity插件合集] AI能力,多人游戏插件,Unity3D StarTrooper

[复制链接]
查看825 | 回复0 | 2023-8-9 09:14:43 | 显示全部楼层 |阅读模式 来自 中国北京
Unity3D StarTrooper 多人游戏插件



该脚本是一个用于网络同步刚体的脚本。
首先,定义了一个内部结构State,用于存储刚体的状态信息,包括时间戳、位置、速度、旋转和角速度。
然后,定义了一个State数组m_BufferedState,用于存储最近20个状态。
接下来,定义了一个OnSerializeNetworkView函数,用于在网络上发送和接收刚体的状态信息。
在发送数据给服务器的情况下,将刚体的位置、旋转、速度和角速度进行序列化,并通过流stream发送。
在接收来自远程客户端的数据的情况下,先反序列化刚体的位置、速度、旋转和角速度,并将最新的状态记录在缓冲区数组m_BufferedState的第一个位置,然后将其他状态依次向后移动一个位置。同时,更新m_TimestampCount的值,确保不超过缓冲区的长度。
此外,还定义了两个公共成员变量m_InterpolationBackTime和m_ExtrapolationLimit,分别表示插值的回退时间和外推的限制时间。




















代码片段和文件信息using UnityEngine;
using System.Collections;

public class NetworkRigidbody : MonoBehaviour {
       
        public double m_InterpolationBackTime = 0.1;
        public double m_ExtrapolationLimit = 0.5;
       
        internal struct  State
        {
                internal double timestamp;
                internal Vector3 pos;
                internal Vector3 velocity;
                internal Quaternion rot;
                internal Vector3 angularVelocity;
        }
       
        // 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) {
                // Send data to server
                if (stream.isWriting)
                {
                        Vector3 pos = rigidbody.position;
                        Quaternion rot = rigidbody.rotation;
                        Vector3 velocity = rigidbody.velocity;
                        Vector3 angularVelocity = rigidbody.angularVelocity;

                        stream.Serialize(ref pos);
                        stream.Serialize(ref velocity);
                        stream.Serialize(ref rot);
                        stream.Serialize(ref angularVelocity);
                }
                // Read data from remote client
                else
                {
                        Vector3 pos = Vector3.zero;
                        Vector3 velocity = Vector3.zero;
                        Quaternion rot = Quaternion.identity;
                        Vector3 angularVelocity = Vector3.zero;
                        stream.Serialize(ref pos);
                        stream.Serialize(ref velocity);
                        stream.Serialize(ref rot);
                        stream.Serialize(ref angularVelocity);
                       
                        // Shift the buffer sideways deleting state 20
                        forint i=m_BufferedState.Length-1;i>=1;i--)
                        {
                                m_BufferedState = m_BufferedState[i-1];
                        }
                       
                        // Record current state in slot 0
                        State state;
                        state.timestamp = info.timestamp;
                        state.pos = pos;
                        state.velocity = velocity;
                        state.rot = rot;
                        state.angularVelocity = angularVelocity;
                        m_BufferedState[0] = state;
                       
                        // Update used slot count however never exceed the buffer size
                        // Slots aren‘t actually freed so this just makes sure the buffer is
                        // filled up and that uninitalized slots aren‘t used.
                        m_TimestampCount = Mathf.Min(m_TimestampCount + 1 m_BufferedState.Length);

                        // Check if states are in order if it is inconsistent you could reshuffel or
                        // drop the out-of-order state. Nothing is done here
                        for (int i=0;i<m_timestampcount-1;i++)
                        {
                                if (m_BufferedState.timestamp < m_BufferedState[i+1].timestamp)
                                        Debug.Log(“State inconsistent“);
                        }       
                }
        }
       
        // 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 extra polation
        void Update () {
                // This is the target playback time of the rigid body
                double interpolationTime = Network.time - m_InterpolationBackTime;
               
                // Use interpolation if the target playback time is present in the buffer
                if (m_BufferedState[0].timestamp > interpolationTime)
                {
                        // Go through buffer and find correct state to play back
                        for (int i=0;i<m_timestampcount;i++)
                        {
                                if (m_BufferedState.timestamp <= interpolationTime || i == m_TimestampCount-1)
                                {
                                        /</m_timestampcount;i++)
</m_timestampcount-1;i++)





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则