powerfun-unity/Assets/Scenes/Ride/Scripts/OtherPlayerController.cs

184 lines
4.5 KiB
C#

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<Animator>();
var mainController = transform.parent.GetComponent<CyclingController>();
map = FindObjectOfType<AbstractMap>();
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
}
}