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
{
}