解决相机抖动和人物移动动画不流畅的问题

This commit is contained in:
lishuo committed 2021-03-30 17:29:39 +08:00
1 parent 0ab0e99597
commit 42fa59d103
24 files changed
+154640 -457

No files matched your search

+168 -76
View File
@@ -4,6 +4,13 @@ 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;
namespace Assets.Scenes.Ride.Scripts
{
@@ -13,106 +20,177 @@ namespace Assets.Scenes.Ride.Scripts
[SerializeField]
GameObject character;
[SerializeField]
float characterSpeed;
[SerializeField]
Animator characterAnimator;
[SerializeField]
AbstractMap map;
Vector3 nextPos;
#region 动画控制参数
Vector3 nextPos;
Vector3 prePos;
private Vector2d currentlatlong; //当前坐标
private Vector2d nextlatlong; //下一个点的坐标
private double totalDistance;
private int ticks;//秒数
public float timer = 1.0f;//计时器
Vector2d currentlatlong; //当前坐标
Vector2d nextlatlong; //下一个点的坐标
float timer = 1.0f;//计时器
#endregion
#region 选手骑行数据
bool isStart;
MapDataModel mapData;
int userId;
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>();
InitializePlayer();
var mainController = transform.parent.GetComponent<MainController>();
mapData = mainController.GetMapData();//获取路书信息
InitializePlayer(mainController.GetCenterCoordinate());//初始人物
}
//初始化人物
void InitializePlayer()
{
//获取玩家初始距离
currentlatlong = map.WorldToGeoPosition(transform.localPosition);
nextlatlong = currentlatlong;
totalDistance = 0;
ticks = 0;
}
void Update()
{
timer -= Time.deltaTime;
if (timer <= 0 && GameManger.IsStart)//定时器
if (timer <= 0)//定时器 一秒执行一次
{
ticks++;
Riding();
Run();
timer = 1.0f;
}
}
//计算当前玩家高度和坡度
Item find(double totalDistance)
#region 骑行逻辑
//当前人物骑行状态 true 开始 false 暂停
public void SetStart(bool start)
{
isStart = start;
}
//初始化玩家距离/朝向
void InitializePlayer(double[] coordinates)
{
ticks = 0;//当前骑行时间
//初始化人物位置
totalDistance = 10;//TODO:根据骑行模式动态取值
currentlatlong = Along(totalDistance);//new Vector2d(coordinates[0], coordinates[1]);//当前坐标
nextlatlong = currentlatlong;//下一秒坐标
////初始化人物转向
//var secondPlace = mapData.List[10].Point;
//var secondVect3d = map.GeoToWorldPosition( new Vector2d(secondPlace[0], secondPlace[1]));
//Quaternion firstRotation = Quaternion.LookRotation(transform.localPosition - secondVect3d);
//character.transform.rotation = Quaternion.Euler(0, firstRotation.eulerAngles.y, 0);
}
//骑行中
void Run()
{
if (IsStart)
{
//CamControl();
ComputeMapData();//计算海拔&坡度&下一个点信息
power = 300;//功率
speed = Helper.CalculateSpeed(elevation, gradev, power, 65, 7);
distance = Math.Round(speed / 3600, 5);
totalDistance += distance;
characterAnimator.SetBool("IsRide", false);//初始化动画状态
if (totalDistance <= mapData.TotalDistance)
{
ticks++;
if (distance > 0)
{
characterAnimator.SetBool("IsRide", true);//开始移动动画
nextlatlong = Along(totalDistance);//下一个坐标
nextPos = map.GeoToWorldPosition(nextlatlong);//下一个点
prePos = transform.localPosition;//当前点
StartCoroutine(LookAtNextPos());//转向
StartCoroutine(MoveTo());//移动
}
}
else
{
//TODO保存骑行数据
}
}
else
{
characterAnimator.SetBool("IsRide", false);
}
}
//TODO:骑行结束
void Finish()
{
//MapInterruptRecordApi api = new MapInterruptRecordApi();
//api.Add(null, null);
}
#endregion
#region 工具类
//当前距离所在的海拔/坡度/距离 下一个点的坡度以及剩余距离
void ComputeMapData()
{
double sumDistance = 0;
MapDataModel mapDataModel = GameManger.MapData;
foreach (var item in mapDataModel.List)
var pointList = mapData.List;
int index = 0;
for (int i = 0; i < pointList.Count; i++)
{
sumDistance += item.Distance;
if (totalDistance < sumDistance)
sumDistance += pointList[i].Distance;
if (totalDistance >= sumDistance)
{
return item;
index = i;
break;
}
}
return mapDataModel.List[0];
//计算当前海拔和坡度
elevation = pointList[index].Elevation;
gradev = pointList[index].Grade;
//计算下一个点的坡度和距离
int nextIndex = index == pointList.Count - 1 ? index : index + 1;
nextSlope = pointList[nextIndex].Grade;
nextSlopeDistance = sumDistance + pointList[nextIndex].Distance - totalDistance;
}
void Riding()
//根据距离计算坐标
Vector2d Along(double endDistance)
{
//yield return new WaitForSeconds(1.0f);
////读取当前速度以及骑行距离
MapDataModel mapDataModel = GameManger.MapData;
Item nextRange = find(totalDistance);
double elevation = nextRange.Elevation;
double gradev = nextRange.Grade;
double power = Random.Range(700, 2000);//TODO
double distance = Helper.CalculateSpeed(elevation, gradev, power, 65, 7) / 3600;
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
characterAnimator.SetBool("IsRide", false);
totalDistance += distance;
if (totalDistance <= mapDataModel.TotalDistance)
{
if (distance > 0)
{
var v = GameManger.Along(totalDistance);
StartCoroutine(CamControl());
//设定动画状态
characterAnimator.SetBool("IsRide", true);
nextPos = map.GeoToWorldPosition(v);
prePos = transform.localPosition;
//转向
StartCoroutine(LookAtNextPos());
//移动
StartCoroutine(MoveTo());
}
}
}
IEnumerator MoveTo()
{
//让人物移动分点增加动画的流畅度
float t = 0;
while (t < 1)
{
t += Time.deltaTime;
Vector3 v = Vector3.Lerp(transform.localPosition, nextPos, t);
transform.localPosition = v;
yield return null;
}
}
#region Character : Rotation
IEnumerator LookAtNextPos()
#region 人物移动与转向控制
IEnumerator LookAtNextPos()
{
Quaternion neededRotation = Quaternion.LookRotation(transform.localPosition - nextPos);
Quaternion thisRotation = character.transform.localRotation;
@@ -126,16 +204,30 @@ namespace Assets.Scenes.Ride.Scripts
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
#region CameraControl
#region 相机控制
[Header("CameraSettings")]
[SerializeField]
Camera cam;
Vector3 previousPos = Vector3.zero;
Vector3 deltaPos = Vector3.zero;
IEnumerator CamControl()
IEnumerator CamControl()//TODO 替换成cinemachine
{
if (cam != null)
{