using Cysharp.Threading.Tasks; using System; using TMPro; using UnityEngine; using UnityEngine.UI; using UVC.Extension; using UVC.UI; using UVC.UI.Loading; namespace UVC.Factory.Playback.UI { public class UIPlayback : MonoBehaviour { private static UIPlayback instance; public static UIPlayback Instance { get { if (instance == null) instance = CreateUIPlayBack(); return instance; } } private static UIPlayback CreateUIPlayBack() { GameObject prefab = Resources.Load("Prefabs/Factory/Playback/UIPlayback"); GameObject go = GameObject.Instantiate(prefab); return go.GetComponent(); } [SerializeField] [Tooltip("종료 버튼")] private Button exitButton; [SerializeField] [Tooltip("종료 버튼")] private TextMeshProUGUI dateTimeTxt0; [SerializeField] [Tooltip("종료 버튼")] private TextMeshProUGUI dateTimeTxt1; [SerializeField] [Tooltip("play 버튼")] private Button playButton; [SerializeField] [Tooltip("play 버튼 이미지")] private Image playButtonImage; [SerializeField] [Tooltip("play 버튼 이미지 Sprite")] private Sprite playButtonImagePlay; [SerializeField] [Tooltip("play 버튼 Puase 이미지 Sprite")] private Sprite playButtonImagePause; [SerializeField] [Tooltip("Speed Slider")] private UISliderWithLabel sliderSpeed; [SerializeField] [Tooltip("투명 조절 Slider")] private SliderWithEvent opacitySlider; [SerializeField] [Tooltip("Progress Bar")] private UIPlaybackProgressBar progressBar; [SerializeField] private CanvasGroup canvasGroup; [SerializeField] private UIDragger uiDragger; private bool isPlaying = false; private bool preparingData = false; private string date; private string time; private string fileName; private bool isTick = false; private bool IsTick { get => isTick; set { if (isTick != value) { var temp = isTick; isTick = value; if (!temp && value) OnTimer().Forget(); } } } private void Init() { exitButton.onClick.AddListener(OnClickExit); playButton.onClick.AddListener(OnClickPlay); progressBar.OnChangeValue += OnChangeProgress; sliderSpeed.OnChangeValue += OnChangeSpeed; opacitySlider.onValueChanged.AddListener(OnValueChangedOpcity); } private void OnDestroy() { exitButton.onClick.RemoveListener(OnClickExit); playButton.onClick.RemoveListener(OnClickPlay); progressBar.OnChangeValue = null; sliderSpeed.OnChangeValue = null; opacitySlider.onValueChanged.RemoveListener(OnValueChangedOpcity); if (isPlaying) IsTick = false; } public void Show() { if (playButton == null) Init(); gameObject.SetActive(true); if (transform.parent == null) { var canvases = GameObject.FindObjectsByType(FindObjectsSortMode.None); foreach (var canvas in canvases) { if (canvas.name == "ModalCanvas") { transform.SetParent(canvas.transform, false); uiDragger.SetDragArea(canvas.transform as RectTransform); break; } } } } public void Hide() { UpdateTimeScale(1); IsTick = false; gameObject.SetActive(false); } private void OnClickExit() { UILoading.Show(); isPlaying = false; UpdatePlayState(); Hide(); PlaybackService.Instance.Exit(); } private void OnClickPlay() { isPlaying = !isPlaying; UpdatePlayState(); } private void OnChangeProgress(int newValue) { ChangePlayTime().Forget(); } private void OnChangeSpeed(int newValue) { if (isPlaying) { //if (Time.timeScale != sliderSpeed.Value) UpdateTimeScale(sliderSpeed.Value); UpdateTimeScale(sliderSpeed.Value); } else { UpdateTimeScale(1); } } private void OnValueChangedOpcity(float newValue) { canvasGroup.alpha = opacitySlider.value; } private async UniTaskVoid ChangePlayTime() { bool tempIsPlaing = isPlaying; isPlaying = false; int newSecond = (int)progressBar.Value; if (newSecond == progressBar.MaxValue) { newSecond -= 60; progressBar.Value = newSecond; } preparingData = true; progressBar.Interactable = !preparingData; IsTick = false; UILoading.Show(); UpdatePlayState(); await UniTask.WaitForSeconds(0.5f); int minute = (int)newSecond / 60; int seconds = (int)newSecond % 60; await PlaybackService.Instance.DispatchBaseInfoData(date, time, fileName, minute.ToString("00"), seconds.ToString("00")); preparingData = false; progressBar.Interactable = !preparingData; if (isPlaying != tempIsPlaing) { isPlaying = tempIsPlaing; UpdatePlayState(); } UILoading.Hide(); await UniTask.WaitForSeconds(0.5f); } public async UniTask SetData(string date, string time, string fileName) { Init(); this.date = date; this.time = time; this.fileName = fileName; Debug.Log($"UIPlayback SetData {date} {time}"); int timeInt = int.Parse(time); dateTimeTxt0.text = dateTimeTxt1.text = date.Substring(2).Replace("-", "."); progressBar.Init(timeInt); sliderSpeed.Init(); UpdateTimeScale(1); canvasGroup.alpha = opacitySlider.value = 1; preparingData = true; progressBar.Interactable = !preparingData; isPlaying = false; UpdatePlayState(); await PlaybackService.Instance.DispatchBaseInfoData(date, time, fileName); preparingData = false; progressBar.Interactable = !preparingData; } private void UpdatePlayState() { playButton.enabled = false; progressBar.enabled = false; playButtonImage.sprite = isPlaying ? playButtonImagePause : playButtonImagePlay; IsTick = isPlaying; progressBar.enabled = true; playButton.enabled = true; OnChangeSpeed(sliderSpeed.Value); } private async UniTaskVoid OnTimer() { if (progressBar.Value == progressBar.MaxValue) { if (isPlaying) OnClickPlay(); return; } progressBar.Value += 1; //PlaybackService.Instance.DispatchingTimelineEvent = false; PlaybackService.Instance.DispatchRealTimeData(progressBar.Value, sliderSpeed.Value).Forget(); if (isTick) { //PlaybackService.Instance.DispatchingTimelineEvent = true; await UniTask.Delay(TimeSpan.FromMilliseconds(1000 / sliderSpeed.Value)); OnTimer().Forget(); } } private void UpdateTimeScale(float timeScale) { PlaybackService.Instance.TimeScale = timeScale; } } }