AR轨迹逻辑

This commit is contained in:
lishuo committed 2022-10-08 13:26:38 +08:00
1 parent 195893a1b0
commit d1c84d0a8a
30 files changed
+159988 -4149

No files matched your search

@@ -8,6 +8,7 @@ using Mapbox.Unity.MeshGeneration.Modifiers;
using Mapbox.Unity.MeshGeneration.Data;
using Mapbox.Unity.Utilities;
using System;
using FluffyUnderware.Curvy;
namespace Assets.Scenes.Ride.Scripts
{
@@ -33,7 +34,7 @@ namespace Assets.Scenes.Ride.Scripts
Material Graph2 { get; set; }
Material linematerial { get; set; }
Vector2d[] ss;
protected virtual void Awake()
{
if (_map == null)
@@ -44,6 +45,14 @@ namespace Assets.Scenes.Ride.Scripts
//_map.OnUpdated += _map_OnUpdated; ;
Graph2 = Resources.Load<Material>("UI/Material/3dGraph2");
linematerial = Resources.Load<Material>("UI/Material/3");
var text = Resources.Load<TextAsset>("UI/bkoolgis");
var arr = text.text.Replace("\r\n", " ").Split(' ');
//ss = new Vector2d[arr.Length];
//for (int i = 0; i < arr.Length; ++i)
//{
// var a = arr[i].Split(',');
// ss[i] = new Vector2d(double.Parse(a[1]), double.Parse(a[0]));
//}
}
private void _map_OnUpdated()
@@ -99,10 +108,14 @@ namespace Assets.Scenes.Ride.Scripts
var mapData = cyclingCotroller.GetMapData();
if (mapData != null && cyclingCotroller.currentPlayer != null)
{
for (int i = 0; i < mapData.List.Count; i++)
//var curvy = CurvySpline.Create();
//curvy.Interpolation = CurvyInterpolation.Bezier;
for (int i = 0; i < mapData.List.Count; i++)
{
var point = mapData.List[i].Point;
Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0], point[1]));
Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0],point[1]));
//curvy.Add(item);
item.y += 1f;
//前后取50个点
decimal diff = i - cyclingCotroller.currentPlayer.CurrentIndex;
@@ -42,7 +42,7 @@ namespace Assets.Scripts.Scenes.VideoRide
public int currentIndex;
public float bearing = 0f;
protected MapDataModel mapData;
protected bool isHit = false;
protected RaycastHit hit;
float timer = 1f;
protected bool start = true;
@@ -92,15 +92,18 @@ namespace Assets.Scripts.Scenes.VideoRide
protected virtual void Update()
{
timer -= Time.deltaTime;
CreateHeadImage();
Turn();
//Turn();
while (timer <= 0)
{
try
{
ComputeNextSlope();//计算下一个坡度
if (GetStart())
{
ticks++;
@@ -122,18 +125,54 @@ namespace Assets.Scripts.Scenes.VideoRide
}
}
//人物碰撞
void OnCollisionEnter(Collision collision)
private void OnTriggerEnter(Collider other)
{
Debug.Log("触发");
}
void RayCastHit()
{
Vector3 pos = transform.position;
Ray ray = new Ray(pos, new Vector3(0, 0, 1));
isHit = Physics.Raycast(ray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
//更新物理位置
Physics.SyncTransforms();
var target = transform;
//前方检测
Vector3 pos = new Vector3(target.position.x, 1, target.position.z);
Vector3 fwd = target.TransformDirection(Vector3.forward);
Ray ray = new Ray(new Vector3(pos.x, 1, pos.z), fwd);
var fHit = Physics.Raycast(ray, out hit,1f, 1 << 0, QueryTriggerInteraction.Collide);
Debug.DrawLine(pos, pos + 15* fwd, Color.red);
//左边检测
Vector3 lft = target.TransformDirection(Vector3.left);
Ray lray = new Ray(new Vector3(pos.x, 1, pos.z), lft);
var lHit = Physics.Raycast(lray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
Debug.DrawLine(pos, pos + lft, Color.red);
//右边检测
Vector3 rft = target.TransformDirection(Vector3.right);
Ray rray = new Ray(new Vector3(pos.x, 1, pos.z), rft);
var rHit = Physics.Raycast(rray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
//如果检测到前方有人坐标就往两边移动
if (fHit)
{
if (!lHit)
{
var newx = transform.localPosition.x - 1;
transform.DOLocalMoveX(newx, 1f);
}
else if (!rHit)
{
var newx = transform.localPosition.x + 1;
transform.DOLocalMoveX(newx, 1f);
}
}
//骑行过程尽可能向中间位置靠拢
if (speed > 0 && !fHit && !lHit && !rHit && ticks % 15 == 0)
{
transform.DOLocalMoveX(0, 1f);
}
}
protected virtual bool GetStart()
@@ -160,10 +199,10 @@ namespace Assets.Scripts.Scenes.VideoRide
animator.SetFloat("grade", (float)currentSlope);
animator.SetFloat("power", (float)power);
//播放喝水和回头的动画
var headBack = ticks % 60 == 0 && speed > 0;
var drink = ticks % 125 == 0 && speed > 0;
animator.SetBool("headBack", headBack);
animator.SetBool("drinking", drink);
//var headBack = ticks % 60 == 0 && speed > 0;
//var drink = ticks % 125 == 0 && speed > 0;
//animator.SetBool("headBack", headBack);
//animator.SetBool("drinking", drink);
}
}
}
@@ -200,7 +239,8 @@ namespace Assets.Scripts.Scenes.VideoRide
var p = new Vector3(0, pre.RotationY, pre.RotationZ);
var q = new Vector3(0, next.RotationY, next.RotationZ);
currentRotation = Vector3.Lerp(p, q, t);
transform.DORotate(currentRotation, 0, RotateMode.Fast);
transform.localEulerAngles = currentRotation;
//transform.DORotate(currentRotation, 0, RotateMode.Fast);
}
//计算人物当前属性
@@ -249,11 +289,11 @@ namespace Assets.Scripts.Scenes.VideoRide
if (currentIndex + 1 < mapData.List.Count)
{
ratio = (float)(speed / mapData.List[currentIndex + 1].Speed);
ratio = (float)(speed / mapData.List[currentIndex + 1].Distance);
}
else
{
ratio = (float)(speed / mapData.List[currentIndex].Speed);
ratio = (float)(speed / mapData.List[currentIndex].Distance);
}
if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId != UserId)
return;
@@ -268,6 +308,10 @@ namespace Assets.Scripts.Scenes.VideoRide
{
ratio = Math.Max(ratio, 0.6f);
}
if (speed == 0)
{
ratio = 1;
}
var info = animator.GetCurrentAnimatorClipInfo(0);
var currentClip = info.FirstOrDefault();
if (currentClip.clip != null && currentClip.clip.isLooping)
@@ -343,7 +387,7 @@ namespace Assets.Scripts.Scenes.VideoRide
if (head != null)
{
//它们的乘积就是高度
Vector3 worldPosition = new Vector3(bone_bottle_2.position.x, bone_bottle_2.position.y+0.8f, bone_bottle_2.position.z);
Vector3 worldPosition = new Vector3(bone_bottle_2.position.x, bone_bottle_2.position.y+1.0f, bone_bottle_2.position.z);
var playerScreenPos = Camera.main.WorldToScreenPoint(worldPosition);
head.transform.position = playerScreenPos;
ftpImage.fillAmount = (float)(wkg / 6);
@@ -1,8 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Assets.Scenes.Ride.Scripts;
using DG.Tweening;
using FluffyUnderware.Curvy.Controllers;
using UnityEngine;
namespace Assets.Scripts.Scenes.VideoRide
@@ -12,6 +14,7 @@ namespace Assets.Scripts.Scenes.VideoRide
public Transform target;
public double diff;
public int frames;
public float xOffset;
private void Start()
{
@@ -38,10 +41,12 @@ namespace Assets.Scripts.Scenes.VideoRide
//var left = totalDistance % mapData.TotalDistance;
//var right = current.totalDistance % mapData.TotalDistance;
//diff = (left - right) * 1000;
if (Math.Abs(diff*1000) > 150)
{
Destroy();
}
//if (Math.Abs(diff*1000) > 150)
//{
// //销毁父容器
// transform.parent.Destroy();
// Destroy();
//}
}
}
@@ -55,56 +60,61 @@ namespace Assets.Scripts.Scenes.VideoRide
protected override void Turn()
{
base.Turn();
if (manager.CurrentPlayer.UserId == UserId)
return;
//计算前后位移
var current = manager.CurrentPlayer;
var interval = this.currentFrame - manager.GetCurrentFrame();
var z = current.transform.position.z + interval / zrate;//diff * 500;//
transform.DOMoveZ((float)z,1f);
//计算上下位移
var targetIndex = manager.CurrentPlayer.currentIndex;
var pointList = mapData.List;
var currentHeight = pointList[currentIndex].Elevation;//当前海拔,
var targetHeight = pointList[targetIndex].Elevation;//目标海拔
var heightOffset = (currentHeight - targetHeight);
var maxEl = pointList.Max(c => c.Elevation);
var minEl = pointList.Min(c => c.Elevation);
var y = diff != 0 ? heightOffset / (diff * 1000) * z-1 : 0;
var target = manager.CurrentPlayer.transform;
if (diff > 0)
{
var h = heightOffset / (diff*1000);
var height = h * (z - target.position.z) - 1;
//if (heightOffset < 0)
//{
// heightOffset *= 2;
//}
//else
//{
// heightOffset /= 100;
//}
if (height != 0)
{
transform.DOMoveY((float)height, 1f);
}
else
{
transform.DOMoveY(-1, 1f);
}
}
//if (splineController != null && manager != null && manager.splineController != null)
//{
// var ratio = this.diff / manager.GetMapData().TotalDistance;
// splineController.Position = (float)(ratio + manager.splineController.Position);
//}
//if (manager.CurrentPlayer.UserId == UserId)
// return;
////计算前后位移
//var current = manager.CurrentPlayer;
//var interval = this.currentFrame - manager.GetCurrentFrame();
//var z = current.transform.position.z + interval / zrate;//diff * 500;//
//transform.DOMoveZ((float)z,1f);
////计算上下位移
//var targetIndex = manager.CurrentPlayer.currentIndex;
//var pointList = mapData.List;
//var currentHeight = pointList[currentIndex].Elevation;//当前海拔,
//var targetHeight = pointList[targetIndex].Elevation;//目标海拔
//var heightOffset = (currentHeight - targetHeight);
//var maxEl = pointList.Max(c => c.Elevation);
//var minEl = pointList.Min(c => c.Elevation);
//var y = diff != 0 ? heightOffset / (diff * 1000) * z-1 : 0;
//var target = manager.CurrentPlayer.transform;
//if (diff > 0)
//{
// var h = heightOffset / (diff*1000);
// var height = h * (z - target.position.z) - 1;
// //if (heightOffset < 0)
// //{
// // heightOffset *= 2;
// //}
// //else
// //{
// // heightOffset /= 100;
// //}
// if (height != 0)
// {
// transform.DOMoveY((float)height, 1f);
// }
// else
// {
// transform.DOMoveY(-1, 1f);
// }
//}
////计算左右倾斜角度
var targetLatlon = manager.CurrentPlayer.currentlatLon; //目标gps
var bearing = TurfHelper.Bearing(targetLatlon.ToArray(), currentlatLon.ToArray());
//var targetLatlon = manager.CurrentPlayer.currentlatLon; //目标gps
//var bearing = TurfHelper.Bearing(targetLatlon.ToArray(), currentlatLon.ToArray());
//currentRotation.y += (float)bearing;
//transform.DORotate(currentRotation, 1, RotateMode.Fast);
//计算左右位移
//x =(z - z1)/tanp + x1;
bearing = (next.RotationY + manager.CurrentPlayer.next.RotationY) * Math.PI / 180;//转化为弧度值
var x =(z - target.position.z) * Math.Tan(bearing) + target.position.x;
Debug.Log($"当前海拔差{heightOffset} 当前角度{bearing} 距离{(z - target.position.z)}*Tan(bearing){Math.Tanh(bearing)}+目标x{target.position.x}=当前x{x}");
transform.DOMoveX((float)x, 1f);
//bearing = (next.RotationY + manager.CurrentPlayer.next.RotationY) * Math.PI / 180;//转化为弧度值
//var x =(z - target.position.z) * Math.Tan(bearing) + target.position.x;
//Debug.Log($"当前海拔差{heightOffset} 当前角度{bearing} 距离{(z - target.position.z)}*Tan(bearing){Math.Tanh(bearing)}+目标x{target.position.x}=当前x{x}");
//transform.DOMoveX((float)x, 1f);
//x轴位移
//var x = bearing + current.bearing;
@@ -168,10 +178,26 @@ namespace Assets.Scripts.Scenes.VideoRide
if (diff < 0)
((RectTransform)head.transform).anchoredPosition = new Vector2(((RectTransform)head.transform).anchoredPosition.x, -800f);
}
//人物碰撞
void OnCollisionEnter(Collision collision)
{
transform.DOMoveX(transform.position.x - 1,1);
}
private SplineController splineController;
private double preTime;
//设置当前玩家属性
public void SetPlayer(string name, double distance, double totalDistance, double cadance,double heartRate, double wkg, int userId,double power,double currentPlayerDistance,int frame)
{
if (manager == null)
{
manager = FindObjectOfType<VideoGameManager>();
}
var f = totalDistance;
StartCoroutine(DoAnimation(this.preTime, f - this.preTime));
preTime = f;
this.wkg = wkg;
this.UserName = name;
this.cadance = cadance;
@@ -182,6 +208,28 @@ namespace Assets.Scripts.Scenes.VideoRide
this.speed = distance * 3600;
this.diff = totalDistance - currentPlayerDistance;
this.currentFrame = frame;
splineController = transform.parent.GetComponent<SplineController>();
}
private IEnumerator DoAnimation(double preFrame,double offset)
{
float t = 0;
while (t < 1)
{
t += Time.deltaTime;
double result = preFrame + offset * t;
//var s1 = manager.frameList.OrderBy(c => c.Second).Where(c => c.Second > result).FirstOrDefault();
//var s2 = manager.frameList.OrderByDescending(c => c.Second).Where(c => c.Second < result).FirstOrDefault();
if (splineController != null)
{
splineController.Position = manager.startOffset + (float)(result * manager.ratio);//(float)(s2.Distance + (result - s2.Second) / (s1.Second - s2.Second) * (s1.Distance - s2.Distance)); //(float)(result / (double)s1.Key * s1.Value);
}
//if (splineController != null)
// splineController.Position = (float)(result / manager.GetMapData().TotalDistance * splineController.Length);
yield return null;
}
}
}
}
@@ -42,11 +42,15 @@ namespace Assets.Scripts.Scenes.VideoRide
UIManager.AddEvent(Day, UnityEngine.EventSystems.EventTriggerType.PointerClick, DayClick);
Container = transform.Find("List/Viewport/Content");
Month.GetComponent<Text>();
#if UNITY_EDITOR
UIManager.InitNow();//重置当前时间
#endif
Refresh();
}
private void Refresh(string type = "month")
{
return;
var list = manager.GetRankingList(type);
if (list != null)
File diff suppressed because it is too large. Load diff
@@ -209,8 +209,12 @@ namespace Assets.Scripts.Scenes.VideoRide
CreateRankingList(list.data.list);
}
}
bool startBtnLock = false;
public void StartRide(BaseEventData baseEvent)
{
if (startBtnLock)
return;
startBtnLock = true;
var ui = manager.GetCanvasTransform();
canvasGroup.DOFade(0, 1).onComplete += () => {
gameObject.SetActive(false);
+118 -18
View File
@@ -3,7 +3,11 @@ using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
using DG.Tweening;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
namespace Assets.Scripts.Scenes.VideoRide
@@ -21,6 +25,9 @@ namespace Assets.Scripts.Scenes.VideoRide
UserName = App.CurrentUser.Nickname;
var light = FindObjectOfType<Light>();
LightTrans = light.transform;
#if UNITY_EDITOR
InitConfig();
#endif
}
protected override bool GetStart()
@@ -56,30 +63,30 @@ namespace Assets.Scripts.Scenes.VideoRide
protected override void Turn()
{
base.Turn();
//控制人物的前后左右
if (manager._viewMode != VideoGameManager.ViewMode.FIRST)
{
var l = new Vector3(pre.PositionX, pre.PositionY, pre.PositionZ);
var s = new Vector3(next.PositionX, next.PositionY, next.PositionZ);
var pos = Vector3.Lerp(l, s, t);
transform.DOMove(pos, 0);
}
//控制光线
var z = new Vector3(50, pre.LightY, 0);
var c = new Vector3(50, next.LightY, 0);
var zc = Vector3.Lerp(z, c, t);
LightTrans.DORotate(zc, 0);
////控制人物的前后左右
//if (manager._viewMode != VideoGameManager.ViewMode.FIRST)
//{
// var l = new Vector3(pre.PositionX, pre.PositionY, pre.PositionZ);
// var s = new Vector3(next.PositionX, next.PositionY, next.PositionZ);
// var pos = Vector3.Lerp(l, s, t);
// transform.DOMove(pos, 0);
//}
////控制光线
//var z = new Vector3(50, pre.LightY, 0);
//var c = new Vector3(50, next.LightY, 0);
//var zc = Vector3.Lerp(z, c, t);
//LightTrans.DORotate(zc, 0);
}
protected override void ComputePlayer()
{
heartRate = manager.UpDateHeart();
power = manager.UpdatePower();
cadance = manager.UpdateCadence();
#if UNITY_EDITOR
power = 280;
cadance = 70;
heartRate = 160;
#endif
//#if UNITY_EDITOR
power = 220;
cadance = 50;
heartRate = 120;
//#endif
weight = App.CurrentUser.Weight;
bicycleWeight = App.CurrentUser.BicycleWeight;
wkg = Math.Round(power / weight, 2);
@@ -166,5 +173,98 @@ namespace Assets.Scripts.Scenes.VideoRide
manager.Save(totalDistance);
}
}
#if UNITY_EDITOR
//人物状态
public const int HERO_UP = 0;
public const int HERO_RIGHT = 1;
public const int HERO_DOWN = 2;
public const int HERO_LEFT = 3;
public const int UP = 4;
public const int DOWN = 5;
private Vector3 rotation = Vector3.zero;
private void LateUpdate()
{
var zdelta = 0.1f;
var delta = 0.2f;
//控制人物方向
if (Input.GetKey(KeyCode.Q))
{
rotation.y -= delta;
transform.DORotate(rotation, 0);
}
if (Input.GetKey(KeyCode.E))
{
rotation.y += delta;
transform.DORotate(rotation, 0);
}
//控制人物左右倾斜
if (Input.GetKey(KeyCode.J))
{
rotation.z += zdelta;
transform.DORotate(rotation, 0);
}
if (Input.GetKey(KeyCode.K))
{
rotation.z -= zdelta;
transform.DORotate(rotation, 0);
}
if (Input.GetKey(KeyCode.Space))
Save();
}
private string ConfigPath = Application.streamingAssetsPath + "/newdirection.txt";
//初始化配置
private void InitConfig()
{
var text = File.ReadAllText(ConfigPath);
var arr = text.Replace("\r\n", " ").Split(' ');
foreach (var item in arr)
{
if (!string.IsNullOrEmpty(item))
{
int key = Convert.ToInt32(item.Split(':')[0]);
list.Add(key, item);
}
}
}
private Dictionary<int, string> list = new Dictionary<int, string>();
private void Save()
{
var key = GetCurrentFrame();
//获取人物inpector面板的rotation值
Vector3 vect3 = Vector3.zero;
Vector3 vect = Vector3.zero;
MethodInfo mth = typeof(Transform).GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
PropertyInfo pi = typeof(Transform).GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
object rotationOrder = null;
if (pi != null)
{
rotationOrder = pi.GetValue(transform, null);
}
if (mth != null)
{
object retVector3 = mth.Invoke(transform, new object[] { rotationOrder });
vect3 = (Vector3)retVector3;
}
//保存记录
var s = $"{key}:{ Math.Round(vect3.y, 3)},{ Math.Round(vect3.z, 3)},{Math.Round(transform.position.x, 3)},{Math.Round(transform.position.y, 3)},{Math.Round(transform.position.z, 3)},{Math.Round(vect.y, 3)}";
Debug.Log(s);
if (list.ContainsKey(key))
{
list[key] = s;
}
else
{
list.Add(key, s);
}
var coll = list.OrderBy(c => c.Key);
StringBuilder sb = new StringBuilder();
foreach (var item in coll)
{
sb.AppendLine(item.Value);
}
File.WriteAllText(ConfigPath, sb.ToString());
}
#endif
}
}
@@ -66,10 +66,10 @@ namespace Assets.Scripts.Scenes.VideoRide
{
mapName.text = manager.GetMapRoute().Name;
#if UNITY_EDITOR
//#if UNITY_EDITOR
infoText.gameObject.SetActive(true);
infoText.text = $"帧数:{manager.GetCurrentFrame()}";
#endif
//#endif
if (manager.CurrentPlayer != null)
{
power.text = Math.Round(manager.CurrentPlayer.power).ToString();
@@ -84,7 +84,7 @@ namespace Assets.Scripts.Scenes.VideoRide
//ftp
ftpImage.fillAmount = (float)(manager.CurrentPlayer.wkg / MAXWKG);
wkg.text = $"{manager.CurrentPlayer.wkg}w/kg";
explosive.SetActive(true);
//explosive.SetActive(true);TODO:心率过高的时候显示
}
}
}
+8 -8
View File
@@ -15,13 +15,13 @@ public class MultiTips:PFUIText
{
base.Awake();
text = GetComponent<Text>();
var result = ConfigHelper.mapApi.GetTipsList();
if (result.result)
{
tips = result.data.ToArray();
random = new System.Random();
currentIndex = random.Next(0, tips.Length);
}
//var result = ConfigHelper.mapApi.GetTipsList();
//if (result.result)
//{
// tips = result.data.ToArray();
// random = new System.Random();
// currentIndex = random.Next(0, tips.Length);
//}
SetText();
}
// Start is called before the first frame update
@@ -31,7 +31,7 @@ public class MultiTips:PFUIText
}
public void SetText()
{
if(text == null || tips.Length == 0)
if(text == null || tips == null|| tips.Length == 0)
{
return;
}