159 lines
5.4 KiB
C#
159 lines
5.4 KiB
C#
|
|
using Assets.Scripts.Apis.Models;
|
|||
|
|
using DG.Tweening;
|
|||
|
|
using Mapbox.Utils;
|
|||
|
|
using System;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Assets.Scripts.Scenes.VideoRide
|
|||
|
|
{
|
|||
|
|
public abstract class AbstractVideoPlayer : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
protected Animator animator;
|
|||
|
|
protected double weight;//体重
|
|||
|
|
protected double bicycleWeight;//车重
|
|||
|
|
protected double preSpeed;
|
|||
|
|
protected double speed;
|
|||
|
|
protected double power;
|
|||
|
|
protected double elevation;
|
|||
|
|
protected double cadance;
|
|||
|
|
protected int? heartRate { get; set; }
|
|||
|
|
public 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;
|
|||
|
|
protected Vector2d currentlatLon;
|
|||
|
|
protected int currentIndex;
|
|||
|
|
protected float bearing = 0f;
|
|||
|
|
protected MapDataModel mapData;
|
|||
|
|
float timer = 1f;
|
|||
|
|
protected bool start = true;
|
|||
|
|
protected VideoGameManager manager { get; set; }
|
|||
|
|
|
|||
|
|
protected virtual void Start()
|
|||
|
|
{
|
|||
|
|
animator = GetComponent<Animator>();
|
|||
|
|
manager = FindObjectOfType<VideoGameManager>();
|
|||
|
|
mapData = manager.GetMapData();
|
|||
|
|
ComputeNextSlope();//初始化坡度等
|
|||
|
|
animator.Play("idle");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Update()
|
|||
|
|
{
|
|||
|
|
timer -= Time.deltaTime;
|
|||
|
|
ComputeAnimator();//控制动画
|
|||
|
|
while (timer <= 0)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (manager.IsStart())
|
|||
|
|
{
|
|||
|
|
ticks++;
|
|||
|
|
ComputeNextSlope();//计算下一个坡度
|
|||
|
|
ComputePlayer();//计算人物属性
|
|||
|
|
ComputeRecord();
|
|||
|
|
ComputeVideo();
|
|||
|
|
}
|
|||
|
|
timer += 1f;
|
|||
|
|
}
|
|||
|
|
catch (Exception e)
|
|||
|
|
{
|
|||
|
|
power = 0;
|
|||
|
|
speed = 0;
|
|||
|
|
Debug.Log(e.Message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//人物碰撞
|
|||
|
|
void OnCollisionEnter(Collision collision)
|
|||
|
|
{
|
|||
|
|
if (collision.transform.name != "mc_all_animations")
|
|||
|
|
{
|
|||
|
|
var curX = collision.transform.position.x;
|
|||
|
|
if (curX == 0)
|
|||
|
|
{
|
|||
|
|
var preX = manager.GetSlotIndex();
|
|||
|
|
collision.transform.DOLocalMoveX(preX.Value, 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//动画状态机
|
|||
|
|
void ComputeAnimator()
|
|||
|
|
{
|
|||
|
|
if (animator != null)
|
|||
|
|
{
|
|||
|
|
animator.SetFloat("preSpeed", (float)preSpeed);
|
|||
|
|
animator.SetFloat("speed", (float)speed);
|
|||
|
|
animator.SetFloat("grade", (float)currentSlope);
|
|||
|
|
var currentFrame = manager.GetCurrentFrame() ?? 0;
|
|||
|
|
if (manager.mockDirection.ContainsKey(currentFrame))
|
|||
|
|
{
|
|||
|
|
bearing = manager.mockDirection[currentFrame];
|
|||
|
|
}
|
|||
|
|
animator.SetFloat("bearing", bearing);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//计算人物当前属性
|
|||
|
|
protected abstract void ComputePlayer();
|
|||
|
|
|
|||
|
|
protected virtual void ComputeVideo(){ }
|
|||
|
|
|
|||
|
|
protected virtual void ComputeRecord() { }
|
|||
|
|
|
|||
|
|
//计算当前区段属性下一个区段属性
|
|||
|
|
void ComputeNextSlope()
|
|||
|
|
{
|
|||
|
|
double sumDistance = 0;
|
|||
|
|
var mapData = manager.GetMapData();
|
|||
|
|
if (mapData == null)
|
|||
|
|
return;
|
|||
|
|
var pointList = mapData.List;
|
|||
|
|
int preIndex = 0;
|
|||
|
|
for (int i = 0; i < pointList.Count; i++)
|
|||
|
|
{
|
|||
|
|
sumDistance += pointList[i].Distance;
|
|||
|
|
decimal left = (decimal)totalDistance * 1000;
|
|||
|
|
decimal right = (decimal)sumDistance;
|
|||
|
|
if (left <= right)
|
|||
|
|
{
|
|||
|
|
currentIndex = i;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
var DOUBLE_DELTA = 1E-6;
|
|||
|
|
if (Math.Abs(totalDistance - mapData.TotalDistance) < DOUBLE_DELTA)
|
|||
|
|
{
|
|||
|
|
currentIndex = pointList.Count - 1;
|
|||
|
|
}
|
|||
|
|
preIndex = currentIndex > 0 ? currentIndex - 1 : 0;//前一个索引
|
|||
|
|
int nextIndex = currentIndex == pointList.Count - 1 ? currentIndex : currentIndex + 1; //计算下一个点的坡度和距离
|
|||
|
|
|
|||
|
|
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[currentIndex].Distance));
|
|||
|
|
//计算累计爬升
|
|||
|
|
totalClimb = 0;
|
|||
|
|
for (int i = 1; i <= currentIndex; i++)
|
|||
|
|
{
|
|||
|
|
var diff = mapData.List[i].Elevation - mapData.List[i - 1].Elevation;
|
|||
|
|
if (diff > 0)
|
|||
|
|
{
|
|||
|
|
totalClimb += diff;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|