客户端简单位置同步
来源:互联网 发布:射雕英雄传电视剧 知乎 编辑:程序博客网 时间: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; }}
阅读全文
0 0
- 客户端简单位置同步
- 客户端简单位置同步
- 一种简单的客户端用户同步机制
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 网络游戏的位置同步
- 游戏服务器位置同步
- 网络游戏的位置同步
- Android安卓带头像电话本实现打电话、发短信功能(源码)
- Eclipse下创建Hibernate工程
- 数据结构 希尔排序
- 个人博客完成撒花(并没有)
- POJ
- 客户端简单位置同步
- 软件著作权申请 源代码编辑
- Android知识总结(问答形式)一
- TS流讲解--什么是ts流
- eclipse 如何向 SQL server写命令
- [HNOI2002]跳蚤 【容斥】
- Cygwin 未找到命令
- Linux系统安装Oracle 10g
- hadoop2.8.2官方文档之单节点集群