| | |
| | | public EffectConfig effectConfig; |
| | | |
| | | public Action<EffectPlayer> onDestroy; |
| | | public Action onComplete; |
| | | |
| | | public float speedRate = 1f; |
| | | |
| | | [Header("是否在显示时播放")] |
| | | public bool isPlayOnEnable = true; |
| | | |
| | | [Header("是否立即播放spine特效")] |
| | | public bool isPlaySpineImmediately = false; |
| | | [Header("是否循环播放spine特效")] |
| | | public bool isPlaySpineLoop = false; |
| | | |
| | | [HideInInspector] public Canvas canvas = null; |
| | | |
| | |
| | | protected List<Renderer> rendererList = new List<Renderer>(); |
| | | |
| | | protected SkeletonGraphic spineComp; |
| | | protected Spine.AnimationState spineAnimationState; |
| | | |
| | | protected void Start() |
| | | protected void OnEnable() |
| | | { |
| | | ReStart(); |
| | | if (isPlayOnEnable) |
| | | { |
| | | Play(); |
| | | } |
| | | } |
| | | |
| | | protected void InitCompnent() |
| | | protected bool InitCompnent() |
| | | { |
| | | if (effectId <= 0) |
| | | { |
| | | effectConfig = null; |
| | | Debug.LogError("EffectPlayer effectId is not set"); |
| | | #if UNITY_EDITOR |
| | | UnityEditor.Selection.activeGameObject = gameObject; |
| | | UnityEditor.EditorGUIUtility.PingObject(gameObject); |
| | | #endif |
| | | return; |
| | | // 根据逻辑需求,动态设置特效的情况 |
| | | // Debug.LogError("EffectPlayer effectId is not set"); |
| | | // #if UNITY_EDITOR |
| | | // UnityEditor.Selection.activeGameObject = gameObject; |
| | | // UnityEditor.EditorGUIUtility.PingObject(gameObject); |
| | | // #endif |
| | | return false; |
| | | } |
| | | |
| | | effectConfig = EffectConfig.Get(effectId); |
| | |
| | | UnityEditor.Selection.activeGameObject = gameObject; |
| | | UnityEditor.EditorGUIUtility.PingObject(gameObject); |
| | | #endif |
| | | return; |
| | | return false; |
| | | } |
| | | |
| | | |
| | |
| | | rendererList.Clear(); |
| | | spineComp = null; |
| | | |
| | | //spine是加载文件,需要提前挂载脚本,unity特效是已经做好的预制体待加载后收集组件 |
| | | if (effectConfig.isSpine != 0) |
| | | { |
| | | spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true); |
| | | spineComp = gameObject.AddMissingComponent<SkeletonGraphic>(); |
| | | |
| | | } |
| | | else |
| | | { |
| | | // 收集组件 |
| | | particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true)); |
| | | animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true)); |
| | | } |
| | | rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true)); |
| | | // else |
| | | // { |
| | | // // 收集组件 |
| | | // particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true)); |
| | | // animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true)); |
| | | // } |
| | | // rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true)); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | public void Stop() |
| | |
| | | { |
| | | if (!isInit) |
| | | { |
| | | if (InitCompnent()) |
| | | { |
| | | isInit = true; |
| | | InitCompnent(); |
| | | } |
| | | else |
| | | { |
| | | //根据逻辑需求,动态设置特效的情况 |
| | | return; |
| | | } |
| | | |
| | | } |
| | | |
| | | if (EffectMgr.Instance.IsNotShowBySetting(effectId)) |
| | |
| | | // YYL TODO |
| | | // 在这里考虑用池的话可能走配置好一点 原本的是无论如何都走池 但是实际上有些特效并不需要 |
| | | |
| | | // 加载特效资源 |
| | | // 加载spine特效资源 |
| | | if (effectConfig.isSpine != 0) |
| | | { |
| | | spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName + "_SkeletonData"); |
| | | spineComp.raycastTarget = false; |
| | | spineComp.Initialize(true); |
| | | spineAnimationState = spineComp.AnimationState; |
| | | spineAnimationState.Complete -= OnSpineAnimationComplete; |
| | | spineAnimationState.Complete += OnSpineAnimationComplete; |
| | | if (isPlaySpineImmediately) |
| | | { |
| | | //UI特效常用方式 |
| | | spineComp.enabled = true; |
| | | // 播放第一个动画(作为默认动画) |
| | | var skeletonData = spineComp.Skeleton.Data; |
| | | if (skeletonData.Animations.Count > 0) |
| | | { |
| | | string defaultAnimationName = skeletonData.Animations.Items[0].Name; |
| | | spineComp.AnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("Spine 数据中没有找到任何动画!" + effectConfig.id); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | spineComp.enabled = false; |
| | | } |
| | | |
| | | |
| | | return; |
| | | } |
| | | |
| | | //加载unity特效 |
| | | var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectConfig.packageName, effectConfig.fxName); |
| | | if (effectPrefab == null) |
| | | { |
| | |
| | | // 实例化特效 |
| | | effectTarget = Instantiate(effectPrefab, transform); |
| | | effectTarget.name = $"Effect_{effectConfig.fxName}"; |
| | | |
| | | //挂载组件后 开始收集 |
| | | particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true)); |
| | | animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true)); |
| | | rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true)); |
| | | |
| | | |
| | | // 思考一下在没有挂在节点的时候 |
| | | if (null == canvas) |
| | |
| | | onDestroy.Invoke(this); |
| | | onDestroy = null; |
| | | } |
| | | if (spineAnimationState != null) |
| | | { |
| | | spineAnimationState.Complete -= OnSpineAnimationComplete; |
| | | } |
| | | } |
| | | |
| | | //单次播放完毕就会触发,即使是循环 |
| | | protected void OnSpineAnimationComplete(Spine.TrackEntry trackEntry) |
| | | { |
| | | if (!isPlaySpineLoop) |
| | | { |
| | | if (onComplete == null) |
| | | { |
| | | if (effectConfig.isSpine != 0) |
| | | { |
| | | spineComp.enabled = false; |
| | | } |
| | | } |
| | | |
| | | onComplete?.Invoke(); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 创建后的特效会自动隐藏 需要手动调用Play才能播放 |
| | | public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false) |