305 lines
7.5 KiB
C#
305 lines
7.5 KiB
C#
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;
|
|
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;
|
|
|
|
/// <summary>
|
|
/// 生命周期完成事件 / Event triggered when lifetime is completed
|
|
/// </summary>
|
|
public event Action OnLifetimeCompleted;
|
|
|
|
private void Awake()
|
|
{
|
|
if (_vfx == null)
|
|
{
|
|
_vfx = GetComponent<ParticleSystem>();
|
|
}
|
|
|
|
if (_vfx != null)
|
|
{
|
|
_originalScale = _vfx.transform.localScale;
|
|
}
|
|
}
|
|
private void OnDestroy()
|
|
{
|
|
if(!string.IsNullOrEmpty(_vfxPath))
|
|
{
|
|
AddressableManager.Instance.UnloadAsset(_vfxPath);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
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
|
|
|
|
/// <summary>
|
|
/// Set VFX scale
|
|
/// </summary>
|
|
public void SetScale(float scale)
|
|
{
|
|
SetScale(new Vector3(scale, scale, scale));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX scale with vector
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX offset
|
|
/// </summary>
|
|
public void SetOffset(Vector3 offset)
|
|
{
|
|
_offset = offset;
|
|
if (_vfx != null)
|
|
{
|
|
_vfx.transform.localPosition = offset;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX world position
|
|
/// </summary>
|
|
public void SetPosition(Vector3 position)
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
_vfx.transform.position = position;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX rotation
|
|
/// </summary>
|
|
public void SetRotation(Quaternion rotation)
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
_vfx.transform.rotation = rotation;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX rotation with euler angles
|
|
/// </summary>
|
|
public void SetRotation(Vector3 eulerAngles)
|
|
{
|
|
SetRotation(Quaternion.Euler(eulerAngles));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX color
|
|
/// </summary>
|
|
public void SetColor(Color color)
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
var main = _vfx.main;
|
|
main.startColor = color;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX duration
|
|
/// </summary>
|
|
public void SetDuration(float duration)
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
var main = _vfx.main;
|
|
main.duration = duration;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set VFX playback speed
|
|
/// </summary>
|
|
public void SetSpeed(float speed)
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
var main = _vfx.main;
|
|
main.simulationSpeed = speed;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Play VFX
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop VFX
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
m_iState = GFX_STATE.ST_STOP;
|
|
_vfx.Stop();
|
|
gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Pause VFX
|
|
/// </summary>
|
|
public void Pause()
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
m_iState = GFX_STATE.ST_PAUSE;
|
|
_vfx.Pause();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear all VFX particles
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
if (_vfx != null)
|
|
{
|
|
_vfx.Clear();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 重新开始播放 / Restart VFX
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查特效是否正在播放 / Check if VFX is playing
|
|
/// </summary>
|
|
public bool IsPlaying()
|
|
{
|
|
return m_iState == GFX_STATE.ST_PLAY;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set lifetime duration
|
|
/// </summary>
|
|
/// <param name="lifeTime">生命周期时长(秒),-1表示无限 / Lifetime in seconds, -1 for infinite</param>
|
|
public void SetLifeTime(float lifeTime)
|
|
{
|
|
_lifeTime = lifeTime;
|
|
_elapsedTime = 0f;
|
|
_lifetimeCompleted = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get lifetime duration
|
|
/// </summary>
|
|
public float GetLifeTime()
|
|
{
|
|
return _lifeTime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get elapsed time
|
|
/// </summary>
|
|
public float GetElapsedTime()
|
|
{
|
|
return _elapsedTime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get remaining lifetime
|
|
/// </summary>
|
|
public float GetRemainingLifeTime()
|
|
{
|
|
if (_lifeTime <= 0)
|
|
return -1f;
|
|
|
|
return Mathf.Max(0f, _lifeTime - _elapsedTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if lifetime is completed
|
|
/// </summary>
|
|
public bool IsLifetimeCompleted()
|
|
{
|
|
return _lifetimeCompleted;
|
|
}
|
|
}
|
|
}
|