客户端简单位置同步

using UnityEngine;
using System.Collections;
using TFrame;
using Message;
using System.Collections.Generic;
using System.Timers;

/// 
/// 玩家移动控制
/// 
public class PlayerMoveControl : MonoBehaviour
{
    /// 
    /// 摇杆
    /// 
    public Joystick joystick;
    /// 
    /// 旋转角度
    /// 
    private float angle;
    /// 
    /// 是否在玩家控制中
    /// 
    private bool isCtrl = true;

    Vector3 vecMove;
    /// 
    /// 位置
    /// 
    Vector3 pos;
    /// 
    /// 旋转
    /// 
    Quaternion qu;

    /// 
    /// 移动速度
    /// 
    public float moveSpeed = 50;

    /// 
    /// 位置同步200毫秒一次
    /// 
    public static float posRate = 200;
    /// 
    /// 定时器
    /// 
    Timer timer = new Timer(posRate);

    /// 
    /// 周围的玩家
    /// 
    public Dictionary otherPlayer = new Dictionary();
    /// 
    /// 当前的位置信息
    /// 
    public Dictionary oldTrans = new Dictionary();
    /// 
    /// 新的位置信息
    /// 
    public Dictionary newTrans = new Dictionary();

    public List otherPlayerUids = new List();
    /// 
    /// 是否同步中
    /// 
    private bool sync = false;
    void Start()
    {
        //注册周围玩家的位置信息
        MsgMgr.Instance.AddListener(typeof(SToCMoves), OnOtherMoves);
        timer.Elapsed += new ElapsedEventHandler(HandleMainTimer);
        timer.AutoReset = false;
        timer.Enabled = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (joystick != null && isCtrl)
        {
            vecMove = new Vector3(joystick.Direction.x, 0, joystick.Direction.y) * Time.deltaTime * moveSpeed / 10;
            transform.localPosition += vecMove;
            angle = Mathf.Atan2(joystick.Direction.x, joystick.Direction.y) * Mathf.Rad2Deg - 10;
            transform.localRotation = Quaternion.Euler(Vector3.up * angle);
            pos = transform.position;
            qu = transform.rotation;
        }
    }

    bool isLerp = false;
    float lerpTimeLength = 0.2f;
    float startLerpTime;
    void FixedUpdate()
    {
        if (sync)
        {
            if (isLerp)
            {
                float timeSinceStarted = Time.time - startLerpTime;
                float percentageComplete = timeSinceStarted / lerpTimeLength;
                foreach (int uid in newTrans.Keys)
                {
                    otherPlayer[uid].transform.position = Vector3.Lerp(new Vector3(oldTrans[uid].x, oldTrans[uid].y, oldTrans[uid].z),
                      new Vector3(newTrans[uid].x, newTrans[uid].y, newTrans[uid].z), percentageComplete);
                    Quaternion q1 = new Quaternion();
                    q1.eulerAngles = new Vector3(0, oldTrans[uid].angle, 0);
                    Quaternion q2 = new Quaternion();
                    q2.eulerAngles = new Vector3(0, newTrans[uid].angle, 0);

                    otherPlayer[uid].transform.rotation = Quaternion.Lerp(q1, q2, percentageComplete);
                }
                if (percentageComplete >= 1.0f)
                {
                    isLerp = false;
                }
            }
        }
    }

    private void HandleMainTimer(object sender, ElapsedEventArgs e)
    {
        SendMove();
        timer.Start();
    }

    /// 
    /// 向服务器发送位置旋转信息
    /// 
    void SendMove()
    {
        CToSMove ctsm = new CToSMove();
        ctsm.uid = GlobeData.uid;
        ctsm.x = pos.x;
        ctsm.y = pos.y;
        ctsm.z = pos.z;
        ctsm.angle = qu.eulerAngles.y;
        NetMgr.Instance.Send(ctsm);
    }

    void OnOtherMoves(object proto)
    {
        //更新位置信息
        Loom.QueueOnMainThread(() =>
        {
            sync = false;
            SToCMoves stcm = proto as SToCMoves;
            otherPlayerUids.Clear();
            oldTrans.Clear();
            newTrans.Clear();
            //Debug.Log(stcm.moves.Count);  
            for (int i = 0; i < stcm.moves.Count; i++)
            {
                CToSMove ctsm = stcm.moves[i];
                if (ctsm.uid != GlobeData.uid)
                {
                    //Debug.Log("Uid:" + ctsm.uid);
                    if (!otherPlayerUids.Contains(ctsm.uid))
                    {
                        otherPlayerUids.Add(ctsm.uid);
                    }
                    if (otherPlayer.ContainsKey(ctsm.uid))
                    {
                        //otherPlayer[ctsm.uid].transform.position = new Vector3(ctsm.x, ctsm.y, ctsm.z);
                        //Quaternion q = new Quaternion();
                        //q.eulerAngles = new Vector3(0, ctsm.angle, 0);
                        //otherPlayer[ctsm.uid].transform.rotation = q;

                        Trans t1 = new Trans();
                        t1.x = otherPlayer[ctsm.uid].transform.position.x;
                        t1.y = otherPlayer[ctsm.uid].transform.position.y;
                        t1.z = otherPlayer[ctsm.uid].transform.position.z;
                        t1.angle = otherPlayer[ctsm.uid].transform.rotation.eulerAngles.y;
                        oldTrans.Add(ctsm.uid, t1);
                        Trans t2 = new Trans();
                        t2.x = ctsm.x;
                        t2.y = ctsm.y;
                        t2.z = ctsm.z;
                        t2.angle = ctsm.angle;
                        newTrans.Add(ctsm.uid, t2);
                    }
                    else
                    {
                        Debug.Log("here");
                        GameObject obj = ResMgr.Instance.Load("player");
                        //添加其他玩家模型
                        GameObject otherPlayerObj = Instantiate(obj);
                        otherPlayerObj.name = ctsm.uid.ToString();
                        //设置位置信息
                        otherPlayerObj.transform.position = new Vector3(ctsm.x, ctsm.y, ctsm.z);
                        Quaternion q = new Quaternion();
                        q.eulerAngles = new Vector3(0, ctsm.angle, 0);
                        otherPlayerObj.transform.rotation = q;
                        otherPlayer.Add(ctsm.uid, otherPlayerObj);
                    }
                }
            }

            foreach (int uid in otherPlayer.Keys)
            {
                if (!otherPlayerUids.Contains(uid))
                {
                    //删除丢失的玩家 
                    Loom.QueueOnMainThread(() =>
                    {
                        Destroy(otherPlayer[uid]);
                        otherPlayer.Remove(uid);
                    });
                }
            }
            sync = true;
            isLerp = true;
            startLerpTime = Time.time;
        });
    }

    private void OnApplicationQuit()
    {
        timer.Stop();
    }

    public struct Trans
    {
        public float x;
        public float y;
        public float z;
        public float angle;
    }
}


客户端简单位置同步_第1张图片

你可能感兴趣的:(Unity)