450 lines
17 KiB
C#
Raw Normal View History

2022-03-10 18:32:53 +08:00
using Assets.Scenes.Ride.Scripts;
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scenes.Ride.Scripts.Model.CyclingModels;
using Assets.Scripts.Apis;
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 System.Threading.Tasks;
using TurfCS;
using UnityEngine;
using DG.Tweening;
2022-03-24 09:36:59 +08:00
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
2022-03-25 09:57:30 +08:00
using UnityEngine.EventSystems;
using UnityEngine.Events;
2022-03-10 18:32:53 +08:00
namespace Assets.Scripts.Scenes.VideoRide
{
public class VideoGameManager : DeviceServiceMonoBase
{
private List<VideoMapModel> videoPointList { get; set; }
2022-03-24 09:36:59 +08:00
public AbstractVideoPlayer CurrentPlayer { get; set; }
2022-03-10 18:32:53 +08:00
private MapDataModel mapData { get; set; }
private MediaPlayer mediaPlayer { get; set; }
private bool isStart { get; set; }
private Route route { get; set; }
2022-03-25 09:57:30 +08:00
public MapRoute mapRoute { get; set; }
2022-03-10 18:32:53 +08:00
public RouteResultParam selectParamModel;
public RouteResult routeResult;
public string recordId { get; set; }
public DateTime startTime { get; set; }
public CyclingModel cyclingModel;
public BaseCycling cyclingController;
public Dictionary<int, int> mockDirection = new Dictionary<int, int>();
private double endDistance { get; set; }
2022-03-24 09:36:59 +08:00
public List<float> slots = new List<float>();
GameObject infoPanel;
GameObject OnlinePlayer;
2022-03-25 09:57:30 +08:00
public enum ARMode
{
INSPECT,
RIDE
}
public enum ViewMode
{
THIRD,
FIRST,
}
//当前是观察者视角还是骑行者视角
public ARMode _aRMode { get; set; }
//当前是第一人称还是第三人称
public ViewMode _viewMode { get; set; }
public int RankingId { get; set; }
2022-03-10 18:32:53 +08:00
private async void Awake()
{
base.Awake();
2022-03-25 09:57:30 +08:00
#if UNITY_EDITOR
App.RouteIdParam = 12353;
#endif
2022-03-24 09:36:59 +08:00
mediaPlayer = FindObjectOfType<MediaPlayer>();
2022-03-10 18:32:53 +08:00
//自动登录
if (App.CurrentUser == null)
{
await Login();
}
DeviceCache.Init(PFConstants.DeviceCacheFolder);
2022-03-24 09:36:59 +08:00
//var check = CheckAnt();//初始化蓝牙设备
2022-03-10 18:32:53 +08:00
recordId = Guid.NewGuid().ToString();
MockDirection();
2022-03-24 09:36:59 +08:00
infoPanel = Resources.Load<GameObject>("UI/Prefab/Ride/OnlineInfoPanel");
OnlinePlayer = Resources.Load<GameObject>("UI/Prefab/OnlineVideoPlayer");
2022-03-10 18:32:53 +08:00
}
void Start()
{
2022-03-24 09:36:59 +08:00
InitSlots();
startTime = DateTime.Now;//UIManager.Now.GetDateTime();
2022-03-25 09:57:30 +08:00
var routeId = App.RouteIdParam;
//获取路书
GetMapRoute();
GetMapData();
2022-03-10 18:32:53 +08:00
route = new Route(mapData, mapRoute);
2022-03-25 09:57:30 +08:00
2022-03-10 18:32:53 +08:00
if (selectParamModel == null)
{
selectParamModel = new RouteResultParam
{
CompetitionId = 0,
ContinueIndex = 0,
ContinueMark = "",
GlobalContinue = false,
EndDistance = 0,
RankingsId = new List<string>(),
OnlineUserId = 0,
RouteId = routeId
};
}
endDistance = 0;
//倒计时5s开始
SetCyclingModel(CyclingModel.Single);
}
// Update is called once per frame
float timer = 1f;
void Update()
{
timer -= Time.deltaTime;
while (timer <= 0)
{
cyclingController?.Run(null);
var onlineRiders = cyclingController.riders;
2022-03-24 09:36:59 +08:00
Debug.Log($"当前在线人数:{ MapUDPService.GetAllOnlineUserCount()}");
CreateOnlineUser(onlineRiders);
2022-03-10 18:32:53 +08:00
timer += 1f;
2022-03-25 09:57:30 +08:00
}
2022-03-24 09:36:59 +08:00
}
private int offSet = 50;
private int currentOnlineCount = 0;
//创建当前线路其他选手
2022-03-25 09:57:30 +08:00
private void CreateOnlineUser(List<BaseRider> list)
2022-03-24 09:36:59 +08:00
{
var players = FindObjectsOfType<OnlineVideoPlayer>();
var current = FindObjectOfType<VideoPlayer>();
//移除
foreach (var item in players)
{
2022-03-24 09:36:59 +08:00
var currentItem = list.Where(c => c.UserId == item.UserId).FirstOrDefault();
if (currentItem == null)
{
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
{
2022-03-25 09:57:30 +08:00
//进来观察 看谁呢 依据谁未中心构建其他玩家
var diff = item.EndDistance - 0;//CurrentPlayer.EndDistance;
2022-03-24 09:36:59 +08:00
if (diff < offSet)
{
var obj = Instantiate(OnlinePlayer, transform);
var online = obj.GetComponent<OnlineVideoPlayer>();
Debug.Log($"{onlineRider.EndDistance}={item.Power}={onlineRider.PreDistance}");
2022-03-25 09:57:30 +08:00
online.SetPlayer(onlineRider.EndDistance, item.Cadence, item.HeartRate, item.UserId);
2022-03-24 09:36:59 +08:00
obj.transform.DOMoveX(slots[currentOnlineCount], 1);
currentOnlineCount++;
}
}
2022-03-10 18:32:53 +08:00
}
2022-03-25 09:57:30 +08:00
//随机选择当前骑行的人作为观察对象
if (_aRMode == ARMode.INSPECT && CurrentPlayer == null)
{
var currentPlayer = players.FirstOrDefault();
if (currentPlayer != null)
{
ChangePlayer(currentPlayer.UserId);
}
}
}
//设置当前是骑行模式还是观察模式
public void SetCurrentMode(ARMode aRMode)
{
_aRMode = aRMode;
var videoPlayer = FindObjectOfType<VideoPlayer>();
if (_aRMode == ARMode.INSPECT)
{
videoPlayer?.gameObject.SetActive(false);
}
else
{
CurrentPlayer = videoPlayer;
}
}
//切换当前人物视角
public void ChangeView()
{
var videoPlayer = FindObjectOfType<VideoPlayer>();
var currentPlayer = CurrentPlayer == null? videoPlayer.transform : CurrentPlayer.transform;
_viewMode = _viewMode == ViewMode.THIRD ? ViewMode.FIRST : ViewMode.THIRD;
if (_viewMode == ViewMode.FIRST)
{
currentPlayer.DOMoveZ(-0.1f, 0f);
currentPlayer.DOMoveY(-1.1f, 0f);
}
else
{
currentPlayer.DOMoveZ(4, 0f);
currentPlayer.DOMoveY(-1f, 0f);
}
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//切换人物
public void ChangePlayer(int userId)
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
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);
}
}
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//初始化骑行选手横向插槽
private void InitSlots()
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
for (float i = -2f; i <= 2; i+=0.5f)
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
if (i != 0)
2022-03-10 18:32:53 +08:00
{
2022-03-24 09:36:59 +08:00
slots.Add(i);
2022-03-10 18:32:53 +08:00
}
}
2022-03-24 09:36:59 +08:00
slots = slots.OrderBy(c => Math.Abs(c)).ToList();
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//获取角色头顶信息预制件
public GameObject GetHeadInfo()
{
return infoPanel;
}
//骑行记录
2022-03-10 18:32:53 +08:00
public async Task ContinueAsync()
{
//继续骑行数据
var r = await ConfigHelper.mapInterruptRecordApi.GetMapInterruptRecord("重庆", 0, 20, "routes");
if (r.result)
{
var first = r.data.FirstOrDefault();
RouteResult routeResult = first.ToObject<RouteResult>();
if (routeResult.ContinueCyclingParam != null)
{
App.RouteIdParam = routeResult.RouteId;
App.routeResult = routeResult;
//骑行结果
if (App.routeResult != null)
{
routeResult = App.routeResult;
selectParamModel = App.routeResult.ContinueCyclingParam;//继续骑行
SetCyclingModel(CyclingModel.Single);
endDistance = routeResult.EndDistance;
var ratio = endDistance / routeResult.TotalDistance;
var frame = Math.Round(ratio * mediaPlayer.Info.GetMaxFrameNumber());
SetCurrentFrame(routeResult.LastFrame ?? 0);
var v = FindObjectOfType<VideoPlayer>();
v.SetEndDistance(endDistance);
}
}
}
}
private void MockDirection()
{
var text = Resources.Load<TextAsset>("UI/direction");
var arr = text.text.Replace("\r\n", ",").Split(',');
foreach (var item in arr)
{
if (string.IsNullOrEmpty(item))
continue;
mockDirection.Add(Convert.ToInt32(item.Split(':')[0]), Convert.ToInt32(item.Split(':')[1]));
}
}
2022-03-24 09:36:59 +08:00
//设置骑行模式
2022-03-10 18:32:53 +08:00
public void SetCyclingModel(CyclingModel mode)
{
this.cyclingModel = mode;
switch (cyclingModel)
{
case CyclingModel.Single:
cyclingController = new SingleModel(route, selectParamModel);
break;
}
}
//模拟登录
private async Task Login()
{
2022-03-24 09:36:59 +08:00
var result = await new UserApi().Login("anyway2019@163.com", "123456", "");
2022-03-10 18:32:53 +08:00
App.CurrentUser = result.data;
}
//开始游戏
public void StartGame()
{
startTime = UIManager.Now.GetDateTime();
isStart = true;
}
2022-03-24 09:36:59 +08:00
//骑行是否开始
2022-03-10 18:32:53 +08:00
public bool IsStart()
{
return isStart;
}
2022-03-24 09:36:59 +08:00
//获取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);
}
}
//设置当前视频播放速度
2022-03-10 18:32:53 +08:00
public void Play(float playbackRate = 1f)
{
if (mediaPlayer != null)
{
2022-03-25 09:57:30 +08:00
mediaPlayer.PlaybackRate = playbackRate;
2022-03-10 18:32:53 +08:00
mediaPlayer.Play();
}
2022-03-25 09:57:30 +08:00
if (startTime == null)
{
startTime = UIManager.Now.GetDateTime();
}
isStart = true;
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//暂停
2022-03-10 18:32:53 +08:00
public void Pause()
{
mediaPlayer?.Pause();
}
2022-03-24 09:36:59 +08:00
//退出骑行
2022-03-10 18:32:53 +08:00
public void Quit()
{
mediaPlayer?.Stop();
}
2022-03-24 09:36:59 +08:00
//获取当前视频帧数
public int GetCurrentFrame()
2022-03-10 18:32:53 +08:00
{
return mediaPlayer.Control.GetCurrentTimeFrames();
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//距离换算成视频帧数
public int DistanceToFrames(double distance)
{
var frames = mediaPlayer.Info.GetMaxFrameNumber(); //视频打开后生效
var TotalDistance = route?.TotalDistance ?? 0;
return TotalDistance > 0 ? Convert.ToInt32(frames / TotalDistance * distance) : 0;
}
//设置当前视频播放进度
2022-03-10 18:32:53 +08:00
public void SetCurrentFrame(int seq)
{
mediaPlayer?.Control.SeekToFrame(seq);
}
2022-03-25 09:57:30 +08:00
//获取路书gps信息
2022-03-24 09:36:59 +08:00
public MapDataModel GetMapData()
{
2022-03-25 09:57:30 +08:00
if (mapData == null)
{
var mapApi = ConfigHelper.mapApi;
int routeId = App.RouteIdParam;
mapData = mapApi.GetData(routeId);//获取路书地理数据
}
2022-03-24 09:36:59 +08:00
return mapData;
}
2022-03-25 09:57:30 +08:00
//获取路书信息
public MapRoute GetMapRoute()
{
if (mapRoute == null)
{
var mapApi = ConfigHelper.mapApi;
int routeId = App.RouteIdParam;
mapRoute = mapApi.GetById(routeId).data;
}
return mapRoute;
}
2022-03-24 09:36:59 +08:00
//保存骑行记录
2022-03-10 18:32:53 +08:00
public void Save(double totalDistance)
{
mediaPlayer?.Pause();//暂停视频
cyclingController.recorderData.EndTime = UIManager.Now.GetDateTime();
isStart = false;
var path = PFConstants.MapWorkoutRecordFolder + "/" + recordId;
Assets.Scenes.Ride.Scripts.Helper.CreateDirectoryIfNotExsit(path);
string imageFileName = path + "/" + Guid.NewGuid().ToString() + ".png";
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 = totalDistance;
cyclingController.recorderData.AntModelId = AntModelId;
cyclingController.recorderData.ManufacturerId = ManufacturerId;
cyclingController.recorderData.ManufacturerName = ManufacturerName;
cyclingController.recorderData.DeviceNumber = DeviceNumber;
cyclingController.recorderData.LastFrame = GetCurrentFrame();
2022-03-25 09:57:30 +08:00
RankingId = cyclingController.recorderData.SaveWithLocalRecordAysnc(cyclingModel, selectParamModel, imageFileName, recordId, path);
}
public void GetUIPanel()
{
}
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);
2022-03-10 18:32:53 +08:00
}
2022-03-24 09:36:59 +08:00
//截图
2022-03-10 18:32:53 +08:00
protected void CaptureCamera(Camera camera, Rect rect, string fileName)
{
byte[] bytes = CaptureCameraReturnByte(camera, rect);
System.IO.File.WriteAllBytes(fileName, bytes);
}
private byte[] CaptureCameraReturnByte(Camera camera, Rect rect)
{
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
camera.targetTexture = rt;
camera.Render();
RenderTexture.active = rt;
Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
2022-03-24 09:36:59 +08:00
screenShot.ReadPixels(rect, 0, 0);
2022-03-10 18:32:53 +08:00
screenShot.Apply();
camera.targetTexture = null;
2022-03-24 09:36:59 +08:00
RenderTexture.active = null;
2022-03-10 18:32:53 +08:00
GameObject.Destroy(rt);
return screenShot.EncodeToJPG();
}
//根据距离计算下一个点坐标
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);
}
}
}
}