using Assets.Scenes.Ride.Scripts; using Assets.Scripts.Apis.Models; using ChartAndGraph; using DG.Tweening; using Mapbox.Utils; using System; using UnityEngine; using UnityEngine.UI; namespace Assets.Scripts.Scenes.VideoRide { public abstract class AbstractVideoPlayer : MonoBehaviour { protected Animator animator; public GameObject head { get; set; } protected Image ftpImage { get; set; } protected Text headName { get; set; } protected Text headWkg { get; set; } public int UserId; public string UserName; public double weight;//体重 protected double bicycleWeight;//车重 protected double preSpeed; public double speed; public double power; protected double elevation; public double cadance; public double wkg; public int? heartRate { get; set; } public int ticks; public double totalDistance; public double currentSlope; protected double nextSlope; protected double nextSlopeDistance; public double distance; protected double currentSlopeDistance; protected double lastEndDistance; public double totalClimb; public Vector2d currentlatLon; public int currentIndex; protected float bearing = 0f; protected MapDataModel mapData; protected bool isHit = false; protected RaycastHit hit; float timer = 1f; protected bool start = true; protected VideoGameManager manager { get; set; } Camera camera; float currenPlayerHeight; protected virtual void Start() { animator = GetComponent(); manager = FindObjectOfType(); mapData = manager.GetMapData(); ComputeNextSlope();//初始化坡度等 animator.Play("idle"); camera = Camera.main; } protected virtual void Update() { timer -= Time.deltaTime; ComputeAnimator();//控制动画 CreateHeadImage(); while (timer <= 0) { try { ComputeNextSlope();//计算下一个坡度 ComputePlayer();//计算人物属性 //animator.Play("touchHead"); if (manager.IsStart()) { ticks++; Forward(); ComputeRecord(); ComputeVideo(); RayCastHit(); Turn(); } timer += 1f; } catch (Exception e) { power = 0; speed = 0; Debug.LogError(e.Message); } } } //人物碰撞 void OnCollisionEnter(Collision collision) { //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) { print(hit.collider.name); } } protected void ComputeRandom() { var offset = 30; 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); } //动画状态机 protected virtual void ComputeAnimator() { if (animator != null) { animator.SetFloat("preSpeed", (float)preSpeed); animator.SetFloat("speed", (float)speed); animator.SetFloat("grade", (float)currentSlope); animator.SetFloat("power", (float)power); } } protected virtual int GetCurrentFrame() { return manager.GetCurrentFrame(); } private bool animated = false; //大转弯是60度 protected virtual void Turn() { 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); } } } //计算人物当前属性 protected virtual void ComputePlayer() { if (power > 0) { preSpeed = speed; speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight); wkg = Math.Round(power / weight,2); } else { speed = 0; distance = 0; } } private void Forward() { distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero); totalDistance += distance; currentlatLon = manager.Along(totalDistance); } 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; 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; } } } public void CreateHeadImage() { if (head == null) { if (manager.GetHeadInfo() != null) { head = Instantiate(manager.GetHeadInfo(), manager.GetCanvasTransform()); ftpImage = head.transform.Find("ftp").GetComponent(); headName = head.transform.Find("name").GetComponent(); headWkg = head.transform.Find("wkg").GetComponent(); } } 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; ftpImage.fillAmount = (float)(wkg / 6); headName.text = UserName; headWkg.text = $"{wkg}W/KG"; } } public void Destroy() { head?.Destroy(); gameObject.Destroy(); } } }