NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Show/RaffleShowComponent.cs

249 lines
6.9 KiB
C#

using cfg.ShowCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay;
using PhxhSDK;
using Sirenix.OdinInspector;
using System;
using System.Collections.Generic;
using Gameplay.Emoji;
using UnityEngine;
using Constants = Framework.Constants;
using Object = UnityEngine.Object;
using cfg.CharacterCfg;
using Gameplay.Utils;
using UnityEngine.Playables;
/// <summary>
/// 抽卡演出组件
/// </summary>
public sealed class RaffleShowComponent : MonoBehaviour, IShow
{
#region 外部序列化字段
/// <summary>
/// 角色根节点
/// </summary>
[LabelText("角色根节点")]
[SerializeField]
private Transform tsCharacterRoot;
/// <summary>
/// 角色演出点根节点
/// </summary>
[LabelText("角色演出点根节点")]
[SerializeField]
private Transform tsCharacterShowPointRoot;
#endregion
/// <summary>
/// 角色动画
/// </summary>
private const string DEFAULT_ANIMATION = "standready001";
private readonly E_ShowSceneType showSceneTyp = E_ShowSceneType.Raffle;
/// <summary>
/// 当前场景所有演出点
/// </summary>
private List<Transform> listShowPoint;
/// <summary>
/// 角色模型字典
/// </summary>
private readonly Dictionary<int, GameObject> dicCharacterModel = new();
/// <summary>
/// 已经加载的资源集合
/// </summary>
private readonly HashSet<string> setAssetToUnload = new();
/// <summary>
/// 表情管理
/// </summary>
private readonly List<UnitEmojiManager> listCacheEmoji = new();
public E_ShowSceneType ShowSceneTyp
{
get { return showSceneTyp; }
}
#if UNITY_EDITOR
/// <summary>
/// 演出点根节点
/// </summary>
public Transform TsShowPointRoot
{
get { return tsCharacterShowPointRoot; }
}
#endif
private void Awake()
{
if (!CommonUtils.IsInGame())
return;
ShowManager.Instance.Add(this);
#region 获取演出点
if (tsCharacterShowPointRoot == null)
listShowPoint = new();
else
{
listShowPoint = new(tsCharacterShowPointRoot.childCount);
for (int i = 0; i < tsCharacterShowPointRoot.childCount; ++i)
{
listShowPoint.Add(tsCharacterShowPointRoot.GetChild(i));
}
}
#endregion
}
private void OnDestroy()
{
foreach (string path in setAssetToUnload)
{
AssetManager.Instance.Unload(path);
}
foreach (var unitEmojiManager in listCacheEmoji)
{
unitEmojiManager.Dispose();
}
}
public float GetRefreshProcess()
{
return 1f;
}
public void PlayeCameraAnim(Action callback, params string[] args)
{
}
public async UniTask RefreshShow(object data = null)
{
if (data is not List<DataCharacterAttri> listCharacterAttris)
return;
HashSet<int> setShowRoleId = new();
// 星高的排前面
listCharacterAttris.Sort((a, b) =>
{
if (null == a)
return 1;
if (null == b)
return -1;
return a.StartStar.CompareTo(b.StartStar);
});
#region 先禁用之前的模型
foreach (GameObject go in dicCharacterModel.Values)
{
go.SetActive(false);
}
#endregion
#region 设置要显示的模型位置
int i = 0;
foreach (DataCharacterAttri cfg in listCharacterAttris)
{
if (cfg == null)
continue;
GameObject goModel = await GetModel(cfg);
if (goModel == null)
continue;
if (setShowRoleId.Contains(cfg.RoleID)) // 重复角色不重复显示
continue;
setShowRoleId.Add(cfg.RoleID);
Transform tsPoint = listShowPoint[i];
goModel.transform.SetPositionAndRotation(tsPoint.position, tsPoint.rotation);
goModel.SetActive(true); // 先激活再设置动画
SetAnim(goModel);
++i;
}
#endregion
}
/// <summary>
/// 异步加载资源
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
private async UniTask<T> LoadAssetAsync<T>(string path) where T : Object
{
T res = await AssetManager.Instance.LoadAssetAsync<T>(path);
if (res != null)
setAssetToUnload.Add(path);
return res;
}
private UnitEmojiManager InitEmoji(GameObject go, DataCharacterAttri cfg)
{
DataCharacterSkin skinData = TableManager.Instance.Tables.SkinCfg.Get(Constants.DEFULT_SKINID, cfg.RoleID);
if (skinData == null)
{
DebugUtil.LogError($"找不到皮肤数据, skinID:{Constants.DEFULT_SKINID}, roleID:{cfg.RoleID}");
return null;
}
string eyebowsType = string.IsNullOrEmpty(cfg.EmojiEyeBowsType) ? "1" : cfg.EmojiEyeBowsType;
string eyesColor = string.IsNullOrEmpty(cfg.EmojiEyesColor) ? "#ff0000" : cfg.EmojiEyesColor;
string eyebowsColor = string.IsNullOrEmpty(cfg.EmojiEyeBowsColor) ? "#ff0000" : cfg.EmojiEyeBowsColor;
UnitEmojiManager unitEmojiManager = new(go, eyesColor, eyebowsType, eyebowsColor);
unitEmojiManager.SwitchEmoji(cfg.DefaultDisplayEmojiId);
return unitEmojiManager;
}
/// <summary>
/// 获取角色模型
/// </summary>
/// <param name="characterDataInfo"></param>
/// <returns></returns>
private async UniTask<GameObject> GetModel(DataCharacterAttri cfg)
{
if (!dicCharacterModel.TryGetValue(cfg.RoleID, out GameObject goModel))
{
string prefabPath = PathEx.GetCharacterDisplayModelPath(cfg.NameID);
goModel = await LoadAssetAsync<GameObject>(prefabPath);
if (goModel == null)
{
DebugUtil.LogError($"找不到模型, path:{prefabPath}");
return null;
}
goModel = Instantiate(goModel, tsCharacterRoot);
if (goModel.TryGetComponent(out PlayableDirector playableDirector))
playableDirector.enabled = false;
goModel.SetLayerEx(Constants.Layer.UIVIEW);
goModel.transform.localScale = new Vector3(8f, 8f, 8f);
UnitEmojiManager unitEmojiManager = InitEmoji(goModel, cfg);
if (unitEmojiManager != null)
listCacheEmoji.Add(unitEmojiManager); // 缓存起来
dicCharacterModel.Add(cfg.RoleID, goModel);
}
return goModel;
}
/// <summary>
/// 设置角色动画
/// </summary>
/// <param name="goRole"></param>
private void SetAnim(GameObject goRole)
{
Animator animator = goRole.GetComponentInChildren<Animator>();
if (animator == null)
return;
animator.Play(DEFAULT_ANIMATION);
}
}