初版ui提交
This commit is contained in:
1 parent
b3b882c51e
commit
57940568c9
85 files changed
+76969
-1624
No files matched your search
@@ -105,6 +105,7 @@ namespace Assets.Scripts.Apis.Models
|
||||
public bool IsFavorite { get; set; }
|
||||
|
||||
public bool Enable3D { get; set; }
|
||||
public bool EnableAR { get; set; }
|
||||
public int TheHeat { get; set; }
|
||||
public string Hard { get; set; }
|
||||
public string CountryCode { get; set; }
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Assets.Scenes.Ride.Scripts.Model.RiderModels
|
||||
public override RiderType riderType => RiderType.Online;
|
||||
|
||||
public double PreDistance { get; set; } = 0;
|
||||
public double Speed { get; set; } = 0;
|
||||
public double WeightKg { get; set; } = 0;
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@@ -11,6 +11,8 @@ using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using Mapbox.Utils;
|
||||
using TurfCS;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts
|
||||
{
|
||||
@@ -24,6 +26,12 @@ namespace Assets.Scenes.Ride.Scripts
|
||||
}
|
||||
return path;
|
||||
}
|
||||
public double Distance(Vector2d from, Vector2d to)
|
||||
{
|
||||
var pt1 = Turf.Point(new double[] { from.x, from.y });
|
||||
var pt2 = Turf.Point(new double[] { to.x, to.y });
|
||||
return Turf.Distance(pt1, pt2);
|
||||
}
|
||||
public static string SubStr(string str, int length)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using DG.Tweening;
|
||||
using Mapbox.Utils;
|
||||
using System;
|
||||
@@ -9,27 +10,31 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
public abstract class AbstractVideoPlayer : MonoBehaviour
|
||||
{
|
||||
protected Animator animator;
|
||||
public GameObject head { get; set; }
|
||||
public int UserId;
|
||||
protected double weight;//体重
|
||||
protected double bicycleWeight;//车重
|
||||
protected double preSpeed;
|
||||
protected double speed;
|
||||
protected double power;
|
||||
public double speed;
|
||||
public double power;
|
||||
protected double elevation;
|
||||
protected double cadance;
|
||||
protected int? heartRate { get; set; }
|
||||
public int ticks;
|
||||
protected double totalDistance;
|
||||
public double totalDistance;
|
||||
protected double currentSlope;
|
||||
protected double nextSlope;
|
||||
protected double nextSlopeDistance;
|
||||
public double distance;
|
||||
protected double currentSlopeDistance;
|
||||
protected double lastEndDistance;
|
||||
protected double totalClimb;
|
||||
public double totalClimb;
|
||||
protected Vector2d currentlatLon;
|
||||
protected int currentIndex;
|
||||
protected float bearing = 0f;
|
||||
protected MapDataModel mapData;
|
||||
protected bool isHit = false;
|
||||
protected RaycastHit hit;
|
||||
float timer = 1f;
|
||||
protected bool start = true;
|
||||
protected VideoGameManager manager { get; set; }
|
||||
@@ -58,10 +63,12 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
ComputeAnimator();//控制动画
|
||||
CreateHeadImage();
|
||||
while (timer <= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
//animator.Play("touchHead");
|
||||
if (manager.IsStart())
|
||||
{
|
||||
ticks++;
|
||||
@@ -69,61 +76,50 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
ComputePlayer();//计算人物属性
|
||||
ComputeRecord();
|
||||
ComputeVideo();
|
||||
ComputeRandom();
|
||||
RayCastHit();
|
||||
Turn();
|
||||
}
|
||||
|
||||
timer += 1f;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
power = 0;
|
||||
speed = 0;
|
||||
Debug.Log(e.Message);
|
||||
}
|
||||
|
||||
//获取player的position信息
|
||||
Vector3 pos = transform.position;
|
||||
pos.y += 3f;
|
||||
//射线碰撞物信息接收
|
||||
RaycastHit hit;
|
||||
//第二种写法
|
||||
//我们可以先创建出一条射线
|
||||
Ray ray = new Ray(pos, new Vector3(0, -5, 22));
|
||||
//然后用这条射线去做射线检测
|
||||
//射线,输出碰撞体信息,射线长度,射线在那一层检测,射线不忽略开启触发器(istrigger)的碰撞体
|
||||
bool isHit = Physics.Raycast(ray, out hit, 15f, 1 << 0, QueryTriggerInteraction.Collide);
|
||||
//在unity窗口画出射线
|
||||
Debug.DrawLine(pos, new Vector3(pos.x, pos.y, pos.z + 5), Color.red);
|
||||
|
||||
if (isHit)//如果射线检测到物体
|
||||
{
|
||||
//打印出被检测物体的名字
|
||||
print(hit.transform.name);
|
||||
transform.DOLocalMoveX(-2, 1);
|
||||
transform.DOLocalMoveZ(27, 1).onComplete+=()=>{
|
||||
transform.DOLocalMoveX(2, 1);
|
||||
};
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//人物碰撞
|
||||
void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (collision.transform.name != "mc_all_animations")
|
||||
//manager.GetSlotIndex();
|
||||
}
|
||||
|
||||
void RayCastHit()
|
||||
{
|
||||
//获取player的position信息
|
||||
Vector3 pos = transform.position;
|
||||
//射线碰撞物信息接收
|
||||
|
||||
//第二种写法
|
||||
//我们可以先创建出一条射线
|
||||
Ray ray = new Ray(pos, new Vector3(0, 0, 1));
|
||||
//然后用这条射线去做射线检测
|
||||
//射线,输出碰撞体信息,射线长度,射线在那一层检测,射线不忽略开启触发器(istrigger)的碰撞体
|
||||
isHit = Physics.Raycast(ray, out hit, 1f, 1 << 0, QueryTriggerInteraction.Collide);
|
||||
if (isHit)
|
||||
{
|
||||
var curX = collision.transform.position.x;
|
||||
if (curX == 0)
|
||||
{
|
||||
var preX = manager.GetSlotIndex();
|
||||
collision.transform.DOLocalMoveX(preX.Value, 1);
|
||||
}
|
||||
print(hit.collider.name);
|
||||
}
|
||||
}
|
||||
void ComputeRandom()
|
||||
protected void ComputeRandom()
|
||||
{
|
||||
var offset = 30;
|
||||
if (ticks % 9 == 0)
|
||||
transform.DOMoveZ(transform.position.z - offset, 1f);
|
||||
if (ticks % 6 == 0)
|
||||
transform.DOMoveZ(transform.position.z - 1.1f*offset, 1f);
|
||||
if (ticks % 5 == 0)
|
||||
transform.DOMoveZ(transform.position.z + offset, 2f);
|
||||
|
||||
@@ -131,36 +127,76 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
transform.DOLocalRotate(new Vector3(0f, bearing, 0f), 1f);
|
||||
}
|
||||
//动画状态机
|
||||
void ComputeAnimator()
|
||||
protected virtual void ComputeAnimator()
|
||||
{
|
||||
if (animator != null)
|
||||
{
|
||||
animator.SetFloat("preSpeed", (float)preSpeed);
|
||||
animator.SetFloat("speed", (float)speed);
|
||||
animator.SetFloat("grade", (float)currentSlope);
|
||||
var currentFrame = manager.GetCurrentFrame();
|
||||
if (manager.mockDirection.ContainsKey(currentFrame))
|
||||
{
|
||||
bearing = manager.mockDirection[currentFrame];
|
||||
}
|
||||
animator.SetFloat("bearing", bearing);
|
||||
animator.SetFloat("power", (float)power);
|
||||
}
|
||||
}
|
||||
//人相对视频不距离不变。 其他人相对视频做前后位移
|
||||
//人与人之前前后距离按照射线检测 扇形射线
|
||||
//人与人左右距离按照碰撞检测
|
||||
//每个人都实时计算前后距离
|
||||
//其他玩家相对当前主人公做正向或者反向位移,左右
|
||||
protected virtual void ChangeToFirst()
|
||||
{
|
||||
transform.DOLocalMoveZ(-1, 1);
|
||||
protected virtual int GetCurrentFrame()
|
||||
{
|
||||
return manager.GetCurrentFrame();
|
||||
}
|
||||
protected virtual void ChangeToThird()
|
||||
private bool animated = false;
|
||||
//大转弯是60度
|
||||
protected virtual void Turn()
|
||||
{
|
||||
transform.DOLocalMoveZ(55, 1);
|
||||
var currentFrame = GetCurrentFrame();
|
||||
if (manager.mockDirection.ContainsKey((int)currentFrame))
|
||||
{
|
||||
bearing = manager.mockDirection[(int)currentFrame];
|
||||
}
|
||||
animator.SetFloat("bearing", bearing);
|
||||
|
||||
if (!animated && Math.Abs(bearing) > 30)
|
||||
{
|
||||
//TODO:大拐弯动画
|
||||
animated = true;
|
||||
var current = transform.position;
|
||||
//transform.DOMove(new Vector3(current.x+5, current.y, current.z), 1f).onComplete += () =>
|
||||
//{
|
||||
// current = transform.position;
|
||||
// transform.DOMove(new Vector3(current.x-5, current.y, current.z), 1f);
|
||||
//};
|
||||
transform.DORotate(new Vector3(0, bearing, 0), 1f);
|
||||
transform.DOMoveX(current.x + 3, 2).onComplete += () =>
|
||||
{
|
||||
};
|
||||
//transform.DOMove(new Vector3(current.x + 5, current.y, current.z), 1f).onComplete += () => {
|
||||
// transform.DOMove(new Vector3(current.x - 5, current.y, current.z), 1f);
|
||||
// animated = false;
|
||||
//};
|
||||
}
|
||||
else
|
||||
{
|
||||
var aniInfo = animator.GetCurrentAnimatorStateInfo(0);
|
||||
if (aniInfo.loop)
|
||||
{
|
||||
transform.DORotate(new Vector3(0, bearing, 0), 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
//计算人物当前属性
|
||||
protected abstract void ComputePlayer();
|
||||
protected virtual void ComputePlayer()
|
||||
{
|
||||
if (power > 0)
|
||||
{
|
||||
preSpeed = speed;
|
||||
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
|
||||
distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
|
||||
totalDistance += distance;
|
||||
currentlatLon = manager.Along(totalDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = 0;
|
||||
distance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ComputeVideo(){ }
|
||||
|
||||
@@ -214,6 +250,26 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateHeadImage()
|
||||
{
|
||||
if (head == null)
|
||||
{
|
||||
if (manager.GetHeadInfo() != null)
|
||||
head = Instantiate(manager.GetHeadInfo(), manager.GetCanvasTransform());
|
||||
}
|
||||
if (head != null)
|
||||
{
|
||||
//它们的乘积就是高度
|
||||
Vector3 worldPosition = new Vector3(transform.position.x, transform.position.y+2, transform.position.z);
|
||||
var playerScreenPos = Camera.main.WorldToScreenPoint(worldPosition);
|
||||
head.transform.position = playerScreenPos;
|
||||
}
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
head?.Destroy();
|
||||
gameObject.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,26 +4,82 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class OnlineVideoPlayer : AbstractVideoPlayer
|
||||
{
|
||||
public double diff { get; set; }
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
}
|
||||
|
||||
//计算
|
||||
protected override void ComputePlayer()
|
||||
{
|
||||
diff = 10;
|
||||
|
||||
//base.ComputePlayer();
|
||||
var current = FindObjectOfType<VideoPlayer>();
|
||||
diff = totalDistance - current.EndDistance;
|
||||
var z = current.transform.position.z + diff;
|
||||
transform.DOMoveZ((float)z, 1f);
|
||||
Push();
|
||||
}
|
||||
//设置当前玩家属性
|
||||
public void SetPlayer(double power,double distance)
|
||||
//人物向前超车 右边超车
|
||||
private void Push()
|
||||
{
|
||||
transform.DOLocalMoveZ(25, 1);
|
||||
this.power = power;
|
||||
this.distance = distance;
|
||||
this.speed = 20;
|
||||
this.totalDistance += distance;
|
||||
try
|
||||
{
|
||||
var offsetX = 1f;
|
||||
var currentPlayer = FindObjectOfType<VideoPlayer>();
|
||||
//根据差距动态位移
|
||||
var current = currentPlayer.transform.position;
|
||||
var x = current.x + offsetX;
|
||||
var z = current.z + diff;
|
||||
var y = current.y;
|
||||
var end = new Vector3(x, y, (float)z);
|
||||
//前方有人
|
||||
if (isHit)
|
||||
{
|
||||
var onlinePlayer = hit.collider.transform.GetComponent<AbstractVideoPlayer>();
|
||||
if (distance - onlinePlayer.distance > 20)
|
||||
{
|
||||
var prePos = onlinePlayer.transform.position;
|
||||
var disx = prePos.x + offsetX;
|
||||
var disz = prePos.z + diff;
|
||||
var disy = prePos.y;
|
||||
end = new Vector3(disx, (float)disz, disy);
|
||||
animator.Play("turnRight");
|
||||
transform.DOMove(end, 1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.DOMoveZ((float)z, 1f);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
print(e.Message);
|
||||
}
|
||||
}
|
||||
protected override void ComputeAnimator()
|
||||
{
|
||||
base.ComputeAnimator();
|
||||
}
|
||||
protected override int GetCurrentFrame()
|
||||
{
|
||||
return manager.DistanceToFrames(diff) + manager.GetCurrentFrame();
|
||||
}
|
||||
|
||||
//设置当前玩家属性
|
||||
public void SetPlayer(double totalDistance, double cadance,double heartRate,int userId)
|
||||
{
|
||||
this.speed = 10;
|
||||
this.cadance = cadance;
|
||||
this.totalDistance = totalDistance;
|
||||
this.heartRate = (int?)heartRate;
|
||||
this.UserId = userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scripts;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using UnityEngine.Video;
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class TestPlayerController : MonoBehaviour
|
||||
{
|
||||
UnityWebRequest request = null;
|
||||
MapDataModel mapData;
|
||||
MapRoute mapRoute;
|
||||
int ticks = 0;
|
||||
float timer = 1f;
|
||||
double heartRate = 0;
|
||||
public double power = 800;
|
||||
double weight = 60;
|
||||
double bicycleWeight = 10;
|
||||
double elevation = 0f;
|
||||
double currentSlope = 0f;
|
||||
double speed = 0f;
|
||||
double distance = 0f;
|
||||
double totalDistance = 0f;
|
||||
double bearingInterval = 0f;//线路当前转向
|
||||
Animator animator;
|
||||
VideoPlayer videoPlayer;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
//测试数据
|
||||
var routeId = 1255;
|
||||
mapData = ConfigHelper.mapApi.GetData(routeId);//获取路书地理数据
|
||||
mapRoute = ConfigHelper.mapApi.GetById(routeId).data;
|
||||
animator = transform.GetComponent<Animator>();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
while (timer <= 0)
|
||||
{
|
||||
//var animInfo = animator.GetCurrentAnimatorStateInfo(0);
|
||||
//if (animInfo.normalizedTime < 0.6)
|
||||
//{
|
||||
// if (speed > 30)
|
||||
// {
|
||||
// animator.Play("New State Right");
|
||||
// }
|
||||
// else if (speed > 15)
|
||||
// {
|
||||
// animator.Play("RideLoop_Medium_01 1");
|
||||
// }
|
||||
// else if (speed == 0)
|
||||
// {
|
||||
// animator.Play("OnBicycle_01_Idle 0");
|
||||
// videoPlayer.Pause();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// animator.Play("RideLoop_01");
|
||||
// }
|
||||
//}
|
||||
ticks++;
|
||||
ComputeNextSlope();
|
||||
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
|
||||
distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
|
||||
totalDistance += distance;
|
||||
Debug.Log($"ticks:{ticks} speed:{speed} totalDistance:{totalDistance} bearing:{bearingInterval}");
|
||||
timer += 1f;
|
||||
transform.DORotate(new Vector3(0f, (float)(180 + bearingInterval), 0f), 1);
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
void ComputeNextSlope()
|
||||
{
|
||||
double sumDistance = 0;
|
||||
if (mapData == null)
|
||||
return;
|
||||
var pointList = mapData.List;
|
||||
for (int i = 0; i < pointList.Count; i++)
|
||||
{
|
||||
sumDistance += pointList[i].Distance;
|
||||
decimal left = (decimal)totalDistance * 1000;
|
||||
decimal right = (decimal)sumDistance;
|
||||
if (left <= right)
|
||||
{
|
||||
currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var DOUBLE_DELTA = 1E-6;
|
||||
if (Math.Abs(totalDistance - mapData.TotalDistance) < DOUBLE_DELTA)
|
||||
{
|
||||
currentIndex = pointList.Count - 1;
|
||||
}
|
||||
elevation = pointList[currentIndex].Elevation;
|
||||
currentSlope = pointList[currentIndex].Grade;
|
||||
var preindex = currentIndex - 1 >= 0 ? currentIndex - 1 : 0;
|
||||
bearingInterval = pointList[currentIndex].Bearing - pointList[preindex].Bearing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,14 @@ using System.Threading.Tasks;
|
||||
using TurfCS;
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoGameManager : DeviceServiceMonoBase
|
||||
{
|
||||
private List<VideoMapModel> videoPointList { get; set; }
|
||||
private VideoPlayer currentVideoPlayer { get; set; }
|
||||
public AbstractVideoPlayer CurrentPlayer { get; set; }
|
||||
private MapDataModel mapData { get; set; }
|
||||
private MediaPlayer mediaPlayer { get; set; }
|
||||
private bool isStart { get; set; }
|
||||
@@ -34,37 +35,37 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
public BaseCycling cyclingController;
|
||||
public Dictionary<int, int> mockDirection = new Dictionary<int, int>();
|
||||
private double endDistance { get; set; }
|
||||
|
||||
public Dictionary<int, bool> slots = new Dictionary<int, bool>();
|
||||
Transform cube;
|
||||
public List<float> slots = new List<float>();
|
||||
GameObject infoPanel;
|
||||
GameObject OnlinePlayer;
|
||||
private async void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
mediaPlayer = FindObjectOfType<MediaPlayer>();
|
||||
//自动登录
|
||||
if (App.CurrentUser == null)
|
||||
{
|
||||
await Login();
|
||||
}
|
||||
DeviceCache.Init(PFConstants.DeviceCacheFolder);
|
||||
//var check = CheckAnt();
|
||||
//var check = CheckAnt();//初始化蓝牙设备
|
||||
recordId = Guid.NewGuid().ToString();
|
||||
startTime = UIManager.Now.GetDateTime();
|
||||
MapUDPService.Init();//初始化TCP
|
||||
MockDirection();
|
||||
InitSlots();
|
||||
|
||||
infoPanel = Resources.Load<GameObject>("UI/Prefab/Ride/OnlineInfoPanel");
|
||||
OnlinePlayer = Resources.Load<GameObject>("UI/Prefab/OnlineVideoPlayer");
|
||||
}
|
||||
void Start()
|
||||
{
|
||||
cube = transform.Find("Cube");
|
||||
//获取媒体播放器
|
||||
mediaPlayer = FindObjectOfType<MediaPlayer>();
|
||||
InitSlots();
|
||||
startTime = DateTime.Now;//UIManager.Now.GetDateTime();
|
||||
var videoPlayer = FindObjectOfType<VideoPlayer>();
|
||||
var mapApi = ConfigHelper.mapApi;
|
||||
const int routeId = 12353;
|
||||
mapData = mapApi.GetData(routeId);//获取路书地理数据
|
||||
mapRoute = mapApi.GetById(routeId).data;
|
||||
route = new Route(mapData, mapRoute);
|
||||
|
||||
CurrentPlayer = videoPlayer;
|
||||
if (selectParamModel == null)
|
||||
{
|
||||
selectParamModel = new RouteResultParam
|
||||
@@ -92,40 +93,86 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
cyclingController?.Run(null);
|
||||
var onlineRiders = cyclingController.riders;
|
||||
Debug.Log($"当前在线人数:{ MapUDPService.GetAllOnlineUserCount()}");
|
||||
CreateOnlineUser(onlineRiders);
|
||||
timer += 1f;
|
||||
|
||||
}
|
||||
var p = FindObjectOfType<VideoPlayer>();
|
||||
if (p.distance > 0)
|
||||
{
|
||||
preFrame = currentFrame;
|
||||
currentFrame = GetCurrentFrame();
|
||||
var dd = (currentFrame - preFrame) / 200f * cube.position.z;
|
||||
cube.DOMoveZ((float)(cube.position.z - dd), 0f);
|
||||
}
|
||||
}
|
||||
private void InitSlots()
|
||||
private int offSet = 50;
|
||||
private int currentOnlineCount = 0;
|
||||
//创建当前线路其他选手
|
||||
private void CreateOnlineUser(List<BaseRider> list)
|
||||
{
|
||||
slots.Add(2, true);
|
||||
slots.Add(4, true);
|
||||
slots.Add(-2, true);
|
||||
slots.Add(-6, true);
|
||||
slots.Add(-4, true);
|
||||
slots.Add(-8, true);
|
||||
}
|
||||
|
||||
public int? GetSlotIndex()
|
||||
{
|
||||
foreach (var item in slots)
|
||||
var players = FindObjectsOfType<OnlineVideoPlayer>();
|
||||
var current = FindObjectOfType<VideoPlayer>();
|
||||
//移除
|
||||
foreach (var item in players)
|
||||
{
|
||||
if (item.Value)
|
||||
var currentItem = list.Where(c => c.UserId == item.UserId).FirstOrDefault();
|
||||
if (currentItem == null)
|
||||
{
|
||||
slots[item.Key] = false;
|
||||
return item.Key;
|
||||
item.Destroy();
|
||||
currentOnlineCount--;
|
||||
}
|
||||
}
|
||||
//新增/更新
|
||||
var pagedList = list.Take(5).ToList();
|
||||
foreach (var item in pagedList)
|
||||
{
|
||||
var onlineRider = item as OnlineRiderModel;
|
||||
var exsit = players.Where(c => c.UserId == item.UserId).FirstOrDefault();
|
||||
if (exsit != null)
|
||||
{
|
||||
var online = exsit.GetComponent<OnlineVideoPlayer>();
|
||||
online.SetPlayer(onlineRider.EndDistance, item.Cadence, item.HeartRate, item.UserId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var diff = item.EndDistance - current.EndDistance;
|
||||
if (diff < offSet)
|
||||
{
|
||||
var obj = Instantiate(OnlinePlayer, transform);
|
||||
var online = obj.GetComponent<OnlineVideoPlayer>();
|
||||
Debug.Log($"{onlineRider.EndDistance}={item.Power}={onlineRider.PreDistance}");
|
||||
online.SetPlayer(onlineRider.EndDistance, item.Cadence, item.HeartRate,item.UserId);
|
||||
obj.transform.DOMoveX(slots[currentOnlineCount], 1);
|
||||
currentOnlineCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//切换人物
|
||||
public void ChangePlayer(int userId)
|
||||
{
|
||||
var players = FindObjectsOfType<AbstractVideoPlayer>();
|
||||
if (players != null) {
|
||||
CurrentPlayer = players.Where(c => c.UserId == userId).FirstOrDefault();
|
||||
if (CurrentPlayer != null) {
|
||||
var currentFrames = DistanceToFrames(CurrentPlayer.totalDistance);
|
||||
//获取当前人物的帧数
|
||||
SetCurrentFrame(currentFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
//初始化骑行选手横向插槽
|
||||
private void InitSlots()
|
||||
{
|
||||
for (float i = -2f; i <= 2; i+=0.5f)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
slots.Add(i);
|
||||
}
|
||||
}
|
||||
slots = slots.OrderBy(c => Math.Abs(c)).ToList();
|
||||
}
|
||||
//获取角色头顶信息预制件
|
||||
public GameObject GetHeadInfo()
|
||||
{
|
||||
return infoPanel;
|
||||
}
|
||||
//骑行记录
|
||||
public async Task ContinueAsync()
|
||||
{
|
||||
//继续骑行数据
|
||||
@@ -165,6 +212,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
mockDirection.Add(Convert.ToInt32(item.Split(':')[0]), Convert.ToInt32(item.Split(':')[1]));
|
||||
}
|
||||
}
|
||||
//设置骑行模式
|
||||
public void SetCyclingModel(CyclingModel mode)
|
||||
{
|
||||
this.cyclingModel = mode;
|
||||
@@ -178,7 +226,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
//模拟登录
|
||||
private async Task Login()
|
||||
{
|
||||
var result = await new UserApi().Login("15261826280", "123456", "");
|
||||
var result = await new UserApi().Login("anyway2019@163.com", "123456", "");
|
||||
App.CurrentUser = result.data;
|
||||
}
|
||||
//开始游戏
|
||||
@@ -187,41 +235,66 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
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 void Play(float playbackRate = 1f)
|
||||
{
|
||||
if (mediaPlayer != null)
|
||||
{
|
||||
mediaPlayer.PlaybackRate = playbackRate;
|
||||
mediaPlayer.PlaybackRate = 1;//TODO:playbackRate;
|
||||
mediaPlayer.Play();
|
||||
}
|
||||
}
|
||||
//暂停游戏
|
||||
//暂停
|
||||
public void Pause()
|
||||
{
|
||||
mediaPlayer?.Pause();
|
||||
}
|
||||
//退出骑行
|
||||
public void Quit()
|
||||
{
|
||||
mediaPlayer?.Stop();
|
||||
}
|
||||
int preFrame = 0;
|
||||
int currentFrame = 0;
|
||||
|
||||
//获取当前视频帧数
|
||||
public int GetCurrentFrame()
|
||||
{
|
||||
return mediaPlayer.Control.GetCurrentTimeFrames();
|
||||
}
|
||||
|
||||
//距离换算成视频帧数
|
||||
public int DistanceToFrames(double distance)
|
||||
{
|
||||
var frames = mediaPlayer.Info.GetMaxFrameNumber(); //视频打开后生效
|
||||
var TotalDistance = route?.TotalDistance ?? 0;
|
||||
return TotalDistance > 0 ? Convert.ToInt32(frames / TotalDistance * distance) : 0;
|
||||
}
|
||||
//设置当前视频播放进度
|
||||
public void SetCurrentFrame(int seq)
|
||||
{
|
||||
mediaPlayer?.Control.SeekToFrame(seq);
|
||||
}
|
||||
|
||||
//获取路书信息
|
||||
public MapDataModel GetMapData()
|
||||
{
|
||||
return mapData;
|
||||
}
|
||||
//保存骑行记录
|
||||
public void Save(double totalDistance)
|
||||
{
|
||||
mediaPlayer?.Pause();//暂停视频
|
||||
@@ -241,47 +314,26 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
cyclingController.recorderData.LastFrame = GetCurrentFrame();
|
||||
var RankingId = cyclingController.recorderData.SaveWithLocalRecordAysnc(cyclingModel, selectParamModel, imageFileName, recordId, path);
|
||||
}
|
||||
//截图
|
||||
protected void CaptureCamera(Camera camera, Rect rect, string fileName)
|
||||
{
|
||||
byte[] bytes = CaptureCameraReturnByte(camera, rect);
|
||||
//var path = Helper.GetDataDir("MapWorkoutRecords/images");
|
||||
//string filename = path + "/" + Guid.NewGuid().ToString() + ".png";
|
||||
System.IO.File.WriteAllBytes(fileName, bytes);
|
||||
//Debug.Log(string.Format("截屏了一张照片: {0}", filename));
|
||||
}
|
||||
private byte[] CaptureCameraReturnByte(Camera camera, Rect rect)
|
||||
{
|
||||
// 创建一个RenderTexture对象
|
||||
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
|
||||
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
|
||||
camera.targetTexture = rt;
|
||||
camera.Render();
|
||||
//ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。
|
||||
//ps: camera2.targetTexture = rt;
|
||||
//ps: camera2.Render();
|
||||
//ps: -------------------------------------------------------------------
|
||||
|
||||
// 激活这个rt, 并从中中读取像素。
|
||||
RenderTexture.active = rt;
|
||||
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
|
||||
screenShot.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素
|
||||
screenShot.ReadPixels(rect, 0, 0);
|
||||
screenShot.Apply();
|
||||
|
||||
// 重置相关参数,以使用camera继续在屏幕上显示
|
||||
camera.targetTexture = null;
|
||||
//ps: camera2.targetTexture = null;
|
||||
RenderTexture.active = null; // JC: added to avoid errors
|
||||
RenderTexture.active = null;
|
||||
GameObject.Destroy(rt);
|
||||
// 最后将这些纹理数据,成一个图片文件
|
||||
return screenShot.EncodeToJPG();
|
||||
}
|
||||
//两个坐标之间的距离
|
||||
public double Distance(Vector2d from, Vector2d to)
|
||||
{
|
||||
var pt1 = Turf.Point(new double[] { from.x, from.y });
|
||||
var pt2 = Turf.Point(new double[] { to.x, to.y });
|
||||
return Turf.Distance(pt1, pt2);
|
||||
}
|
||||
//根据距离计算下一个点坐标
|
||||
public Vector2d Along(double endDistance)
|
||||
{
|
||||
@@ -298,17 +350,5 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
return new Vector2d(0, 0);
|
||||
}
|
||||
}
|
||||
public MapDataModel GetMapData()
|
||||
{
|
||||
return mapData;
|
||||
}
|
||||
public float GetPlayRatio()
|
||||
{
|
||||
return mediaPlayer.Control.GetPlaybackRate();
|
||||
}
|
||||
public List<VideoMapModel> getVideoPointList()
|
||||
{
|
||||
return videoPointList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoLoading : MonoBehaviour
|
||||
{
|
||||
Button download { get; set; }
|
||||
UnityWebRequest request { get; set; }
|
||||
VideoGameManager manager { get; set; }
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
manager = FindObjectOfType<VideoGameManager>();
|
||||
var button = transform.Find("Panel/Button").GetComponent<Button>();
|
||||
var Start = transform.Find("Panel/Start").GetComponent<Button>();
|
||||
var Back = transform.Find("Panel/Back").GetComponent<Button>();
|
||||
var canvasGroup = transform.GetComponent<CanvasGroup>();
|
||||
var ui = manager.GetCanvasTransform();
|
||||
|
||||
var text = transform.GetComponentInChildren<Text>();
|
||||
var fileName = "12067924_720p.mp4";
|
||||
var url = @"http://192.168.0.97:6031/12067924_720p.mp4";
|
||||
var currentPath = "";
|
||||
var path = PFConstants.VideoFolder;
|
||||
var filepath = path + "/" + fileName;
|
||||
|
||||
if (File.Exists(filepath))
|
||||
{
|
||||
button.gameObject.SetActive(false);
|
||||
Start.gameObject.SetActive(true);
|
||||
manager.SetMedia(filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
//检查本地文件是否存在 如果存在直接设置mediaPlayer 否则显示下载按钮
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
StartCoroutine(Utils.DownloadVideo(fileName, url
|
||||
, (p, req) =>
|
||||
{
|
||||
text.text = Math.Round(p * 100, 2).ToString() + "%";
|
||||
request = req;
|
||||
}
|
||||
, (p) =>
|
||||
{
|
||||
text.text = "100%";
|
||||
currentPath = p;
|
||||
Start.gameObject.SetActive(true);
|
||||
manager.SetMedia(p);
|
||||
}
|
||||
));
|
||||
});
|
||||
}
|
||||
var g = gameObject;
|
||||
Start.onClick.AddListener(() =>
|
||||
{
|
||||
canvasGroup.DOFade(0, 1).onComplete+=()=> {
|
||||
g.SetActive(false);
|
||||
ui.Find("Panel").gameObject.SetActive(true);
|
||||
};
|
||||
});
|
||||
Back.onClick.AddListener(() =>
|
||||
{
|
||||
SceneManager.LoadScene("MainScene");
|
||||
});
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d44d40e0ce48544ab744a5936f71d19
|
||||
guid: 1f3705d27cb576f498459e5540d88906
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -7,6 +7,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class VideoPlayer : AbstractVideoPlayer
|
||||
{
|
||||
public double EndDistance => totalDistance;
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
@@ -30,6 +31,16 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
start = false;
|
||||
manager.Save(totalDistance);
|
||||
}
|
||||
protected override void ComputeAnimator()
|
||||
{
|
||||
base.ComputeAnimator();
|
||||
var currentFrame = manager.GetCurrentFrame();
|
||||
if (manager.mockDirection.ContainsKey(currentFrame))
|
||||
{
|
||||
bearing = manager.mockDirection[currentFrame];
|
||||
}
|
||||
animator.SetFloat("bearing", bearing);
|
||||
}
|
||||
protected override void ComputePlayer()
|
||||
{
|
||||
heartRate = manager.UpDateHeart();
|
||||
@@ -39,20 +50,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
bicycleWeight = App.CurrentUser.BicycleWeight;
|
||||
//发送阻力
|
||||
manager.TrackResistance(currentSlope);
|
||||
if (power > 0)
|
||||
{
|
||||
preSpeed = speed;
|
||||
speed = Helper.CalculateSpeed(elevation, currentSlope, power, weight, bicycleWeight);
|
||||
distance = Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
|
||||
totalDistance += distance;
|
||||
currentlatLon = manager.Along(totalDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
speed = 0;
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
base.ComputePlayer();
|
||||
}
|
||||
//控制视频播放速度
|
||||
protected override void ComputeVideo()
|
||||
@@ -80,7 +78,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
protected override void ComputeRecord()
|
||||
{
|
||||
var mapData = manager.GetMapData();
|
||||
Debug.Log($"ticks:{ticks}-{manager.GetCurrentFrame()}-endistance:{totalDistance}-totalDistance:{mapData.TotalDistance}-index:{currentIndex}-speed:{speed}-currentSlope:{currentSlope}-GetCurrentFrame:{manager.GetCurrentFrame()}-currentlatLon:{bearing}");
|
||||
//Debug.Log($"ticks:{ticks}-{manager.GetCurrentFrame()}-endistance:{totalDistance}-totalDistance:{mapData.TotalDistance}-index:{currentIndex}-speed:{speed}-currentSlope:{currentSlope}-GetCurrentFrame:{manager.GetCurrentFrame()}-currentlatLon:{bearing}");
|
||||
//记录骑行数据
|
||||
var recorderData = manager.cyclingController.recorderData;
|
||||
var targetData = new TargetData
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections;
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
@@ -38,11 +40,6 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
UIManager.AddEvent(start, UnityEngine.EventSystems.EventTriggerType.PointerClick, (s) =>
|
||||
{
|
||||
videoPlayer.SetPower(200);
|
||||
var list = FindObjectsOfType<OnlineVideoPlayer>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
item.SetPlayer(100, 10);
|
||||
}
|
||||
manager.StartGame();
|
||||
});
|
||||
UIManager.AddEvent(stop, UnityEngine.EventSystems.EventTriggerType.PointerClick, (s) =>
|
||||
@@ -50,6 +47,7 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
sb.AppendLine($"{manager.GetCurrentFrame()}:{0}");
|
||||
Debug.Log(sb.ToString());
|
||||
videoPlayer.SetPower(0);
|
||||
manager.Pause();//暂停视频
|
||||
});
|
||||
UIManager.AddEvent(save, UnityEngine.EventSystems.EventTriggerType.PointerClick, (s) =>
|
||||
{
|
||||
@@ -64,8 +62,25 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
sb.AppendLine($"{manager.GetCurrentFrame()}:{5}");
|
||||
});
|
||||
ShowPlayerInfo();
|
||||
}
|
||||
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; }
|
||||
private void ShowPlayerInfo()
|
||||
{
|
||||
power = transform.Find("Panel/PowerPanel/Power").GetComponent<Text>();
|
||||
cadance = transform.Find("Panel/PowerPanel/Cadance").GetComponent<Text>();
|
||||
heartRate = transform.Find("Panel/PowerPanel/Hrv").GetComponent<Text>();
|
||||
speed = transform.Find("Panel/ComputerPanel/Speed").GetComponent<Text>();
|
||||
totalDistance = transform.Find("Panel/ComputerPanel/Distance").GetComponent<Text>();
|
||||
totalClimbed = transform.Find("Panel/ComputerPanel/TotalClimb").GetComponent<Text>();
|
||||
ridingTime = transform.Find("Panel/ComputerPanel/Timer").GetComponent<Text>();
|
||||
}
|
||||
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
@@ -73,6 +88,15 @@ namespace Assets.Scripts.Scenes.VideoRide
|
||||
if (videoPlayer != null && manager != null)
|
||||
{
|
||||
infoText.text = $"帧数:{manager.GetCurrentFrame()}";
|
||||
power.text = Math.Round(videoPlayer.power).ToString();
|
||||
speed.text = Math.Round(videoPlayer.speed,2).ToString();
|
||||
totalDistance.text = Math.Round(videoPlayer.totalDistance,2).ToString();
|
||||
totalClimbed.text = Math.Round(videoPlayer.totalClimb).ToString();
|
||||
|
||||
if (manager.CurrentPlayer != null)
|
||||
{
|
||||
ridingTime.text = Helper.FormatTicks(manager.CurrentPlayer.ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
using Assets.Scenes.Ride.Scripts;
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scripts;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Video;
|
||||
namespace Assets.Scripts.Scenes.VideoRide
|
||||
{
|
||||
public class testDownLoad : MonoBehaviour
|
||||
{
|
||||
UnityWebRequest request = null;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
//测试UI
|
||||
var button = transform.GetComponent<Button>();
|
||||
var text = transform.GetComponentInChildren<Text>();
|
||||
var inputFiled = transform.parent.GetComponentInChildren<InputField>();
|
||||
var player = FindObjectOfType<VideoPlayer>();
|
||||
var testPlayer = FindObjectOfType<TestPlayerController>();
|
||||
var url = @"http://192.168.0.97:6031/12067924_720p.mp4";
|
||||
var currentPath = "";
|
||||
inputFiled.onValueChanged.AddListener((s) =>
|
||||
{
|
||||
testPlayer.power = Convert.ToDouble(s);
|
||||
});
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
StartCoroutine(Utils.DownloadVideo("sdsd.mp4", url
|
||||
, (p, req) =>
|
||||
{
|
||||
text.text = Math.Round(p * 100, 2).ToString() + "%";
|
||||
request = req;
|
||||
}
|
||||
, (path) =>
|
||||
{
|
||||
text.text = "100%";
|
||||
currentPath = path;
|
||||
//player.url = path;
|
||||
}
|
||||
));
|
||||
if (!string.IsNullOrEmpty(currentPath))
|
||||
{
|
||||
//player.url = currentPath;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1334799e672a05949b3e33f7abab3641
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -472,7 +472,7 @@ namespace Assets.Scripts
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
var filepath= path+$"/{fileName}.mp4";
|
||||
var filepath= path+$"/{fileName}";
|
||||
if (File.Exists(filepath))
|
||||
{
|
||||
local = filepath;
|
||||
|
||||
Reference in new issue
Block a user