288 lines
8.0 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 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;
AbstractMap map;
//AbstractMap map;
#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 { 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();
}
#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();//获取路书信息
}
protected virtual void Excute()
{
//CamControl();
timer -= Time.deltaTime;
if (timer <= 0)//定时器 一秒执行一次
{
SendTcp();
Run();
timer = 1.0f;
}
}
public bool stopRecord = false;
//骑行中
protected virtual void Run()
{
ComputeNextSlope();//计算下一个坡度相关数据
//人物动画控制
if (characterAnimator != null && mapData != null)
{
characterAnimator.SetFloat("Speed", (float)speed);
if (totalDistance >= mapData.TotalDistance)
{
characterAnimator.SetBool("ReachEnd", true);//到达终点
}
}
//开始骑行
if (mainController.isStart)
{
if (index > 0)
{
totalClimb = 0;
//计算累计爬升
for (int i = 1; i <= index; i++)
{
var diff = mapData.List[i].Elevation - mapData.List[i - 1].Elevation;
if (diff > 0)
{
totalClimb += diff;
}
}
}
ticks++;
Compute();//接受蓝牙设备数据计算
if (totalDistance > mapData.TotalDistance)
{
distance = totalDistance - mapData.TotalDistance;
totalDistance = mapData.TotalDistance;
stopRecord = true;
StartCoroutine("LateUpload");
}
//数据处理
nextPos = map.GeoToWorldPosition(currentlatlong);//下一个点
nextPos.y += 1.15f;//提高y轴让人物站在地图上面
prePos = transform.localPosition;//当前点
thisRotation = transform.localRotation;
//移动动画控制
if (distance > 0)
{
StartCoroutine(MoveTo());//移动
}
}
}
protected virtual void SendTcp()
{
}
//计算功率 速度 当前骑行总里程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 = 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 = nextPosition;
transform.localPosition = nextPosition;
//Camera.main.transform.localPosition = nextPosition;
}
yield return new WaitForEndOfFrame();
}
}
#endregion
}
}