using System.Collections.Generic; using System.Linq; using Cysharp.Threading.Tasks; using Gameplay; using PhxhSDK; using UnityEngine; using UnityEngine.Playables; using UnityEngine.SceneManagement; using UnityEngine.Timeline; using Framework; using Gameplay.Common; using Gameplay.Emoji; using Gameplay.Level; using Constants = Framework.Constants; using YooAsset; public class FightWinComponent: MonoBehaviour { private Scene _scene; private List _characterIDs; private uint _vehicleID; private GameObject _objRoot; private List _posTransList; private Camera _camera; private PlayableDirector _timelinePlayable; private Dictionary _needToRelease; private List _emojiMgrList = new List(); private TimelineClip _cacheTimelineClip; //test private List _testObjs = new List(); private readonly int Vehicle_Model_Index = 5; #region Unity EventFunction private void Awake() { _SetData(); _camera = GameObject.Find("CameraRoot").GetComponent().Camera; _objRoot = GameObject.Find("Content/ObjRoot"); var posRootTrans = GameObject.Find("Content/PosRoot").transform; _posTransList = new List(); for (int i = 0; i < posRootTrans.childCount; i++) { var child = posRootTrans.GetChild(i); _posTransList.Add(child); } EventManager.Instance.Register(EventManager.EventName.FightCmpTimelinePause, _OnPauseEvent); _needToRelease = new Dictionary(); _Load(); } private void OnDestroy() { EventManager.Instance.Unregister(EventManager.EventName.FightCmpTimelinePause, _OnPauseEvent); foreach (var emojiMgr in _emojiMgrList) { emojiMgr.Dispose(); } _emojiMgrList.Clear(); foreach (var path in _needToRelease) { //handle.Release(); } } #endregion private void _SetData() { SetData(LevelManager.Instance.ShowCharIDs, LevelManager.Instance.ShowVehicleID); } private async void _Load() { await _LoadModels(); await _LoadTimeline(); await UniTask.DelayFrame(1); _timelinePlayable.Play(); } private void _OnPauseEvent() { if (_timelinePlayable) { _timelinePlayable.Pause(); } } private async UniTask _LoadModels() { if (_characterIDs != null) { for (int i = 0; i < _characterIDs.Count; i++) { await _AddCharacterModel(_characterIDs[i], i); } } if (_vehicleID != Constants.INVALID_UINT_ID) { await _AddVehicleModel(_vehicleID); } } private async UniTask _AddCharacterModel(uint uid, int idx) { var modelPath = CommonUtils.GetCharacterShowModelPath(uid); if (modelPath != null) { var prefab = await AssetManager.Instance.LoadAssetAsync(modelPath); var model = Instantiate(prefab, _objRoot.transform); var posTrans = _posTransList[idx]; model.transform.SetPositionAndRotation(posTrans.position, posTrans.rotation); model.transform.localScale = posTrans.localScale; model.SetLayerEx(LayerDefine.TeamEdit); var charDataCfg = TableManager.Instance.Tables.CharacterAttri; if (charDataCfg.DataMap.TryGetValue((int)uid, out var charSingleData)) { var emojiMgr = new UnitEmojiManager(model, charSingleData.EmojiEyesColor, charSingleData.EmojiEyeBowsType, charSingleData.EmojiEyeBowsColor); emojiMgr.SwitchEmoji(charSingleData.DefaultDisplayEmojiId); _emojiMgrList.Add(emojiMgr); } } } private async UniTask _AddVehicleModel(uint uid) { var modelPath = CommonUtils.GetVehicleShowModelPath(uid); if (modelPath != null) { var prefab = await AssetManager.Instance.LoadAssetAsync(modelPath); var model = Instantiate(prefab, _objRoot.transform); var posTrans = _posTransList[Vehicle_Model_Index]; model.transform.SetPositionAndRotation(posTrans.position, posTrans.rotation); model.transform.localScale = posTrans.localScale; model.SetLayerEx(LayerDefine.TeamEdit); } } private async UniTask _LoadTimeline() { var timeLineObj = new GameObject("GameTimeLine"); timeLineObj.transform.SetParent(transform); timeLineObj.SetLayerEx(LayerDefine.TeamEdit); var timeline = timeLineObj.AddComponent(); var timeLineAsset = ScriptableObject.CreateInstance();//playable as TimelineAsset; if (!timeLineAsset) { DebugUtil.LogError("加载的TimeLine资源为空!!!"); return; } timeline.playableAsset = timeLineAsset; timeline.timeUpdateMode = DirectorUpdateMode.GameTime; timeline.playOnAwake = false; _timelinePlayable = timeline; //新建轨道 for (int i = 0; i < 5; i++) { if (i >= _characterIDs.Count) { break; } var child = _objRoot.transform.GetChild(i); if (!child) { continue; } var track = timeLineAsset.CreateTrack(); var animObj = child.GetChild(0).gameObject; var anim = animObj.GetComponent(); if (!anim) { DebugUtil.LogError("TimeLine使用的模型未绑定Animator组件!!!"); } timeline.SetGenericBinding(track, anim); anim.cullingMode = AnimatorCullingMode.AlwaysAnimate; } var trackCamera = timeLineAsset.CreateTrack(); var animCamera = _camera.GetComponent(); if (animCamera) { timeline.SetGenericBinding(trackCamera, animCamera); animCamera.cullingMode = AnimatorCullingMode.AlwaysAnimate; } var trackIEnumerable = timeLineAsset.GetOutputTracks(); int index = 0; var cameraAnimPath = "Assets/Art/Animations/Level/VictoryCameraAnimation.anim"; foreach (var trackAsset in trackIEnumerable) { var animTrackAsset = trackAsset as AnimationTrack; if (index < _characterIDs.Count) { var animPaths = GetAnimPaths(_characterIDs[index], index == 0); List animClips = new List(); var animClip1 = await AssetManager.Instance.LoadAssetAsync(animPaths[0]); var animClip2 = await AssetManager.Instance.LoadAssetAsync(animPaths[1]); _needToRelease.TryAdd(animPaths[0], true); _needToRelease.TryAdd(animPaths[1], true); animClips.Add(animClip1); animClips.Add(animClip2); if (animTrackAsset) { if (index == 0) { var clip0 = animTrackAsset.CreateClip(animClips[0]); clip0.start = 2.516667;//capClipInfo[0].Item1; clip0.duration = 5.683333;//capClipInfo[0].Item2; clip0.blendOutDuration = 0.683333; var clip1 = animTrackAsset.CreateClip(animClips[1]); clip1.blendInDuration = 0.683333; clip1.start = 7.516667;//capClipInfo[1].Item1; clip1.duration = 4.6; //capClipInfo[1].Item2; } else { var clip0 = animTrackAsset.CreateClip(animClips[0]); clip0.start = 0;//teamClipInfo[0].Item1; clip0.duration = 5.683333;//teamClipInfo[0].Item2; clip0.blendOutDuration = 0.683333; var clip1 = animTrackAsset.CreateClip(animClips[1]); clip1.blendInDuration = 0.683333; clip1.start = 5;//teamClipInfo[1].Item1; clip1.duration = 4.6; //teamClipInfo[1].Item2; } } } else if(index == _characterIDs.Count) { var cameraClip = await AssetManager.Instance.LoadAssetAsync(cameraAnimPath); if (animTrackAsset) { animTrackAsset.trackOffset = TrackOffset.ApplyTransformOffsets; var clip = animTrackAsset.CreateClip(cameraClip); var animAsset = clip.asset as AnimationPlayableAsset; if (animAsset) { animAsset.removeStartOffset = false; animAsset.useTrackMatchFields = false; animAsset.matchTargetFields = MatchTargetFields.PositionX | MatchTargetFields.PositionY | MatchTargetFields.PositionZ | MatchTargetFields.RotationX | MatchTargetFields.RotationY | MatchTargetFields.RotationZ; animAsset.ResetOffsets(); } clip.asset = animAsset; clip.start = 0; _cacheTimelineClip = clip; } break; } index++; _timelinePlayable.RebindPlayableGraphOutputs(); await UniTask.DelayFrame(1); } } private List GetAnimPaths(uint charID, bool isCaptain = false) { List retAnimClips = new List(); var cfg = CharacterDataInfoManager.Instance.DataDic[charID].Cfg; var weaponID = cfg.WeaponId; var weaponCfg = TableManager.Instance.Tables.WeaponConfig.GetOrDefault(weaponID); if (weaponCfg == null) { weaponCfg = TableManager.Instance.Tables.WeaponConfig.GetOrDefault(1); } string fbxPath; if (isCaptain) { fbxPath = weaponCfg.SettleCapAnimPath; } else { fbxPath = weaponCfg.SettleTeamAnimPath; } retAnimClips.Add(fbxPath + ".anim"); retAnimClips.Add(fbxPath + "_idle.anim"); return retAnimClips; } #region API public void SetData(List charIDList) { _characterIDs = charIDList; } public void SetData(uint vehicleID) { _vehicleID = vehicleID; } public void SetData(List charIDList, uint vehicleID) { _characterIDs = charIDList; _vehicleID = vehicleID; } public void StartPlay() { _timelinePlayable.Play(); } #endregion }