using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; /// /// 注意:1.此脚本和动画共用时,需要注意动画激活时,位置会被锁死,无法移动。 /// 2.有控制权才能移动,结束后需释放控制权(控制权专属除外) /// public class FunctionSync_PositionRoate : SyncBase { public static Dictionary positionRoateSyncObejctList = new Dictionary(); [Tooltip("同步坐标")] public bool isPositionSync; [HideInInspector] public bool isLocalPotion=true; [Tooltip("同步角度")] public bool isRoateSync; [HideInInspector] public bool isLocalRoate=true; /// /// 是否本地锁定 /// [DisplayOnly] public bool isLock=true; //同步的位置 [DisplayOnly] public float[] pos = new float[6]; private Vector3 tmpPos = new Vector3(); private Vector3 tmpRat = new Vector3(); private st_Motions st_Motions = new st_Motions { m_iOperaType = 10007 }; private int lastindex; private void OnDestroy() { if(positionRoateSyncObejctList.ContainsKey(Id)) { positionRoateSyncObejctList.Remove(Id); } } public void Init() { if (!hasInit) { if (!positionRoateSyncObejctList.ContainsValue(this)) { InitDynamic("move_" + gameObject.name); } } } /// /// 初始化 /// /// /// 是否获取控制权 public void InitDynamic(string id,bool isControl=false) { if (GameManage.Instance.is单机模式) { return; } if (hasInit) { Debug.Log("已经初始化,不能重复初始化"); return; } if (string.IsNullOrEmpty(id)) { if (string.IsNullOrEmpty(Id)) { Debug.LogError("Id为空"); return; } } else { Id = id; } if (LoadManage.Instance != null) { st_Motions.area = LoadManage.Instance.currentRoomArea; } isLock = !isControl; //初始化缓存 if(isPositionSync) { lastpos = isLocalPotion ? transform.localPosition : transform.position; } if(isRoateSync) { lastrot = isLocalRoate ? transform.localEulerAngles : transform.eulerAngles; } List tmpbytes = new List(); //syncId if (LoadManage.Instance != null) { tmpbytes.AddRange(BitConverter.GetBytes(LoadManage.Instance.SyncId)); } //id byte[] data = Encoding.UTF8.GetBytes(Id); tmpbytes.AddRange(BitConverter.GetBytes(data.Length)); tmpbytes.AddRange(data); //类型 if(isPositionSync&& !isRoateSync) { tmpbytes.Add(0); lastindex = tmpbytes.Count; //坐标系 tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); } else if(!isPositionSync && isRoateSync) { tmpbytes.Add(1); lastindex = tmpbytes.Count; //坐标系 tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); } else if(isPositionSync && isRoateSync) { tmpbytes.Add(2); lastindex = tmpbytes.Count; //坐标系 tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); } else { tmpbytes.Add(3); lastindex = tmpbytes.Count; //坐标系 tmpbytes.Add(isLocalPotion ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); tmpbytes.Add(isLocalRoate ? (byte)1 : (byte)0); tmpbytes.AddRange(new byte[12]); } //初始化 pos[0] = isLocalPotion ? transform.localPosition.x : transform.position.x; pos[1] = isLocalPotion ? transform.localPosition.y : transform.position.y; pos[2] = isLocalPotion ? transform.localPosition.z : transform.position.z; pos[3] = isLocalPotion ? transform.localEulerAngles.x : transform.eulerAngles.x; pos[4] = isLocalPotion ? transform.localEulerAngles.y : transform.eulerAngles.y; pos[5] = isLocalPotion ? transform.localEulerAngles.z : transform.eulerAngles.z; st_Motions.m_sOperaData = tmpbytes.ToArray(); positionRoateSyncObejctList.Add(Id, this); hasInit = true; } /// /// 获取控制权 /// public void GetControl() { isLock = false; Debug.Log("获取控制权:" + Id); } /// /// 释放控制权 /// public void ReleaseControl() { isLock = true; SendSync(); Debug.Log("释放控制权:" + Id); } [DisplayOnly] public float PostionOnceTime = 0.06f; [DisplayOnly] public float RoateOneTime = 1; Vector3 lastpos = new Vector3(); Vector3 lastrot = new Vector3(); public virtual void LateUpdate() { if (!GameManage.Instance.is单机模式) { //发同步 if (!isLock) { bool isAlreadySend = false; if (isPositionSync) { if (isLocalPotion) { if (Vector3.Distance(lastpos, transform.localPosition) >= PostionOnceTime) { SendSync(); isAlreadySend = true; } } else { if (Vector3.Distance(lastpos, transform.position) >= PostionOnceTime) { if (!isLock) { SendSync(); isAlreadySend = true; } } } } //位置没法同步时判断角度是否发 if (isRoateSync && !isAlreadySend) { if (isLocalRoate) { if (Vector3.Distance(lastrot, transform.localEulerAngles) >= RoateOneTime) { SendSync(); } } else { if (Vector3.Distance(lastrot, transform.eulerAngles) >= RoateOneTime) { SendSync(); } } } } else { //锁定位置 if (isPositionSync) { tmpPos.x = pos[0]; tmpPos.y = pos[1]; tmpPos.z = pos[2]; if (!isLocalPotion) { transform.position = tmpPos; lastpos = transform.position; } else { transform.localPosition = tmpPos; lastpos = transform.localPosition; } } if (isRoateSync) { tmpRat.x = pos[3]; tmpRat.y = pos[4]; tmpRat.z = pos[5]; if (!isLocalRoate) { transform.eulerAngles = tmpRat; lastrot = transform.eulerAngles; } else { transform.localEulerAngles = tmpRat; lastrot = transform.localEulerAngles; } } } } } public void SendSync() { if (!GameManage.Instance.is单机模式) { if (isPositionSync) { Vector3 tmp; if (isLocalPotion) { tmp = transform.localPosition; lastpos = transform.localPosition; } else { tmp = transform.position; lastpos = transform.position; } SetPos(isLocalPotion, tmp.x, tmp.y, tmp.z); } if (isRoateSync) { Vector3 tmp; if (isLocalRoate) { tmp = transform.localEulerAngles; lastrot = transform.localEulerAngles; } else { tmp = transform.eulerAngles; lastrot = transform.eulerAngles; } SetRot(isLocalRoate, tmp.x, tmp.y, tmp.z); } if (isPositionSync && !isRoateSync) { st_Motions.m_sOperaData[lastindex] = (isLocalPotion ? (byte)1 : (byte)0); Array.Copy(BitConverter.GetBytes(pos[0]), 0, st_Motions.m_sOperaData, lastindex + 1, 4); Array.Copy(BitConverter.GetBytes(pos[1]), 0, st_Motions.m_sOperaData, lastindex + 5, 4); Array.Copy(BitConverter.GetBytes(pos[2]), 0, st_Motions.m_sOperaData, lastindex + 9, 4); } else if (!isPositionSync && isRoateSync) { st_Motions.m_sOperaData[lastindex] = (isLocalRoate ? (byte)1 : (byte)0); Array.Copy(BitConverter.GetBytes(pos[3]), 0, st_Motions.m_sOperaData, lastindex + 1, 4); Array.Copy(BitConverter.GetBytes(pos[4]), 0, st_Motions.m_sOperaData, lastindex + 5, 4); Array.Copy(BitConverter.GetBytes(pos[5]), 0, st_Motions.m_sOperaData, lastindex + 9, 4); } else if (isPositionSync && isRoateSync) { st_Motions.m_sOperaData[lastindex] = (isLocalPotion ? (byte)1 : (byte)0); Array.Copy(BitConverter.GetBytes(pos[0]), 0, st_Motions.m_sOperaData, lastindex + 1, 4); Array.Copy(BitConverter.GetBytes(pos[1]), 0, st_Motions.m_sOperaData, lastindex + 5, 4); Array.Copy(BitConverter.GetBytes(pos[2]), 0, st_Motions.m_sOperaData, lastindex + 9, 4); st_Motions.m_sOperaData[lastindex + 13] = (isLocalPotion ? (byte)1 : (byte)0); Array.Copy(BitConverter.GetBytes(pos[3]), 0, st_Motions.m_sOperaData, lastindex + 14, 4); Array.Copy(BitConverter.GetBytes(pos[4]), 0, st_Motions.m_sOperaData, lastindex + 18, 4); Array.Copy(BitConverter.GetBytes(pos[5]), 0, st_Motions.m_sOperaData, lastindex + 22, 4); } LoadManage.Instance.RSclient.Send(st_Motions); } } public void SetPos(bool islocalPos,float x,float y,float z) { this.isLocalPotion = islocalPos; pos[0] = x; pos[1] = y; pos[2] = z; } public void SetRot(bool islocalRoate,float x,float y,float z) { this.isLocalRoate = islocalRoate; pos[3] = x; pos[4] = y; pos[5] = z; } public void SetValue(int start,byte[] data) { if(data[start]==0) { //只同步坐标 if (data[start+1]==1) { //local isLocalPotion = true; } else { //世界 isLocalPotion = false; } pos[0] = BitConverter.ToSingle(data, start + 2); pos[1] = BitConverter.ToSingle(data, start + 6); pos[2] = BitConverter.ToSingle(data, start + 10); } else if(data[start]==1) { //只同步角度 if (data[start + 1] == 1) { //local isLocalRoate = true; } else { //世界 isLocalRoate = false; } pos[3] = BitConverter.ToSingle(data, start + 2); pos[4] = BitConverter.ToSingle(data, start + 6); pos[5] = BitConverter.ToSingle(data, start + 10); } else if(data[start]==2) { //同步位置和角度 if (data[start + 1] == 1) { //local isLocalPotion = true; } else { //世界 isLocalPotion = false; } pos[0] = BitConverter.ToSingle(data, start + 2); pos[1] = BitConverter.ToSingle(data, start + 6); pos[2] = BitConverter.ToSingle(data, start + 10); if (data[start + 14] == 1) { //local isLocalRoate = true; } else { //世界 isLocalRoate = false; } pos[3] = BitConverter.ToSingle(data, start + 15); pos[4] = BitConverter.ToSingle(data, start + 19); pos[5] = BitConverter.ToSingle(data, start + 23); } } } public class DisplayOnly : PropertyAttribute { }