using UnityEngine;
namespace DanroJump.Vfx
{
///
/// Служба визуальных эффектов, программно создающая и настраивающая системы частиц Unity.
/// Позволяет избежать зависимости от префабов в редакторе и обеспечивает высокую переносимость.
///
public sealed class GameVfxService : IVfxService
{
public void SpawnJumpEffect(Vector3 position)
{
var go = new GameObject("VFX_Jump");
go.transform.position = position;
var ps = go.AddComponent();
var main = ps.main;
main.startColor = new Color(0.9f, 0.9f, 0.9f, 0.5f);
main.startSize = new ParticleSystem.MinMaxCurve(0.08f, 0.22f);
main.startSpeed = new ParticleSystem.MinMaxCurve(1.5f, 3.5f);
main.startLifetime = new ParticleSystem.MinMaxCurve(0.2f, 0.45f);
main.duration = 0.25f;
main.loop = false;
main.gravityModifier = 0.6f;
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Cone;
shape.angle = 35f;
shape.radius = 0.15f;
shape.rotation = new Vector3(90f, 0f, 0f); // Направление вниз под ноги
var emission = ps.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 12) });
var colorOverLifetime = ps.colorOverLifetime;
colorOverLifetime.enabled = true;
var gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(0.6f, 0f), new GradientAlphaKey(0f, 1f) }
);
colorOverLifetime.color = gradient;
ps.Play();
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
}
public void SpawnCoinCollectedEffect(Vector3 position)
{
var go = new GameObject("VFX_CoinCollected");
go.transform.position = position;
var ps = go.AddComponent();
var main = ps.main;
main.startColor = new Color(1.0f, 0.85f, 0.0f, 0.9f); // Золотой цвет
main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.25f);
main.startSpeed = new ParticleSystem.MinMaxCurve(2f, 4f);
main.startLifetime = new ParticleSystem.MinMaxCurve(0.3f, 0.6f);
main.duration = 0.3f;
main.loop = false;
main.gravityModifier = -0.2f; // Легкий подъем вверх
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Sphere;
shape.radius = 0.1f;
var emission = ps.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 18) });
var colorOverLifetime = ps.colorOverLifetime;
colorOverLifetime.enabled = true;
var gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.9f, 0.2f), 0f), new GradientColorKey(new Color(1f, 0.5f, 0f), 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
);
colorOverLifetime.color = gradient;
ps.Play();
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
}
public void SpawnPlayerDeathEffect(Vector3 position)
{
var go = new GameObject("VFX_PlayerDeath");
go.transform.position = position;
var ps = go.AddComponent();
var main = ps.main;
main.startColor = new Color(0.8f, 0.1f, 0.1f, 0.8f); // Красный / серый взрыв
main.startSize = new ParticleSystem.MinMaxCurve(0.15f, 0.35f);
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 7f);
main.startLifetime = new ParticleSystem.MinMaxCurve(0.4f, 0.8f);
main.duration = 0.5f;
main.loop = false;
main.gravityModifier = 0.8f;
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Sphere;
shape.radius = 0.25f;
var emission = ps.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 35) });
var colorOverLifetime = ps.colorOverLifetime;
colorOverLifetime.enabled = true;
var gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(new Color(0.9f, 0.2f, 0.2f), 0f), new GradientColorKey(new Color(0.3f, 0.3f, 0.3f), 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
);
colorOverLifetime.color = gradient;
ps.Play();
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
}
public void SpawnPrizeEffect(Vector3 position)
{
var go = new GameObject("VFX_PrizeWin");
go.transform.position = position;
var ps = go.AddComponent();
var main = ps.main;
main.startColor = Color.white; // Конфетти будут разных цветов
main.startSize = new ParticleSystem.MinMaxCurve(0.12f, 0.28f);
main.startSpeed = new ParticleSystem.MinMaxCurve(4f, 8f);
main.startLifetime = new ParticleSystem.MinMaxCurve(0.6f, 1.2f);
main.duration = 0.8f;
main.loop = false;
main.gravityModifier = 0.4f;
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Hemisphere; // Разлет вверх полусферой
shape.radius = 0.3f;
shape.rotation = new Vector3(-90f, 0f, 0f); // Поворот вверх
var emission = ps.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 50) });
// Добавим смену цветов
var colorBySpeed = ps.colorBySpeed; // Используем градиент для создания разноцветных конфетти
var colorOverLifetime = ps.colorOverLifetime;
colorOverLifetime.enabled = true;
// Настроим случайный цвет при рождении через градиент с множеством ключей или Random Between Two Colors
main.startColor = new ParticleSystem.MinMaxGradient(
new Color(0.2f, 0.6f, 1.0f), // Голубой
new Color(1.0f, 0.2f, 0.6f) // Розовый
);
ps.Play();
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
}
public void SpawnComErrorEffect(Vector3 position)
{
var go = new GameObject("VFX_ComError");
go.transform.position = position;
var ps = go.AddComponent();
var main = ps.main;
main.startColor = new Color(1.0f, 0.3f, 0.0f, 0.9f); // Оранжевые тревожные искры
main.startSize = new ParticleSystem.MinMaxCurve(0.06f, 0.18f);
main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 6f);
main.startLifetime = new ParticleSystem.MinMaxCurve(0.25f, 0.5f);
main.duration = 0.4f;
main.loop = false;
main.gravityModifier = 0.3f;
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Cone;
shape.angle = 60f;
shape.radius = 0.1f;
var emission = ps.emission;
emission.rateOverTime = 0;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 20) });
var colorOverLifetime = ps.colorOverLifetime;
colorOverLifetime.enabled = true;
var gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.5f, 0f), 0f), new GradientColorKey(new Color(0.8f, 0.1f, 0f), 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0f, 1f) }
);
colorOverLifetime.color = gradient;
ps.Play();
Object.Destroy(go, main.duration + main.startLifetime.constantMax);
}
}
}