VFX & Particle System
Unity는 CPU 기반 Particle System과 GPU 기반 VFX Graph 두 입자 시스템을 제공합니다. 불·연기·비·마법 FX에 쓰며 플랫폼·입자 수에 따라 고릅니다. Play·Emit·SendEvent와 풀링으로 성능을 잡는 VFX·파티클 실전 가이드입니다.
상상해 보세요...
Particle System은 손으로 쏘는 폭죽 — rate·각도·색을 정하면 CPU가 입자마다 갱신합니다. 정밀하지만 수가 많으면 느립니다. VFX Graph는 산업용 폭죽 기계 — GPU에서 병렬로 돌아 수백만 입자가 가능하지만 강한 GPU와 URP/HDRP가 필요합니다. 입자 수·타깃 플랫폼·행동 복잡도에 따라 고르세요.
개념 자세히
Particle System(일명 Shuriken)은 GameObject의 컴포넌트로 CPU에서 입자를 만들고 갱신합니다. 각 입자는 위치·속도·색·크기·수명을 가집니다. 모듈(Emission, Shape, Velocity, Color over Lifetime, Force, Collision…)로 세밀 제어. 적합: 작은 불, 비, 눈, 히트 FX, 연기 — 수십~수천 입자.
VFX Graph(Visual Effect Graph)는 GPU compute shader에서 전부 돕니다. Shader Graph와 비슷한 노드 그래프로 갱신 로직을 만듭니다 (Initialize, Update, Output). 수백만 입자도 좋은 성능. 필요: URP 또는 HDRP, Compute Shader 지원 GPU(2015+ 대부분), 구형 Android/iOS는 불가.
VFX Graph는 입자를 나눕니다: Spawn(rate/burst), Initialize(초기 속성), Update(프레임별 물리·색·크기), Output(그리는 방식: quad, mesh, ribbon). Context가 데이터 흐름으로 연결됩니다 — 렌더 파이프라인처럼.
성능: Particle System은 라이브 입자 ~1000 이하면 모바일·콘솔에서도
괜찮습니다. maxParticles로 캡하고 재생 후
Stop Action = Disable. VFX Graph는 더 잘 스케일하지만
타깃 플랫폼에서 프로파일하세요.
Particle System vs VFX Graph
| 기준 | Particle System | VFX Graph |
|---|---|---|
| 처리 | CPU | GPU (Compute Shader) |
| 최적 파티클 수 | 100 – 10,000 | 10,000 – 10,000,000+ |
| Pipeline | Built-in, URP, HDRP | URP, HDRP only |
| Mobile | ✅ 좋음 | ⚠️ 제한적 |
| Interface | Inspector module | Node graph editor |
| Script API | 완전한 C# API | Limited (SetFloat, SetTexture) |
| 사용할 때 | 불, 비, 히트 FX, 연기 | 은하, 유체, 군중, 파괴 |
실습 단계 (Particle System)
Particle System 만들기
GameObject → Effects → Particle System, 또는 기존 GO에 Add Component → Particle System.
Main 모듈 설정
Duration, Looping, Start Lifetime, Start Speed, Start Size, Start Color — 기본.
방출 Shape 고르기
Shape 모듈: Cone(불), Sphere(폭발), Box(위에서의 비), Circle(링). Radius와 Arc 조절.
Color over Lifetime 켜기
그라디언트 추가: 빨강 → 주황 → 노랑 → 투명으로 불을 페이드 아웃.
필요할 때 코드로 Play
ps.Play() / ps.Stop() / ps.Emit(count) — 또는 EmitParams로 즉시 burst.
인터랙티브 시뮬레이터
Particle System 파라미터를 조절하고 Burst / 프리셋으로 효과를 보세요.
코드 예제
기본Particle System Play/Stop과 요청 시 burst emit(예: 히트 이펙트).
using UnityEngine;
public class HitEffect : MonoBehaviour
{
public ParticleSystem sparks;
public ParticleSystem smoke;
// Call on bullet impact — PlayOneShot a prefab at a position
public static void PlayAt(Vector3 pos, Vector3 normal,
GameObject fxPrefab)
{
GameObject fx = Instantiate(fxPrefab, pos,
Quaternion.LookRotation(normal));
Destroy(fx, 2f); // Clean up after 2 seconds
}
// Burst emit: 30 particles immediately, no looping
public void BurstEmit()
{
ParticleSystem.EmitParams ep = new ParticleSystem.EmitParams();
ep.position = transform.position;
sparks.Emit(ep, 30);
smoke.Play();
}
// Change particle color at runtime via Main module
public void SetColor(Color color)
{
var main = sparks.main;
main.startColor = new ParticleSystem.MinMaxGradient(color);
}
}코드 예제
고급C#에서 VFX Graph 구동 — ExposedProperty로 속성과 이벤트.
using UnityEngine;
using UnityEngine.VFX;
public class VFXController : MonoBehaviour
{
public VisualEffect vfx;
// Property IDs — must match Exposed Property names in VFX Graph
static readonly int SpawnRateID = Shader.PropertyToID("SpawnRate");
static readonly int ColorID = Shader.PropertyToID("BaseColor");
static readonly int ExplodeID = Shader.PropertyToID("OnExplode");
void Start()
{
vfx.SetFloat(SpawnRateID, 50f);
vfx.SetVector4(ColorID, new Vector4(1f, 0.5f, 0f, 1f));
}
public void Explode()
{
// SendEvent fires an event in VFX Graph (Burst spawn)
vfx.SendEvent(ExplodeID);
}
public void SetIntensity(float t)
{
// Spawn rate 0 → 500 from intensity
vfx.SetFloat(SpawnRateID, Mathf.Lerp(0f, 500f, t));
}
}📌 빠른 정리
- ▸Particle System: CPU, 모든 플랫폼, <10k 입자
- ▸VFX Graph: GPU, URP/HDRP만, 수백만 입자
- ▸Stop Action = Disable로 재사용(오브젝트 풀링)
- ▸ps.main.startColor는 struct로 재할당해야 함
- ▸VFX Graph: SendEvent()가 Burst context를 발사
⚠️ 흔한 실수
❌ Destroy 없이 PS prefab을 많이 스폰
수천 Particle System 누적 → 심한 렉
✅ PS를 풀하거나 끝난 뒤 Destroy(fx, lifetime)
❌ ps.main.startColor.color를 직접 수정
struct 복사 — 변경이 적용되지 않음
✅ var main = ps.main; main.startColor = new MinMaxGradient(c);