客户端简单位置同步

来源:互联网 发布:射雕英雄传电视剧 知乎 编辑:程序博客网 时间:2024/06/05 08:49

这里写图片描述

using UnityEngine;using System.Collections;using TFrame;using Message;using System.Collections.Generic;using System.Timers;/// <summary>/// 玩家移动控制/// </summary>public class PlayerMoveControl : MonoBehaviour{    /// <summary>    /// 摇杆    /// </summary>    public Joystick joystick;    /// <summary>    /// 旋转角度    /// </summary>    private float angle;    /// <summary>    /// 是否在玩家控制中    /// </summary>    private bool isCtrl = true;    Vector3 vecMove;    /// <summary>    /// 位置    /// </summary>    Vector3 pos;    /// <summary>    /// 旋转    /// </summary>    Quaternion qu;    /// <summary>    /// 移动速度    /// </summary>    public float moveSpeed = 50;    /// <summary>    /// 位置同步200毫秒一次    /// </summary>    public static float posRate = 200;    /// <summary>    /// 定时器    /// </summary>    Timer timer = new Timer(posRate);    /// <summary>    /// 周围的玩家    /// </summary>    public Dictionary<int, GameObject> otherPlayer = new Dictionary<int, GameObject>();    /// <summary>    /// 当前的位置信息    /// </summary>    public Dictionary<int, Trans> oldTrans = new Dictionary<int, Trans>();    /// <summary>    /// 新的位置信息    /// </summary>    public Dictionary<int, Trans> newTrans = new Dictionary<int, Trans>();    public List<int> otherPlayerUids = new List<int>();    /// <summary>    /// 是否同步中    /// </summary>    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();    }    /// <summary>    /// 向服务器发送位置旋转信息    /// </summary>    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;    }}
原创粉丝点击