powerfun-unity/Assets/Scripts/Scenes/VideoRide/AbstractVideoPlayer.cs

288 lines
10 KiB
C#
Raw Normal View History

2022-03-24 09:36:59 +08:00
using Assets.Scenes.Ride.Scripts;
using Assets.Scripts.Apis.Models;
2022-03-25 09:57:30 +08:00
using ChartAndGraph;
2022-03-10 18:32:53 +08:00
using DG.Tweening;
using Mapbox.Utils;
using System;
using UnityEngine;
namespace Assets.Scripts.Scenes.VideoRide
{
public abstract class AbstractVideoPlayer : MonoBehaviour
{
protected Animator animator;
2022-03-24 09:36:59 +08:00
public GameObject head { get; set; }
public int UserId;
2022-03-10 18:32:53 +08:00
protected double weight;//体重
protected double bicycleWeight;//车重
protected double preSpeed;
2022-03-24 09:36:59 +08:00
public double speed;
public double power;
2022-03-10 18:32:53 +08:00
protected double elevation;
2022-03-25 09:57:30 +08:00
public double cadance;
public int? heartRate { get; set; }
2022-03-10 18:32:53 +08:00
public int ticks;
2022-03-24 09:36:59 +08:00
public double totalDistance;
2022-03-10 18:32:53 +08:00
protected double currentSlope;
protected double nextSlope;
protected double nextSlopeDistance;
public double distance;
2022-03-10 18:32:53 +08:00
protected double currentSlopeDistance;
protected double lastEndDistance;
2022-03-24 09:36:59 +08:00
public double totalClimb;
2022-03-25 09:57:30 +08:00
public Vector2d currentlatLon;
public int currentIndex;
2022-03-10 18:32:53 +08:00
protected float bearing = 0f;
protected MapDataModel mapData;
2022-03-24 09:36:59 +08:00
protected bool isHit = false;
protected RaycastHit hit;
2022-03-10 18:32:53 +08:00
float timer = 1f;
protected bool start = true;
protected VideoGameManager manager { get; set; }
Camera camera;
float currenPlayerHeight;
2022-03-25 09:57:30 +08:00
//UI对象
protected GameObject headPanel;
protected GraphChartBase graph;
protected ChartDataSourceScript chartDataSourceScript;
2022-03-10 18:32:53 +08:00
protected virtual void Start()
{
animator = GetComponent<Animator>();
manager = FindObjectOfType<VideoGameManager>();
mapData = manager.GetMapData();
ComputeNextSlope();//初始化坡度等
animator.Play("idle");
camera = Camera.main;
2022-03-25 09:57:30 +08:00
var GraphChart = manager.GetCanvasTransform().Find("GraphChart").gameObject;
chartDataSourceScript = GraphChart.GetComponent<ChartDataSourceScript>();
graph = GraphChart.GetComponent<GraphChartBase>();
2022-03-10 18:32:53 +08:00
}
protected virtual void Update()
2022-03-10 18:32:53 +08:00
{
timer -= Time.deltaTime;
ComputeAnimator();//控制动画
2022-03-24 09:36:59 +08:00
CreateHeadImage();
2022-03-10 18:32:53 +08:00
while (timer <= 0)
{
try
{
2022-03-25 09:57:30 +08:00
ComputeNextSlope();//计算下一个坡度
ComputePlayer();//计算人物属性
2022-03-24 09:36:59 +08:00
//animator.Play("touchHead");
2022-03-10 18:32:53 +08:00
if (manager.IsStart())
{
ticks++;
2022-03-25 09:57:30 +08:00
Forward();
2022-03-10 18:32:53 +08:00
ComputeRecord();
ComputeVideo();
2022-03-24 09:36:59 +08:00
RayCastHit();
Turn();
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
2022-03-10 18:32:53 +08:00
timer += 1f;
}
catch (Exception e)
{
power = 0;
speed = 0;
2022-03-24 09:36:59 +08:00
Debug.LogError(e.Message);
}
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
2022-03-10 18:32:53 +08:00
}
2022-03-10 18:32:53 +08:00
//人物碰撞
void OnCollisionEnter(Collision collision)
{
2022-03-24 09:36:59 +08:00
//manager.GetSlotIndex();
}
void RayCastHit()
{
//获取player的position信息
Vector3 pos = transform.position;
//射线碰撞物信息接收
//第二种写法
//我们可以先创建出一条射线
Ray ray = new Ray(pos, new Vector3(0, 0, 1));
//然后用这条射线去做射线检测
//射线,输出碰撞体信息,射线长度,射线在那一层检测,射线不忽略开启触发器(istrigger)的碰撞体
isHit = Physics.Raycast(ray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
if (isHit)
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
print(hit.collider.name);
2022-03-10 18:32:53 +08:00
}
}
2022-03-24 09:36:59 +08:00
protected void ComputeRandom()
{
var offset = 30;
2022-03-24 09:36:59 +08:00
if (ticks % 6 == 0)
transform.DOMoveZ(transform.position.z - 1.1f*offset, 1f);
if (ticks % 5 == 0)
transform.DOMoveZ(transform.position.z + offset, 2f);
//人物的rotation y
transform.DOLocalRotate(new Vector3(0f, bearing, 0f), 1f);
}
2022-03-10 18:32:53 +08:00
//动画状态机
2022-03-24 09:36:59 +08:00
protected virtual void ComputeAnimator()
2022-03-10 18:32:53 +08:00
{
if (animator != null)
{
animator.SetFloat("preSpeed", (float)preSpeed);
animator.SetFloat("speed", (float)speed);
animator.SetFloat("grade", (float)currentSlope);
2022-03-24 09:36:59 +08:00
animator.SetFloat("power", (float)power);
2022-03-10 18:32:53 +08:00
}
}
2022-03-24 09:36:59 +08:00
protected virtual int GetCurrentFrame()
{
return manager.GetCurrentFrame();
}
2022-03-24 09:36:59 +08:00
private bool animated = false;
//大转弯是60度
protected virtual void Turn()
{
2022-03-24 09:36:59 +08:00
var currentFrame = GetCurrentFrame();
if (manager.mockDirection.ContainsKey((int)currentFrame))
{
bearing = manager.mockDirection[(int)currentFrame];
}
animator.SetFloat("bearing", bearing);
if (!animated && Math.Abs(bearing) > 30)
{
//TODO:大拐弯动画
animated = true;
var current = transform.position;
//transform.DOMove(new Vector3(current.x+5, current.y, current.z), 1f).onComplete += () =>
//{
// current = transform.position;
// transform.DOMove(new Vector3(current.x-5, current.y, current.z), 1f);
//};
transform.DORotate(new Vector3(0, bearing, 0), 1f);
transform.DOMoveX(current.x + 3, 2).onComplete += () =>
{
};
//transform.DOMove(new Vector3(current.x + 5, current.y, current.z), 1f).onComplete += () => {
// transform.DOMove(new Vector3(current.x - 5, current.y, current.z), 1f);
// animated = false;
//};
}
else
{
var aniInfo = animator.GetCurrentAnimatorStateInfo(0);
if (aniInfo.loop)
{
transform.DORotate(new Vector3(0, bearing, 0), 1f);
}
}
2022-03-10 18:32:53 +08:00
}
//计算人物当前属性
2022-03-24 09:36:59 +08:00
protected virtual void ComputePlayer()
{
if (power > 0)
{
preSpeed = speed;
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
}
else
{
speed = 0;
distance = 0;
}
}
2022-03-10 18:32:53 +08:00
2022-03-25 09:57:30 +08:00
private void Forward()
{
distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
totalDistance += distance;
currentlatLon = manager.Along(totalDistance);
}
2022-03-10 18:32:53 +08:00
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 left = (decimal)totalDistance % (decimal)mapData.TotalDistance;//处理多圈的情况
left *= 1000;
2022-03-10 18:32:53 +08:00
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;
}
}
}
2022-03-24 09:36:59 +08:00
public void CreateHeadImage()
{
if (head == null)
{
if (manager.GetHeadInfo() != null)
head = Instantiate(manager.GetHeadInfo(), manager.GetCanvasTransform());
}
if (head != null)
{
//它们的乘积就是高度
Vector3 worldPosition = new Vector3(transform.position.x, transform.position.y+2, transform.position.z);
var playerScreenPos = Camera.main.WorldToScreenPoint(worldPosition);
head.transform.position = playerScreenPos;
}
}
2022-03-25 09:57:30 +08:00
protected virtual void MoveGraphHead(bool init = false)
{
}
2022-03-10 18:32:53 +08:00
2022-03-24 09:36:59 +08:00
public void Destroy()
{
head?.Destroy();
gameObject.Destroy();
}
2022-03-10 18:32:53 +08:00
}
}