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

280 lines
9.9 KiB
C#
Raw Normal View History

using System;
2022-04-01 18:41:31 +08:00
using System.Linq;
2022-03-10 18:32:53 +08:00
using UnityEngine;
2022-03-30 18:41:06 +08:00
using UnityEngine.UI;
2022-12-05 18:29:49 +08:00
using Assets.Core;
using Assets.Scripts.Apis.Models;
using DG.Tweening;
using Mapbox.Utils;
using Assets.Scenes.Ride.Scripts;
using UnityEngine.Assertions;
2022-03-10 18:32:53 +08:00
namespace Assets.Scripts.Scenes.VideoRide
{
2022-12-05 18:29:49 +08:00
public abstract class AbstractVideoPlayer : MonoBehaviour, IRider
2022-03-10 18:32:53 +08:00
{
2022-12-08 19:17:34 +08:00
public double Diff { get;set; }
protected int currentFrame { get; set; }
protected Animator animator { get; set; }
2022-03-24 09:36:59 +08:00
public GameObject head { get; set; }
2022-03-30 18:41:06 +08:00
protected Image ftpImage { get; set; }
protected Text headName { get; set; }
protected Text headWkg { get; set; }
2022-12-05 18:29:49 +08:00
public int userId { get; set; }
public string userName { get; set; }
2022-03-30 18:41:06 +08:00
public double weight;//体重
2022-03-10 18:32:53 +08:00
protected double bicycleWeight;//车重
protected double preSpeed;
2022-03-24 09:36:59 +08:00
public double speed;
public double distance;
2022-03-24 09:36:59 +08:00
public double power;
public double elevation { get; set; }
public double cadance { get; set; }
public double wkg { get; set; }
2022-03-25 09:57:30 +08:00
public int? heartRate { get; set; }
2022-11-24 17:20:19 +08:00
public double totalDistance { get; set; }
public double currentSlope { get; set; }
protected double nextSlope { get; set; }
protected double nextSlopeDistance { get; set; }
protected double currentSlopeDistance { get; set; }
public double totalClimb { get; set; }
2022-03-31 18:40:19 +08:00
public Vector2d currentlatLon { get; set; }
public int currentIndex { get; set; }
public int ticks { get; set; }
2022-03-10 18:32:53 +08:00
protected MapDataModel mapData;
protected bool start = true;
protected VideoGameManager manager { get; set; }
Transform bone_bottle_2 { get; set; }
2022-12-08 19:17:34 +08:00
public double Speed { get; set; }
public double StartDistance { get; set; }
public double PreDistance { get; set; }
public double EndDistance { get; set; }
public double OnlineSpeed { get; set; }
2022-12-05 18:29:49 +08:00
public int UserId => this.userId;
public string UserName => this.userName;
2022-03-25 09:57:30 +08:00
2023-01-13 10:45:42 +08:00
public double mockpower { get; set; }
protected float ratio = 1;
private static readonly int PreSpeed = Animator.StringToHash("preSpeed");
private static readonly int AnimatorSpeed = Animator.StringToHash("speed");
private static readonly int Grade = Animator.StringToHash("grade");
private static readonly int Power = Animator.StringToHash("power");
2023-01-13 10:45:42 +08:00
2022-03-10 18:32:53 +08:00
protected virtual void Start()
{
animator = GetComponent<Animator>();
manager = FindObjectOfType<VideoGameManager>();
mapData = manager.GetMapData();
ComputeNextSlope();//初始化坡度等
bone_bottle_2 = transform.Find("bone_cable_20");
2022-03-10 18:32:53 +08:00
}
protected virtual void Update()
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
CreateHeadImage();
ComputeAnimator();//控制动画
ComputeAnimatorSpeed();//控制动画速度
}
public void StartAction()
{
try
2022-03-10 18:32:53 +08:00
{
if (manager.IsStart())
2022-03-10 18:32:53 +08:00
{
ComputeTimerTick();
2022-03-25 09:57:30 +08:00
ComputeNextSlope();//计算下一个坡度
ComputePlayer();//计算人物属性
Forward();
ComputeRecord();
2022-03-10 18:32:53 +08:00
}
else
2022-03-10 18:32:53 +08:00
{
power = 0;
OnlineSpeed = 0;
PreDistance = EndDistance;
2022-03-10 18:32:53 +08:00
speed = 0;
distance = 0;
}
2022-03-10 18:32:53 +08:00
}
catch (Exception e)
{
power = 0;
speed = 0;
Debug.LogError(e.Message);
}
2022-03-10 18:32:53 +08:00
}
private void ComputeTimerTick()
{
ticks++;
}
public virtual void ComputeAnimator()
2022-03-10 18:32:53 +08:00
{
if (animator != null)
{
animator.SetFloat(PreSpeed, (float)preSpeed);
2023-03-10 14:22:41 +08:00
animator.SetFloat(AnimatorSpeed, (float)OnlineSpeed);
animator.SetFloat(Grade, (float)currentSlope);
animator.SetFloat(Power, (float)power);
2022-03-10 18:32:53 +08:00
}
}
2022-03-10 18:32:53 +08:00
//计算人物当前属性
public virtual void ComputePlayer()
2022-03-24 09:36:59 +08:00
{
if (power > 0)
{
preSpeed = speed;
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
}
else
{
speed = 0;
distance = 0;
}
}
2022-05-30 15:17:55 +08:00
//计算当前人物的经纬度
public virtual void Forward()
2022-03-25 09:57:30 +08:00
{
2022-03-31 18:40:19 +08:00
try
{
if (mapData == null)
mapData = manager.GetMapData();
currentlatLon = manager.Along(totalDistance % mapData.TotalDistance);
}
catch (Exception e)
{
Debug.LogError(e);
}
2022-03-25 09:57:30 +08:00
}
public virtual void ComputeAnimatorSpeed()
2022-03-31 18:40:19 +08:00
{
Assert.IsNotNull(manager);
mapData = manager.GetMapData();
var safeIndex = currentIndex + 1 < mapData.List.Count ? currentIndex + 1 : currentIndex;
var num = speed == 0 ? 1f : (float)(speed / mapData.List[safeIndex].Distance);
ratio = Mathf.Clamp(num, 0.3f, 1.2f);
2022-05-25 18:40:47 +08:00
var info = animator.GetCurrentAnimatorClipInfo(0);
if (info == null) return;
var currentClip = info.FirstOrDefault();
if (currentClip.clip != null)
{
animator.speed = ratio;
}
2022-03-31 18:40:19 +08:00
}
public virtual void ComputeRecord() { }
2023-03-10 14:22:41 +08:00
private const double DoubleDelta = 1E-6;
private const double GradeFactor = 0.5f;
2022-03-10 18:32:53 +08:00
//计算当前区段属性下一个区段属性
public void ComputeNextSlope()
2022-03-10 18:32:53 +08:00
{
double sumDistance = 0;
2022-03-31 18:40:19 +08:00
mapData = manager.GetMapData();
2022-03-10 18:32:53 +08:00
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;
}
}
2023-03-10 14:22:41 +08:00
if (Math.Abs(totalDistance - mapData.TotalDistance) < DoubleDelta)
2022-03-10 18:32:53 +08:00
{
currentIndex = pointList.Count - 1;
}
2023-03-10 14:22:41 +08:00
Debug.Log(currentIndex);
2022-03-10 18:32:53 +08:00
preIndex = currentIndex > 0 ? currentIndex - 1 : 0;//前一个索引
int nextIndex = currentIndex == pointList.Count - 1 ? currentIndex : currentIndex + 1; //计算下一个点的坡度和距离
elevation = pointList[currentIndex].Elevation;
2023-03-10 14:22:41 +08:00
currentSlope = pointList[currentIndex].Grade * GradeFactor;
2022-03-10 18:32:53 +08:00
//CurrentDistance = pointList[currentIndex].Distance;
//计算下一个海拔和坡度&当前区间距离
2023-03-10 14:22:41 +08:00
nextSlope = pointList[nextIndex].Grade * GradeFactor;
2022-03-10 18:32:53 +08:00
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-12-08 19:17:34 +08:00
private void OnDisable()
{
head?.SetActive(false);
}
2023-01-17 18:07:49 +08:00
private void OnEnable()
{
head?.SetActive(true);
}
//显示人物头顶的名字
public virtual void CreateHeadImage()
2022-03-24 09:36:59 +08:00
{
if (head == null)
{
if (manager.GetHeadInfo() != null)
2022-03-30 18:41:06 +08:00
{
2022-03-24 09:36:59 +08:00
head = Instantiate(manager.GetHeadInfo(), manager.GetCanvasTransform());
2022-03-30 18:41:06 +08:00
ftpImage = head.transform.Find("ftp").GetComponent<Image>();
headName = head.transform.Find("name").GetComponent<Text>();
headWkg = head.transform.Find("wkg").GetComponent<Text>();
}
2022-03-24 09:36:59 +08:00
}
if (head != null)
{
//它们的乘积就是高度
2022-10-08 13:26:38 +08:00
Vector3 worldPosition = new Vector3(bone_bottle_2.position.x, bone_bottle_2.position.y+1.0f, bone_bottle_2.position.z);
2022-03-24 09:36:59 +08:00
var playerScreenPos = Camera.main.WorldToScreenPoint(worldPosition);
head.transform.position = playerScreenPos;
2022-03-30 18:41:06 +08:00
ftpImage.fillAmount = (float)(wkg / 6);
headName.text = UserName;
headWkg.text = $"{wkg}W/KG";
head.SetActive(bone_bottle_2.position.z > 0);
2022-03-24 09:36:59 +08:00
}
}
public void SetStartDistance(double distance)
{
this.StartDistance = distance *1000;
}
2022-03-24 09:36:59 +08:00
public void Destroy()
{
2022-03-31 18:40:19 +08:00
if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId == UserId)
{
manager.Pause();
}
2022-03-24 09:36:59 +08:00
head?.Destroy();
gameObject.Destroy();
}
2022-12-08 19:17:34 +08:00
//设置当前玩家属性
public abstract void SetPlayer(string name, double speed, double preDistance, double endDistance, double cadance, double heartRate, double wkg, int userId, double power, double currentPlayerDistance, int frame);
2022-03-10 18:32:53 +08:00
}
}