430 lines
14 KiB
C#
430 lines
14 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// 注意:1.此脚本和动画共用时,需要注意动画激活时,位置会被锁死,无法移动。
|
||
/// 2.有控制权才能移动,结束后需释放控制权(控制权专属除外)
|
||
/// </summary>
|
||
public class FunctionSync_PositionRoate : SyncBase
|
||
{
|
||
public static Dictionary<string, FunctionSync_PositionRoate> positionRoateSyncObejctList = new Dictionary<string, FunctionSync_PositionRoate>();
|
||
[Tooltip("同步坐标")]
|
||
public bool isPositionSync;
|
||
[HideInInspector]
|
||
public bool isLocalPotion=true;
|
||
[Tooltip("同步角度")]
|
||
public bool isRoateSync;
|
||
[HideInInspector]
|
||
public bool isLocalRoate=true;
|
||
/// <summary>
|
||
/// 是否本地锁定
|
||
/// </summary>
|
||
[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);
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 初始化
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <param name="Tmpislock">是否获取控制权</param>
|
||
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<byte> tmpbytes = new List<byte>();
|
||
//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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取控制权
|
||
/// </summary>
|
||
public void GetControl()
|
||
{
|
||
isLock = false;
|
||
Debug.Log("获取控制权:" + Id);
|
||
}
|
||
/// <summary>
|
||
/// 释放控制权
|
||
/// </summary>
|
||
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
|
||
{
|
||
|
||
} |