2022-12-09 16:45:54 +08:00

489 lines
20 KiB
C#

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; }
GameObject infoPanel;
GameObject Player;
GameObject Player_NV;
GameObject OnlinePlayer;
GameObject OnlinePlayer_NV;
private bool isStop { get; set; }
public enum ARMode
{
RIDE,
INSPECT
}
public enum ViewMode
{
THIRD,
FIRST,
}
VideoLoading videoLoading { get; set; }
//当前是第一人称还是第三人称
public ViewMode _viewMode { get; set; }
//当前是观察者视角还是骑行者视角
public ARMode _aRMode { get; set; }
public int RankingId { get; set; }
public Dictionary<IRider,RiderRenderer> rideObjs = new Dictionary<IRider, RiderRenderer>();
protected override void Awake()
{
base.Awake();
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;
protected override void Update()
{
timer -= Time.deltaTime;
while (timer <= 0)
{
if (cyclingController == null)
return;
cyclingController.Run(null);
var onlineRiders = cyclingController.riders;
try
{
CreateOnlineUser(onlineRiders);
}
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)
{
if (list == null || list.Count == 0)
{
var currentList = FindObjectsOfType<RiderRenderer>();
foreach (var item in currentList)
{
item.Speed = 0;
item.Paused = true;
}
return;
}
var trainController = GetComponent<ARTrainingController>();
//移除退出的选手
var players = FindObjectsOfType<OnlineVideoPlayer>();
foreach (var item in players)
{
var currentItem = list.Where(c => c.UserId == item.UserId).FirstOrDefault();
if (currentItem == null)
{
rideObjs.Remove(item);
visibleRiders.Remove(item);
//trainController.RemoveRider(item.UserId);
}
}
var currentPlayerInfo = list.Where(c => c.IsSelf).FirstOrDefault();
var needUpdateList = list.OrderByDescending(c=>c.IsSelf).ToList();
foreach (var item in needUpdateList)
{
var onlineRider = item as OnlineRiderModel;
var visibleItem = visibleRiders.Where(c => c.UserId == item.UserId).FirstOrDefault();
//更新
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);
}
else
{
if (currentPlayerInfo == null)
return;
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<RiderRenderer>();
online.SetStartDistance(item.EndDistance);
rideObj.Distance = (float)online.StartDistance;
rideObj.RouteDistance = rideObj.Distance;
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);
}
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);
}
CurrentPlayer = videoPlayer.GetComponent<AbstractVideoPlayer>();
var vv = videoPlayer.GetComponent<VideoPlayer>();
vv.SetEndDistance(item.EndDistance);
CurrentPlayer.SetStartDistance(item.EndDistance);
var rideObj = videoPlayer.GetComponent<RiderRenderer>();
rideObj.Distance = (float)CurrentPlayer.StartDistance;
rideObj.RouteDistance = rideObj.Distance;
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;
var uimanager = FindObjectOfType<VideoUIManager>();
uimanager.SetCurrentMode(aRMode);
if (_aRMode != ARMode.INSPECT)
{
//InitCurrentPlayer();
Debug.Log("ContinueAsync");
ContinueAsync();
}
else
{
SetCyclingModel(CyclingModel.Single);
}
}
public GameObject videoPlayer;
public GameObject target;
//切换人物 TODO:替换写法
public void ChangePlayer(int userId)
{
var players = FindObjectsOfType<OnlineVideoPlayer>();
if (players != null)
{
CurrentPlayer = players.Where(c => c.UserId == userId).FirstOrDefault();
if (CurrentPlayer == null)
{
var onlineRiders = cyclingController.riders;
var currentPlayer = onlineRiders.Where(c => c.UserId == userId).FirstOrDefault();
if (currentPlayer != null)
{
var onlineRider = currentPlayer as OnlineRiderModel;
var obj = Instantiate(OnlinePlayer, transform);
var online = obj.GetComponent<OnlineVideoPlayer>();
online.SetPlayer(onlineRider.NickName, onlineRider.Speed,onlineRider.PreDistance, onlineRider.EndDistance, onlineRider.Cadence, onlineRider.HeartRate, 0, onlineRider.UserId, onlineRider.Power, onlineRider.EndDistance, onlineRider.FrameRate.Value);
CurrentPlayer = online;
}
var clearList = players.Where(c => c.UserId != userId);
foreach (var item in clearList)
{
item.Destroy();
}
}
}
}
//获取角色头顶信息预制件
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;
//mediaPlayer.Control.SeekToFrame(routeResult.LastFrame ?? 0);
}
}
//设置骑行模式
public void SetCyclingModel(CyclingModel mode)
{
//startTime = UIManager.Now.GetDateTime();
Debug.Log("SetCyclingModel" + mode.ToString());
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 IsReady()
{
return 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();
}
public float ratio = 111.676f;
public float startOffset = 0f;
//获取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 Save(double totalDistance)
{
Quit();
cyclingController.recorderData.EndTime = UIManager.Now.GetDateTime();
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();
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);
}
//截图
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);
screenShot.ReadPixels(rect, 0, 0);
screenShot.Apply();
camera.targetTexture = null;
RenderTexture.active = null;
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);
}
}
private void OnDestroy()
{
App.gameRoomDetail = null;
}
}
}