353 lines
12 KiB
C#
353 lines
12 KiB
C#
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<uint> _characterIDs;
|
||
private List<uint> _vehicleIDs;
|
||
private GameObject _objRoot;
|
||
private List<Transform> _posTransList;
|
||
|
||
private Camera _camera;
|
||
private PlayableDirector _timelinePlayable;
|
||
private Dictionary<string, bool> _needToRelease;
|
||
private List<UnitEmojiManager> _emojiMgrList = new List<UnitEmojiManager>();
|
||
|
||
private TimelineClip _cacheTimelineClip;
|
||
|
||
//test
|
||
private List<GameObject> _testObjs = new List<GameObject>();
|
||
|
||
private readonly int vehicleStartIndex = 7; //第七位开始算,载具的位置起始点
|
||
private readonly int Vehicle_Model_Index = 5;
|
||
|
||
#region Unity EventFunction
|
||
private void Awake()
|
||
{
|
||
_SetData();
|
||
_camera = GameObject.Find("CameraRoot").GetComponent<CameraRoot>().Camera;
|
||
_objRoot = GameObject.Find("Content/ObjRoot");
|
||
var posRootTrans = GameObject.Find("Content/PosRoot").transform;
|
||
_posTransList = new List<Transform>();
|
||
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<string, bool>();
|
||
_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();
|
||
}
|
||
|
||
//_timelinePlayable.stopped -= OnPlayableStopped;
|
||
}
|
||
|
||
#endregion
|
||
|
||
private void _SetData()
|
||
{
|
||
SetData(LevelManager.Instance.ShowCharIDs, LevelManager.Instance.ShowVehicleID);
|
||
}
|
||
|
||
private async void _Load()
|
||
{
|
||
await _LoadModels();
|
||
await _LoadTimeline();
|
||
await UniTask.DelayFrame(1);
|
||
_timelinePlayable.extrapolationMode = DirectorWrapMode.Hold;
|
||
_timelinePlayable.Play();
|
||
//_timelinePlayable.stopped += OnPlayableStopped;
|
||
}
|
||
|
||
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 (_vehicleIDs != null)
|
||
{
|
||
await _AddVehicleModel(_vehicleIDs);
|
||
}
|
||
|
||
}
|
||
|
||
private async UniTask _AddCharacterModel(uint uid, int idx)
|
||
{
|
||
var modelPath = CommonUtils.GetCharacterShowModelPath(uid);
|
||
if (modelPath != null)
|
||
{
|
||
var prefab = await AssetManager.Instance.LoadAssetAsync<GameObject>(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(List<uint> vehicleIDs)
|
||
{
|
||
for (int i = 0; i < vehicleIDs.Count; i++)
|
||
{
|
||
var vehicleID = vehicleIDs[i];
|
||
var modelPath = CommonUtils.GetVehicleShowModelPath(vehicleID);
|
||
if (modelPath != null)
|
||
{
|
||
var prefab = await AssetManager.Instance.LoadAssetAsync<GameObject>(modelPath);
|
||
var model = Instantiate(prefab, _objRoot.transform);
|
||
var posTrans = _posTransList[vehicleStartIndex + i];
|
||
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<PlayableDirector>();
|
||
|
||
var timeLineAsset = ScriptableObject.CreateInstance<TimelineAsset>();//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 < _characterIDs.Count; i++)
|
||
{
|
||
// if (i >= _characterIDs.Count)
|
||
// {
|
||
// break;
|
||
// }
|
||
var child = _objRoot.transform.GetChild(i);
|
||
if (!child)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
var track = timeLineAsset.CreateTrack<AnimationTrack>();
|
||
var animObj = child.GetChild(0).gameObject;
|
||
|
||
var anim = animObj.GetComponent<Animator>();
|
||
if (!anim)
|
||
{
|
||
DebugUtil.LogError("TimeLine使用的模型未绑定Animator组件!!!");
|
||
}
|
||
timeline.SetGenericBinding(track, anim);
|
||
anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||
}
|
||
var trackCamera = timeLineAsset.CreateTrack<AnimationTrack>();
|
||
var animCamera = _camera.GetComponent<Animator>();
|
||
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<AnimationClip> animClips = new List<AnimationClip>();
|
||
var animClip1 = await AssetManager.Instance.LoadAssetAsync<AnimationClip>(animPaths[0]);
|
||
var animClip2 = await AssetManager.Instance.LoadAssetAsync<AnimationClip>(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<AnimationClip>(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<string> GetAnimPaths(uint charID, bool isCaptain = false)
|
||
{
|
||
List<string> retAnimClips = new List<string>();
|
||
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;
|
||
}
|
||
|
||
private void OnPlayableStopped(PlayableDirector playable)
|
||
{
|
||
for (int i = 0; i < _objRoot.transform.childCount; i++)
|
||
{
|
||
var trans = _objRoot.transform.GetChild(i);
|
||
if (trans.gameObject.name.Contains("P_S"))
|
||
{
|
||
var anim = trans.GetChild(0).GetComponent<Animator>();
|
||
if (anim)
|
||
{
|
||
anim.Play("standready001");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#region API
|
||
|
||
public void SetData(List<uint> charIDList)
|
||
{
|
||
_characterIDs = charIDList;
|
||
}
|
||
|
||
|
||
public void SetData(List<uint> charIDList, List<uint> vehicleIDs)
|
||
{
|
||
_characterIDs = charIDList;
|
||
_vehicleIDs = vehicleIDs;
|
||
}
|
||
|
||
public void StartPlay()
|
||
{
|
||
_timelinePlayable.Play();
|
||
}
|
||
#endregion
|
||
} |