318 lines
8.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
using Assets.Scripts.Apis.Models;
using ChartAndGraph;
using DG.Tweening;
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;
using UnityEngine.UI;
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
#region UI对象
//UI对象
protected GameObject headPanel;
protected GraphChartBase graph;
protected ChartDataSourceScript chartDataSourceScript;
#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<Animator>();
mainController = transform.parent.GetComponent<CyclingController>();
map = transform.parent.Find("Map").GetComponent<AbstractMap>();
mapData = mainController.GetMapData();//获取路书信息
//获取海拔图UI对象
var graphObject = transform.parent.Find("SingleUI/Panel/GraphChart");
chartDataSourceScript = graphObject.GetComponent<ChartDataSourceScript>();
graph = graphObject.GetComponent<GraphChartBase>();
}
protected virtual void Excute()
{
//CamControl();
timer -= Time.deltaTime;
if (timer <= 0)//定时器 一秒执行一次
{
BeforeRun();
Run();
timer = 1.0f;
}
}
public bool stopRecord = false;
//骑行中
protected virtual void Run()
{
if (mapData == null)
return;
ComputeNextSlope();//计算下一个坡度相关数据
MoveGraphHead();//移动海拔图头像
//人物动画控制
if (characterAnimator != null)
{
characterAnimator.SetFloat("Speed", (float)speed);
characterAnimator.SetFloat("Slope", (float)currentSlope);
if (currentSlope > 5)
{
characterAnimator.speed = 0.5f;
}
else
{
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());//移动
}
}
}
//游戏开始开关
public 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()
{
if (prePos != nextPos)
{
Quaternion neededRotation = Quaternion.LookRotation(prePos - nextPos);
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);
currentPos = v;
transform.localPosition = v;
yield return new WaitForEndOfFrame();
}
}
#endregion
#region UI行为
protected virtual void MoveGraphHead()
{
}
#endregion
}
}