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; using Sirenix.Utilities; /// /// 抽卡演出组件 /// public sealed class RaffleShowComponent : MonoBehaviour, IShow { #region 外部序列化字段 /// /// 角色根节点 /// [LabelText("角色根节点")] [SerializeField] private Transform tsCharacterRoot; /// /// 角色演出点根节点 /// [LabelText("角色演出点根节点")] [SerializeField] private Transform tsCharacterShowPointRoot; #endregion /// /// 角色动画 /// private readonly string[] animationNames = { "standready001", "squatready001", "standready002" }; private readonly E_ShowSceneType showSceneTyp = E_ShowSceneType.Raffle; /// /// 当前场景所有演出点 /// private List listShowPoint; /// /// 角色模型字典 /// private readonly Dictionary dicCharacterModel = new(); /// /// 已经加载的资源集合 /// private readonly HashSet setAssetToUnload = new(); /// /// 表情管理 /// private readonly List listCacheEmoji = new(); public E_ShowSceneType ShowSceneTyp { get { return showSceneTyp; } } #if UNITY_EDITOR /// /// 演出点根节点 /// 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 listCharacterAttris) return; HashSet setShowRoleId = new(); List listCfg = new(listCharacterAttris); // 星高的排前面 listCfg.Sort((a, b) => { if (null == a) return 0; if (null == b) return 0; 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 listCfg) { 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 } /// /// 异步加载资源 /// /// /// /// private async UniTask LoadAssetAsync(string path) where T : Object { T res = await AssetManager.Instance.LoadAssetAsync(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; } /// /// 获取角色模型 /// /// /// private async UniTask GetModel(DataCharacterAttri cfg) { if (!dicCharacterModel.TryGetValue(cfg.RoleID, out GameObject goModel)) { string prefabPath = PathEx.GetCharacterDisplayModelPath(cfg.NameID); goModel = await LoadAssetAsync(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; } /// /// 设置角色动画 /// /// private void SetAnim(GameObject goRole) { Animator animator = goRole.GetComponentInChildren(); if (null == animator) return; string animName = CommonUtils.GetRandomItem(animationNames); animator.Play(animName); } }