您现在的位置是:首页 > 前端 > UnityUnity

Unity帧同步Transform(position,rotation,localScale)思路

Tdou2021-04-07【Unity】人已围观

简介网络同步时使用一个ushort type 2字节16位,其中9位 作为同步 position,rotation,localScale 标志那个改变, position 可能会很大所以使用 3个float ,(4*3 12字节), rotation使用四元数,四元数x,y,z,w 4个可以使用4个byte 0~90 所以(1*4 4字节),localScale 一般不会很大, 所以暂定使用 sbyte (1*4 4字节),网络同步时候根据type按位去计算。0为需要同步,1不需要同步。

网络同步时使用一个ushort type 2字节16位,其中9位 作为同步 position,rotation,localScale 标志

position 可能会很大所以使用 3个float ,(4*3 12字节),
rotation 使用四元数,四元数x,y,z,w 4个可以使用4个byte 0~90 所以(1*4 4字节)
localScale 一般不会很大, 所以暂定使用 sbyte (1*4 4字节)

网络同步时候根据type按位去计算。0为需要同步,1不需要同步。然后按需去裁剪发生的包体大小

例如:
   最小一个网络同步包,可能1个type=2字节+ 任意一个旋转或者缩放字节
   最大一个网络同步包, type=2 position=12 rotation=4 localScale=4  22字节

以下为实现代码(未实际运行测试)理想可行,如果有哪位大神测试后可以给一些反馈,谢谢





using UnityEngine;

public class TransformUtils
{
    private const ushort TI_POS_X = 200; // 0000 0010 0000 0000
    private const ushort TI_POS_Y = 100; // 0000 0001 0000 0000
    private const ushort TI_POS_Z = 80; // 0000 0000 1000 0000

    private const ushort TI_ROTATION_X = 40; // 0000 0000 0100 0000
    private const ushort TI_ROTATION_Y = 20; // 0000 0000 0010 0000
    private const ushort TI_ROTATION_Z = 10; // 0000 0000 0001 0000
    private const ushort TI_ROTATION_W = 8; // 0000 0000 0000 1000

    private const ushort TI_SCALE_X = 4; // 0000 0000 0000 0100
    private const ushort TI_SCALE_Y = 2; // 0000 0000 0000 0010
    private const ushort TI_SCALE_Z = 1; // 0000 0000 0000 0001


    /// <summary>
    /// 对比2个Transform 算出Transform不一样的内容
    /// </summary>
    /// <param name="self"></param>
    /// <param name="target"></param>
    /// <param name="distance"></param>
    /// <returns></returns>
    public TransformInfo CheckTransform(Transform self, Transform target, float distance = 0.02f)
    {
        TransformInfo info = new TransformInfo();

        if (Mathf.Abs(self.position.x - target.position.x) > distance)
        {
            info.pX = target.position.x;
            info.Choose(TI_POS_X);
        }

        if (Mathf.Abs(self.position.y - target.position.y) > distance)
        {
            info.pY = target.position.y;
            info.Choose(TI_POS_Y);
        }

        if (Mathf.Abs(self.position.z - target.position.z) > distance)
        {
            info.pZ = target.position.z;
            info.Choose(TI_POS_Z);
        }


        if (Mathf.Abs(self.rotation.x - target.rotation.x) > distance)
        {
            info.rX = (byte) target.rotation.x;
            info.Choose(TI_ROTATION_X);
        }

        if (Mathf.Abs(self.rotation.y - target.rotation.y) > distance)
        {
            info.rY = (byte) target.rotation.y;
            info.Choose(TI_ROTATION_Y);
        }

        if (Mathf.Abs(self.rotation.z - target.rotation.z) > distance)
        {
            info.rZ = (byte) target.rotation.z;
            info.Choose(TI_ROTATION_Z);
        }

        if (Mathf.Abs(self.rotation.w - target.rotation.w) > distance)
        {
            info.rZ = (byte) target.rotation.w;
            info.Choose(TI_ROTATION_W);
        }


        if (Mathf.Abs(self.localScale.x - target.localScale.x) > distance)
        {
            info.sX = (sbyte) target.localScale.x;
            info.Choose(TI_ROTATION_X);
        }

        if (Mathf.Abs(self.localScale.y - target.localScale.y) > distance)
        {
            info.sY = (sbyte) target.localScale.y;
            info.Choose(TI_ROTATION_Y);
        }

        if (Mathf.Abs(self.localScale.z - target.localScale.z) > distance)
        {
            info.sZ = (sbyte) target.localScale.z;
            info.Choose(TI_ROTATION_Z);
        }

        return info;
    }

    public void SyncTransform(Transform self, TransformInfo info)
    {
        Vector3 pos = self.position;
        if (info.IsChoose(TI_POS_X))
        {
            pos.x = (float) info.pX;
        }

        if (info.IsChoose(TI_POS_Y))
        {
            pos.y = (float) info.pY;
        }

        if (info.IsChoose(TI_POS_Z))
        {
            pos.z = (float) info.pZ;
        }

        self.position = pos;

        Quaternion rotation = self.rotation;
        if (info.IsChoose(TI_ROTATION_X))
        {
            rotation.x = (float) info.rX;
        }

        if (info.IsChoose(TI_ROTATION_Y))
        {
            rotation.y = (float) info.rY;
        }

        if (info.IsChoose(TI_ROTATION_Z))
        {
            rotation.z = (float) info.rW;
        }

        if (info.IsChoose(TI_ROTATION_W))
        {
            rotation.w = (float) info.rZ;
        }

        self.rotation = rotation;

        Vector3 scale = self.localScale;
        if (info.IsChoose(TI_SCALE_X))
        {
            scale.x = (float) info.sX;
        }

        if (info.IsChoose(TI_SCALE_Y))
        {
            scale.y = (float) info.sY;
        }

        if (info.IsChoose(TI_SCALE_Z))
        {
            scale.z = (float) info.sZ;
        }

        self.localScale = scale;
    }
}

public struct TransformInfo
{
    public ushort type; // 0~65535    2个字节  16位

    public float? pX, pY, pZ; // 位置    4*3 12字节
    public byte? rX, rY, rZ, rW; // 旋转 0~90  4个字节
    public sbyte? sX, sY, sZ; // 缩放 ~128-127 4个字节

    public void Choose(ushort index)
    {
        type |= (ushort) (1 << index);
    }

    public void UnChoose(ushort index)
    {
        type &= (ushort) ~(1 << index);
    }

    public bool IsChoose(ushort index)
    {
        int isHave = type & (1 << index);
        return isHave != 0;
    }
}

Tags:

很赞哦! ()

  • 微信收款码
  • 支付宝收款码
打赏

文章评论

站点信息

  • 建站时间:2019-12-11
  • 网站程序:帝国CMS7.5
  • 主题模板《今夕何夕》
  • 文章统计57篇文章
  • 标签管理标签云
  • 统计数据百度统计
  • 微信公众号:扫描二维码,关注我们