您现在的位置是:首页 > 前端 > 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:
很赞哦! ()
微信收款码
支付宝收款码
上一篇:xasset 6.0 录播
下一篇:Unity开发之零碎小知识汇总
相关文章
随机图文
UGUI添加Canvas 组件调整渲染队列点击无响应解决方案
使用UGUI拼UI时候 需要通过canvas组件调整UI的渲染队列 ,但是添加后 整个组件和面板 无法点击 根据Canvas 调整渲染队列 还需要添加一个 Graphic Raycaster 组件 触发对应的[Unity 3d] Unity资源优化(图片、声音)
图片资源优化,声音资源优化[Unity 3d] Unity Logs Viewer (Unity真机查看log调试框)
Unity-Logs-Viewer, - Unity 真机可以查看Log的可视化插件。 GitHub 上的工程多如牛毛,有些好的code,但不经意间错过了就很难找回,故稍作整理,希望能帮助到有心人。Unity 开源框架推荐
开源框架&库汇总 Ellan Jiang @Game Framework、熊猫 @ET、Catlib、凉鞋 @QFramework
文章评论
点击排行

猜你喜欢
- Unity 图片压缩格式设置
- Unity 打包 报错I2CPP问题解决方案
- Unity SRP URP HDRP 的区别、渲染管道
- UGUI添加Canvas 组件调整渲染队列点击无响应解决方案
- Unity帧同步Transform(position,rotation,localScale)思路
- Unity 技术开放日-北京站
- Mac 升级macOS Catalina(10.15.6)后Unity无法打包Android解决方案
- Unity开发之零碎小知识-父子级活跃状态
- [Unity 3d] Unity Logs Viewer (Unity真机查看log调试框)
- [Unity 3d] 用户邮件反馈模块