using System;
using BrewMonster.Scripts;
using UnityEngine;
namespace BrewMonster.PerfectWorld.Scripts.Vfx
{
public enum GFX_STATE
{
ST_STOP = 0,
ST_PLAY = 1,
ST_PAUSE = 2,
ST_EDITMODE = 3
}
public class BaseVfxObject : MonoBehaviour
{
[SerializeField] private ParticleSystem _vfx;
[SerializeField] private float _lifeTime =-1;
[SerializeField] private bool _isLoopVfx;
private string _vfxPath;
private Vector3 _originalScale = Vector3.one;
private Vector3 _offset = Vector3.zero;
[SerializeField]private GFX_STATE m_iState;
private float _elapsedTime = 0f;
private bool _lifetimeCompleted = false;
///
/// 生命周期完成事件 / Event triggered when lifetime is completed
///
public event Action OnLifetimeCompleted;
private void Awake()
{
if (_vfx == null)
{
_vfx = GetComponent();
}
if (_vfx != null)
{
_originalScale = _vfx.transform.localScale;
}
}
private void OnDestroy()
{
if(!string.IsNullOrEmpty(_vfxPath))
{
AddressableManager.Instance.ReleaseAsset(_vfxPath);
}
}
private void Update()
{
if(_isLoopVfx) return;
if (_lifeTime > 0 && m_iState == GFX_STATE.ST_PLAY && !_lifetimeCompleted)
{
_elapsedTime += Time.deltaTime;
if (_elapsedTime >= _lifeTime)
{
_lifetimeCompleted = true;
Stop();
OnLifetimeCompleted?.Invoke();
}
}
}
public void Init(string vfxPath)
{
_vfxPath = vfxPath;
}
#region EC
public GFX_STATE GetState() { return m_iState; }
#endregion
///
/// Set VFX scale
///
public void SetScale(float scale)
{
SetScale(new Vector3(scale, scale, scale));
}
///
/// Set VFX scale with vector
///
public void SetScale(Vector3 scale)
{
if (_vfx != null)
{
_vfx.transform.localScale = Vector3.Scale(_originalScale, scale);
// 调整粒子大小 / Adjust particle size
var main = _vfx.main;
main.startSizeMultiplier *= scale.magnitude / Mathf.Sqrt(3);
}
}
///
/// Set VFX offset
///
public void SetOffset(Vector3 offset)
{
_offset = offset;
if (_vfx != null)
{
_vfx.transform.localPosition = offset;
}
}
///
/// Set VFX world position
///
public void SetPosition(Vector3 position)
{
if (_vfx != null)
{
_vfx.transform.position = position;
}
}
///
/// Set VFX rotation
///
public void SetRotation(Quaternion rotation)
{
if (_vfx != null)
{
_vfx.transform.rotation = rotation;
}
}
///
/// Set VFX rotation with euler angles
///
public void SetRotation(Vector3 eulerAngles)
{
SetRotation(Quaternion.Euler(eulerAngles));
}
///
/// Set VFX color
///
public void SetColor(Color color)
{
if (_vfx != null)
{
var main = _vfx.main;
main.startColor = color;
}
}
///
/// Set VFX duration
///
public void SetDuration(float duration)
{
if (_vfx != null)
{
var main = _vfx.main;
main.duration = duration;
}
}
///
/// Set VFX playback speed
///
public void SetSpeed(float speed)
{
if (_vfx != null)
{
var main = _vfx.main;
main.simulationSpeed = speed;
}
}
///
/// Play VFX
///
public void Play()
{
Stop();
if (_vfx != null)
{
m_iState = GFX_STATE.ST_PLAY;
gameObject.SetActive(true);
_vfx.Play();
// 重置生命周期计时器 / Reset lifetime timer
_elapsedTime = 0f;
_lifetimeCompleted = false;
}
}
///
/// Stop VFX
///
public void Stop(bool resetParent = false)
{
if (_vfx != null)
{
m_iState = GFX_STATE.ST_STOP;
_vfx.Stop();
gameObject.SetActive(false);
if(resetParent) gameObject.transform.parent = null;
}
}
///
/// Pause VFX
///
public void Pause()
{
if (_vfx != null)
{
m_iState = GFX_STATE.ST_PAUSE;
_vfx.Pause();
}
}
///
/// Clear all VFX particles
///
public void Clear()
{
if (_vfx != null)
{
_vfx.Clear();
}
}
///
/// 重新开始播放 / Restart VFX
///
public void Restart()
{
if (_vfx != null)
{
_vfx.Stop();
_vfx.Clear();
_vfx.Play();
// 重置生命周期计时器 / Reset lifetime timer
m_iState = GFX_STATE.ST_PLAY;
_elapsedTime = 0f;
_lifetimeCompleted = false;
}
}
///
/// 检查特效是否正在播放 / Check if VFX is playing
///
public bool IsPlaying()
{
return m_iState == GFX_STATE.ST_PLAY;
}
///
/// Set lifetime duration
///
/// 生命周期时长(秒),-1表示无限 / Lifetime in seconds, -1 for infinite
public void SetLifeTime(float lifeTime)
{
_lifeTime = lifeTime;
_elapsedTime = 0f;
_lifetimeCompleted = false;
}
///
/// Get lifetime duration
///
public float GetLifeTime()
{
return _lifeTime;
}
///
/// Get elapsed time
///
public float GetElapsedTime()
{
return _elapsedTime;
}
///
/// Get remaining lifetime
///
public float GetRemainingLifeTime()
{
if (_lifeTime <= 0)
return -1f;
return Mathf.Max(0f, _lifeTime - _elapsedTime);
}
///
/// Check if lifetime is completed
///
public bool IsLifetimeCompleted()
{
return _lifetimeCompleted;
}
}
}