using GameCore; using asap.core; using UnityEngine; using UnityEngine.Playables; using System; using UniRx; using System.Threading.Tasks; public enum EBuildingType { UpgradeBuilding = 0, Pause = 1, Continue = 2, Next = 3, OpenFix = 4, CampPhoto = 5, } public class SwitchBuildingData { } public class OnUpgradeBuildingData { public OnUpgradeBuildingData(EBuildingType buildingType, bool CanContinue = true) { this.type = buildingType; this.CanContinue = CanContinue; } public EBuildingType type;//0-UpgradeBuilding;1-暂停;2-继续;3-下一步 (-1-打开修复) public bool CanContinue;//是否可以继续 public int TimelineId; public float StartTime; public float Duration; public float Speed = 1; public string NextPrefab; public string CurrentPrefab; } public class OnUpgradeBuildingFix { public TaskCompletionSource ts = new TaskCompletionSource(); } public class SwitchVirtualCameraEvent { public int type; public bool isDrag = true; } public class Building : MonoBehaviour { public PlayableDirector[] directors; public PlayableDirector fix; public PlayableDirector fade; public PlayableDirector enter; double _targetTime; PlayableDirector _currentDirector; private OnUpgradeBuildingData _upgradeBuildingData; private void Awake() { if (fix == null && transform.parent != null) { fix = transform.parent.Find("Fix")?.GetComponent(); } if (directors != null && directors.Length > 0) { for (int i = 0; i < directors.Length; i++) { var director = directors[i]; director.initialTime = 0; director.Evaluate(); } } } public void SetTimelineDone(int index) { if (index >= directors.Length) { Debug.LogError($"[Building::SetTimelineDone] index {index} is out of range, directors length is {directors.Length}"); index = directors.Length - 1; } var director = directors[index]; director.time = director.duration; director.initialTime = director.time; } public void SetTimelineAllDone() { for (int i = 0; i < directors.Length; i++) { var director = directors[i]; director.time = director.duration; director.initialTime = director.time; director.Evaluate(); } } public void SetCurrentTimeLine(int index, float startTime, float duration, bool evaluate) { if (index >= directors.Length) { Debug.LogError($"[Building::SetCurrentTimeLine] index {index} is out of range, directors length is {directors.Length}"); index = directors.Length - 1; } var director = directors[index]; if (!evaluate) { director.time = 0; director.initialTime = 0; } if (director.time >= startTime + duration) { return; } director.time = startTime; director.initialTime = startTime; _targetTime = startTime + duration; if (_targetTime > director.duration + 0.01f) { Debug.LogError($"[Building::SetCurrentTimeLine] _targetTime {startTime + duration} is greater than director duration {director.duration}, clamping to duration."); _targetTime = (float)director.duration; } if (evaluate) { director.Evaluate(); _currentDirector = director; } } public void EvaluateAllDrictors() { for (int i = 0; i < directors.Length; i++) { var director = directors[i]; director.Evaluate(); } } public void Show(CampDataMM campData) { if (_currentDirector != null) _currentDirector.Pause(); if (campData != null && campData.TimelineId >= 0 && campData.TimelineId < directors.Length) { _currentDirector = directors[campData.TimelineId]; } else { _currentDirector = directors[^1]; Debug.LogError($"[Building::Show] campData is null or TimelineId {campData?.TimelineId} is out of range, directors length is {directors.Length}"); } _currentDirector.gameObject.SetActive(true); _currentDirector.Evaluate(); // _currentDirector.time = campData.StepInfo.StartTime; // _currentDirector.initialTime = campData.StepInfo.StartTime; // _currentDirector.Evaluate(); // _targetTime = MathF.Min( // campData.StepInfo.StartTime + campData.StepInfo.PlayTime, // (float)_currentDirector.duration); // Debug.Log($"[Building::Show] director {_currentDirector.state} {_currentDirector.name} time {_currentDirector.time} {_targetTime}"); } public void ShowFix() { if (fix != null) { fix.initialTime = 0; fix.Evaluate(); fix.gameObject.SetActive(true); } else { Debug.LogError("fix is null"); } } public void OnUpgradeBuilding(OnUpgradeBuildingData data) { switch (data.type) { case EBuildingType.UpgradeBuilding: //Debug.Log($"[Building::OnUpgradeBuilding update] director {_currentDirector.state} {_currentDirector.name} time {_currentDirector.time} {_targetTime}"); _currentDirector.Play(); _currentDirector.playableGraph.GetRootPlayable(0).SetSpeed(data.Speed); _upgradeBuildingData = data; break; case EBuildingType.Pause: _currentDirector.Pause(); break; case EBuildingType.Continue: _currentDirector.Resume(); break; case EBuildingType.Next: OnNext(data.TimelineId, data.StartTime, data.Duration); break; #if UNITY_EDITOR case EBuildingType.OpenFix: ShowFix(); break; #endif default: break; } } private void OnNext(int TimelineId, float startTime, float duration) { SetCurrentTimeLine(TimelineId, startTime, duration, true); } public async void OnFix(OnUpgradeBuildingFix onUpgradeBuildingFix, Action onFixed) { if (fix) { fix.Play(); await Awaiters.Seconds((float)fix.duration); if (fix) { fix.Stop(); fix.gameObject.SetActive(false); } onFixed?.Invoke(); } } public double Fade() { if (fade == null) return 0; fade.time = 0; fade.initialTime = 0; _currentDirector = null; fade.Play(); return fade.duration; } public double Enter() { if (enter == null) return 0; enter.time = 0; enter.initialTime = 0; enter.Play(); return enter.duration; } //public double GetRestTime() //{ //if(_currentDirector == null) //return 0; //if(_currentDirector.state != PlayState.Playing) //return 0; //return _targetTime - _currentDirector.time; //} private void Update() { if (_currentDirector != null && _currentDirector.state == PlayState.Playing) { if (_targetTime - _currentDirector.time < 0.001f) { _currentDirector.Pause(); _currentDirector.time = _targetTime; if (_upgradeBuildingData != null) { _upgradeBuildingData.CanContinue = true; _upgradeBuildingData = null; } } } } }