From 871594462e82d6bc1341918d39e11ab036d59563 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 18 九月 2025 19:26:28 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.1.20:10010/r/Project_SG_scripts
---
Main/Component/UI/Effect/EffectPlayer.cs | 516 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 422 insertions(+), 94 deletions(-)
diff --git a/Main/Component/UI/Effect/EffectPlayer.cs b/Main/Component/UI/Effect/EffectPlayer.cs
index cc2211a..ceeddc6 100644
--- a/Main/Component/UI/Effect/EffectPlayer.cs
+++ b/Main/Component/UI/Effect/EffectPlayer.cs
@@ -4,14 +4,53 @@
using Spine.Unity;
using UnityEngine;
using Spine;
+using UnityEngine.UI;
+using Cysharp.Threading.Tasks;
+// 鐗规晥鎾斁鍣紝棰勫埗浣撳璞℃睜绠$悊锛寀nity鐨勯鍒朵綋姹犱娇鐢ㄦ湁闂锛�1涓壒鏁�1涓睜浣嗗鐢ㄥ張浣庯級鍚庣画淇敼
+// unity鐗规晥銆婇鍒朵綋銆嬫槸鐗规晥甯堝湪鍒朵綔鐨勬椂鍊欑敓鎴愮殑涓嶅悓棰勫埗浣擄紝unity鐗规晥蹇呴』鎸傝浇璁剧疆鎾斁鏃堕暱鑴氭湰 EffectTime
+// spine鐗规晥鏄壒鏁堝笀鍒朵綔鐨勫姩鐢绘枃浠讹紝鍙叡鍚屽鐢ㄤ竴涓�婇鍒朵綋銆�
public class EffectPlayer : MonoBehaviour
{
- public int effectId;
+ [SerializeField]
+ private int m_EffectID;
+ public int effectId
+ {
+ get
+ {
+ return m_EffectID;
+ }
+ set
+ {
+ if (value != m_EffectID)
+ {
+ Stop();
+ isInit = false;
+ m_EffectID = value;
+ }
+ }
+ }
- public bool autoDestroy = false;
- public float destroyDelay = 0f;
+
+ public EffectConfig effectConfig;
+
+ public float speedRate = 1f;
+
+ [Header("鏄惁寰幆鎾斁spine鐗规晥")]
+ public bool isPlaySpineLoop = false;
+
+ [Header("鏄惁鍦ㄦ樉绀烘椂鎾斁")]
+ public bool isPlayOnEnable = false;
+
+ [Header("寤惰繜鎾斁(姣)")]
+ public int playDelayTime = 0;
+
+ public int playSpineAnimIndex = -1; //鎾斁spine鐗规晥鍔ㄧ敾绱㈠紩,浠g爜鎺у埗
+
+
+ [Header("鎾斁瀹屾瘯绔嬪嵆鍥炴敹")]
+ public bool isReleaseImmediately = false; //鐣岄潰鐗规晥涓�鑸笉闇�瑕佽嚜鎴戦攢姣侊紝璺熼殢鐣岄潰鎴栬�呯埗瀵硅薄閿�姣佸氨琛�
public Action<EffectPlayer> onDestroy;
@@ -21,102 +60,328 @@
protected EffectPenetrationBlocker blocker = null;
- protected void Start()
- {
- ReStart();
- }
+ protected bool isInit = false;
+ protected bool isPlaying = false;
- public void Stop()
+ protected List<ParticleSystem> particleList = new List<ParticleSystem>();
+
+ protected List<Animator> animatorList = new List<Animator>();
+
+ protected List<Renderer> rendererList = new List<Renderer>();
+
+ protected SkeletonGraphic spineComp;
+ protected Spine.AnimationState spineAnimationState;
+
+ public GameObjectPoolManager.GameObjectPool pool;
+
+ public Action onComplete;
+
+ protected virtual void OnEnable()
{
- if (null != effectTarget)
+
+ if (isPlayOnEnable)
{
- DestroyImmediate(effectTarget);
- effectTarget = null;
+ Play(false);
+ }
+ else if (spineComp != null)
+ {
+ if (!isPlaying)
+ {
+ //闅愯棌锛屼細鏈夐潤鎬佹樉绀洪棶棰�
+ spineComp.enabled = false;
+ }
}
}
- public void Play()
+ protected void InitComponent(bool showLog = true)
{
- if (!isActiveAndEnabled)
+ if (effectId <= 0)
{
- gameObject.SetActive(true);
- }
- ReStart();
- }
-
-
- protected void ReStart()
- {
- if (EffectMgr.Instance.IsNotShowBySetting(effectId))
- {
+ effectConfig = null;
+#if UNITY_EDITOR
+ if (showLog)
+ {
+ Debug.LogError("EffectPlayer effectId is not set");
+ UnityEditor.Selection.activeGameObject = gameObject;
+ UnityEditor.EditorGUIUtility.PingObject(gameObject);
+ }
+#endif
return;
}
- if (null != effectTarget)
- {
- DestroyImmediate(effectTarget);
- effectTarget = null;
- }
+ effectConfig = EffectConfig.Get(effectId);
- EffectConfig effectCfg = EffectConfig.Get(effectId);
-
- if (null == effectCfg)
+ if (null == effectConfig)
{
+#if UNITY_EDITOR
+ Debug.LogError("could not find effect config, effect id is " + effectId);
+ UnityEditor.Selection.activeGameObject = gameObject;
+ UnityEditor.EditorGUIUtility.PingObject(gameObject);
+#endif
return;
}
- // YYL TODO
- // 鍦ㄨ繖閲岃�冭檻鐢ㄦ睜鐨勮瘽鍙兘璧伴厤缃ソ涓�鐐� 鍘熸湰鐨勬槸鏃犺濡備綍閮借蛋姹� 浣嗘槸瀹為檯涓婃湁浜涚壒鏁堝苟涓嶉渶瑕�
+ Clear();
+ return;
+ }
- // 鍔犺浇鐗规晥璧勬簮
- var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectCfg.packageName, effectCfg.fxName);
+ protected virtual void Clear()
+ {
+ isInit = false;
+ particleList.Clear();
+ animatorList.Clear();
+ rendererList.Clear();
+
+ if (spineComp != null)
+ {
+ spineComp.skeletonDataAsset = null;
+ // spineComp.Initialize(false);
+ spineComp.Clear();
+ }
+
+ spineComp = null;
+ }
+
+ public virtual void Stop()
+ {
+ if (null != effectTarget)
+ {
+ // 濡傛灉浣跨敤浜嗙壒鏁堥鍒朵綋姹狅紝鍒欏綊杩樺埌姹犱腑
+ if (pool != null)
+ {
+ pool.Release(effectTarget);
+ }
+ effectTarget = null;
+ }
+ if (spineComp != null)
+ {
+ spineComp.enabled = false;
+ }
+ isPlaying = false;
+ playSpineAnimIndex = -1;
+ }
+
+ protected void Release()
+ {
+ Stop();
+
+ Clear();
+ }
+
+ public virtual void Play(bool showLog = true, bool closePMA = false)
+ {
+ isPlaying = true;
+ if (!isInit)
+ {
+ InitComponent(showLog);
+ //effeid 涓�0涔熷垵濮嬪寲鎴愬姛锛岄伩鍏嶉噸澶嶅鐞嗭紝鍦ㄥ彉鏇磂ffectid鏃朵細閲嶆柊鍒濆鍖�
+ isInit = true;
+ }
+ else
+ {
+ //閬垮厤閲嶅鍒涘缓
+ if (!this.gameObject.activeSelf)
+ {
+ this.gameObject.SetActive(true);
+ }
+ //闃茶寖effeid 涓�0
+ if (effectConfig != null && effectConfig.isSpine != 0)
+ {
+ PlaySpineEffect(closePMA);
+ }
+ return;
+ }
+ if (effectConfig == null)
+ return;
+
+ if (EffectMgr.IsNotShowBySetting(effectId))
+ {
+ return;
+ }
+
+ if (null != effectTarget)
+ {
+ if (pool != null)
+ pool.Release(effectTarget);
+ effectTarget = null;
+ }
+
+ if (!this.gameObject.activeSelf)
+ {
+ this.gameObject.SetActive(true);
+ }
+
+ // 鍔犺浇spine鐗规晥璧勬簮
+ if (effectConfig.isSpine != 0)
+ {
+ PlaySpineEffect(closePMA);
+ }
+ else
+ {
+ PlayerEffect();
+ }
+
+ SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
+
+ }
+
+
+ // protected virtual void PlaySpineEffect()
+ // {
+ // spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true);
+ // spineComp.raycastTarget = false;
+ // spineComp.Initialize(true);
+ // spineAnimationState = spineComp.AnimationState;
+ // spineAnimationState.Complete -= OnSpineAnimationComplete;
+ // spineAnimationState.Complete += OnSpineAnimationComplete;
+
+ // // 澶栧眰鎺у埗鍏蜂綋鎾斁鍝釜鍔ㄧ敾
+ // spineComp.enabled = true;
+
+ // return;
+ // }
+
+
+
+ protected void PlaySpineEffect(bool closePMA = false)
+ {
+
+ // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
+ if (spineComp == null)
+ {
+ spineComp = gameObject.AddMissingComponent<SkeletonGraphic>();
+ }
+
+ if (spineComp.skeletonDataAsset == null || spineAnimationState == null)
+ {
+ //LoadAsset 宸茬粡鏈夌紦瀛楽keletonDataAsset
+ spineComp.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
+ spineComp.MeshGenerator.settings.pmaVertexColors = !closePMA; //涓簍rue鏃朵細鏈夐儴鍒嗙壒鏁堜笉鏄剧ず 濡備富鐣岄潰瑁呭鐗规晥
+ spineComp.raycastTarget = false;
+ spineComp.Initialize(true);
+ spineComp.timeScale = speedRate;
+ // 妫�鏌ュ姩鐢绘槸鍚︽湁鐩稿姞妯″紡
+ // bool hasAdditiveBlend = CheckForAdditiveBlend(spineComp.Skeleton);
+ // if (hasAdditiveBlend)
+ // {
+ // spineComp.material = ResManager.Instance.LoadAsset<Material>("UIEffect/" + effectConfig.packageName, effectConfig.fxName.Split('_')[0] + "_Material-Additive");
+ // }
+ // else
+ // {
+ // spineComp.material = null;
+ // }
+ spineComp.material = ResManager.Instance.LoadAsset<Material>("Materials", "SkeletonGraphicDefault-Straight");
+
+ spineAnimationState = spineComp.AnimationState;
+ spineAnimationState.Data.DefaultMix = 0f;
+ spineAnimationState.Complete -= OnSpineAnimationComplete;
+ spineAnimationState.Complete += OnSpineAnimationComplete;
+ }
+
+ spineComp.enabled = true;
+ PlayerTheSpineAnim();
+ }
+
+ // 鎾斁鎸囧畾鍔ㄧ敾
+ void PlayerTheSpineAnim()
+ {
+ spineComp.enabled = true;
+ var skeletonData = spineComp.Skeleton.Data;
+ if (skeletonData.Animations.Count > 0)
+ {
+ //鎸夐厤缃垨鑰呴粯璁ょ涓�涓�
+ int defaultAnimIndex = Math.Max(0, effectConfig.animIndex.Length == 0 ? 0 : effectConfig.animIndex[0]);
+ if (playSpineAnimIndex >= skeletonData.Animations.Count)
+ {
+ playSpineAnimIndex = -1;
+ Debug.LogError("鐗规晥锛�" + effectConfig.id + " 绱㈠紩瓒呭嚭鎾斁榛樿鍔ㄧ敾銆� error锛�" + playSpineAnimIndex);
+ }
+ string defaultAnimationName = skeletonData.Animations.Items[playSpineAnimIndex == -1 ? defaultAnimIndex : playSpineAnimIndex].Name;
+ spineAnimationState.SetAnimation(0, defaultAnimationName, isPlaySpineLoop);
+ }
+ else
+ {
+ Debug.LogError("Spine 鏁版嵁涓病鏈夋壘鍒颁换浣曞姩鐢伙紒" + effectConfig.id);
+ }
+ }
+
+
+ private bool CheckForAdditiveBlend(Spine.Skeleton skeleton)
+ {
+ // 閬嶅巻鎵�鏈夋彃妲斤紝妫�鏌ユ槸鍚︽湁鐩稿姞妯″紡
+ foreach (var slot in skeleton.Slots)
+ {
+ if (slot.Data.BlendMode == Spine.BlendMode.Additive)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ //unity鐗规晥
+ protected virtual void PlayerEffect()
+ {
+ var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
if (effectPrefab == null)
{
- Debug.LogError($"鍔犺浇UI鐗规晥澶辫触: {effectCfg.packageName}");
+ Debug.LogError($"鍔犺浇UI鐗规晥澶辫触: {effectConfig.packageName}");
return;
}
- // 瀹炰緥鍖栫壒鏁�
- effectTarget = Instantiate(effectPrefab, transform);
- effectTarget.name = $"Effect_{effectCfg.fxName}";
+ if (effectConfig.isSpine == 0)
+ {
+ //unity鐗规晥 鍒ゆ柇棰勫埗浣撴槸鍚︽寕杞紼ffectTime
+ var timeObj = effectPrefab.GetComponent<EffectTime>();
+ if (null == timeObj)
+ {
+ Debug.LogError($"{effectPrefab.name}棰勫埗浣撴病鏈夋寕杞紼ffectTime");
+ return;
+ }
+ }
+
+ // 浠庣壒鏁堥鍒朵綋姹犺幏鍙栫壒鏁�
+ pool = GameObjectPoolManager.Instance.RequestPool(effectPrefab);
+ effectTarget = pool.Request();
+ // 璁剧疆鐖惰妭鐐瑰拰浣嶇疆
+ effectTarget.transform.SetParent(transform);
+ effectTarget.transform.localPosition = Vector3.zero;
+ effectTarget.transform.localScale = Vector3.one;
+ effectTarget.transform.localRotation = Quaternion.identity;
+ effectTarget.name = $"Effect_{effectConfig.fxName}";
+
+
+ //鎸傝浇缁勪欢鍚� 寮�濮嬫敹闆�
+ particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
+ animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
+ rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
+ OnUnityAnimationComplete();
+
if (null == canvas)
canvas = GetComponentInParent<Canvas>();
- if (null == canvas)
- {
- Debug.LogError("can not find canvas for UIEffect " + effectId);
- return;
- }
-
// 娣诲姞鐗规晥绌块�忛樆鎸″櫒
blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>();
- blocker.parentCanvas = canvas;
- // 寤惰繜涓�甯ф墠鐢熸晥
- this.DelayFrame(blocker.UpdateSortingOrder);
-
- // blocker.UpdateSortingOrder();
-
- // 鑷姩閿�姣�
- if (autoDestroy)
+ // 濡傛灉娌℃湁canvas鐨勮瘽 姝e父鏄洜涓轰笉鍦˙attleWin涓嬮潰鐨勮妭鐐� 鎰忔�濆氨鏄綋鍓嶆病鏈夋樉绀� 绛夊埌鍒囧洖鎴樻枟鐨勬椂鍊欏啀閫氳繃BattleField.UpdateCanvas鏉ユ洿鏂�
+ if (canvas != null)
{
- Destroy(effectTarget, destroyDelay);
+ blocker.SetParentCanvas(canvas);
}
}
- public void SetSortingOrderOffset(int offset)
+ public async UniTask PlayAsync(bool showLog = true, bool closePMA = false)
{
- // 琚獶estroy涔嬪悗effectTarget == null 涓� true 浣嗘槸璁块棶鍐呭浼氭姤閿�
- if (blocker != null && effectTarget != null)
+ await UniTask.Delay(playDelayTime);
+ try
{
- blocker.sortingOrderOffset = offset;
- blocker.UpdateSortingOrder();
+ Play(showLog, closePMA);
}
- else
+ catch (Exception e)
{
- blocker = null;
- effectTarget = null;
+ Debug.LogError(e);
}
}
@@ -127,11 +392,57 @@
onDestroy.Invoke(this);
onDestroy = null;
}
+ // 鍋滄鐗规晥骞跺綊杩樺埌姹犱腑
+ Release();
+
+ if (spineAnimationState != null)
+ {
+ spineAnimationState.Complete -= OnSpineAnimationComplete;
+ }
+
+
}
- // 鍒涘缓鍚庣殑鐗规晥浼氳嚜鍔ㄩ殣钘� 闇�瑕佹墜鍔ㄨ皟鐢≒lay鎵嶈兘鎾斁
- public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false, bool _autoDestroy = true, float _destroyDelay = 5f)
+ //鍗曟鎾斁瀹屾瘯灏变細瑙﹀彂锛屽嵆浣挎槸寰幆
+ protected virtual void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
{
+ if (!isPlaySpineLoop)
+ {
+ spineComp.enabled = false;
+ isPlaying = false;
+ onComplete?.Invoke();
+ if (isReleaseImmediately)
+ {
+ Release();
+ }
+
+ }
+ }
+
+
+ private void OnUnityAnimationComplete()
+ {
+ var timeObj = effectTarget.GetComponent<EffectTime>();
+ if (!timeObj.isLoop)
+ {
+ this.SetWait(timeObj.playTime);
+ this.DoWaitRestart();
+ this.OnWaitCompelete(OnEffectComplete);
+ }
+ }
+
+ private void OnEffectComplete(Component comp)
+ {
+ this.DoWaitStop();
+ if (isReleaseImmediately)
+ Release();
+ }
+
+
+ // 鍒涘缓鍚庣殑鐗规晥浼氳嚜鍔ㄩ殣钘� 闇�瑕佹墜鍔ㄨ皟鐢≒lay鎵嶈兘鎾斁
+ public static EffectPlayer Create(int effectId, Transform parent, bool createNewChild = false)
+ {
+ // 鐩存帴鍒涘缓鐗规晥鎾斁鍣紝涓嶄娇鐢ㄥ璞℃睜
EffectPlayer effectPlayer = null;
if (createNewChild)
@@ -143,35 +454,44 @@
else
{
effectPlayer = parent.AddMissingComponent<EffectPlayer>();
- effectPlayer.effectId = effectId;
- effectPlayer.autoDestroy = _autoDestroy;
- effectPlayer.destroyDelay = _destroyDelay;
}
- effectPlayer.SetActive(false);
+
+ effectPlayer.effectId = effectId;
+ effectPlayer.SetActive(true);
return effectPlayer;
}
+
+ /// <summary>
+ /// 璁剧疆娓告垙瀵硅薄婵�娲荤姸鎬�
+ // /// </summary>
+ // public void SetActive(bool active)
+ // {
+ // if (gameObject != null)
+ // {
+ // gameObject.SetActive(active);
+ // }
+ // }
public void Pause()
{
if (effectTarget == null) return;
// Spine鍔ㄧ敾
- var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true);
- foreach (var sg in spineGraphics)
+ // var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true);
+ // foreach (var sg in spineGraphics)
+ if (spineComp != null)
{
- sg.timeScale = 0f;
+ spineComp.timeScale = 0f;
}
// Animator鍔ㄧ敾
- var animators = effectTarget.GetComponentsInChildren<Animator>(true);
- foreach (var animator in animators)
+ foreach (var animator in animatorList)
{
animator.speed = 0f;
}
// 绮掑瓙鐗规晥
- var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true);
- foreach (var ps in particles)
+ foreach (var ps in particleList)
{
ps.Pause();
}
@@ -181,23 +501,19 @@
{
if (effectTarget == null) return;
- // Spine鍔ㄧ敾
- var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true);
- foreach (var sg in spineGraphics)
+ if (spineComp != null)
{
- sg.timeScale = 1f;
+ spineComp.timeScale = speedRate;
}
// Animator鍔ㄧ敾
- var animators = effectTarget.GetComponentsInChildren<Animator>(true);
- foreach (var animator in animators)
+ foreach (var animator in animatorList)
{
- animator.speed = 1f;
+ animator.speed = speedRate;
}
// 绮掑瓙鐗规晥
- var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true);
- foreach (var ps in particles)
+ foreach (var ps in particleList)
{
ps.Play();
}
@@ -208,18 +524,13 @@
if (effectTarget == null) return true;
// Spine鍔ㄧ敾
- var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true);
- foreach (var sg in spineGraphics)
+ if (!spineComp.AnimationState.GetCurrent(0).IsComplete)
{
- if (!sg.AnimationState.GetCurrent(0).IsComplete)
- {
- return false;
- }
+ return false;
}
// Animator鍔ㄧ敾
- var animators = effectTarget.GetComponentsInChildren<Animator>(true);
- foreach (var animator in animators)
+ foreach (var animator in animatorList)
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
@@ -231,8 +542,7 @@
}
// 绮掑瓙鐗规晥
- var particles = effectTarget.GetComponentsInChildren<ParticleSystem>(true);
- foreach (var ps in particles)
+ foreach (var ps in particleList)
{
if (ps.IsAlive())
{
@@ -242,4 +552,22 @@
return true;
}
+
+ /// <summary>
+ /// 璁剧疆閬僵锛堟敮鎸丷ectMask2D銆丮ask銆丼moothMask绛夛級
+ /// </summary>
+ public void SetMask(RectTransform maskArea = null)
+ {
+ if (effectTarget == null || blocker == null)
+ return;
+
+ // 浼樺厛浣跨敤浼犲叆鐨刴askArea
+ if (maskArea != null)
+ {
+ blocker.PerformMask(maskArea);
+ return;
+ }
+ }
+
+
}
--
Gitblit v1.8.0