67 lines
2.2 KiB
C#
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;
|
|
}
|
|
}
|