using Assets.Scenes.Ride.Scripts.Model.CyclingModels; using Assets.Scripts.Apis.Models; using GeoJSON.Net.Geometry; using Mapbox.Unity.Map; using Mapbox.Utils; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TurfCS; using UnityEngine; namespace Assets.Scenes.Ride.Scripts { public abstract class AbstractPlayer: MonoBehaviour { [Header("Character")] [SerializeField] GameObject character; [SerializeField] Animator characterAnimator; protected AbstractMap map; //AbstractMap map; public bool IsShowInfo { get; set; } #region 动画控制参数 public Vector3 nextPos; Vector3 prePos = Vector3.zero; float timer = 1.0f;//计时器 #endregion #region 选手骑行数据 protected Vector2d nextlatlong; //下一个点的坐标 protected Vector2d currentlatlong; //当前坐标 //protected bool isStart;//开始或者暂停 //public bool isQuit;//true 中途退出 或者到达终点 protected bool isMajor;//是否是主人公 protected MapDataModel mapData; //protected int userId; protected DateTime startTime;//开始骑行时间 protected DateTime endTime;//结束骑行时间 protected double weight;//体重 protected double bicycleWeight;//车重 protected double speed; protected double power; protected double elevation; protected double cadance; protected int heartRate; protected int ticks; protected double totalDistance; protected double currentSlope; protected double nextSlope; protected double nextSlopeDistance; protected double distance; protected double currentSlopeDistance; protected double lastEndDistance; protected double totalClimb; public double TotalClimb { get => totalClimb; } public int UserId { set; get; }//{ get => userId; } public double Speed { get => speed; } public double Power { get => power; } public double Cadance { get => cadance; } public double HeartRate { get => heartRate; } public int TotalTicks { get => ticks; } public double TotalDistance { get => totalDistance; } public double Distance { get => distance; } public double CurrentSlope { get => currentSlope; } public double NextSlope { get => nextSlope; } public double NextSlopeDistance { get => nextSlopeDistance; } public double CurrentSlopeDistance { get => currentSlopeDistance; } public double Elevation { get => elevation; } public double LastEndDistance { get => lastEndDistance; } public Vector2d Currentlatlong { get => currentlatlong; } #endregion void Start() { Init(); } void Update() { Excute(); AfterExcute(); } protected virtual void AfterExcute() { } #region 骑行逻辑 //初始化骑行数据 protected CyclingController mainController; protected BaseCycling cyclingExcutor; protected virtual void Init() { characterAnimator = GetComponentInChildren(); mainController = transform.parent.GetComponent(); map = transform.parent.Find("Map").GetComponent(); mapData = mainController.GetMapData();//获取路书信息 } protected virtual void Excute() { //CamControl(); timer -= Time.deltaTime; if (timer <= 0)//定时器 一秒执行一次 { BeforeRun(); Run(); timer = 1.0f; } } public bool stopRecord = false; //骑行中 protected virtual void Run() { ComputeNextSlope();//计算下一个坡度相关数据 //人物动画控制 if (characterAnimator != null && mapData != null) { characterAnimator.SetFloat("Speed", (float)speed); characterAnimator.SetFloat("Slope", (float)currentSlope); if (currentSlope > 5) { characterAnimator.speed = 0.5f; } else { characterAnimator.speed = 1f; } //if (speed < 20 && speed >= 10) //{ // characterAnimator.speed = 0.8f; //} //if (speed >= 20) //{ // characterAnimator.speed = 1f; //} if (totalDistance >= mapData.TotalDistance) { characterAnimator.SetBool("ReachEnd", true);//到达终点 } } //开始骑行 if (GetStart()) { ticks++; Compute();//接受蓝牙设备数据计算 if (totalDistance > mapData.TotalDistance) { distance = totalDistance - mapData.TotalDistance; totalDistance = mapData.TotalDistance; stopRecord = true; StartCoroutine("LateUpload"); } //数据处理 nextPos = map.GeoToWorldPosition(currentlatlong);//下一个点 nextPos.y += 1.35f;//提高y轴让人物站在地图上面 prePos = transform.localPosition;//当前点 thisRotation = transform.localRotation; //移动动画控制 if (distance > 0) { StartCoroutine(MoveTo());//移动 } } } //游戏开始开关 protected virtual bool GetStart() { return mainController.isStart; } protected virtual void BeforeRun() { } //计算功率 速度 当前骑行总里程(M)心率 踏频 等 protected virtual void Compute() { } //当前用户调用来上传骑行记录 public virtual void Upload() { } #endregion #region 工具类 IEnumerator LateUpload() { yield return new WaitForSeconds(1); Upload(); StopCoroutine("LateUpload"); } public int CurrentIndex; private int index; public double CurrentDistance;//当前所处区间距离 public double NextSlopeTotalDistance; //当前距离所在的海拔/坡度/距离 下一个点的坡度以及剩余距离 void ComputeNextSlope() { double sumDistance = 0; if (mapData == null) return; var pointList = mapData.List; int preIndex = 0; for (int i = 0; i < pointList.Count; i++) { sumDistance += pointList[i].Distance; if (totalDistance * 1000 <= sumDistance) { index = i; break; } } preIndex = index > 0 ? index - 1:0;//前一个索引 CurrentIndex = index;//当前索引 int nextIndex = index == pointList.Count - 1 ? index : index + 1; //计算下一个点的坡度和距离 PreElevation = pointList[preIndex].Elevation; //计算上一个海拔 PreSlope = pointList[preIndex].Grade; //计算上一个坡度 //计算当前海拔和坡度&当前区间距离 elevation = pointList[CurrentIndex].Elevation; currentSlope = pointList[CurrentIndex].Grade; CurrentDistance = pointList[CurrentIndex].Distance; //计算下一个海拔和坡度&当前区间距离 nextSlope = pointList[nextIndex].Grade; nextSlopeDistance = sumDistance - totalDistance * 1000; NextSlopeTotalDistance = pointList[nextIndex].Distance; currentSlopeDistance = (totalDistance * 1000 - (sumDistance - pointList[index].Distance));// CurrentDistance-( totalDistance * 1000 - (sumDistance - pointList[index].Distance)); } public double PreElevation; public double PreSlope; #endregion #region 人物移动与转向控制 Quaternion thisRotation; public Quaternion currentRotation; IEnumerator LookAtNextPos() { Quaternion neededRotation = Quaternion.LookRotation(prePos - nextPos); //Quaternion thisRotation = character.transform.localRotation; float t = 0; while (t < 1.0f) { t += Time.deltaTime / 0.5f; currentRotation = Quaternion.Slerp(thisRotation, neededRotation, t); character.transform.rotation = Quaternion.Euler(0, currentRotation.eulerAngles.y, 0); yield return null; } } Vector3 deltaPos = Vector3.zero; Vector3 previousPos = Vector3.zero; void CamControl() { deltaPos = transform.position - previousPos; deltaPos.y = 0; Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position, Camera.main.transform.position + deltaPos, Time.time); previousPos = transform.position; } public Vector3 currentPos = new Vector3(0,0,0); //人物移动控制 IEnumerator MoveTo() { StartCoroutine(LookAtNextPos());//转向 //让人物移动分点增加动画的流畅度 float t = 0; while (t < 1) { t += Time.deltaTime; Vector3 v = Vector3.Lerp(prePos, nextPos, t); //Vector3 nextPosition = new Vector3((float)Math.Round(v.x, 2), (float)Math.Round(v.y, 2), (float)Math.Round(v.z, 2)); //if (!nextPosition.Equals(transform.localPosition)) { currentPos = v; transform.localPosition = v; //Camera.main.transform.localPosition = nextPosition; } yield return new WaitForEndOfFrame(); } } #endregion } }