466 lines
19 KiB
C#

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}");
});
}
}
}
}