using System.Collections; using UnityEngine; using Mapbox.Unity.Map; using Mapbox.Utils; using Assets.Scripts.Apis.Models; using static Assets.Scripts.Apis.Models.MapDataModel; using System; using Random = UnityEngine.Random; using Assets.Scripts.Apis; using GeoJSON.Net.Geometry; using TurfCS; using System.Linq; using System.Collections.Generic; using System.Text; using System.Globalization; namespace Assets.Scenes.Ride.Scripts { public class OtherPlayerController : MonoBehaviour { [Header("Character")] [SerializeField] GameObject character; [SerializeField] Animator characterAnimator; AbstractMap map; #region 动画控制参数 Vector3 nextPos; Vector3 prePos; Vector2d currentlatlong; //当前坐标 Vector2d nextlatlong; //下一个点的坐标 float timer = 1.0f;//计时器 #endregion #region 选手骑行数据 bool isStart; bool isMajor;//是否是主人公 MapDataModel mapData; int userId; DateTime startTime;//开始骑行时间 double speed; double power; double gradev; double elevation; double cadance; double heartRate; int ticks; double totalDistance; double currentSlope; double nextSlope; double nextSlopeDistance; double distance; public int UserId { get => userId; } public bool IsStart { get => isStart; } public double Speed { get => speed; } public double Power { get => power; } public double Cadance { get => cadance; } public double HeartRate { get => heartRate; } public int TotalTicks { get => ticks; } public double TotalDistance { get => totalDistance; } public double CurrentSlope { get => currentSlope; } public double NextSlope { get => nextSlope; } public double NextSlopeDistance { get => nextSlopeDistance; } public double Gradev { get => gradev; } public double Elevation { get => elevation; } #endregion void Start() { characterAnimator = GetComponentInChildren(); var mainController = transform.parent.GetComponent(); map = FindObjectOfType(); mapData = mainController.GetMapData();//获取路书信息 isStart = true; } void Update() { timer -= Time.deltaTime; if (timer <= 0)//定时器 一秒执行一次 { Run(); timer = 1.0f; } } #region 骑行逻辑 //骑行中 void Run() { if (IsStart) { power = 900;//功率 speed = Helper.CalculateSpeed(elevation, 0, power, 65, 7); distance = Math.Round(speed / 3600, 6); totalDistance += distance; characterAnimator.SetBool("IsRide", false);//初始化动画状态 if (totalDistance <= mapData.TotalDistance) { //数据处理 ticks++; nextlatlong = Along(totalDistance);//下一个坐标 nextPos = map.GeoToWorldPosition(nextlatlong);//下一个点 nextPos.y += 0.3f; prePos = transform.localPosition;//当前点 //动画控制 if (distance > 0) { characterAnimator.SetBool("IsRide", true);//开始移动动画 StartCoroutine(LookAtNextPos());//转向 StartCoroutine(MoveTo());//移动 } } else { //TODO保存骑行数据 characterAnimator.SetBool("ReachEnd", true); } } else { characterAnimator.SetBool("IsRide", false); } } #endregion #region 工具类 public int CurrentIndex; //根据距离计算坐标 Vector2d Along(double endDistance) { if (mapData != null) { var list = mapData.List.Select(p => new GeoJSON.Net.Geometry.GeographicPosition(p.Point[0], p.Point[1])); LineString lineString = new LineString(list); var pt1 = Turf.Along(lineString, endDistance); var ll = ((GeographicPosition)((GeoJSON.Net.Geometry.Point)pt1.Geometry).Coordinates); return new Vector2d(ll.Latitude, ll.Longitude); } return nextlatlong; } #endregion #region 人物移动与转向控制 IEnumerator LookAtNextPos() { Quaternion neededRotation = Quaternion.LookRotation(transform.localPosition - nextPos); Quaternion thisRotation = character.transform.localRotation; float t = 0; while (t < 1.0f) { t += Time.deltaTime / 0.25f; var rotationValue = Quaternion.Slerp(thisRotation, neededRotation, t); character.transform.rotation = Quaternion.Euler(0, rotationValue.eulerAngles.y, 0); yield return null; } } //人物移动控制 IEnumerator MoveTo() { //让人物移动分点增加动画的流畅度 float t = 0; while (t < 1) { t += Time.deltaTime; Vector3 v = Vector3.Lerp(prePos, nextPos, t); transform.localPosition = v; //控制海拔图的位置 yield return null; } } #endregion } }