MiniGames/Assets/CoinVFXAdder.cs
2025-09-11 18:46:20 +05:00

67 lines
2.2 KiB
C#

using UnityEngine;
[DisallowMultipleComponent]
public class CoinVFXAdder : MonoBehaviour
{
[Header("VFX Prefab (one-shot)")]
public ParticleSystem vfxPrefab;
[Header("Spawn Options")]
public Vector3 spawnOffsetLocal; // offset in source local space
public bool inheritRotation = false; // use source.rotation
public Transform parentOverride; // null = world
[Header("Lifetime")]
public bool autoDestroyIfNeeded = true;
public float extraLifetime = 0.25f;
/// <summary>Spawn at this component's transform (still supported).</summary>
public void SpawnVFX()
{
SpawnAt(transform);
}
/// <summary>Spawn at a specific source (e.g., the coin), so this can sit on an ancestor.</summary>
public void SpawnAt(Transform source)
{
if (!vfxPrefab || !source) return;
Vector3 pos = source.TransformPoint(spawnOffsetLocal);
Quaternion rot = inheritRotation ? source.rotation : Quaternion.identity;
Transform parent = parentOverride ? parentOverride : null;
var ps = Instantiate(vfxPrefab, pos, rot, parent);
ps.Play(true);
if (ps.main.stopAction == ParticleSystemStopAction.Destroy) return;
if (autoDestroyIfNeeded)
{
Destroy(ps.gameObject, EstimateLifetime(ps) + extraLifetime);
}
}
private static float EstimateLifetime(ParticleSystem ps)
{
var main = ps.main;
float dur = main.duration;
float lt = 0f;
var c = main.startLifetime;
switch (c.mode)
{
case ParticleSystemCurveMode.Constant:
lt = c.constant; break;
case ParticleSystemCurveMode.TwoConstants:
lt = Mathf.Max(c.constantMin, c.constantMax); break;
case ParticleSystemCurveMode.Curve:
if (c.curve != null && c.curve.length > 0) lt = c.curve.keys[^1].time; break;
case ParticleSystemCurveMode.TwoCurves:
float a = (c.curveMin != null && c.curveMin.length > 0) ? c.curveMin.keys[^1].time : 0f;
float b = (c.curveMax != null && c.curveMax.length > 0) ? c.curveMax.keys[^1].time : 0f;
lt = Mathf.Max(a, b); break;
}
return dur + lt;
}
}