部分代码重构
This commit is contained in:
1 parent
431d128ad8
commit
191efae2dd
46 files changed
+214
-209
No files matched your search
@@ -0,0 +1,297 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Assets.Core;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using DG.Tweening;
|
||||
using Mapbox.Utils;
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public abstract class AbstractVideoPlayer : MonoBehaviour, IRider
|
||||
{
|
||||
public double Diff { get;set; }
|
||||
protected int currentFrame { get; set; }
|
||||
protected Animator animator { get; set; }
|
||||
public GameObject head { get; set; }
|
||||
protected Image ftpImage { get; set; }
|
||||
protected Text headName { get; set; }
|
||||
protected Text headWkg { get; set; }
|
||||
|
||||
public int userId { get; set; }
|
||||
public string userName { get; set; }
|
||||
public double weight;//体重
|
||||
protected double bicycleWeight;//车重
|
||||
protected double preSpeed;
|
||||
public double speed;
|
||||
public double distance;
|
||||
public double power;
|
||||
public double elevation { get; set; }
|
||||
public double cadance { get; set; }
|
||||
public double wkg { get; set; }
|
||||
public int? heartRate { get; set; }
|
||||
public double totalDistance { get; set; }
|
||||
public double currentSlope { get; set; }
|
||||
protected double nextSlope { get; set; }
|
||||
protected double nextSlopeDistance { get; set; }
|
||||
protected double currentSlopeDistance { get; set; }
|
||||
public double totalClimb { get; set; }
|
||||
public Vector2d currentlatLon { get; set; }
|
||||
public int currentIndex { get; set; }
|
||||
|
||||
public int ticks { get; set; }
|
||||
|
||||
protected MapDataModel mapData;
|
||||
protected bool start = true;
|
||||
protected VideoGameManager manager { get; set; }
|
||||
Transform bone_bottle_2 { get; set; }
|
||||
|
||||
public double Speed { get; set; }
|
||||
public double StartDistance { get; set; }
|
||||
public double PreDistance { get; set; }
|
||||
public double EndDistance { get; set; }
|
||||
public double OnlineSpeed { get; set; }
|
||||
public int UserId => this.userId;
|
||||
public string UserName => this.userName;
|
||||
|
||||
public double mockpower { get; set; }
|
||||
protected float ratio = 1;
|
||||
private static readonly int PreSpeed = Animator.StringToHash("preSpeed");
|
||||
private static readonly int AnimatorSpeed = Animator.StringToHash("speed");
|
||||
private static readonly int Grade = Animator.StringToHash("grade");
|
||||
private static readonly int Power = Animator.StringToHash("power");
|
||||
|
||||
private Camera mainCamera;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
mapData = manager.GetMapData();
|
||||
ComputeNextSlope();//初始化坡度等
|
||||
bone_bottle_2 = transform.Find("bone_cable_20");
|
||||
mainCamera = Camera.main;
|
||||
}
|
||||
protected virtual void Update()
|
||||
{
|
||||
CreateHeadImage();
|
||||
ComputeAnimator();//控制动画
|
||||
ComputeAnimatorSpeed();//控制动画速度
|
||||
}
|
||||
|
||||
public void StartAction()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (manager.IsStart())
|
||||
{
|
||||
ComputeTimerTick();
|
||||
ComputeNextSlope();//计算下一个坡度
|
||||
ComputePlayer();//计算人物属性
|
||||
Forward();
|
||||
ComputeRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
power = 0;
|
||||
OnlineSpeed = 0;
|
||||
PreDistance = EndDistance;
|
||||
speed = 0;
|
||||
distance = 0;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
power = 0;
|
||||
speed = 0;
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ComputeTimerTick()
|
||||
{
|
||||
ticks++;
|
||||
}
|
||||
|
||||
public virtual void ComputeAnimator()
|
||||
{
|
||||
if (animator != null)
|
||||
{
|
||||
animator.SetFloat(PreSpeed, (float)preSpeed);
|
||||
animator.SetFloat(AnimatorSpeed, (float)OnlineSpeed);
|
||||
animator.SetFloat(Grade, (float)currentSlope);
|
||||
animator.SetFloat(Power, (float)power);
|
||||
}
|
||||
}
|
||||
//计算人物当前属性
|
||||
public virtual void ComputePlayer()
|
||||
{
|
||||
if (power > 0)
|
||||
{
|
||||
preSpeed = speed;
|
||||
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = 0;
|
||||
distance = 0;
|
||||
}
|
||||
}
|
||||
//计算当前人物的经纬度
|
||||
public virtual void Forward()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (mapData == null)
|
||||
mapData = manager.GetMapData();
|
||||
currentlatLon = manager.Along(totalDistance % mapData.TotalDistance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
public virtual void ComputeAnimatorSpeed()
|
||||
{
|
||||
Assert.IsNotNull(manager);
|
||||
|
||||
mapData = manager.GetMapData();
|
||||
|
||||
var safeIndex = currentIndex + 1 < mapData.List.Count ? currentIndex + 1 : currentIndex;
|
||||
var num = speed == 0 ? 1f : (float)(speed / mapData.List[safeIndex].Distance);
|
||||
|
||||
ratio = Mathf.Clamp(num, 0.3f, 1.2f);
|
||||
|
||||
var info = animator.GetCurrentAnimatorClipInfo(0);
|
||||
if (info == null) return;
|
||||
|
||||
var currentClip = info.FirstOrDefault();
|
||||
if (currentClip.clip != null)
|
||||
{
|
||||
animator.speed = ratio;
|
||||
}
|
||||
}
|
||||
public virtual void ComputeRecord() { }
|
||||
|
||||
private const double DoubleDelta = 1E-6;
|
||||
|
||||
private const double GradeFactor = 0.5f;
|
||||
//计算当前区段属性下一个区段属性
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.Abs(totalDistance - mapData.TotalDistance) < DoubleDelta)
|
||||
{
|
||||
currentIndex = pointList.Count - 1;
|
||||
}
|
||||
Debug.Log(currentIndex);
|
||||
preIndex = currentIndex > 0 ? currentIndex - 1 : 0;//前一个索引
|
||||
int nextIndex = currentIndex == pointList.Count - 1 ? currentIndex : currentIndex + 1; //计算下一个点的坡度和距离
|
||||
|
||||
elevation = pointList[currentIndex].Elevation;
|
||||
currentSlope = pointList[currentIndex].Grade * GradeFactor;
|
||||
//CurrentDistance = pointList[currentIndex].Distance;
|
||||
//计算下一个海拔和坡度&当前区间距离
|
||||
nextSlope = pointList[nextIndex].Grade * GradeFactor;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
head?.SetActive(false);
|
||||
}
|
||||
private void OnEnable()
|
||||
{
|
||||
head?.SetActive(true);
|
||||
}
|
||||
//显示人物头顶的名字
|
||||
public virtual void CreateHeadImage()
|
||||
{
|
||||
if (head == null)
|
||||
{
|
||||
if (manager.GetHeadInfo() != null)
|
||||
{
|
||||
head = Instantiate(manager.GetHeadInfo(), manager.GetCanvasTransform());
|
||||
ftpImage = head.transform.Find("ftp").GetComponent<Image>();
|
||||
headName = head.transform.Find("name").GetComponent<Text>();
|
||||
headWkg = head.transform.Find("wkg").GetComponent<Text>();
|
||||
}
|
||||
}
|
||||
UpdateHead();
|
||||
}
|
||||
|
||||
private void UpdateHead()
|
||||
{
|
||||
if (head == null) return;
|
||||
//update position
|
||||
var position = bone_bottle_2.position;
|
||||
var worldPosition = new Vector3(position.x, position.y + transform.localScale.y, position.z);
|
||||
var playerScreenPos = mainCamera.WorldToScreenPoint(worldPosition);
|
||||
playerScreenPos.y += 16f;
|
||||
head.transform.position = playerScreenPos;
|
||||
//update info
|
||||
ftpImage.fillAmount = (float)(wkg / 6);
|
||||
headName.text = UserName;
|
||||
headWkg.text = $"{wkg}W/KG";
|
||||
}
|
||||
|
||||
private void OnBecameInvisible()
|
||||
{
|
||||
head.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnBecameVisible()
|
||||
{
|
||||
head.SetActive(true);
|
||||
}
|
||||
|
||||
public void SetStartDistance(double distance)
|
||||
{
|
||||
this.StartDistance = distance *1000;
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
if (manager.CurrentPlayer != null && manager.CurrentPlayer.UserId == UserId)
|
||||
{
|
||||
manager.Pause();
|
||||
}
|
||||
head?.Destroy();
|
||||
gameObject.Destroy();
|
||||
}
|
||||
//设置当前玩家属性
|
||||
public abstract void SetPlayer(string name, double speed, double preDistance, double endDistance, double cadance, double heartRate, double wkg, int userId, double power, double currentPlayerDistance, int frame);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fecc58cd22dcfb4b87afc96b5be9d2e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,264 @@
|
||||
using Mapbox.Unity.Map;
|
||||
using Mapbox.Unity.MeshGeneration.Data;
|
||||
using Mapbox.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class InitMiniMapScript : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
AbstractMap _map;
|
||||
[SerializeField]
|
||||
Camera _minicamera;
|
||||
[SerializeField]
|
||||
GameObject _player;
|
||||
|
||||
GameObject _mipMapRoute;
|
||||
public RectTransform RectRoot { get; set; }
|
||||
TrailRenderer trail;
|
||||
Transform uitransform { get; set; }
|
||||
private bool init { get; set; } = false;
|
||||
private float timer { get; set; } = 0f;
|
||||
private GameObject _mipMapPath;
|
||||
private Material pathMaterial { get; set; }
|
||||
|
||||
VideoGameManager cyclingCotroller;
|
||||
public AbstractVideoPlayer playerController { get; set; }
|
||||
|
||||
private void Start()
|
||||
{
|
||||
cyclingCotroller = FindObjectOfType<VideoGameManager>();
|
||||
|
||||
if (cyclingCotroller != null)
|
||||
{
|
||||
playerController = cyclingCotroller.CurrentPlayer;
|
||||
var map = cyclingCotroller.GetMapData();
|
||||
//初始化map
|
||||
if (_map != null && map != null)
|
||||
{
|
||||
_map.OnInitialized += _map_OnInitialized;
|
||||
_map.OnUpdated += _map_OnUpdated;
|
||||
_map.Initialize(new Vector2d(map.Center[0], map.Center[1]), 12);
|
||||
var bbox = map.Bbox;
|
||||
var bounds = new Vector2dBounds(new Vector2d(bbox[1], bbox[0]), new Vector2d(bbox[3], bbox[2]));
|
||||
var screenBounds = GetScreenBounds();
|
||||
var z = SetZoomToFitBounds(bounds, screenBounds);
|
||||
}
|
||||
uitransform = cyclingCotroller.GetCanvasTransform();
|
||||
RectRoot = uitransform.Find("MiniMap/MiniMap").GetComponent<RectTransform>();
|
||||
}
|
||||
pathMaterial = Resources.Load<Material>("UI/Material/2");
|
||||
SetTrailRender();
|
||||
}
|
||||
|
||||
//设置小地图上人物移动路径
|
||||
private void SetTrailRender()
|
||||
{
|
||||
trail = transform.parent.Find("Sphere").GetComponent<TrailRenderer>();
|
||||
trail.startWidth = 5f;
|
||||
trail.endWidth = 5f;
|
||||
trail.startColor = new Color(0.9764706f, 0.1882353f, 0.5254902f, 1f);
|
||||
trail.endColor = new Color(0.9764706f, 0.1882353f, 0.5254902f, 1f);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (cyclingCotroller.CurrentPlayer == null) return;
|
||||
|
||||
uitransform = cyclingCotroller.GetCanvasTransform();
|
||||
var tr = uitransform.Find("MiniMap/MiniMap/arrow");
|
||||
tr.SetSiblingIndex(9999);
|
||||
|
||||
var pos = _map.GeoToWorldPosition(cyclingCotroller.CurrentPlayer.currentlatLon);
|
||||
pos.y += 15f;
|
||||
_player.transform.localPosition = pos;
|
||||
|
||||
var vp2 = _minicamera.WorldToViewportPoint(_player.transform.localPosition);//将三维物体的世界坐标转换为视口坐标
|
||||
((RectTransform)tr.transform).anchoredPosition = new Vector2((vp2.x * RectRoot.sizeDelta.x) - (RectRoot.sizeDelta.x * 0.5f), (vp2.y * RectRoot.sizeDelta.y) - (RectRoot.sizeDelta.y * 0.5f));
|
||||
trail.enabled = cyclingCotroller.CurrentPlayer.power > 0;
|
||||
|
||||
timer += Time.deltaTime;
|
||||
while (timer >= 1)
|
||||
{
|
||||
CreateMiniPath();
|
||||
timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void _map_OnInitialized()
|
||||
{
|
||||
init = true;
|
||||
var visualizer = _map.MapVisualizer;
|
||||
visualizer.OnMapVisualizerStateChanged += (s) =>
|
||||
{
|
||||
if (s == ModuleState.Finished)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/mapbox/mapbox-unity-sdk/issues/1580
|
||||
/// </summary>
|
||||
/// <param name="targetBounds">路线的边界</param>
|
||||
/// <param name="screenBounds">小地图边界</param>
|
||||
private int SetZoomToFitBounds(Vector2dBounds targetBounds, Vector2dBounds screenBounds)
|
||||
{
|
||||
var targetLonDelta = targetBounds.East - targetBounds.West;
|
||||
var targetLatDelta = targetBounds.North - targetBounds.South;
|
||||
|
||||
var screenLonDelta = screenBounds.East - screenBounds.West;
|
||||
var screenLatDelta = screenBounds.North - screenBounds.South;
|
||||
|
||||
var zoomLatMultiplier = screenLatDelta / targetLatDelta;
|
||||
var zoomLonMultiplier = screenLonDelta / targetLonDelta;
|
||||
|
||||
var latZoom = Math.Log(zoomLatMultiplier, 2);
|
||||
var lonZoom = Math.Log(zoomLonMultiplier, 2);
|
||||
|
||||
var zoom = (float)(_map.Zoom + Math.Min(latZoom, lonZoom));
|
||||
|
||||
_map.SetZoom((float)Math.Floor(zoom));
|
||||
_map.UpdateMap();
|
||||
return (int)Math.Floor(zoom);
|
||||
}
|
||||
|
||||
private Vector2dBounds GetScreenBounds()
|
||||
{
|
||||
var screenWidth = UnityEngine.Screen.width;
|
||||
var screenHeight = UnityEngine.Screen.height;
|
||||
|
||||
var sw_world = _minicamera.ViewportToWorldPoint(new Vector3(0f, 0f, 160));
|
||||
var sw = _map.WorldToGeoPosition(sw_world);
|
||||
var ne_world = _minicamera.ViewportToWorldPoint(new Vector3(1f, 1f, 90));
|
||||
var ne = _map.WorldToGeoPosition(ne_world);
|
||||
|
||||
return new Vector2dBounds(new Vector2d(sw.x, sw.y), new Vector2d(ne.x, ne.y));
|
||||
}
|
||||
|
||||
private void _map_OnUpdated()
|
||||
{
|
||||
CreateMiniRoute();
|
||||
}
|
||||
|
||||
private void CreateMiniRoute()
|
||||
{
|
||||
var dat = new List<Vector3>();
|
||||
|
||||
var mapData = cyclingCotroller.GetMapData();
|
||||
if (mapData == null) return;
|
||||
|
||||
var count = mapData.List.Count;
|
||||
var interval = Math.Max(Math.Ceiling(count / 100D), 1f);
|
||||
for (var i = 0; i < mapData.List.Count; i++)
|
||||
{
|
||||
if (i % interval == 0)
|
||||
{
|
||||
var point = mapData.List[i].Point;
|
||||
Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0], point[1]));
|
||||
item.y += 1f;
|
||||
dat.Add(item);
|
||||
}
|
||||
}
|
||||
//创建小地图路线
|
||||
var feat = new VectorFeatureUnity();
|
||||
feat.Points.Add(dat);
|
||||
CreateLineRender(feat);
|
||||
}
|
||||
|
||||
private void CreateMiniPath()
|
||||
{
|
||||
var dat = new List<Vector3>();
|
||||
var mapData = cyclingCotroller.GetMapData();
|
||||
if (mapData == null) return;
|
||||
|
||||
var count = mapData.List.Count;
|
||||
var interval = Math.Max(Math.Ceiling(count / 100D), 1f);
|
||||
for (int i = 0; i < mapData.List.Count; i++)
|
||||
{
|
||||
if (i % interval == 0)
|
||||
{
|
||||
var point = mapData.List[i].Point;
|
||||
Vector3 item = _map.GeoToWorldPosition(new Vector2d(point[0], point[1]));
|
||||
item.y += 5f;
|
||||
if (cyclingCotroller.CurrentPlayer.currentIndex >= i)
|
||||
{
|
||||
dat.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
//创建路径
|
||||
var feat = new VectorFeatureUnity();
|
||||
feat.Points.Add(dat);
|
||||
CreateRedLineRender(feat);
|
||||
}
|
||||
|
||||
//创建小地图路线
|
||||
private void CreateLineRender(VectorFeatureUnity feat)
|
||||
{
|
||||
if (_mipMapRoute != null)
|
||||
{
|
||||
_mipMapRoute.Destroy();
|
||||
}
|
||||
|
||||
_mipMapRoute = new GameObject("MiniMapRoute")
|
||||
{
|
||||
transform =
|
||||
{
|
||||
parent = transform.parent
|
||||
}
|
||||
};
|
||||
|
||||
var lineRender = _mipMapRoute.AddComponent<LineRenderer>();
|
||||
lineRender.material = Resources.Load<Material>("UI/Material/1");
|
||||
var dat = feat.Points[0];
|
||||
lineRender.endColor = Color.white;
|
||||
lineRender.startColor = Color.white;
|
||||
//设置宽度
|
||||
lineRender.startWidth = 15f;
|
||||
lineRender.endWidth = 15f;
|
||||
lineRender.positionCount = dat.Count;
|
||||
lineRender.SetPositions(feat.Points[0].ToArray());
|
||||
lineRender.numCornerVertices = 20;
|
||||
lineRender.numCapVertices = 20;
|
||||
lineRender.loop = false;
|
||||
_mipMapRoute.layer = 9;
|
||||
_map.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void CreateRedLineRender(VectorFeatureUnity feat)
|
||||
{
|
||||
if (_mipMapPath != null)
|
||||
{
|
||||
_mipMapPath.Destroy();
|
||||
}
|
||||
_mipMapPath = new GameObject("MiniMapPath")
|
||||
{
|
||||
transform =
|
||||
{
|
||||
parent = transform.parent
|
||||
}
|
||||
};
|
||||
var lineRender = _mipMapPath.AddComponent<LineRenderer>();
|
||||
|
||||
lineRender.material = pathMaterial;
|
||||
var dat = feat.Points[0];
|
||||
lineRender.endColor = Color.red;
|
||||
lineRender.startColor = Color.red;
|
||||
//设置宽度
|
||||
lineRender.startWidth = 20f;
|
||||
lineRender.endWidth = 20f;
|
||||
lineRender.positionCount = dat.Count;
|
||||
lineRender.SetPositions(feat.Points[0].ToArray());
|
||||
lineRender.numCornerVertices = 20;
|
||||
lineRender.numCapVertices = 20;
|
||||
lineRender.loop = false;
|
||||
_mipMapPath.layer = 9;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c536d01b43b2f643a86ef176910485a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class OnlineVideoPlayer : AbstractVideoPlayer
|
||||
{
|
||||
public override void CreateHeadImage()
|
||||
{
|
||||
base.CreateHeadImage();
|
||||
if (Diff < 0)
|
||||
HideHeadRectTransform();
|
||||
}
|
||||
|
||||
//隐藏其他玩家的头像
|
||||
private void HideHeadRectTransform()
|
||||
{
|
||||
((RectTransform)head.transform).anchoredPosition = new Vector2(((RectTransform)head.transform).anchoredPosition.x, -800f);
|
||||
}
|
||||
|
||||
public override void SetPlayer(string name, double speed, double preDistance, double endDistance, double cadance, double heartRate, double wkg, int userId, double power, double currentPlayerDistance, int frame)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
}
|
||||
this.wkg = wkg;
|
||||
this.userName = name;
|
||||
this.cadance = cadance;
|
||||
this.totalDistance = endDistance;
|
||||
this.heartRate = (int?)heartRate;
|
||||
this.userId = userId;
|
||||
this.power = power;
|
||||
this.speed = speed;
|
||||
this.Speed = speed;
|
||||
this.OnlineSpeed = this.Speed/3.6f;
|
||||
this.Diff = endDistance - currentPlayerDistance;
|
||||
this.currentFrame = frame;
|
||||
this.PreDistance = preDistance * 1000;
|
||||
this.EndDistance = endDistance * 1000;
|
||||
}
|
||||
|
||||
public override void ComputePlayer()
|
||||
{
|
||||
distance = this.speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a56584ff2ae65dd43af5e8299544f32f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdac326eaff04872bcebc003689d480b
|
||||
timeCreated: 1683888648
|
||||
@@ -0,0 +1,136 @@
|
||||
using ChartAndGraph;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class ElevationBarDataFeed : MonoBehaviour
|
||||
{
|
||||
VideoGameManager manager { get; set; }
|
||||
[SerializeField]
|
||||
Material _lightColor;
|
||||
[SerializeField]
|
||||
Material _mediumColor;
|
||||
[SerializeField]
|
||||
Material _hardColor;
|
||||
[SerializeField]
|
||||
Material _heavyColor;
|
||||
|
||||
GameObject headPanel { get; set; }
|
||||
|
||||
void Start()
|
||||
{
|
||||
manager= FindObjectOfType<VideoGameManager>();
|
||||
|
||||
BarChart barChart = GetComponent<BarChart>();
|
||||
barChart.DataSource.ClearCategories();
|
||||
barChart.DataSource.ClearValues();
|
||||
if (barChart != null)
|
||||
{
|
||||
var list = manager.GetMapData().List;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
barChart.DataSource.AddCategory($"Player {i}", getChartMaterial(list[i].Grade));
|
||||
barChart.DataSource.SetValue($"Player {i}", "Group 1", list[i].Elevation);
|
||||
}
|
||||
}
|
||||
headPanel = Resources.Load<GameObject>("UI/Prefab/AR/HeadPanel");
|
||||
}
|
||||
|
||||
float timer = 1f;
|
||||
private void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer < 0)
|
||||
{
|
||||
|
||||
timer += 0.5f;
|
||||
}
|
||||
MoveOnlinePlayerHead();
|
||||
}
|
||||
|
||||
//移动海拔线上人物位置
|
||||
private void MoveOnlinePlayerHead()
|
||||
{
|
||||
if (manager.cyclingController == null)
|
||||
return;
|
||||
var players = manager.cyclingController.riders;
|
||||
players = players.Where(c => ((OnlineRiderModel)c).IsWatcher == false).ToList();
|
||||
var headList = FindObjectsOfType<HeadScript>();
|
||||
var videoPlayer = manager.CurrentPlayer;
|
||||
foreach (var item in players)
|
||||
{
|
||||
BarChart barChart = GetComponent<BarChart>();
|
||||
Vector3 vector3 = Vector3.back;
|
||||
var distance = item.EndDistance; //% manager.mapRoute.Distance;
|
||||
|
||||
var currentIndex = Mathf.Clamp((float)(distance / manager.mapRoute.Distance * manager.GetMapData().List.Count),0, manager.GetMapData().List.Count-1);
|
||||
barChart.GetBarTrackPosition($"Player {Math.Round(currentIndex,0)}", "Group 1", out vector3);
|
||||
|
||||
var currentHead = headList.Where(c => c.UserId == item.UserId).FirstOrDefault();
|
||||
if (currentHead == null)
|
||||
{
|
||||
var onlineHead = Instantiate(headPanel, transform);
|
||||
onlineHead.GetComponent<HeadScript>().UserId = item.UserId;
|
||||
onlineHead.transform.position = vector3;
|
||||
currentHead = onlineHead.GetComponent<HeadScript>();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentHead.transform.position = vector3;
|
||||
}
|
||||
//控制海拔图头像
|
||||
if (manager.CurrentUserId == item.UserId)
|
||||
{
|
||||
currentHead.transform.Find("Main").gameObject.SetActive(true);
|
||||
currentHead.transform.SetAsLastSibling();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentHead.transform.Find("Main").gameObject.SetActive(false);
|
||||
currentHead.transform.SetAsFirstSibling();
|
||||
}
|
||||
}
|
||||
//删除离线的人
|
||||
foreach (var item in headList)
|
||||
{
|
||||
if (item.UserId != 0)
|
||||
{
|
||||
var player = players.Where(c => c.UserId == item.UserId).FirstOrDefault();
|
||||
if (player == null)
|
||||
{
|
||||
item.gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ChartDynamicMaterial getChartMaterial(double grade = 0d)
|
||||
{
|
||||
//1: ≥7°坡 红色
|
||||
//2: 3°~7°坡 橙色
|
||||
//3: 0°~3°坡 黄色
|
||||
//4: ≤0°坡 绿色
|
||||
ChartDynamicMaterial chartDynamicMaterial;
|
||||
if (grade > 7)
|
||||
{
|
||||
chartDynamicMaterial = new ChartDynamicMaterial(_heavyColor);
|
||||
}
|
||||
else if (grade > 3)
|
||||
{
|
||||
chartDynamicMaterial = new ChartDynamicMaterial(_hardColor);
|
||||
}
|
||||
else if (grade > 0)
|
||||
{
|
||||
chartDynamicMaterial = new ChartDynamicMaterial(_mediumColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
chartDynamicMaterial = new ChartDynamicMaterial(_lightColor);
|
||||
}
|
||||
return chartDynamicMaterial;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3b2e5abc80332645b6ab677873adeec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class ExplosiveScript : MonoBehaviour
|
||||
{
|
||||
Image image;
|
||||
private void Awake()
|
||||
{
|
||||
image = transform.GetComponent<Image>();
|
||||
}
|
||||
float flag = 0f;
|
||||
float alph = 0f;
|
||||
private void Update()
|
||||
{
|
||||
flag += Time.deltaTime;
|
||||
if (flag >= 0.5f)
|
||||
{
|
||||
alph -= Time.deltaTime;
|
||||
if (alph <= 0)
|
||||
{
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alph += Time.deltaTime;
|
||||
}
|
||||
image.color = new Color(image.color.r, image.color.g, image.color.b, alph);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a04020ffe9892d498bfe3031bac76ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class HeadScript : MonoBehaviour
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public int UserId { get; set; }
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1092a970c15e99c47b4fce5495b5a7f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using PolyAndCode.UI;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class ListItem : MonoBehaviour, ICell
|
||||
{
|
||||
//UI
|
||||
public Text nameLabel;
|
||||
public Text genderLabel;
|
||||
public Text idLabel;
|
||||
public Text powerLabel;
|
||||
public GameObject master;
|
||||
|
||||
//Model
|
||||
private ContactInfo _contactInfo;
|
||||
private int _cellIndex;
|
||||
public string Id;
|
||||
public string Rank;
|
||||
public string Name;
|
||||
private float timer = 1f;
|
||||
private VideoGameManager manager { get; set; }
|
||||
|
||||
private void Start()
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
GetComponent<Button>().onClick.AddListener(ButtonListener);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer < 0)
|
||||
{
|
||||
if (manager != null)
|
||||
{
|
||||
var riders = manager.cyclingController?.riders;
|
||||
if (riders != null)
|
||||
{
|
||||
var current = riders.FirstOrDefault(c => c.UserId.ToString() == Id);
|
||||
if (current == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
timer += 1f;
|
||||
}
|
||||
}
|
||||
|
||||
//This is called from the SetCell method in DataSource
|
||||
public void ConfigureCell(ContactInfo contactInfo, int cellIndex)
|
||||
{
|
||||
Id = contactInfo.id;
|
||||
_cellIndex = cellIndex;
|
||||
_contactInfo = contactInfo;
|
||||
|
||||
nameLabel.text = contactInfo.Name;
|
||||
genderLabel.text = contactInfo.Gender;
|
||||
idLabel.text = contactInfo.id;
|
||||
powerLabel.text = contactInfo.Power.ToString("f0") + "W";
|
||||
}
|
||||
|
||||
public void UpdateItem(string name,string gender,string id)
|
||||
{
|
||||
nameLabel.text = name;
|
||||
genderLabel.text = gender;
|
||||
idLabel.text = id;
|
||||
master.SetActive(manager.CurrentPlayer?.UserId.ToString() == id);
|
||||
}
|
||||
|
||||
private void ButtonListener()
|
||||
{
|
||||
if(manager._aRMode == VideoGameManager.ARMode.INSPECT)
|
||||
manager.ChangePlayer(Convert.ToInt32(Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 057cbb0cadd9caf4c9031a94f9ca6d39
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using DG.Tweening;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class NearByScript: MonoBehaviour
|
||||
{
|
||||
Text rideNum {get;set;}
|
||||
Text btnRideNum { get; set; }
|
||||
GameObject Hide { get; set; }
|
||||
GameObject Show { get; set; }
|
||||
VideoPlayer videoPlayer { get; set; }
|
||||
|
||||
private bool isAnimating = false;
|
||||
VerticalLayoutGroup group { get; set; }
|
||||
GameObject stickyItem { get; set; }
|
||||
VideoGameManager manager { get; set; }
|
||||
RectTransform viewRec { get; set; }
|
||||
private void Start()
|
||||
{
|
||||
rideNum = transform.Find("Head/RideNum/Number").GetComponent<Text>();
|
||||
btnRideNum = transform.Find("Head/Show/Panel/Number").GetComponent<Text>();
|
||||
Hide = transform.Find("Head/Hide").gameObject;
|
||||
Show = transform.Find("Head/Show").gameObject;
|
||||
var viewPort = transform.Find("List/Viewport");
|
||||
stickyItem = transform.Find("List/VideoPlayerInfo").gameObject;
|
||||
UIManager.AddEvent(Hide, UnityEngine.EventSystems.EventTriggerType.PointerClick, Hidehandler);
|
||||
UIManager.AddEvent(Show, UnityEngine.EventSystems.EventTriggerType.PointerClick, Showhandler);
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
viewRec = ((RectTransform)viewPort);
|
||||
}
|
||||
public void Hidehandler(BaseEventData data)
|
||||
{
|
||||
if (isAnimating)
|
||||
return;
|
||||
isAnimating = true;
|
||||
transform.DOLocalMoveX(913, 1f).onComplete += () => {
|
||||
Show.SetActive(true);
|
||||
Hide.SetActive(false);
|
||||
isAnimating = false;
|
||||
};
|
||||
}
|
||||
public void Showhandler(BaseEventData data)
|
||||
{
|
||||
if (isAnimating)
|
||||
return;
|
||||
isAnimating = true;
|
||||
Show.SetActive(false);
|
||||
Hide.SetActive(true);
|
||||
transform.DOLocalMoveX(667.55f, 1f).onComplete += () => {
|
||||
isAnimating = false;
|
||||
};
|
||||
}
|
||||
float timer = 1f;
|
||||
private void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer < 0) {
|
||||
var list = MapUDPService.GetOnlineUsers(App.RouteIdParam);//最新列表
|
||||
list = list.Where(c => c.IsWatcher == false).ToList();
|
||||
rideNum.text = $"{list.Count}";
|
||||
btnRideNum.text = rideNum.text;
|
||||
if (manager._aRMode == VideoGameManager.ARMode.RIDE)
|
||||
{
|
||||
stickyItem.SetActive(true);
|
||||
viewRec.DOLocalMoveY(256, 0f);
|
||||
viewRec.DOSizeDelta(new Vector2(viewRec.sizeDelta.x, 546), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
stickyItem.SetActive(false);
|
||||
viewRec.DOLocalMoveY(300, 0f);
|
||||
viewRec.DOSizeDelta(new Vector2(viewRec.sizeDelta.x,590f), 0);
|
||||
}
|
||||
timer += 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 626b431b9a468f94b89fce5f20a2cc36
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,151 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
|
||||
using PolyAndCode.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class ContactInfo
|
||||
{
|
||||
public string Name;
|
||||
public string Gender;
|
||||
public string id;
|
||||
public double Power;
|
||||
}
|
||||
class NearVideoPlayerList : MonoBehaviour, IRecyclableScrollRectDataSource
|
||||
{
|
||||
[SerializeField]
|
||||
RecyclableScrollRect _recyclableScrollRect;
|
||||
|
||||
[SerializeField]
|
||||
RectTransform _rectTransform;
|
||||
|
||||
[SerializeField]
|
||||
private int _dataLength;
|
||||
|
||||
|
||||
private bool _isInit;
|
||||
|
||||
//Dummy data List
|
||||
private List<ContactInfo> _contactList = new List<ContactInfo>();
|
||||
|
||||
private VideoGameManager manager { get; set; }
|
||||
|
||||
//Recyclable scroll rect's data source must be assigned in Awake.
|
||||
private void Awake()
|
||||
{
|
||||
InitData();
|
||||
_recyclableScrollRect.DataSource = this;
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
}
|
||||
|
||||
private void InitData()
|
||||
{
|
||||
if (_contactList != null) _contactList.Clear();
|
||||
var list = MapUDPService.GetOnlineUsers(App.RouteIdParam);
|
||||
list = list.Where(c => c.IsWatcher == false).ToList();
|
||||
var currentPlayer = list.Where(c => c.IsSelf).FirstOrDefault();
|
||||
list = list.Where(c => c.Id != App.CurrentUser.Id).ToList();
|
||||
foreach (var item in list)
|
||||
{
|
||||
_isInit = true;
|
||||
ContactInfo obj = new ContactInfo();
|
||||
obj.Name = item.Name;
|
||||
obj.Gender = "";
|
||||
obj.id = item.Id.ToString();
|
||||
obj.Power = item.Power;
|
||||
_contactList.Add(obj);
|
||||
}
|
||||
}
|
||||
float timer = 1f;
|
||||
private void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer < 0)
|
||||
{
|
||||
if (manager.CurrentPlayer == null)
|
||||
return;
|
||||
var totalDitance = manager.GetMapData().TotalDistance;
|
||||
var currentDistance = manager.CurrentPlayer.totalDistance;
|
||||
var currenList = GetComponentsInChildren<ListItem>(true);
|
||||
var list = MapUDPService.GetOnlineUsers(App.RouteIdParam,manager.cyclingController.recorderData.RoomId);//最新列表
|
||||
list = list.Where(c => c.IsWatcher == false).ToList();
|
||||
var currentPlayerInfo = list.Where(c => c.Id.ToString() == manager.CurrentPlayer.UserId.ToString()).FirstOrDefault();
|
||||
list = list.Where(c => c.Id != App.CurrentUser.Id).OrderByDescending(c=>c.EndDistance).ToList();
|
||||
if (currenList.Count() == 0 && list.Count() > 0)
|
||||
{
|
||||
InitData();
|
||||
if (_recyclableScrollRect.SelfInitialize)
|
||||
{
|
||||
_recyclableScrollRect.ReloadData();
|
||||
}
|
||||
}
|
||||
|
||||
var currentPlayer = manager.CurrentPlayer;
|
||||
if (currentPlayer == null)
|
||||
return;
|
||||
foreach (ListItem o in currenList)
|
||||
{
|
||||
if (currentPlayer.UserId.ToString() == o.Id)
|
||||
continue;
|
||||
var needUpdate = list.Where(c => c.Id.ToString() == o.Id).FirstOrDefault();
|
||||
if (needUpdate != null && currentPlayerInfo != null)
|
||||
{
|
||||
var left = Math.Round((needUpdate.EndDistance - currentPlayerInfo.EndDistance) * 1000);
|
||||
o.UpdateItem(needUpdate.Name, left.ToString() + "M", needUpdate.Id.ToString());
|
||||
o.gameObject.SetActive(true);
|
||||
o.transform.SetSiblingIndex((int)left);
|
||||
}
|
||||
else
|
||||
{
|
||||
o.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
var newOne = _contactList.Where(c => c.id == item.Id.ToString()).FirstOrDefault();
|
||||
if (newOne == null)
|
||||
{
|
||||
var one = new ContactInfo();
|
||||
one.Name = item.Name;
|
||||
one.Gender = "";
|
||||
one.id = item.Id.ToString();
|
||||
_contactList.Add(one);
|
||||
_recyclableScrollRect.ReloadData();
|
||||
}
|
||||
}
|
||||
timer +=1f;
|
||||
}
|
||||
}
|
||||
|
||||
#region DATA-SOURCE
|
||||
|
||||
/// <summary>
|
||||
/// Data source method. return the list length.
|
||||
/// </summary>
|
||||
public int GetItemCount()
|
||||
{
|
||||
return _contactList.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data source method. Called for a cell every time it is recycled.
|
||||
/// Implement this method to do the necessary cell configuration.
|
||||
/// </summary>
|
||||
public void SetCell(ICell cell, int index)
|
||||
{
|
||||
//Casting to the implemented Cell
|
||||
var item = cell as ListItem;
|
||||
item.ConfigureCell(_contactList[index], index);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad9c66572ce69ea4fba3bc35e6db3d86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class RankingItemScript:MonoBehaviour
|
||||
{
|
||||
Text rankingText;
|
||||
Text nameText;
|
||||
Text timerText;
|
||||
|
||||
RawImage head;
|
||||
RawImage country;
|
||||
private void Awake()
|
||||
{
|
||||
rankingText = transform.Find("Rank").GetComponent<Text>();
|
||||
nameText = transform.Find("Name").GetComponent<Text>();
|
||||
timerText = transform.Find("Distance").GetComponent<Text>();
|
||||
// head = transform.Find("Head").GetComponent<RawImage>();
|
||||
country = transform.Find("Country").GetComponent<RawImage>();
|
||||
}
|
||||
|
||||
public void SetRanking(string ranking)
|
||||
{
|
||||
rankingText.text = ranking.PadLeft(2,'0');
|
||||
}
|
||||
public void SetName(string name)
|
||||
{
|
||||
nameText.text = name;
|
||||
}
|
||||
public void SetTimer(string timer)
|
||||
{
|
||||
timerText.text = timer;
|
||||
}
|
||||
public void SetHead(string url)
|
||||
{
|
||||
Utils.DisplayImage(head, url);
|
||||
}
|
||||
public void SetCountry(Texture texture)
|
||||
{
|
||||
country.texture = texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8032c539f5d80584da36ae53a0f52e1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,115 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using DG.Tweening;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class RankingScript: MonoBehaviour
|
||||
{
|
||||
GameObject Hide { get; set; }
|
||||
GameObject Show { get; set; }
|
||||
GameObject Month { get; set; }
|
||||
GameObject Week { get; set; }
|
||||
GameObject Day { get; set; }
|
||||
VideoGameManager manager { get; set; }
|
||||
Transform Container { get; set; }
|
||||
Text MonthTxt { get; set; }
|
||||
Text WeekTxt { get; set; }
|
||||
Text DayTxt { get; set; }
|
||||
private bool isAnimating = false;
|
||||
private void Start()
|
||||
{
|
||||
Hide = transform.Find("Head/Hide").gameObject;
|
||||
Show = transform.Find("Head/Show").gameObject;
|
||||
Month = transform.Find("Head/Month").gameObject;
|
||||
Week = transform.Find("Head/Week").gameObject;
|
||||
Day = transform.Find("Head/Day").gameObject;
|
||||
|
||||
MonthTxt = transform.Find("Head/Month/Text").GetComponent<Text>();
|
||||
MonthTxt.color = Color.red;
|
||||
WeekTxt = transform.Find("Head/Week/Text").GetComponent<Text>();
|
||||
DayTxt = transform.Find("Head/Day/Text").GetComponent<Text>();
|
||||
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
Container = transform.Find("List/Viewport/Content");
|
||||
Month.GetComponent<Text>();
|
||||
|
||||
UIManager.AddEvent(Hide, UnityEngine.EventSystems.EventTriggerType.PointerClick, Hidehandler);
|
||||
UIManager.AddEvent(Show, UnityEngine.EventSystems.EventTriggerType.PointerClick, Showhandler);
|
||||
UIManager.AddEvent(Month, UnityEngine.EventSystems.EventTriggerType.PointerClick, MonthClick);
|
||||
UIManager.AddEvent(Week, UnityEngine.EventSystems.EventTriggerType.PointerClick, WeekClick);
|
||||
UIManager.AddEvent(Day, UnityEngine.EventSystems.EventTriggerType.PointerClick, DayClick);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UIManager.InitNow();//重置当前时间
|
||||
#endif
|
||||
Refresh();
|
||||
}
|
||||
|
||||
//TODO: 重构
|
||||
private void Refresh(string type = "month")
|
||||
{
|
||||
return;
|
||||
var list = manager.GetRankingList(type);
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
var prefab = Resources.Load<GameObject>("UI/Prefab/AR/RankingItem");
|
||||
Container.DestroyChildren();
|
||||
foreach (var item in list.list)
|
||||
{
|
||||
GameObject newObj = (GameObject)Instantiate(prefab, Container);
|
||||
var itemScript = newObj.GetComponent<RankingItemScript>();
|
||||
itemScript.SetName(item.NickName);
|
||||
var texture = manager.GetCountryImageByCode(item.CountryCode);
|
||||
itemScript.SetCountry(texture);
|
||||
itemScript.SetTimer(item.TotalTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Hidehandler(BaseEventData data)
|
||||
{
|
||||
if (isAnimating)
|
||||
return;
|
||||
isAnimating = true;
|
||||
transform.DOLocalMoveX(-913, 1f).onComplete+=()=> {
|
||||
Show.SetActive(true);
|
||||
Hide.SetActive(false);
|
||||
isAnimating = false;
|
||||
};
|
||||
}
|
||||
public void Showhandler(BaseEventData data)
|
||||
{
|
||||
if (isAnimating)
|
||||
return;
|
||||
isAnimating = true;
|
||||
Show.SetActive(false);
|
||||
Hide.SetActive(true);
|
||||
transform.DOLocalMoveX(-667, 1f).onComplete += () => {
|
||||
isAnimating = false;
|
||||
};
|
||||
}
|
||||
public void MonthClick(BaseEventData data)
|
||||
{
|
||||
MonthTxt.color = Color.red;
|
||||
WeekTxt.color = Color.white;
|
||||
DayTxt.color = Color.white;
|
||||
Refresh("month");
|
||||
}
|
||||
public void WeekClick(BaseEventData data)
|
||||
{
|
||||
MonthTxt.color = Color.white;
|
||||
WeekTxt.color = Color.red;
|
||||
DayTxt.color = Color.white;
|
||||
Refresh("week");
|
||||
}
|
||||
public void DayClick(BaseEventData data)
|
||||
{
|
||||
MonthTxt.color = Color.white;
|
||||
WeekTxt.color = Color.white;
|
||||
DayTxt.color = Color.red;
|
||||
Refresh("day");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5125c2c61c26934d858b75fa9dfd187
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class RideSettingController : PFUIPanel
|
||||
{
|
||||
public Slider PowerSlider;
|
||||
public Text PowerText;
|
||||
private VideoGameManager manager;
|
||||
|
||||
void Start()
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
//设置模拟功率
|
||||
PowerSlider.onValueChanged.AddListener(e =>
|
||||
{
|
||||
PowerText.text = e.ToString("f0") + "W";
|
||||
if (manager.CurrentPlayer != null)
|
||||
{
|
||||
manager.CurrentPlayer.mockpower = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c630a81d1477c842ad1599135a73d2d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using PolyAndCode.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class StickyListItem : MonoBehaviour, ICell
|
||||
{
|
||||
//UI
|
||||
public Text nameLabel;
|
||||
public Text distanceLabel;
|
||||
public GameObject master;
|
||||
//Model
|
||||
private ContactInfo _contactInfo;
|
||||
private int _cellIndex;
|
||||
public string Id;
|
||||
public string Rank;
|
||||
public string Name;
|
||||
private VideoPlayer videoPlayer { get; set; }
|
||||
private float timer = 1f;
|
||||
private void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer < 0)
|
||||
{
|
||||
videoPlayer = FindObjectOfType<VideoPlayer>();
|
||||
if (videoPlayer != null)
|
||||
{
|
||||
nameLabel.text = videoPlayer.UserName;
|
||||
distanceLabel.text = "0M";///videoPlayer.totalDistance.ToString("f1");
|
||||
Id = videoPlayer.UserId.ToString();
|
||||
}
|
||||
timer += 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5b781a8c7954144ea7de573333f09ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,466 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.EventSystems;
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using System.Linq;
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.AR;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoLoading : MonoBehaviour, IProgress<float>
|
||||
{
|
||||
VideoGameManager manager { get; set; }
|
||||
|
||||
private Text mapName;
|
||||
private RawImage mapRouteImage;
|
||||
private CanvasGroup canvasGroup;
|
||||
private Slider slider;
|
||||
private Text processText;
|
||||
private Text rideNowText;
|
||||
private Button rideNow;
|
||||
private Button cancel;
|
||||
private Text mapDescText;
|
||||
private Text distance;
|
||||
private Text elevaction;
|
||||
private Text slope;
|
||||
private GameObject panel;
|
||||
private GameObject download;
|
||||
private GameObject watch;
|
||||
|
||||
protected GameObject loadingPanel { get; set; }
|
||||
|
||||
private Text level;
|
||||
private Text rideNum;
|
||||
private Text uploadByUserName;
|
||||
private RawImage head;
|
||||
private RawImage country;
|
||||
private RawImage mapCountry;
|
||||
private RawImage altitudeGraph { get; set; }
|
||||
private Transform mapRanking;
|
||||
private Text mapId;
|
||||
private Text downloadText { get; set; }
|
||||
private Transform ui;
|
||||
private MapRoute route;
|
||||
|
||||
protected float process = 0;//0-100 %
|
||||
|
||||
private bool startBtnLock = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if(App.gameRoomDetail != null)
|
||||
ShowGameRoomLoading();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
ui = manager.GetCanvasTransform();
|
||||
route = manager.GetMapRoute();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
InitGameObject();
|
||||
InitGameObjectData();
|
||||
}
|
||||
|
||||
private void ShowGameRoomLoading()
|
||||
{
|
||||
UIManager.SetModalPanel(transform.Find("ModalPanel").GetComponent<PFUIPanel>());
|
||||
UIManager.ShowGameRoomLoadingPanel();
|
||||
}
|
||||
|
||||
private void InitGameObject()
|
||||
{
|
||||
panel = transform.Find("Panel").gameObject;
|
||||
mapName = panel.transform.Find("MapName").GetComponent<Text>();
|
||||
distance = panel.transform.Find("Distance").GetComponent<Text>();
|
||||
elevaction = panel.transform.Find("Elevaction").GetComponent<Text>();
|
||||
slope = panel.transform.Find("Slope").GetComponent<Text>();
|
||||
mapRouteImage = panel.transform.Find("MapRouteImage").GetComponent<RawImage>();
|
||||
slider = panel.transform.Find("Process").GetComponent<Slider>();
|
||||
slider.gameObject.SetActive(true);
|
||||
processText = panel.transform.Find("ProcessText").GetComponent<Text>();
|
||||
processText.gameObject.SetActive(false);
|
||||
mapDescText = panel.transform.Find("MapDesc").GetComponent<Text>();
|
||||
rideNow = panel.transform.Find("RideNow").GetComponent<Button>();
|
||||
rideNowText = rideNow.transform.Find("Text").GetComponent<Text>();
|
||||
cancel = panel.transform.Find("Cancel").GetComponent<Button>();
|
||||
UIManager.AddEvent(rideNow.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, StartRide);
|
||||
UIManager.AddEvent(cancel.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, Cancel);
|
||||
slider.onValueChanged.AddListener((f) =>
|
||||
{
|
||||
processText.text = $"{(f).ToString("#0")}%";
|
||||
});
|
||||
|
||||
|
||||
download = transform.Find("Panel/Download").gameObject;
|
||||
watch = transform.Find("Panel/Watch").gameObject;
|
||||
|
||||
UIManager.AddEvent(watch, UnityEngine.EventSystems.EventTriggerType.PointerClick, WatchHandler);
|
||||
canvasGroup = transform.GetComponent<CanvasGroup>();
|
||||
|
||||
var fileName = route.FileName;// "12067924_720p.mp4";
|
||||
var url = route.Url; //@"http://192.168.0.97:6031/12067924_720p.mp4";
|
||||
var path = PFConstants.VideoFolder;
|
||||
var filepath = path + "/" + fileName;
|
||||
|
||||
if (File.Exists(filepath))
|
||||
{
|
||||
watch.SetActive(true);
|
||||
slider.value = 100;
|
||||
download.gameObject.SetActive(false);
|
||||
manager.SetMedia(filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
watch.SetActive(false);
|
||||
//检查本地文件是否存在 如果存在直接设置mediaPlayer 否则显示下载按钮
|
||||
UIManager.AddEvent(download.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, DownloadAsync);
|
||||
}
|
||||
#region
|
||||
level = panel.transform.Find("level/Text").GetComponent<Text>();
|
||||
rideNum = panel.transform.Find("RideNum").GetComponent<Text>();
|
||||
uploadByUserName = panel.transform.Find("UploadByUserName").GetComponent<Text>();
|
||||
country = panel.transform.Find("UploadByCountry").GetComponent<RawImage>();
|
||||
mapCountry = panel.transform.Find("Country").GetComponent<RawImage>();
|
||||
head = panel.transform.Find("UploadByHead").GetComponent<RawImage>();
|
||||
altitudeGraph = panel.transform.Find("AltitudeGraph").GetComponent<RawImage>();
|
||||
mapRanking = panel.transform.Find("MapRanking");
|
||||
mapId = panel.transform.Find("MapId").GetComponent<Text>();
|
||||
|
||||
UIManager.RemoveEvent(distance.gameObject);
|
||||
UIManager.RemoveEvent(slope.gameObject);
|
||||
UIManager.RemoveEvent(elevaction.gameObject);
|
||||
UIManager.RemoveEvent(rideNum.gameObject);
|
||||
UIManager.AddEvent(distance.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerEnter, b =>
|
||||
{
|
||||
panel.transform.Find("DistanceTip").GetComponent<CanvasGroup>().DOFade(1, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(distance.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerExit, b =>
|
||||
{
|
||||
panel.transform.Find("DistanceTip").GetComponent<CanvasGroup>().DOFade(0, 0.5f);
|
||||
});
|
||||
|
||||
UIManager.AddEvent(slope.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerEnter, b =>
|
||||
{
|
||||
panel.transform.Find("SlopeTip").GetComponent<CanvasGroup>().DOFade(1, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(slope.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerExit, b =>
|
||||
{
|
||||
panel.transform.Find("SlopeTip").GetComponent<CanvasGroup>().DOFade(0, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(elevaction.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerEnter, b =>
|
||||
{
|
||||
panel.transform.Find("ElevactionTip").GetComponent<CanvasGroup>().DOFade(1, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(elevaction.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerExit, b =>
|
||||
{
|
||||
panel.transform.Find("ElevactionTip").GetComponent<CanvasGroup>().DOFade(0, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(rideNum.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerEnter, b =>
|
||||
{
|
||||
panel.transform.Find("RideTip").GetComponent<CanvasGroup>().DOFade(1, 0.5f);
|
||||
});
|
||||
UIManager.AddEvent(rideNum.gameObject, UnityEngine.EventSystems.EventTriggerType.PointerExit, b =>
|
||||
{
|
||||
panel.transform.Find("RideTip").GetComponent<CanvasGroup>().DOFade(0, 0.5f);
|
||||
});
|
||||
#endregion
|
||||
|
||||
downloadText = rideNow.GetComponentInChildren<Text>();//视频下载进度text
|
||||
}
|
||||
|
||||
protected void InitGameObjectData()
|
||||
{
|
||||
var route = manager.mapRoute;
|
||||
#region 绑定路书基本信息
|
||||
mapName.text = route.Name.ToEllipsisString(40);
|
||||
level.text = route.Hard;
|
||||
elevaction.text = Math.Round(route.TotalClimb.GetValueOrDefault(0), 2) + "M";
|
||||
slope.text = Math.Round(route.AverageGrade, 2) + "%";
|
||||
rideNum.text = route.TheHeat.ToString();
|
||||
distance.text = route.Distance.ToString("f1") + "KM";
|
||||
mapDescText.text = route.Dec.ToEllipsisString(255);
|
||||
mapId.text = $"#{route.Id.ToString()}";
|
||||
var userList = ConfigHelper.mapApi.GetOnlineUserInfo(new int[] { route.UserId }).data;
|
||||
if (userList.Count > 0)
|
||||
{
|
||||
uploadByUserName.text = userList[0].Name;
|
||||
var countryUrl = App.Host + $"User/GetCountryImg?userid={userList[0].Id}";
|
||||
Utils.DisplayImage(head, userList[0].HeadImage);//头像
|
||||
country.texture = manager.GetCountryImageByName(userList[0].Country);//上传者国家
|
||||
mapCountry.texture = manager.GetCountryImageByCode(route.CountryCode);//路书国家
|
||||
}
|
||||
#endregion
|
||||
Utils.DisplayImage(altitudeGraph, route.AltitudeGraph,true,null,1f);//渲染海拔图
|
||||
//显示线路背景图
|
||||
DrawMapRouteAsync(route.Id);
|
||||
//查询排行榜 TODO优化
|
||||
var list = ConfigHelper.mapApi.GetRouteRanking(route.Id, "1", 0, 10000, "");
|
||||
if (list.result)
|
||||
{
|
||||
CreateRankingList(list.data.list);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartRide(BaseEventData baseEvent)
|
||||
{
|
||||
if (startBtnLock) return;
|
||||
|
||||
startBtnLock = true;
|
||||
|
||||
InitClientState(false);
|
||||
|
||||
InitAR();
|
||||
|
||||
canvasGroup.DOFade(0, 1).onComplete += () => {
|
||||
gameObject.SetActive(false);
|
||||
manager.StartGame();
|
||||
manager.SetCyclingModel(Assets.Scenes.Ride.Scripts.Model.CyclingModel.Single);
|
||||
manager.SetCurrentMode(VideoGameManager.ARMode.RIDE);
|
||||
};
|
||||
}
|
||||
|
||||
private async void InitAR()
|
||||
{
|
||||
route = manager.mapRoute;
|
||||
var arDataPath = $"{PFConstants.ARFolder}/{route.Id}/{route.Id}.json";
|
||||
var videoRoute = $"{PFConstants.ARFolder}/{route.Id}/route-{route.Id}.json";
|
||||
|
||||
ARData aRData = null;
|
||||
RouteDetailData routeDetailData = null;
|
||||
|
||||
await Task.Run<ARData>((Func<ARData>)(() => aRData = ARData.LoadFromFile(arDataPath)));
|
||||
await Task.Run<RouteDetailData>((Func<RouteDetailData>)(() => routeDetailData = RouteDetailData.LoadFromFile(videoRoute)));
|
||||
|
||||
var arController = FindObjectOfType<ARTrainingController>();
|
||||
arController.Initialize(aRData, routeDetailData);
|
||||
}
|
||||
|
||||
public void StartRide(int seconds)
|
||||
{
|
||||
InitClientState(false);
|
||||
|
||||
var ui = manager.GetCanvasTransform();
|
||||
canvasGroup.DOFade(0, 0).onComplete += () => {
|
||||
InitAR();
|
||||
gameObject.SetActive(false);
|
||||
manager.SetCyclingModel(CyclingModel.GameRoom);
|
||||
manager.SetCurrentMode(VideoGameManager.ARMode.RIDE);
|
||||
ui.Find("Panel").gameObject.SetActive(true);
|
||||
};
|
||||
|
||||
UIManager.ShowGameRoomCountDownPanel(seconds,()=> {
|
||||
manager.StartGame();
|
||||
},false,true);
|
||||
}
|
||||
|
||||
private bool downloading = false;
|
||||
private CancellationTokenSource cancelToken;
|
||||
private async void DownloadAsync(BaseEventData baseEvent)
|
||||
{
|
||||
if (downloading)
|
||||
return;
|
||||
|
||||
beforeDownload();
|
||||
await startDownloading();
|
||||
}
|
||||
|
||||
private void beforeDownload()
|
||||
{
|
||||
downloading = true;
|
||||
download.SetActive(false);
|
||||
rideNow.enabled = false;
|
||||
rideNow.interactable = false;
|
||||
downloadText.text = "0%";
|
||||
}
|
||||
|
||||
private async Task startDownloading()
|
||||
{
|
||||
var route = manager.mapRoute;
|
||||
var path = PFConstants.VideoFolder;
|
||||
|
||||
var localPath = PFConstants.ARFolder;
|
||||
var arDataPath = route.ARConfig;
|
||||
var videoRoute = route.VideoRoute;
|
||||
var dataPath = $"{localPath}/{route.Id}";
|
||||
|
||||
Helper.CreateDirectoryIfNotExsit(dataPath);
|
||||
Helper.CreateDirectoryIfNotExsit(dataPath);
|
||||
|
||||
cancelToken = new CancellationTokenSource();
|
||||
|
||||
await Loom.DownloadToFileAsync(arDataPath, $"{dataPath}/{route.Id}.json");
|
||||
await Loom.DownloadToFileAsync(videoRoute, $"{dataPath}/route-{route.Id}.json");
|
||||
var res = await Loom.DownloadToFileAsync(route.Url, $"{path}/{route.FileName}",this,cancelToken);
|
||||
if (res.isDone)
|
||||
{
|
||||
var filepath = $"{PFConstants.VideoFolder}/{route.FileName}";
|
||||
manager.SetMedia(filepath);
|
||||
|
||||
rideNow.enabled = true;
|
||||
rideNow.interactable = true;
|
||||
|
||||
downloadText.text = App.GetLocalString("Ride Now");
|
||||
downloading = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Report(float value)
|
||||
{
|
||||
if (cancelToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
slider.value = value < 1 ? (float)Math.Round(value * 100, 0) : 100;
|
||||
downloadText.text = slider.value.ToString(CultureInfo.InvariantCulture) + "%";
|
||||
}
|
||||
//进入观察模式
|
||||
private void WatchHandler(BaseEventData data)
|
||||
{
|
||||
InitAR();
|
||||
InitClientState(true);
|
||||
|
||||
var canvas = transform.GetComponent<CanvasGroup>();
|
||||
var canvasTransform = manager.GetCanvasTransform();
|
||||
canvas.DOFade(0, 1).onComplete += () => {
|
||||
gameObject.SetActive(false);
|
||||
canvasTransform.gameObject.SetActive(true);
|
||||
manager.SetCurrentMode(VideoGameManager.ARMode.INSPECT);
|
||||
manager.StartGame();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 告诉服务器是观察模式还是骑行模式
|
||||
/// </summary>
|
||||
/// <param name="isWatch"></param>
|
||||
private static void InitClientState(bool isWatch)
|
||||
{
|
||||
MapUDPService.IsWatch = isWatch;
|
||||
MapUDPService.SendGizpModel();
|
||||
}
|
||||
|
||||
private void Cancel(BaseEventData baseEvent)
|
||||
{
|
||||
if (cancelToken == null)
|
||||
{
|
||||
SceneManager.LoadSceneAsync("MainScene");
|
||||
return;
|
||||
}
|
||||
|
||||
UIManager.SetModalPanel(transform.Find("ModalPanel").GetComponent<PFUIPanel>());
|
||||
UIManager.ShowConfirm("Tips", "CancelDownloadConfirm",
|
||||
() =>
|
||||
{
|
||||
cancelToken?.Cancel();
|
||||
SceneManager.LoadSceneAsync("MainScene");
|
||||
UIManager.CloseConfirm();
|
||||
},
|
||||
2,
|
||||
() =>
|
||||
{
|
||||
UIManager.CloseConfirm();
|
||||
});
|
||||
}
|
||||
private async void DrawMapRouteAsync(int routeId, int type = 0)
|
||||
{
|
||||
var result = await ConfigHelper.mapApi.GetMapLoadingCoverageUrl(routeId, type);
|
||||
if (!result.result)
|
||||
return;
|
||||
var url = result.data;
|
||||
if (App.TextureCache.ContainsKey(url))
|
||||
{
|
||||
mapRouteImage.texture = App.TextureCache[url];
|
||||
var canvasGroup = mapRouteImage.GetComponent<CanvasGroup>();
|
||||
canvasGroup.DOFade(1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.DisplayImageAysnc(StartCoroutine, mapRouteImage, url, DowloadCallBack);
|
||||
}
|
||||
}
|
||||
private void DowloadCallBack(string url, RawImage rawImage)
|
||||
{
|
||||
if (!App.TextureCache.ContainsKey(url))
|
||||
{
|
||||
App.TextureCache.Add(url, rawImage?.texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
App.TextureCache[url] = rawImage?.texture;
|
||||
}
|
||||
var canvasGroup = rawImage.GetComponent<CanvasGroup>();
|
||||
canvasGroup?.DOFade(1, 1);
|
||||
}
|
||||
|
||||
private int RankingPageSize = 10;
|
||||
//创建排行榜
|
||||
public void CreateRankingList(List<MapRouteRanking> list)
|
||||
{
|
||||
var prefab = Resources.Load<GameObject>("UI/Prefab/Ride/RankingItem");
|
||||
var myprefab = Resources.Load<GameObject>("UI/Prefab/Ride/MySelfRankingItem");
|
||||
var viewAllbtn = Resources.Load<GameObject>("UI/Prefab/Ride/ViewAll");
|
||||
var parent = panel.transform.Find("MapRanking");
|
||||
var title = panel.transform.Find("RankingTitle").gameObject;
|
||||
title.SetActive(list.Count != 0);
|
||||
int index = 0;
|
||||
foreach (var item in list)
|
||||
{
|
||||
index++;
|
||||
if (index > RankingPageSize)
|
||||
break;
|
||||
GameObject newObj = (GameObject)Instantiate(prefab, parent);
|
||||
var selectPlayerItemScript = newObj.GetComponent<Assets.Scenes.Ride.Scripts.RankingItemScript>();
|
||||
selectPlayerItemScript.SetRanking(item.RowNumber.ToString());
|
||||
selectPlayerItemScript.SetName(item.NickName);
|
||||
selectPlayerItemScript.SetTimer(item.IsDNF ? "DNF" : item.TotalTime);
|
||||
selectPlayerItemScript.SetHead(item.WxHeadImg);
|
||||
var texture = manager.GetCountryImageByCode(item.CountryCode);
|
||||
selectPlayerItemScript.SetCountry(texture);
|
||||
}
|
||||
//如果有自己的记录显示自己的排名
|
||||
var myself = list.Where(c => c.MySelf).FirstOrDefault();
|
||||
GameObject myselfObj = (GameObject)Instantiate(myprefab, parent);
|
||||
var myselfItemScript = myselfObj.GetComponent<Assets.Scenes.Ride.Scripts.RankingItemScript>();
|
||||
if (myself == null)
|
||||
{
|
||||
myselfItemScript.SetRanking("--");
|
||||
myselfItemScript.SetName(App.CurrentUser.Nickname);
|
||||
myselfItemScript.SetTimer("--:--:--");
|
||||
myselfItemScript.SetHead(App.CurrentUser.WxHeadImg);
|
||||
var texture = manager.GetCountryImageByName(App.CurrentUser.Country);
|
||||
myselfItemScript.SetCountry(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
myselfItemScript.SetRanking(myself.RowNumber.ToString());
|
||||
myselfItemScript.SetName(myself.NickName);
|
||||
myselfItemScript.SetTimer(myself.IsDNF ? "DNF" : myself.TotalTime);
|
||||
myselfItemScript.SetHead(myself.WxHeadImg);
|
||||
var texture = manager.GetCountryImageByCode(myself.CountryCode);
|
||||
myselfItemScript.SetCountry(texture);
|
||||
}
|
||||
//显示查询全部按钮
|
||||
if (list.Count > 0)
|
||||
{
|
||||
GameObject ViewAll = (GameObject)Instantiate(viewAllbtn, parent);
|
||||
UIManager.AddEvent(ViewAll, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
|
||||
{
|
||||
Application.OpenURL($"{App.CurrentUser.WebHost}Routes/{manager.mapRoute.Id}?Token={App.CurrentUser.cookie}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f3705d27cb576f498459e5540d88906
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Facebook.Unity;
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoResultScript : MonoBehaviour
|
||||
{
|
||||
#region 路书信息
|
||||
Text date;
|
||||
Text time;
|
||||
Text level;
|
||||
Text mapName;
|
||||
Text distance;
|
||||
RawImage country;
|
||||
RawImage altudeGraph;
|
||||
#endregion
|
||||
|
||||
#region 骑行结果
|
||||
Text rideTime;
|
||||
Text rideDistance;
|
||||
Text totalClimbed;
|
||||
Text wkgText;
|
||||
Text avCadence;
|
||||
Text avHeatrate;
|
||||
Text maxPower;
|
||||
Text avPower;
|
||||
Text maxSpeed;
|
||||
Text avSpeed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 功能按钮
|
||||
GameObject goResultBtn;
|
||||
GameObject cancelBtn;
|
||||
GameObject shareWxBtn;
|
||||
GameObject shareWxGpButton;
|
||||
Transform toolbar;
|
||||
Image DNF;
|
||||
Image newRecord;
|
||||
#endregion
|
||||
|
||||
VideoGameManager cyclingController;
|
||||
private void Awake()
|
||||
{
|
||||
#region 路书信息
|
||||
date = transform.Find("MapPanel/Date").GetComponent<Text>();
|
||||
time = transform.Find("MapPanel/Timer").GetComponent<Text>();
|
||||
level = transform.Find("MapPanel/Level/Text").GetComponent<Text>();
|
||||
mapName = transform.Find("MapPanel/MapName").GetComponent<Text>();
|
||||
distance = transform.Find("MapPanel/Distance").GetComponent<Text>();
|
||||
country = transform.Find("MapPanel/Country").GetComponent<RawImage>();
|
||||
altudeGraph = transform.Find("MapPanel/AltudeGraph").GetComponent<RawImage>();
|
||||
#endregion
|
||||
#region 骑行记录
|
||||
rideTime = transform.Find("TimePanel/Timer").GetComponent<Text>();
|
||||
rideDistance = transform.Find("DistancePanel/Distance").GetComponent<Text>();
|
||||
totalClimbed = transform.Find("FitPanel/TotalClimbedView/Value").GetComponent<Text>();
|
||||
wkgText = transform.Find("FitPanel/FTPView/Value").GetComponent<Text>();
|
||||
avCadence = transform.Find("FitPanel/CadenceView/Value").GetComponent<Text>();
|
||||
avHeatrate = transform.Find("FitPanel/HeartView/Value").GetComponent<Text>();
|
||||
maxPower = transform.Find("FitPanel/MaxPowerView/Value").GetComponent<Text>();
|
||||
avPower = transform.Find("FitPanel/AveragePowerView/Value").GetComponent<Text>();
|
||||
maxSpeed = transform.Find("FitPanel/MaxSpeedView/Value").GetComponent<Text>();
|
||||
avSpeed = transform.Find("FitPanel/AverageSpeed/Value").GetComponent<Text>();
|
||||
#endregion
|
||||
goResultBtn = transform.Find("ConFirmButton").gameObject;
|
||||
cancelBtn = transform.Find("CloseButton").gameObject;
|
||||
toolbar = transform.Find("ToolBarPanel");
|
||||
#if UNITY_ANDROID || UNITY_IOS
|
||||
shareWxBtn = transform.Find("ToolBarPanel/WeChatButton").gameObject;
|
||||
shareWxGpButton = transform.Find("ToolBarPanel/GoogleButton").gameObject;
|
||||
#endif
|
||||
DNF = transform.Find("DNF").GetComponent<Image>();
|
||||
newRecord = transform.Find("TimePanel/NewRecord").GetComponent<Image>();
|
||||
}
|
||||
|
||||
public void InjectController(VideoGameManager controller)
|
||||
{
|
||||
cyclingController = controller;
|
||||
controller.AddEvent(goResultBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, GoResult);
|
||||
controller.AddEvent(cancelBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, Cancel);
|
||||
#if UNITY_ANDROID || UNITY_IOS
|
||||
cyclingController.AddEvent(shareWxBtn, EventTriggerType.PointerClick, shareToWx);
|
||||
cyclingController.AddEvent(shareWxGpButton, EventTriggerType.PointerClick, shareToWxGp);
|
||||
var fbButton = transform.Find("ToolBarPanel/FaceBookButton").gameObject;
|
||||
cyclingController.AddEvent(fbButton, EventTriggerType.PointerClick, shareToFb);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void shareToFb(BaseEventData arg0)
|
||||
{
|
||||
FB.ShareLink(contentURL: new Uri($"{App.CurrentUser.WebHost}RoutesRecords/{cyclingController.RankingId}?Token={App.CurrentUser.cookie}"),
|
||||
contentTitle: cyclingController.mapRoute.Name,
|
||||
contentDescription: "By " + App.CurrentUser.Nickname,
|
||||
photoURL: new Uri(cyclingController.mapRoute.CoverImage));
|
||||
}
|
||||
|
||||
private void shareToWx(BaseEventData b)
|
||||
{
|
||||
if (App.weChatController.IsWeChatAppInstalled())
|
||||
{
|
||||
App.weChatController.ShareWebpageToWX(0, $"{App.CurrentUser.WebHost}RoutesRecords/{cyclingController.RankingId}?Token={App.CurrentUser.cookie}", cyclingController.mapRoute.Name, "By " + App.CurrentUser.Nickname, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.showToast(null, "未安装微信");
|
||||
}
|
||||
}
|
||||
|
||||
private void shareToWxGp(BaseEventData b)
|
||||
{
|
||||
if (App.weChatController.IsWeChatAppInstalled())
|
||||
{
|
||||
App.weChatController.ShareWebpageToWX(1, $"{App.CurrentUser.WebHost}RoutesRecords/{cyclingController.RankingId}?Token={App.CurrentUser.cookie}", cyclingController.mapRoute.Name, "By " + App.CurrentUser.Nickname, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.showToast(null, "未安装微信");
|
||||
}
|
||||
}
|
||||
|
||||
private void GoResult(BaseEventData baseEventData)
|
||||
{
|
||||
if (App.MainSceneParam.ContainsKey("Name"))
|
||||
{
|
||||
App.MainSceneParam["Name"] = "UserInfoPanel";
|
||||
}
|
||||
else
|
||||
{
|
||||
App.MainSceneParam.Add("Name", "UserInfoPanel");
|
||||
}
|
||||
|
||||
Application.OpenURL($"{App.CurrentUser.WebHost}Mine/Detail/{cyclingController.RankingId}?Token={App.CurrentUser.cookie}");
|
||||
SceneManager.LoadScene("MainScene");
|
||||
}
|
||||
|
||||
private void Cancel(BaseEventData baseEventData)
|
||||
{
|
||||
SceneManager.LoadScene("MainScene");
|
||||
}
|
||||
public void SetDataSource(RecorderDataModel record)
|
||||
{
|
||||
var route = record.CurrentRoute.RouteInstance;
|
||||
var dataformt = App.GetLocalLanguage().Equals("zh") ? "yyyy-MM-dd" : "dd-MM-yyyy";
|
||||
date.text = record.StartTime.ToString(dataformt);
|
||||
time.text = record.StartTime.ToShortTimeString();
|
||||
level.text = route.Hard;
|
||||
mapName.text = route.Name;
|
||||
distance.text = route.Distance.ToString("f1") + "KM";
|
||||
country.texture = cyclingController.GetCountryImageByCode(route.CountryCode);
|
||||
Utils.DisplayImage(altudeGraph, route.AltitudeGraph);
|
||||
//绑定骑行记录结果
|
||||
rideTime.text = Helper.FormatTicks(record.RiderDatas.Count);
|
||||
rideDistance.text = record.RiderDatas.Last()._Distance.ToString("f1") + "KM";
|
||||
totalClimbed.text = record.RiderDatas.Last()._TotalClimb.ToString("f1");
|
||||
var power = Math.Round(record.RiderDatas.Average(c => c._Power), 0);
|
||||
avPower.text = power.ToString();
|
||||
maxPower.text = record.RiderDatas.Max(c => c._Power).ToString("f0");
|
||||
avHeatrate.text = record.RiderDatas.Average(c => c._HeartRate.GetValueOrDefault(0)).ToString("f0");
|
||||
avSpeed.text = record.RiderDatas.Average(c => c._Speed).ToString("f1");
|
||||
maxSpeed.text = record.RiderDatas.Max(c => c._Speed).ToString("f1");
|
||||
wkgText.text = Math.Round(power / record.CurrentUser.Weight, 2).ToString();
|
||||
avCadence.text = record.RiderDatas.Average(c => c._Cadence).GetValueOrDefault(0).ToString("f0");
|
||||
|
||||
DNF.gameObject.SetActive(!record.IsCompleted);
|
||||
var recordImagePath = App.GetLocalLanguage().Equals("zh") ? "Images/Ride/img_newrecord_cn" : "img_newrecord";
|
||||
newRecord.sprite = Resources.Load<Sprite>(recordImagePath);
|
||||
newRecord.gameObject.SetActive(record.IsCompleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf670cbf2ee31f54e948d1ae90112d81
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,340 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
|
||||
using static Assets.Scripts.Scenes.VideoRide.VideoGameManager;
|
||||
using Assets.AR;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoUIManager : MonoBehaviour
|
||||
{
|
||||
private const float MAXPOWER = 450f;
|
||||
private const float MAXPOWER_RATE = 600f;
|
||||
private const float MAXHEARRATE = 200f;
|
||||
private const float MAXWKG = 6f;
|
||||
private const float MAX_HEART_RATIO = 0.9f;
|
||||
GameObject ComputerPanel { get; set; }
|
||||
GameObject WatchPanel { get; set; }
|
||||
GameObject explosive { get; set; }
|
||||
GameObject button;
|
||||
GameObject remainTime;
|
||||
VideoGameManager manager;
|
||||
VideoPlayer videoPlayer;
|
||||
|
||||
Text infoText { get; set; }
|
||||
//ComputerPanel
|
||||
Text power { get; set; }
|
||||
Text cadance { get; set; }
|
||||
Text heartRate { get; set; }
|
||||
Text speed { get; set; }
|
||||
Text totalDistance { get; set; }
|
||||
Text totalClimbed { get; set; }
|
||||
Text ridingTime { get; set; }
|
||||
Text mapName { get; set; }
|
||||
Image left { get; set; }
|
||||
Image right { get; set; }
|
||||
//ToolBarPanel
|
||||
GameObject settingBtn { get; set; }
|
||||
GameObject deviceBtn { get; set; }
|
||||
GameObject changeViewBtn { get; set; }
|
||||
GameObject quitBtn { get; set; }
|
||||
//minimap
|
||||
Text playerTimer { get; set; }
|
||||
Text distance { get; set; }
|
||||
Text slope { get; set; }
|
||||
Transform wave { get; set; }
|
||||
Image waveimage { get; set; }
|
||||
//modal
|
||||
GameObject settingPanel { get; set; }
|
||||
GameObject resultPanel { get; set; }
|
||||
GameObject gameRoomResultPanel { get; set; }
|
||||
|
||||
//ftp
|
||||
GameObject ftpPanel { get; set; }
|
||||
Image ftpImage { get; set; }
|
||||
Text wkg { get; set; }
|
||||
|
||||
private void Start()
|
||||
{
|
||||
UIManager.SetModalPanel(transform.Find("ModalPanel").GetComponent<PFUIPanel>());
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (manager != null)
|
||||
{
|
||||
mapName.text = manager.GetMapRoute().Name;
|
||||
if (manager.CurrentPlayer != null)
|
||||
{
|
||||
power.text = Math.Round(manager.CurrentPlayer.power).ToString();
|
||||
speed.text = manager.CurrentPlayer.speed.ToString("f1");
|
||||
heartRate.text = Math.Round((manager.CurrentPlayer.heartRate ?? 0d)).ToString();
|
||||
cadance.text = Math.Round(manager.CurrentPlayer.cadance).ToString();
|
||||
playerTimer.text = Helper.FormatTicks(manager.CurrentPlayer.ticks);
|
||||
distance.text = $"{Math.Round((manager.CurrentPlayer.totalDistance),2)}KM";
|
||||
left.fillAmount = (float)(Math.Round(manager.CurrentPlayer.power) / MAXPOWER_RATE);
|
||||
right.fillAmount = (float)(Math.Round((manager.CurrentPlayer.heartRate ?? 0f)) / MAXHEARRATE);
|
||||
SetSlopePanel();
|
||||
ftpImage.fillAmount = (float)(manager.CurrentPlayer.wkg / MAXWKG);
|
||||
wkg.text = $"{manager.CurrentPlayer.wkg}w/kg";
|
||||
SetHeartRateAlert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//心率过高的时候显示
|
||||
private void SetHeartRateAlert()
|
||||
{
|
||||
if (manager.CurrentPlayer.UserId == App.CurrentUser.Id)
|
||||
{
|
||||
explosive.SetActive(ComputeHearRateRatio(manager.CurrentPlayer.heartRate ?? 0) > MAX_HEART_RATIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
explosive.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
//距离终点
|
||||
public void ShowUpRemainTime(double remain)
|
||||
{
|
||||
if (remain > 110) return;
|
||||
|
||||
remain -= 20;
|
||||
|
||||
var canvas = remainTime.GetComponent<CanvasGroup>();
|
||||
if (remain <= 0)
|
||||
{
|
||||
if (canvas.alpha == 1)
|
||||
canvas.DOFade(0, 1).onComplete = () => { remainTime.SetActive(false); };
|
||||
}
|
||||
else
|
||||
{
|
||||
remainTime.SetActive(true);
|
||||
remainTime.transform.Find("Bg/Distance").GetComponent<Text>().text = remain.ToString().PadLeft(2,'0');
|
||||
|
||||
if (canvas.alpha == 0)
|
||||
canvas.DOFade(1, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
// 220 - 年龄= 最大心率 ratio = heartRate /最大心率
|
||||
private float ComputeHearRateRatio(int heartRate)
|
||||
{
|
||||
var age = DateTime.Now.Year - App.CurrentUser.Birthday?.Year;
|
||||
if (DateTime.Now.Month - App.CurrentUser.Birthday?.Month > 0 && DateTime.Now.Day - App.CurrentUser.Birthday?.Day > 0)
|
||||
{
|
||||
age += 1;
|
||||
}
|
||||
age = age ?? 0;
|
||||
var ratio = heartRate / (220 - age);
|
||||
return (float)ratio;
|
||||
}
|
||||
|
||||
public void SetCurrentMode(VideoGameManager.ARMode aRMode)
|
||||
{
|
||||
if (aRMode == VideoGameManager.ARMode.INSPECT)
|
||||
{
|
||||
ComputerPanel.SetActive(false);
|
||||
WatchPanel.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
WatchPanel.SetActive(false);
|
||||
ComputerPanel.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
remainTime = transform.Find("Panel/Remain").gameObject;
|
||||
infoText = transform.Find("InfoText").GetComponentInChildren<Text>();
|
||||
ComputerPanel = transform.Find("Panel/ComputerPanel").gameObject;
|
||||
WatchPanel = transform.Find("Panel/WatchPanel").gameObject;
|
||||
power = transform.Find("Panel/ComputerPanel/Power").GetComponent<Text>();
|
||||
cadance = transform.Find("Panel/ComputerPanel/Cadance").GetComponent<Text>();
|
||||
heartRate = transform.Find("Panel/ComputerPanel/Hr").GetComponent<Text>();
|
||||
speed = transform.Find("Panel/ComputerPanel/Speed").GetComponent<Text>();
|
||||
left = transform.Find("Panel/ComputerPanel/Left").GetComponent<Image>();
|
||||
right = transform.Find("Panel/ComputerPanel/Right").GetComponent<Image>();
|
||||
//ToolBarPanel
|
||||
settingBtn = transform.Find("Panel/ToolBarPanel/SettingButton").gameObject;
|
||||
quitBtn = transform.Find("Panel/ToolBarPanel/ExitButton").gameObject;
|
||||
changeViewBtn = transform.Find("Panel/ToolBarPanel/ChangeView").gameObject;
|
||||
deviceBtn = transform.Find("Panel/ToolBarPanel/DeviceButton").gameObject;
|
||||
//minmap
|
||||
playerTimer = transform.Find("Panel/MiniMap/Panel/Timer").GetComponent<Text>();
|
||||
distance = transform.Find("Panel/MiniMap/Panel/Distance").GetComponent<Text>();
|
||||
mapName = transform.Find("Panel/MiniMap/Head/MapName").GetComponent<Text>();
|
||||
slope = transform.Find("Panel/MiniMap/Panel/Circle/slope").GetComponent<Text>();
|
||||
wave = transform.Find("Panel/MiniMap/Panel/Circle/wave");
|
||||
waveimage = wave.GetComponent<Image>();
|
||||
//FtpPanel
|
||||
ftpPanel = transform.Find("Panel/FtpPanel").gameObject;
|
||||
ftpImage = transform.Find("Panel/FtpPanel/ftp").GetComponent<Image>();
|
||||
wkg = transform.Find("Panel/FtpPanel/wkg").GetComponent<Text>();
|
||||
//modal
|
||||
settingPanel = transform.Find("Panel/SettingPanel").gameObject;
|
||||
resultPanel = transform.Find("Panel/ResultPanel").gameObject;
|
||||
gameRoomResultPanel = transform.Find("Panel/GameRoomResult").gameObject;
|
||||
//
|
||||
explosive = transform.Find("Panel/Explosive").gameObject;
|
||||
//toolbar 事件注册
|
||||
UIManager.AddEvent(settingBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, ShowSetting);
|
||||
UIManager.AddEvent(changeViewBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, ChangeViewClick);
|
||||
UIManager.AddEvent(deviceBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, DeviceClick);
|
||||
UIManager.AddEvent(quitBtn, UnityEngine.EventSystems.EventTriggerType.PointerClick, QuitClick);
|
||||
|
||||
}
|
||||
//设置坡度信息
|
||||
private void SetSlopePanel()
|
||||
{
|
||||
var normalizedSlope = (float)Math.Round(manager.CurrentPlayer.currentSlope, 1);
|
||||
slope.text = normalizedSlope > 0 ? "+"+normalizedSlope.ToString():normalizedSlope.ToString();
|
||||
var strength = 3;//增强旋转角度系数
|
||||
if (normalizedSlope > 10) {
|
||||
normalizedSlope = 10f;
|
||||
}
|
||||
if (normalizedSlope < -10) {
|
||||
normalizedSlope = -10f;
|
||||
}
|
||||
wave.DORotate(new Vector3(0f, 0f, normalizedSlope*strength),1f);
|
||||
SetWaveColor(normalizedSlope);
|
||||
}
|
||||
|
||||
private void SetWaveColor(double currentSlope)
|
||||
{
|
||||
if (currentSlope > 7)
|
||||
{
|
||||
waveimage.color = PFConstants.Red;
|
||||
}
|
||||
else if (currentSlope > 3)
|
||||
{
|
||||
waveimage.color = PFConstants.Orange;
|
||||
}
|
||||
else if (currentSlope > 0)
|
||||
{
|
||||
waveimage.color = PFConstants.Yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
waveimage.color = PFConstants.Green;
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowSetting(BaseEventData e)
|
||||
{
|
||||
UIManager.ShowRideSettingPanel();
|
||||
}
|
||||
private void DeviceClick(BaseEventData e)
|
||||
{
|
||||
UIManager.Show(UIManager.Instance.DevicePanel, null, true);
|
||||
}
|
||||
|
||||
private void ChangeViewClick(BaseEventData e)
|
||||
{
|
||||
var nearByScript = FindObjectOfType<NearByScript>();
|
||||
var rankingScript = FindObjectOfType<RankingScript>();
|
||||
var arController = FindObjectOfType<ARTrainingController>();
|
||||
var cameraImage = changeViewBtn.transform.Find("Camera").gameObject;
|
||||
|
||||
manager._viewMode = manager._viewMode == ViewMode.THIRD ? ViewMode.FIRST : ViewMode.THIRD;
|
||||
if (manager._viewMode == ViewMode.FIRST)
|
||||
{
|
||||
ftpPanel.SetActive(manager._aRMode != ARMode.INSPECT);
|
||||
nearByScript.Hidehandler(null);
|
||||
rankingScript.Hidehandler(null);
|
||||
cameraImage.SetActive(true);
|
||||
arController.RiderCameraDistance = CameraDistance.FirstPerson;
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpPanel.SetActive(false);
|
||||
nearByScript.Showhandler(null);
|
||||
rankingScript.Showhandler(null);
|
||||
cameraImage.SetActive(false);
|
||||
arController.RiderCameraDistance = CameraDistance.Middle;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowResultPanel()
|
||||
{
|
||||
resultPanel.SetActive(true);
|
||||
resultPanel.transform.SetAsLastSibling();
|
||||
var videoResultScript = resultPanel.GetComponent<VideoResultScript>();
|
||||
videoResultScript.InjectController(manager);
|
||||
videoResultScript.SetDataSource(manager.cyclingController.recorderData);
|
||||
}
|
||||
public void SaveAndShowResult()
|
||||
{
|
||||
if (manager._aRMode == VideoGameManager.ARMode.INSPECT)
|
||||
SceneManager.LoadScene("MainScene");
|
||||
videoPlayer = FindObjectOfType<VideoPlayer>();
|
||||
videoPlayer?.Upload();
|
||||
//show result
|
||||
if (manager.cyclingController is GameModel)
|
||||
{
|
||||
gameRoomResultPanel.SetActive(true);
|
||||
gameRoomResultPanel.transform.SetAsLastSibling();
|
||||
}
|
||||
else
|
||||
{
|
||||
resultPanel.SetActive(true);
|
||||
resultPanel.transform.SetAsLastSibling();
|
||||
var videoResultScript = resultPanel.GetComponent<VideoResultScript>();
|
||||
videoResultScript.InjectController(manager);
|
||||
videoResultScript.SetDataSource(manager.cyclingController.recorderData);
|
||||
}
|
||||
}
|
||||
private void QuitClick(BaseEventData e)
|
||||
{
|
||||
var idMainRider = manager.CurrentPlayer != null && manager.CurrentPlayer.UserId == App.CurrentUser.Id;
|
||||
var shortDistance = idMainRider && (manager.CurrentPlayer.ticks == 0 || manager.cyclingController.recorderData.RiderDatas.Count == 0 || manager.CurrentPlayer.EndDistance - manager.CurrentPlayer.StartDistance < 0.1f);
|
||||
if (shortDistance)
|
||||
{
|
||||
UIManager.ShowConfirm(App.GetLocalString("Quit"), App.GetLocalString("Current ride distance too short to save."), () => {
|
||||
UIManager.CloseConfirm();
|
||||
SceneManager.LoadSceneAsync("MainScene");
|
||||
}, 2, () => { UIManager.CloseConfirm(); });
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager._aRMode == VideoGameManager.ARMode.RIDE)
|
||||
{
|
||||
|
||||
UIManager.ShowConfirm(App.GetLocalString("Quit"), App.GetLocalString("Do you want to keep the record?"),
|
||||
() =>
|
||||
{
|
||||
SaveAndShowResult();
|
||||
UIManager.CloseConfirm();
|
||||
},
|
||||
2,
|
||||
() =>
|
||||
{
|
||||
UIManager.CloseConfirm();
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIManager.ShowConfirm(App.GetLocalString("Quit"), App.GetLocalString("Do you want to quit?"), () =>
|
||||
{
|
||||
UIManager.CloseConfirm();
|
||||
SceneManager.LoadSceneAsync("MainScene");
|
||||
},
|
||||
2,
|
||||
() =>
|
||||
{
|
||||
UIManager.CloseConfirm();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: deea375efff5f3d46a95e5b7b7165151
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class WatchPanelScript:MonoBehaviour
|
||||
{
|
||||
private VideoGameManager manager { get; set; }
|
||||
private Text userName { get; set; }
|
||||
private void Start()
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
userName = transform.Find("name").GetComponent<Text>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (manager != null)
|
||||
{
|
||||
userName.text = manager.CurrentPlayer?.UserName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee330a42f7b6a6f4391c18a98ef5f3c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,493 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using Assets.Scripts.UI.Prefab.Device;
|
||||
using GeoJSON.Net.Geometry;
|
||||
using Mapbox.Utils;
|
||||
using RenderHeads.Media.AVProVideo;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TurfCS;
|
||||
using UnityEngine;
|
||||
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Events;
|
||||
using Helper = Assets.Scenes.Ride.Scripts.Helper;
|
||||
using System.Collections;
|
||||
using Assets.AR;
|
||||
using Assets.Core;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoGameManager : DeviceServiceMonoBase
|
||||
{
|
||||
public ARTrainingController trainingController;
|
||||
public AbstractVideoPlayer CurrentPlayer { get; set; }
|
||||
private MapDataModel mapData { get; set; }
|
||||
private MediaPlayer mediaPlayer { get; set; }
|
||||
private bool isStart { get; set; }
|
||||
private Route route { get; set; }
|
||||
public MapRoute mapRoute { get; set; }
|
||||
public RouteResultParam selectParamModel { get; set; }
|
||||
public RouteResult routeResult;
|
||||
public string recordId { get; set; }
|
||||
public DateTime startTime { get; set; }
|
||||
public CyclingModel cyclingModel { get; set; }
|
||||
public BaseCycling cyclingController { get; set; }
|
||||
private double endDistance { get; set; }
|
||||
private GameObject infoPanel;
|
||||
private GameObject Player;
|
||||
private GameObject Player_NV;
|
||||
private GameObject OnlinePlayer;
|
||||
private GameObject OnlinePlayer_NV;
|
||||
|
||||
private bool isStop { get; set; }
|
||||
|
||||
|
||||
VideoLoading videoLoading { get; set; }
|
||||
//当前是第一人称还是第三人称
|
||||
public ViewMode _viewMode { get; set; }
|
||||
//当前是观察者视角还是骑行者视角
|
||||
public ARMode _aRMode { get; set; }
|
||||
public int RankingId { get; set; }
|
||||
|
||||
public Dictionary<IRider, PlayerRenderer> rideObjs = new Dictionary<IRider, PlayerRenderer>();
|
||||
|
||||
private VideoUIManager _uiManager { get; set; }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_uiManager = FindObjectOfType<VideoUIManager>();
|
||||
trainingController = GetComponent<ARTrainingController>();
|
||||
mediaPlayer = FindObjectOfType<MediaPlayer>();
|
||||
DeviceCache.Init(PFConstants.DeviceCacheFolder);
|
||||
var check = CheckAnt();//初始化蓝牙设备
|
||||
|
||||
recordId = Guid.NewGuid().ToString();
|
||||
|
||||
infoPanel = Resources.Load<GameObject>("UI/Prefab/AR/VideoPlayerHead");
|
||||
OnlinePlayer = Resources.Load<GameObject>("UI/Prefab/AR/OnlineVideoPlayer");
|
||||
OnlinePlayer_NV = Resources.Load<GameObject>("UI/Prefab/AR/OnlineVideoPlayer_NV");
|
||||
Player = Resources.Load<GameObject>("UI/Prefab/AR/VidePlayer");
|
||||
Player_NV = Resources.Load<GameObject>("UI/Prefab/AR/VidePlayer_NV");
|
||||
StartCoroutine(Init());
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
UIManager.Instance.MainPanel = GetCanvasTransform().GetComponent<PFUIPanel>();
|
||||
UIManager.Instance.ModalsPanel = this.transform.Find("Canvas/ModalPanel").GetComponent<PFUIPanel>();
|
||||
var routeId = App.RouteIdParam;
|
||||
//获取路书
|
||||
GetMapRoute();
|
||||
GetMapData();
|
||||
route = new Route(mapData, mapRoute);
|
||||
|
||||
if (selectParamModel == null)
|
||||
{
|
||||
selectParamModel = new RouteResultParam
|
||||
{
|
||||
CompetitionId = 0,
|
||||
ContinueIndex = 0,
|
||||
ContinueMark = "",
|
||||
GlobalContinue = false,
|
||||
EndDistance = 0,
|
||||
RankingsId = new List<string>(),
|
||||
OnlineUserId = 0,
|
||||
RouteId = routeId
|
||||
};
|
||||
}
|
||||
Debug.Log("start");
|
||||
endDistance = 0;
|
||||
videoLoading = FindObjectOfType<VideoLoading>();
|
||||
}
|
||||
|
||||
private IEnumerator Init()
|
||||
{
|
||||
yield return null;
|
||||
videoLoading.Init();//初始化loading页面
|
||||
}
|
||||
float timer = 0f;
|
||||
int ticks = 0;
|
||||
protected override void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer <= 0)
|
||||
{
|
||||
if (cyclingController == null)
|
||||
return;
|
||||
cyclingController.Run(null);
|
||||
var onlineRiders = cyclingController.riders;
|
||||
try
|
||||
{
|
||||
CreateOnlineUser(onlineRiders);
|
||||
if (isStart)
|
||||
{
|
||||
var riders = FindObjectsOfType<OnlineVideoPlayer>();
|
||||
foreach (var rider in riders)
|
||||
{
|
||||
rider.StartAction();
|
||||
}
|
||||
//解决当前用户setActive(false)时仍能计算数据
|
||||
if (CurrentPlayer != null && CurrentPlayer is VideoPlayer)
|
||||
{
|
||||
CurrentPlayer.StartAction();
|
||||
}
|
||||
ticks++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log(e.Message);
|
||||
}
|
||||
timer += 1f;
|
||||
}
|
||||
}
|
||||
MapRouteRankingList rankingList;
|
||||
public MapRouteRankingList GetRankingList(string type = "month")
|
||||
{
|
||||
var endTime = UIManager.Now == null ? DateTime.Now : UIManager.Now.GetDateTime();
|
||||
var startTime = Helper.GetStartTime(endTime, type);
|
||||
var list = ConfigHelper.mapApi.GetRouteRanking(App.RouteIdParam, "1", 0, 10, "", startTime, endTime);
|
||||
if (list.result)
|
||||
{
|
||||
rankingList = list.data;
|
||||
}
|
||||
return rankingList;
|
||||
}
|
||||
|
||||
public List<AbstractVideoPlayer> visibleRiders = new List<AbstractVideoPlayer>();//当前线路上的人
|
||||
private const int limits = 5;//在线的其他人数
|
||||
private double MaxVisibleDistance = 200d;//最大显示距离
|
||||
//创建当前线路其他选手
|
||||
private void CreateOnlineUser(List<BaseRider> list)
|
||||
{
|
||||
list = list.Where(c => ((OnlineRiderModel)c).IsWatcher == false).ToList();
|
||||
//断网移除所有用户
|
||||
if (list == null || list.Count == 0)
|
||||
{
|
||||
foreach (var item in visibleRiders)
|
||||
{
|
||||
Debug.Log($"销毁了{item}");
|
||||
DestroyImmediate(item.gameObject);
|
||||
}
|
||||
rideObjs.Clear();
|
||||
visibleRiders.Clear();
|
||||
CurrentPlayer = null;
|
||||
return;
|
||||
}
|
||||
var trainController = GetComponent<ARTrainingController>();
|
||||
//移除退出的选手
|
||||
var players = FindObjectsOfType<OnlineVideoPlayer>();
|
||||
foreach (var item in players)
|
||||
{
|
||||
var currentItem = list.FirstOrDefault(c => c.UserId == item.UserId);
|
||||
if (currentItem == null)
|
||||
{
|
||||
rideObjs.Remove(item);
|
||||
visibleRiders.Remove(item);
|
||||
}
|
||||
}
|
||||
var currentPlayerInfo = list.FirstOrDefault(c => c.IsSelf);
|
||||
var needUpdateList = list.OrderByDescending(c => c.IsSelf).ToList();
|
||||
//如果当前为观察者模式且currentPlayerInfo为null随机选择以为用户观察
|
||||
if (currentPlayerInfo == null)
|
||||
{
|
||||
currentPlayerInfo = needUpdateList.FirstOrDefault(c => c.UserId == CurrentUserId);
|
||||
if(currentPlayerInfo == null)
|
||||
currentPlayerInfo = needUpdateList.FirstOrDefault();
|
||||
}
|
||||
//更新和新增用户
|
||||
foreach (var item in needUpdateList)
|
||||
{
|
||||
var onlineRider = item as OnlineRiderModel;
|
||||
var visibleItem = visibleRiders.FirstOrDefault(c => c.UserId == item.UserId);
|
||||
if (visibleItem != null)
|
||||
{
|
||||
visibleItem.SetPlayer(onlineRider.NickName, onlineRider.Speed, onlineRider.PreDistance, onlineRider.EndDistance, item.Cadence, item.HeartRate, onlineRider.WeightKg, item.UserId, onlineRider.Power, currentPlayerInfo.EndDistance, onlineRider.FrameRate.Value);
|
||||
if (visibleItem.userId == CurrentUserId)
|
||||
{
|
||||
CurrentPlayer = visibleItem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = item.EndDistance % mapData.TotalDistance - currentPlayerInfo.EndDistance % mapData.TotalDistance;
|
||||
if (Math.Abs(diff * 1000) <= MaxVisibleDistance)
|
||||
{
|
||||
GameObject obj = null;
|
||||
if (!item.IsSelf)
|
||||
{
|
||||
if (onlineRider.Sex == 1)
|
||||
{
|
||||
obj = Instantiate(OnlinePlayer, transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = Instantiate(OnlinePlayer_NV, transform);
|
||||
}
|
||||
var online = obj.GetComponentInChildren<OnlineVideoPlayer>();
|
||||
var rideObj = obj.GetComponentInChildren<PlayerRenderer>();
|
||||
online.SetStartDistance(item.EndDistance);
|
||||
rideObj.Distance = (float)online.StartDistance;
|
||||
rideObj.RouteDistance = rideObj.Distance;
|
||||
rideObj.UserId = item.UserId;
|
||||
rideObjs.Add(online, rideObj);
|
||||
visibleRiders.Add(online);
|
||||
trainController.AddRider(onlineRider);
|
||||
online.SetPlayer(onlineRider.NickName, onlineRider.Speed, onlineRider.PreDistance, onlineRider.EndDistance, item.Cadence, item.HeartRate, onlineRider.WeightKg, item.UserId, onlineRider.Power, currentPlayerInfo.EndDistance, onlineRider.FrameRate.Value);
|
||||
if (online.userId == CurrentUserId)
|
||||
{
|
||||
CurrentPlayer = visibleItem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (App.CurrentUser.Sex == 1)
|
||||
{
|
||||
var playerprefab = Resources.Load<GameObject>("UI/Prefab/AR/VidePlayer");
|
||||
videoPlayer = Instantiate(playerprefab, transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
var playerprefabNV = Resources.Load<GameObject>("UI/Prefab/AR/VidePlayer_NV");
|
||||
videoPlayer = Instantiate(playerprefabNV, transform);
|
||||
}
|
||||
|
||||
CurrentUserId = App.CurrentUser.Id;
|
||||
CurrentPlayer = videoPlayer.GetComponent<AbstractVideoPlayer>();
|
||||
|
||||
var vp = videoPlayer.GetComponent<VideoPlayer>();
|
||||
vp.SetEndDistance(item.EndDistance);
|
||||
CurrentPlayer.SetStartDistance(item.EndDistance);
|
||||
|
||||
var rideObj = videoPlayer.GetComponent<PlayerRenderer>();
|
||||
rideObj.Distance = (float)CurrentPlayer.StartDistance;
|
||||
rideObj.RouteDistance = rideObj.Distance;
|
||||
rideObj.IsMain = true;
|
||||
rideObj.UserId = item.UserId;
|
||||
rideObjs.Add(CurrentPlayer, rideObj);
|
||||
visibleRiders.Add(CurrentPlayer);
|
||||
|
||||
CurrentPlayer.SetPlayer(onlineRider.NickName, onlineRider.Speed, onlineRider.PreDistance, onlineRider.EndDistance, item.Cadence, item.HeartRate, onlineRider.WeightKg, item.UserId, onlineRider.Power, currentPlayerInfo.EndDistance, onlineRider.FrameRate.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//设置当前是骑行模式还是观察模式
|
||||
public void SetCurrentMode(ARMode aRMode)
|
||||
{
|
||||
_aRMode = aRMode;
|
||||
_uiManager.SetCurrentMode(aRMode);
|
||||
if (_aRMode != ARMode.INSPECT)
|
||||
{
|
||||
CurrentUserId = App.CurrentUser.Id;
|
||||
ContinueAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCyclingModel(CyclingModel.Single);
|
||||
}
|
||||
}
|
||||
public GameObject videoPlayer;
|
||||
public GameObject target;
|
||||
public int CurrentUserId { get; set; }
|
||||
//切换人物
|
||||
public void ChangePlayer(int userId)
|
||||
{
|
||||
Debug.Log($"切换到{userId}");
|
||||
CurrentUserId = userId;
|
||||
}
|
||||
//获取角色头顶信息预制件
|
||||
public GameObject GetHeadInfo()
|
||||
{
|
||||
return infoPanel;
|
||||
}
|
||||
//继续骑行
|
||||
public void ContinueAsync()
|
||||
{
|
||||
//骑行结果
|
||||
if (App.routeResult != null)
|
||||
{
|
||||
routeResult = App.routeResult;
|
||||
selectParamModel = App.routeResult.ContinueCyclingParam;
|
||||
Debug.Log("selectParamModel"+ selectParamModel.ContinueMark);
|
||||
SetCyclingModel(CyclingModel.Single);
|
||||
endDistance = routeResult.EndDistance;
|
||||
App.routeResult = null;
|
||||
//mediaPlayer.Control.SeekToFrame(routeResult.LastFrame ?? 0);
|
||||
}
|
||||
}
|
||||
//设置骑行模式
|
||||
public void SetCyclingModel(CyclingModel mode)
|
||||
{
|
||||
this.cyclingModel = mode;
|
||||
switch (cyclingModel)
|
||||
{
|
||||
case CyclingModel.Single:
|
||||
cyclingController = new ARSingleModel(route, selectParamModel);
|
||||
break;
|
||||
case CyclingModel.GameRoom:
|
||||
cyclingController = new GameModel(route, selectParamModel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//开始游戏
|
||||
public void StartGame()
|
||||
{
|
||||
//if (startTime != DateTime.MinValue)
|
||||
{
|
||||
startTime = UIManager.Now.GetDateTime();
|
||||
}
|
||||
isStart = true;
|
||||
}
|
||||
//骑行是否开始
|
||||
public bool IsStart()
|
||||
{
|
||||
return isStart;
|
||||
}
|
||||
//获取UI
|
||||
public Transform GetCanvasTransform()
|
||||
{
|
||||
return transform.Find("Canvas/Panel");
|
||||
}
|
||||
//设置视频源文件
|
||||
public void SetMedia(string path)
|
||||
{
|
||||
if (mediaPlayer != null)
|
||||
{
|
||||
mediaPlayer.OpenMedia(new MediaPath(path,MediaPathType.AbsolutePathOrURL),false);
|
||||
}
|
||||
}
|
||||
//是否停止
|
||||
public bool IsQuit()
|
||||
{
|
||||
return isStop;
|
||||
}
|
||||
|
||||
//暂停
|
||||
public void Pause()
|
||||
{
|
||||
isStart = !isStart;
|
||||
isStop = !isStop;
|
||||
}
|
||||
//退出骑行
|
||||
public void Quit()
|
||||
{
|
||||
mediaPlayer?.Pause();//暂停视频
|
||||
isStart = false;
|
||||
isStop = true;
|
||||
mediaPlayer?.Stop();
|
||||
}
|
||||
//获取当前视频帧数
|
||||
public int GetCurrentFrame()
|
||||
{
|
||||
return mediaPlayer.Control.GetCurrentTimeFrames();
|
||||
}
|
||||
|
||||
//获取AR骑行配置信息
|
||||
//获取路书gps信息
|
||||
public MapDataModel GetMapData()
|
||||
{
|
||||
if (mapData == null)
|
||||
{
|
||||
var mapApi = ConfigHelper.mapApi;
|
||||
int routeId = App.RouteIdParam;
|
||||
if(routeId > 0)
|
||||
mapData = mapApi.GetData(routeId,0);//获取路书地理数据
|
||||
}
|
||||
return mapData;
|
||||
}
|
||||
//获取路书信息
|
||||
public MapRoute GetMapRoute()
|
||||
{
|
||||
if (mapRoute == null)
|
||||
{
|
||||
var mapApi = ConfigHelper.mapApi;
|
||||
int routeId = App.RouteIdParam;
|
||||
mapRoute = mapApi.GetById(routeId).data;
|
||||
}
|
||||
return mapRoute;
|
||||
}
|
||||
|
||||
|
||||
public void ShowUpRemainTime(double remain)
|
||||
{
|
||||
_uiManager.ShowUpRemainTime(remain);
|
||||
}
|
||||
|
||||
//保存骑行记录
|
||||
public void SaveData(double totalDistance)
|
||||
{
|
||||
if (cyclingController.recorderData == null || cyclingController.recorderData.Saved)
|
||||
return;
|
||||
|
||||
Quit();
|
||||
|
||||
cyclingController.recorderData.EndTime = UIManager.Now.GetDateTime();
|
||||
var path = PFConstants.MapWorkoutRecordFolder + "/" + recordId;
|
||||
Helper.CreateDirectoryIfNotExsit(path);
|
||||
var imageFileName = path + "/" + Guid.NewGuid().ToString() + ".png";
|
||||
Helper.CaptureCamera(Camera.main, new Rect(Screen.width * 0f, Screen.height * 0f, Screen.width * 0.5f, Screen.height * 0.5f), imageFileName);
|
||||
|
||||
cyclingController.recorderData.StartTime = startTime;
|
||||
cyclingController.recorderData.IsCompleted = totalDistance >= mapData.TotalDistance;
|
||||
cyclingController.recorderData.EndDistance = cyclingController.recorderData.IsCompleted ? mapData.TotalDistance : totalDistance;
|
||||
cyclingController.recorderData.AntModelId = AntModelId;
|
||||
cyclingController.recorderData.ManufacturerId = ManufacturerId;
|
||||
cyclingController.recorderData.ManufacturerName = ManufacturerName;
|
||||
cyclingController.recorderData.DeviceNumber = DeviceNumber;
|
||||
cyclingController.recorderData.LastFrame = GetCurrentFrame();
|
||||
|
||||
RankingId = cyclingController.recorderData.SaveWithLocalRecordAysnc(cyclingModel, selectParamModel, imageFileName, recordId, path);
|
||||
}
|
||||
public void AddEvent(GameObject sender, EventTriggerType eventType, UnityAction<BaseEventData> unityAction)
|
||||
{
|
||||
UIManager.AddEvent(sender, eventType, unityAction);
|
||||
}
|
||||
public Texture GetCountryImageByCode(string code)
|
||||
{
|
||||
return UIManager.Instance.loginRegOptions.GetCountryImage(code);
|
||||
}
|
||||
public Texture GetCountryImageByName(string name)
|
||||
{
|
||||
return UIManager.Instance.loginRegOptions.GetCountryImageByName(name);
|
||||
}
|
||||
public 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Vector2d(0, 0);
|
||||
}
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
App.gameRoomDetail = null;
|
||||
}
|
||||
|
||||
public enum ARMode
|
||||
{
|
||||
RIDE,
|
||||
INSPECT
|
||||
}
|
||||
|
||||
public enum ViewMode
|
||||
{
|
||||
THIRD,
|
||||
FIRST,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 693e7abaf474b6a498a2940d602e0d8e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,155 @@
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoPlayer : AbstractVideoPlayer
|
||||
{
|
||||
private bool isSingle = true;
|
||||
VideoUIManager _uimanager;
|
||||
private bool gameRoomHandled { get; set; }
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
animator.Play("idle");
|
||||
userId = App.CurrentUser.Id;
|
||||
userName = App.CurrentUser.Nickname;
|
||||
_uimanager= FindObjectOfType<VideoUIManager>();
|
||||
}
|
||||
|
||||
public void SetEndDistance(double distance)
|
||||
{
|
||||
this.totalDistance = distance;
|
||||
this.PreDistance = distance * 1000;
|
||||
this.EndDistance = PreDistance;
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
start = false;
|
||||
StartCoroutine(ShowResult());
|
||||
}
|
||||
|
||||
private IEnumerator ShowResult()
|
||||
{
|
||||
yield return new WaitForSeconds(2f);
|
||||
UIManager.CloseGameRoomCountDownPanel();
|
||||
_uimanager?.SaveAndShowResult();
|
||||
}
|
||||
|
||||
public override void ComputePlayer()
|
||||
{
|
||||
heartRate = manager.UpDateHeart();
|
||||
power = manager.UpdatePower();
|
||||
cadance = manager.UpdateCadence();
|
||||
//#if UNITY_EDITOR
|
||||
if (mockpower > 0)
|
||||
{
|
||||
power = mockpower;
|
||||
// cadance = 50;
|
||||
// heartRate = 160;
|
||||
}
|
||||
//#endif
|
||||
weight = App.CurrentUser.Weight;
|
||||
bicycleWeight = App.CurrentUser.BicycleWeight;
|
||||
wkg = Math.Round(power / weight, 2);
|
||||
|
||||
//发送阻力
|
||||
manager.TrackResistance(currentSlope * App.RideSetting.Sensitivity / 100);
|
||||
base.ComputePlayer();
|
||||
//比人先完成触发关门时间
|
||||
HandleForGameRoom();
|
||||
}
|
||||
|
||||
//房间倒计时保存
|
||||
private void HandleForGameRoom()
|
||||
{
|
||||
var model = manager.cyclingController as GameModel;
|
||||
if (model != null && model.FirstEndTime.HasValue && !gameRoomHandled && App.CurrentUser.Id != model.FirstUserId)
|
||||
{
|
||||
gameRoomHandled = true;
|
||||
var gap = model.FirstEndTime.Value - UIManager.Now.GetDateTime();
|
||||
var seconds = Math.Floor(gap.TotalSeconds);
|
||||
UIManager.ShowGameRoomCountDownPanel((int)seconds, () =>
|
||||
{
|
||||
Upload();
|
||||
var uiManager = FindObjectOfType<VideoUIManager>();
|
||||
uiManager.ShowResultPanel();
|
||||
},true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ComputeRecord()
|
||||
{
|
||||
var mapData = manager.GetMapData();
|
||||
//记录骑行数据
|
||||
var recorderData = manager.cyclingController.recorderData;
|
||||
var targetData = new TargetData
|
||||
{
|
||||
Ticks = ticks,
|
||||
_Power = power,
|
||||
_Speed = speed,
|
||||
_Distance = totalDistance > mapData.TotalDistance ? mapData.TotalDistance : totalDistance,
|
||||
_Cadence = cadance,
|
||||
_HeartRate = heartRate,
|
||||
_Lat = currentlatLon.x,
|
||||
_Lon = currentlatLon.y,
|
||||
_TotalClimb = totalClimb,
|
||||
_FrameRate = manager.GetCurrentFrame()
|
||||
};
|
||||
|
||||
var preDistance = totalDistance >= mapData.TotalDistance ? targetData._Distance : targetData._Distance - distance;
|
||||
if (!isSingle)
|
||||
{
|
||||
preDistance = targetData._Distance - distance;
|
||||
}
|
||||
recorderData.PreDistance = Math.Round(preDistance, 6, MidpointRounding.AwayFromZero);
|
||||
recorderData.EndDistance = Math.Round(targetData._Distance, 6, MidpointRounding.AwayFromZero);
|
||||
recorderData.RiderDatas.Add(targetData);
|
||||
|
||||
//默认启用多圈
|
||||
if (isSingle && totalDistance >= mapData.TotalDistance)
|
||||
{
|
||||
Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private double RemainingDistance => Math.Round((mapData.TotalDistance - totalDistance) * 1000);
|
||||
|
||||
public override void Forward()
|
||||
{
|
||||
base.Forward();
|
||||
distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
|
||||
totalDistance += distance;
|
||||
}
|
||||
//保存骑行记录
|
||||
public void Upload()
|
||||
{
|
||||
manager.SaveData(totalDistance);
|
||||
}
|
||||
|
||||
public override void SetPlayer(string name, double speed, double preDistance, double endDistance, double cadance, double heartRate, double wkg, int userId, double power, double currentPlayerDistance, int frame)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
}
|
||||
this.PreDistance = preDistance * 1000;
|
||||
this.EndDistance = endDistance * 1000;
|
||||
|
||||
this.Speed = speed;
|
||||
if (manager.IsQuit())
|
||||
{
|
||||
this.OnlineSpeed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.OnlineSpeed = speed / 3.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21a384a3224d3b248b1d79d68a1e7578
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user