using Assets.Scenes.Ride.Scripts; using Assets.Scripts.Apis.Models; using DG.Tweening; using Mapbox.Utils; using System; using System.Linq; 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 { get; set; } 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();//初始化坡度等 if (speed > 0) { animator.Play("rideLoop"); } else { 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); var headBack = ticks % 10 == 0 && speed > 0 && bearing == 0; var drink = ticks % 15 == 0 && speed > 0 && bearing == 0; animator.SetBool("headBack", headBack); animator.SetBool("drinking", drink); } } protected virtual int GetCurrentFrame() { return manager.GetCurrentFrame(); } private bool animated = false; //大转弯是60度 private int offset = 0; protected virtual void Turn() { var currentFrame = GetCurrentFrame(); var result = manager.mockDirection.Where(c => c.Start < currentFrame && c.End > currentFrame).FirstOrDefault(); if (result != null) { bearing = result.Value; } animator.SetFloat("bearing", bearing); if (Math.Abs(bearing) > 50) { if (!animated) { animated = true; transform.DOMoveX(transform.position.x + 3, 1).onComplete += () => { offset = -3; }; print(176); } } else { if (offset != 0) { transform.DOMoveX(transform.position.x + offset, 1f).onComplete += () => { animated = false; }; offset = 0; } } transform.DORotate(new Vector3(0, bearing, 0), 1f); //var aniInfo = animator.GetCurrentAnimatorStateInfo(0); //if (aniInfo.loop) //{ //} } //计算人物当前属性 protected virtual void ComputePlayer() { if (power > 0) { preSpeed = speed; speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight); } else { speed = 0; distance = 0; } //一旦有功率就开始骑行、否则暂停 if (!manager.IsQuit() && manager.CurrentPlayer.UserId == UserId && !manager.IsQuit()) { if (power > 0) { manager.StartGame(); } } } private void Forward() { try { if (mapData == null) mapData = manager.GetMapData(); distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero); totalDistance += distance; currentlatLon = manager.Along(totalDistance % mapData.TotalDistance); } catch (Exception e) { Debug.LogError(e); } } protected virtual void ComputeVideo() { mapData = manager.GetMapData(); float ratio = 1; if (currentIndex + 1 < mapData.List.Count) { ratio = (float)(speed / mapData.List[currentIndex + 1].Speed); } else { ratio = (float)(speed / mapData.List[currentIndex].Speed); } if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId != UserId) return; manager.Play(ratio); } protected virtual void ComputeRecord() { } //计算当前区段属性下一个区段属性 void ComputeNextSlope() { double sumDistance = 0; 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+1.5f, 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() { if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId == UserId) { manager.Pause(); } head?.Destroy(); gameObject.Destroy(); } } }