客户端简单位置同步

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


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地狱为王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值