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

409 lines
14 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-08-05 15:10:09 +08:00
using Assets.Scenes.Ride.Scripts.Model;
2022-03-10 18:32:53 +08:00
using DG.Tweening;
using Mapbox.Utils;
using System;
using System.Collections;
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-03-10 18:32:53 +08:00
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; }
2022-03-30 18:41:06 +08:00
protected Image ftpImage { get; set; }
protected Text headName { get; set; }
protected Text headWkg { get; set; }
2022-03-24 09:36:59 +08:00
public int UserId;
2022-03-30 18:41:06 +08:00
public string UserName;
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 power;
2022-03-10 18:32:53 +08:00
protected double elevation;
2022-03-25 09:57:30 +08:00
public double cadance;
2022-03-30 18:41:06 +08:00
public double wkg;
2022-03-25 09:57:30 +08:00
public int? heartRate { get; set; }
2022-03-10 18:32:53 +08:00
public int ticks;
2022-11-24 17:20:19 +08:00
public double totalDistance { get; set; }
2022-03-30 18:41:06 +08:00
public double currentSlope;
2022-03-10 18:32:53 +08:00
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-31 18:40:19 +08:00
public Vector2d currentlatLon { get; set; }
2022-03-25 09:57:30 +08:00
public int currentIndex;
public float bearing = 0f;
2022-03-10 18:32:53 +08:00
protected MapDataModel mapData;
2022-10-08 13:26:38 +08:00
2022-03-24 09:36:59 +08:00
protected RaycastHit hit;
2022-03-10 18:32:53 +08:00
float timer = 1f;
protected bool start = true;
protected Sequence sequence;
2022-03-10 18:32:53 +08:00
protected VideoGameManager manager { get; set; }
Camera camera { get; set; }
float currenPlayerHeight;
Transform bone_bottle_2 { get; set; }
2022-08-24 18:43:43 +08:00
//切换视角
public double offsetX = 0d;
public double offsetY = 0d;
public double offsetZ = 0d;
2022-03-25 09:57:30 +08:00
2022-03-10 18:32:53 +08:00
protected virtual void Start()
{
animator = GetComponent<Animator>();
manager = FindObjectOfType<VideoGameManager>();
mapData = manager.GetMapData();
ComputeNextSlope();//初始化坡度等
2022-03-31 18:40:19 +08:00
if (speed > 0)
{
animator.Play("rideLoop");
}
else
{
animator.Play("idle");
}
camera = Camera.main;
//bone_bottle_2
bone_bottle_2 = transform.Find("bone_cable_20");
2022-11-24 17:20:19 +08:00
//var config = manager.mockDirection;
//pre = config[0];
//next = config[0];
2022-03-10 18:32:53 +08:00
}
2022-05-30 15:17:55 +08:00
//人物状态
public const int HERO_UP = 0;
public const int HERO_RIGHT = 1;
public const int HERO_DOWN = 2;
public const int HERO_LEFT = 3;
//人物当前行走的方向状态
public int state = 0;
//人物移动速度
public int moveSpeed = 2;
protected virtual void Update()
2022-03-10 18:32:53 +08:00
{
2022-10-08 13:26:38 +08:00
2022-03-10 18:32:53 +08:00
timer -= Time.deltaTime;
2022-03-24 09:36:59 +08:00
CreateHeadImage();
2022-10-08 13:26:38 +08:00
//Turn();
2022-03-10 18:32:53 +08:00
while (timer <= 0)
{
try
{
2022-03-25 09:57:30 +08:00
ComputeNextSlope();//计算下一个坡度
2022-10-08 13:26:38 +08:00
if (GetStart())
2022-03-10 18:32:53 +08:00
{
ticks++;
2022-08-05 15:10:09 +08:00
ComputePlayer();//计算人物属性
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();
2022-03-10 18:32:53 +08:00
}
ComputeAnimator();//控制动画
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-10-08 13:26:38 +08:00
private void OnTriggerEnter(Collider other)
2022-03-10 18:32:53 +08:00
{
2022-10-08 13:26:38 +08:00
Debug.Log("触发");
2022-03-24 09:36:59 +08:00
}
2022-05-30 15:17:55 +08:00
void RayCastHit()
2022-03-24 09:36:59 +08:00
{
2022-10-08 13:26:38 +08:00
//更新物理位置
Physics.SyncTransforms();
var target = transform;
//前方检测
Vector3 pos = new Vector3(target.position.x, 1, target.position.z);
Vector3 fwd = target.TransformDirection(Vector3.forward);
Ray ray = new Ray(new Vector3(pos.x, 1, pos.z), fwd);
var fHit = Physics.Raycast(ray, out hit,1f, 1 << 0, QueryTriggerInteraction.Collide);
Debug.DrawLine(pos, pos + 15* fwd, Color.red);
//左边检测
Vector3 lft = target.TransformDirection(Vector3.left);
Ray lray = new Ray(new Vector3(pos.x, 1, pos.z), lft);
var lHit = Physics.Raycast(lray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
Debug.DrawLine(pos, pos + lft, Color.red);
//右边检测
Vector3 rft = target.TransformDirection(Vector3.right);
Ray rray = new Ray(new Vector3(pos.x, 1, pos.z), rft);
var rHit = Physics.Raycast(rray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
//如果检测到前方有人坐标就往两边移动
if (fHit)
{
if (!lHit)
{
var newx = transform.localPosition.x - 1;
transform.DOLocalMoveX(newx, 1f);
}
else if (!rHit)
{
var newx = transform.localPosition.x + 1;
transform.DOLocalMoveX(newx, 1f);
}
}
//骑行过程尽可能向中间位置靠拢
if (speed > 0 && !fHit && !lHit && !rHit && ticks % 15 == 0)
{
transform.DOLocalMoveX(0, 1f);
}
2022-03-10 18:32:53 +08:00
}
protected virtual bool GetStart()
{
return true;
}
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)
{
2022-08-24 18:43:43 +08:00
if (manager._viewMode == VideoGameManager.ViewMode.FIRST &&manager.CurrentPlayer.UserId == App.CurrentUser.Id)
{
animator.SetFloat("preSpeed", (float)preSpeed);
2022-09-06 13:47:45 +08:00
animator.SetFloat("speed", (float)Math.Min(speed,25));
2022-08-24 18:43:43 +08:00
animator.SetFloat("grade", (float)currentSlope);
animator.SetFloat("power", (float)power);
}
else
{
animator.SetFloat("preSpeed", (float)preSpeed);
animator.SetFloat("speed", (float)speed);
animator.SetFloat("grade", (float)currentSlope);
animator.SetFloat("power", (float)power);
//播放喝水和回头的动画
2022-10-08 13:26:38 +08:00
//var headBack = ticks % 60 == 0 && speed > 0;
//var drink = ticks % 125 == 0 && speed > 0;
//animator.SetBool("headBack", headBack);
//animator.SetBool("drinking", drink);
2022-08-24 18:43:43 +08:00
}
2022-03-10 18:32:53 +08:00
}
}
2022-05-30 15:17:55 +08:00
protected virtual int GetCurrentFrame()
{
2022-03-24 09:36:59 +08:00
return manager.GetCurrentFrame();
}
2022-05-30 15:17:55 +08:00
2022-06-02 18:05:41 +08:00
protected CustomRange pre { get; set; }
2022-08-17 18:28:28 +08:00
public CustomRange next { get; set; }
2022-06-02 18:05:41 +08:00
2022-08-17 18:28:28 +08:00
protected float t { get; set; }
protected Vector3 currentRotation;
protected virtual void Turn()
{
2022-05-30 15:17:55 +08:00
//控制人物的转向
2022-03-24 09:36:59 +08:00
var currentFrame = GetCurrentFrame();
2022-05-30 15:17:55 +08:00
var config = manager.mockDirection;
2022-06-02 18:05:41 +08:00
if (config.Count == 0)
return;
2022-05-30 15:17:55 +08:00
for (int i = 0; i < config.Count; i++)
2022-03-24 09:36:59 +08:00
{
2022-05-30 15:17:55 +08:00
if (config[i].KeyFrame >= currentFrame)
2022-03-24 09:36:59 +08:00
{
2022-05-30 15:17:55 +08:00
pre = i > 0 ? config[i - 1] : config[i];
next = config[i];
break;
}
2022-05-25 18:40:47 +08:00
}
2022-08-17 18:28:28 +08:00
t = next.KeyFrame - pre.KeyFrame == 0 ? 1 : (float)(currentFrame - pre.KeyFrame) / (float)(next.KeyFrame - pre.KeyFrame);
2022-05-30 15:17:55 +08:00
var p = new Vector3(0, pre.RotationY, pre.RotationZ);
var q = new Vector3(0, next.RotationY, next.RotationZ);
2022-08-17 18:28:28 +08:00
currentRotation = Vector3.Lerp(p, q, t);
2022-10-08 13:26:38 +08:00
transform.localEulerAngles = currentRotation;
//transform.DORotate(currentRotation, 0, RotateMode.Fast);
2022-03-10 18:32:53 +08:00
}
2022-05-30 15:17:55 +08:00
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-08-05 15:10:09 +08:00
////一旦有功率就开始骑行、否则暂停
//if (!manager.IsQuit() && manager.CurrentPlayer.UserId == UserId && !manager.IsQuit() && manager.cyclingModel == CyclingModel.Single)
//{
// if (power > 0)
// {
// manager.StartGame();
// }
//}
2022-03-24 09:36:59 +08:00
}
2022-05-30 15:17:55 +08:00
Vector3 current { get; set; }
Vector3 forward { get; set; }
//计算当前人物的经纬度
protected 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
}
2022-05-30 15:17:55 +08:00
protected float ratio = 1;//视频播放速率
2022-03-25 09:57:30 +08:00
2022-03-31 18:40:19 +08:00
protected virtual void ComputeVideo()
{
mapData = manager.GetMapData();
2022-03-31 18:40:19 +08:00
if (currentIndex + 1 < mapData.List.Count)
{
2022-10-08 13:26:38 +08:00
ratio = (float)(speed / mapData.List[currentIndex + 1].Distance);
2022-03-31 18:40:19 +08:00
}
else
{
2022-10-08 13:26:38 +08:00
ratio = (float)(speed / mapData.List[currentIndex].Distance);
2022-03-31 18:40:19 +08:00
}
if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId != UserId)
return;
2022-08-05 15:10:09 +08:00
//ratio = (float)Math.Round(ratio, 1);
2022-11-24 17:20:19 +08:00
manager.Play(currentIndex,currentSlopeDistance);
2022-05-25 18:40:47 +08:00
if (ratio > 1)
{
ratio = Math.Min(ratio, 1.2f);
}
if (ratio < 1)
{
ratio = Math.Max(ratio, 0.6f);
}
2022-10-08 13:26:38 +08:00
if (speed == 0)
{
ratio = 1;
}
var info = animator.GetCurrentAnimatorClipInfo(0);
var currentClip = info.FirstOrDefault();
if (currentClip.clip != null && currentClip.clip.isLooping)
{
animator.speed = ratio;
}
2022-03-31 18:40:19 +08:00
}
2022-03-10 18:32:53 +08:00
protected virtual void ComputeRecord() { }
//计算当前区段属性下一个区段属性
void ComputeNextSlope()
{
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;
}
}
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-05-30 15:17:55 +08:00
//显示人物海拔图的头像
2022-07-06 17:48:55 +08:00
protected 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";
2022-03-24 09:36:59 +08:00
}
}
2022-03-10 18:32:53 +08:00
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-03-10 18:32:53 +08:00
}
}