Files
Main/Assets/GameAssets/Resources/GameUI/Form/UIComponents/Scripts/UIVfxSkinCompoent.cs
2025-01-25 04:38:09 +08:00

374 lines
11 KiB
C#

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<FGameObjectBase> 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<FGameObjectBase> 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<UIPanel>();
_rootPanel.onRenderQueueChanged = RenderQueueChanged;
_rootPanel.onParentChanged = OnParentChanged;
if (_synRQ)
{
_vfx.RenderQueue = _rootPanel.startingRenderQueue;
}
InitClipPanel();
}
public void OnSetInfo(int layer, MyAction<FGameObjectBase> 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);
}
/// <summary>
/// 设置特效缩放倍数
/// </summary>
/// <param name="size"></param>
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
}
}