using System.Collections; using Thousandto.Cfg.Data; using Thousandto.Core.Asset; using Thousandto.Core.Base; using UnityEngine; using UnityEngine.Profiling; using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool; namespace Thousandto.GameUI.Form { public class UIVfxSkinCompoent : MonoBehaviour { //transform实例 private Transform _transformInst = null; private FGameObjectVFX _vfx = null; private Transform _parent = null; private GameObject _parentGo = null; private UIPanel _rootPanel = null; //Clip以那个Panel为标准 public UIPanel _clipPanel = null; //是否需要进行clip public bool _needClip = false; //是否同步RenderQueue private bool _synRQ = true; private Vector3 _panelLastPostion = Vector3.one * 999999; private Vector3 _panelLastAngle = Vector3.one * 999999; private Vector3 _panelLastScale = Vector3.one * 999999; private int _showFrameCount = 0; public Transform TransformInst { get { if (_transformInst == null) { _transformInst = transform; } return _transformInst; } } public Transform VfxRootTrans { get { if (_parent == null) { _parent = TransformInst.Find("Root"); } return _parent; } } public bool IsPlaying { get { if (_vfx != null) return _vfx.VFXPlayState == VFXPlayState.Playing; return false; } } //以这个Panel为基准进行剪切 public UIPanel ClipPanel { get { return _clipPanel; } set { if(_clipPanel != value) { UninitClipPanel(); _clipPanel = value; InitClipPanel(); } } } //是否需要进行剪切 public bool NeedClip { get { return _needClip; } set { _needClip = value; if (_vfx != null) { _vfx.UseClipRect = _needClip; } } } //特效的事迹对象 public FGameObjectVFX FGO { get { return _vfx; } } #region 公有函数 public void OnCreateAndPlay(ModelTypeCode type, int id, int layer, MyAction OnFinishedCallBack = null,bool synRQ = true) { OnDestroy(); var _id = id; if(_id > 99999) { var _cfg = DeclareModelConfig.Get(id); if (_cfg != null) _id = _cfg.Model; } _vfx = new FGameObjectVFX(type, _id, true, false); OnSetInfo(layer, Vector3.zero, OnFinishedCallBack,true,true,false,true, synRQ); OnPlay(); } public void OnCreateVfx(ModelTypeCode type, int id, bool immediatelyLoad = true, bool needPlaceHolder = false) { OnDestroy(); _vfx = new FGameObjectVFX(type, id, immediatelyLoad, needPlaceHolder); _vfx.UseClipRect = _needClip; } public void OnSetInfo(int layer, Vector3 position, MyAction OnFinishedCallBack = null, bool recursive = true, bool isReset = true, bool isLockDir = false, bool IsFinishDestroy = true, bool synRQ = true) { if (_parent == null) { _parent = TransformInst.Find("Root"); _parentGo = _parent.gameObject; } _synRQ = synRQ; _vfx.SetParent(_parent, isReset); _vfx.SetLayer(layer, recursive); _vfx.IsLockDir = isLockDir; _vfx.IsFinishDestroy = IsFinishDestroy; _vfx.OnLoadFinishedCallBack = OnFinishedCallBack; _vfx.UseClipRect = _needClip; if (position != Vector3.zero) _vfx.SetPosition(position); _rootPanel = TransformInst.GetComponent(); _rootPanel.onRenderQueueChanged = RenderQueueChanged; _rootPanel.onParentChanged = OnParentChanged; if (_synRQ) { _vfx.RenderQueue = _rootPanel.startingRenderQueue; } InitClipPanel(); } public void OnSetInfo(int layer, MyAction OnFinishedCallBack = null) { OnSetInfo(layer, Vector3.zero, OnFinishedCallBack); } public void OnSetPosition(Vector3 position) { if (_vfx == null) return; if (position != Vector3.zero) { _vfx.SetPosition(position); } } //初始化ClipPanel private void InitClipPanel() { //把_clipPanel进行清理 if (_clipPanel != null) { _clipPanel.onClipMove -= OnPanelClipMove; _clipPanel.onClipMove += OnPanelClipMove; if (_vfx != null && _needClip) { _vfx.ClipRect = _clipPanel.finalClipRectByWorld; SaveTransform(_clipPanel.cachedTransform); //延迟3帧 CoroutinePool.AddTask(DelaySetVFXClipRect(3)); } } } //卸载ClipPanel private void UninitClipPanel() { //把_clipPanel进行清理 if (_clipPanel != null) { _clipPanel.onClipMove -= OnPanelClipMove; } _clipPanel = null; } //延迟几帧设置特效的裁剪区域 private IEnumerator DelaySetVFXClipRect(int delayFrameCount) { while (delayFrameCount > 0) { yield return new WaitForEndOfFrame(); delayFrameCount--; } //这里做判断,说不定两帧之后,这两个对象凉凉了 if (_vfx != null && _clipPanel != null) { _vfx.ClipRect = _clipPanel.finalClipRectByWorld; SaveTransform(_clipPanel.cachedTransform); //Debug.Log(string.Format("DelaySetVFXClipRect:({0:F4},{1:F4},{2:F4},{3:F4}):{4:D}", _vfx.ClipRect.x, _vfx.ClipRect.y, _vfx.ClipRect.z, _vfx.ClipRect.w, Time.frameCount)); } } private void OnDestroy() { OnDestory(); UninitClipPanel(); } public void OnDestory() { if (_vfx != null) _vfx.Destroy(); _vfx = null; var root = TransformInst.Find("Root"); while (root.childCount > 0) { GameObject.DestroyImmediate(root.GetChild(0).gameObject, true); } } public void OnPlay(float speed = 1f, bool isSynPlay = false, MyAction playingCallBack = null) { if (_parent == null) { _parent = TransformInst.Find("Root"); _parentGo = _parent.gameObject; } _showFrameCount = 2; _parentGo.SetActive(false); if (_vfx != null) _vfx.Play(speed, isSynPlay, playingCallBack); } /// /// 设置特效缩放倍数 /// /// public void OnSetSize(Vector3 size) { if(_parent == null) { _parent = TransformInst.Find("Root"); _parentGo = _parent.gameObject; } if(_parent != null) { _parent.localScale = size; } } public VFXPlayState OnGetVfxState() { if (_vfx != null) return _vfx.VFXPlayState; return VFXPlayState.None; } private void RenderQueueChanged(int sq) { if (_synRQ) { if (_vfx != null) { if (_vfx.RenderQueue != sq + 1) { _vfx.RenderQueue = sq + 1; } } } } private void OnParentChanged(UIPanel panel) { InitClipPanel(); } private void OnPanelClipMove(UIPanel panel) { if (_vfx != null && _needClip) { _vfx.ClipRect = _clipPanel.finalClipRectByWorld; SaveTransform(_clipPanel.cachedTransform); //Debug.Log(string.Format("vfx.ClipRect:({0:F4},{1:F4},{2:F4},{3:F4}):{4:D}", _vfx.ClipRect.x, _vfx.ClipRect.y, _vfx.ClipRect.z, _vfx.ClipRect.w, Time.frameCount)); } } private void OnEnable() { if (_parent == null) { _parent = TransformInst.Find("Root"); _parentGo = _parent.gameObject; } _showFrameCount = 2; _parentGo.SetActive(false); } private void Awake() { if (_parent == null) { _parent = TransformInst.Find("Root"); _parentGo = _parent.gameObject; } _showFrameCount = 2; _parentGo.SetActive(false); } private void Update() { --_showFrameCount; if (_rootPanel != null && _parentGo != null) { var active = _rootPanel.finalAlpha > 0.003f && _showFrameCount <= 0; if (active != _parentGo.activeSelf) { _parentGo.SetActive(active); } } if (_clipPanel != null && _needClip && _vfx != null) { if (CheckTransformChanged(_clipPanel.cachedTransform)) { SaveTransform(_clipPanel.cachedTransform); _vfx.ClipRect = _clipPanel.finalClipRectByWorld; //Debug.Log(string.Format("Update:({0:F4},{1:F4},{2:F4},{3:F4}):{4:D}", _vfx.ClipRect.x, _vfx.ClipRect.y, _vfx.ClipRect.z, _vfx.ClipRect.w, Time.frameCount)); } } } //保存ClipPanel的Transform信息 private void SaveTransform(Transform trans) { _panelLastPostion = trans.position; _panelLastAngle = trans.eulerAngles; _panelLastScale = trans.lossyScale; } //判断Transform是否改变 private bool CheckTransformChanged(Transform trans) { return (trans.position - _panelLastPostion).sqrMagnitude > 0.01f || (trans.eulerAngles - _panelLastAngle).sqrMagnitude > 0.01f || (trans.lossyScale * 320f - _panelLastScale * 320f).sqrMagnitude > 0.00001f; } #endregion } }