部分代码重构

This commit is contained in:
lishuo committed 2023-05-15 15:11:50 +08:00
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:
+3
View File
@@ -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:
+18
View File
@@ -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:
+82
View File
@@ -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:
+466
View File
@@ -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:
+155
View File
@@ -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: