powerfun-unity/Assets/Scripts/Scenes/AR/VideoGameManager.cs
2023-05-15 15:11:50 +08:00

493 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
//解决当前用户setActivefalse时仍能计算数据
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,
}
}
}