유니티 엔진에서 파티클 효과에 대한 충돌 후 데칼 메시 생성 구현 - Whitmem
유니티 엔진에서 파티클 효과에 대한 충돌 후 데칼 메시 생성 구현
게임 개발 및 엔진
2026-01-05 20:53 게시 05061911b54c8f74c99d

0
0
49
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
저작물 참고 필자도 해당 내용을 공부하고 있는 입장으로 주로 오픈 문서, 포럼, AI 질의 응답을 활용하여 관련 내용을 공부하였습니다. 따라서 틀린 내용이 있을 수 있습니다. 다만, 타인(AI 등)의 저작물을 침해하지 않도록 순서, 과정, 스크린샷, 코드 등 다른 저작물을 활용 또는 포함하지 않았으며, AI 등 인터넷 자료는 오로지 기술 원리 이해의 목표로만 활용하고, 본 게시글에 언급된 과정, 흐름, 본문, 게시한 코드는 AI의 복붙 없이 모두 필자가 사전에 알고 있는 그래픽스 기술과 인터넷 상에 공개된 개념을 통해 모두 직접 시도하며 직접 작성하였음을 밝힙니다. 부득이하게 어떤 자료를 인용하는 경우는 링크로 출처를 남기고 인용합니다.
일단 이번 게시글에서 구현할 사항은 유니티 엔진에서 제공하는 파티클 시스템을 사용해서 특정 평면과 충돌 처리를 하는 경우, 해당 위치에 데칼 메시를 생성하여 충돌 자국을 나타내는 것 까지를 주요 목표로 한다. 매우 쉬운 방법으로 기록할 것인데, 매우 쉬운 만큼 퍼포먼스에 지장이 있을 수 있다. 즉 수십만개, 수백 만개를 표현하기에는 무리가 있는 기법이기에 이런 경우 GPU 인스턴싱을 사용하거나 구현해야 하는데 이 경우는 매우 복잡해진다.
컴퓨트 쉐이더라는 것을 나는 사용해본 적이 없는데 컴퓨팅 쉐이더를 통해 구현이 가능하다고 하니 이는 추후 시도해보고 기록으로 게시할 것이다.
아무튼 엔진에서 파티클 시스템을 하나 생성한다. 여러가지 설정이 있는데 설정에 관련해서는 AI에게 물어보면 잘 답변해주므로 여기서는 모두 다루지는 않는다. 나도 대부분 모르는 것들이다. (내가 파티클 시스템을 구현한 것이 아니기 때문이다.) 우선 기본적으로 Particle 시스템의 속성들을 보면 다양하게 있는데 Renderer 항목이 주요 렌더에 관련된 사항들이다. 아무래도 CPU 렌더링 방식이다보니 속성이 매우 다양하다. 기본 값은 Billboard 모드로 되어 있는데 하나의 평면이 생성되어 사용자 카메라를 향하는 모습으로 구현된다. 따라서 어디에서 보든지 모양이 방향이 동일하다.
Render Mode에는 다음과 같은 속성이 있다.
Billboard
Streched Billboard
Horizontal Billboard
Vertical Billboard
Mesh
None
Billboard 는 항상 카메라를 바라보는 모드이고, Streched Billboard 는 속도에 따른 것이라고 하는데 잘 모르겠다. 뭐 총알 불꽃 같은 느낌이려나?
다음으로 Horizontal, Vertical 이 있는데, 특정 축만 고정하고 특정 축만 카메라를 향하도록 해준다. 쉽게 말하면 Horizontal은 무조건 땅에 붙어있는 것... 이고 Vertical은 무조건 세워져있는 것... 정도라고 보면 된다. Vertical 은 비 정도로 생각하면 좋다. 단순히 Plane을 만들어서 땅으로 내리면 Plane 위의 텍스처가 화면 시점이 바뀜에 따라서 그 객체의 회전 정도가 눈에 보이기 때문에 어색하다. 따라서 y축의 회전을 카메라의 방향 벡터와 동기화시켜두면 아래로 흐르는 느낌은 들되 카메라 방향이 회전되어도 따라오도록 구현할 수 있다.
위 방식은 파티클이 어떤 방향으로 내리든지 무조건 수평을 향한다. (옆으로 떨어진다 한들) Horizontal Billboard이다.
위 방식은 파티클이 어떤 방향으로 내리든지 무조건 수직을 향한다. Vertical Billboard이다.
위 방식은 무조건 카메라의 정 방향을 향한다. (카메라 뷰 벡터만큼 회전) Billboard이다.
위 방식은 일반 Mesh이다. 큐브가 그려진 것을 볼 수 있다. 어떤 파티클을 구현해야하는지에 따라서 사용해야하는 옵션이 다르다는 것을 눈으로 느낄 수 있다. 일단 비 효과를 일반 Billboard를 사용하면 제법 어색할 수 있다.위에서 볼때 수직으로 내려야 하는데 무조건 정방향이 정직하게 카메라를 바라보고 있기 때문이다. 이 경우에는 Vertical Billboard를 사용할 수 있다.
이제 내가 원하는 텍스처를 지정할 수 있는데, Material 을 지정하면 된다. 아무런 Material을 가져다 사용하는 것은 아니고, Particle 시스템에 맞게끔 설계된 Shader가 적용된 material을 가져다 써야 한다.
Material을 생성하고 Universal Render PipeLine/Particles/Unlit 을 찾아서 넣는다.
그리고, 해당 Material에 원하는 텍스처 등을 넣고 Particle System의 Renderer 의 Material에 적용한다. 이는 라이트 표현을 무시한다.
한편, Particles 쉐이더(Material을 지정할때 Particles/Lit으로) 안에 Lit 모드도 있는데, lit 쉐이더를 적용해주면
이렇게 빛을 받는 것을 볼 수 있다.
아무튼 기본 파티클 설정은 여기서 그만두고, 이제 충돌이나 트리거 설정을 보도록 한다.
파티클 설정의 우측 Inspector을 보면 CollisionsTriggers가 있다. Collision 은 충돌시 어떤 물리적 효과를 객체에 적용하고 이벤트를 반환하도록 도와주고, Triggers는 트리거되면 코드에서 판별할 수 있도록만 제공한다. 만약 Collision 을 사용하면 Trigger 는 굳이 사용할 필요 없어보인다.
다만 물리 처리는 원치 않고 충돌 여부만 검사하고 싶은 경우 Trigger를 사용하면 된다.
Collision을 사용하는 경우 Send Collision Messages 를 활성화 해 주면 해당 파티클 시스템에 삽입된 스크립트에서 OnParticleCollision으로 받을 수 있다.
여기서는 Collision 위주로 볼 것인데, Dampen 은 마찰, Bounce는 튕기는 정도, 이외 제거 시간, Radius Scale은 충돌 지점까지의 반지름(여유 거리) 크기인 것 같다.
기본 Type은 Planes로 되어 있는데, World로 하면 세계에 배치된 각 오브젝트를 엔진이 충돌 검사하여 처리하도록 도와준다. 다만 이는 성능 퍼포먼스를 많이 잡아먹고 원하는 오브젝트만 쉽게 나누지는 못하는 듯 싶다.
따라서 내가 원하는 평면과만 충돌 처리를 하는 것이 유리하며, 이의 경우 Planes를 설정후 아래 + 버튼을 눌러 평면 성질을 가지는 객체의 Transform(객체를 드래그 하면 된다.)를 넣어주면 해당 객체와 평면 교차 충돌 검사를 수행한다.
스크립트측에서는 OnParticleCollision로 충돌 트리거를 잡으면 된다. GameObject 로 넘어오는 object는 충돌한 대상이기 때문에 파티클 정보가 아니다. 파티클 1000개가 각 메시에 부딪힐 때 메시 정보가 other에 담겨오고 각 파티클 정보는 파티클 시스템에 제공되는 GetCollisionEvents를 통해 가져와야 한다.
particleSystem.GetCollisionEvents
즉 해당하는 ParticleSystem 컴포넌트를 가져와서 GetCollisionEvents 를 수행하면 된다.
이 때 GetcollisionEvents 는 메모리에 기록된 충돌 정보를 모두 쿼리해서 가져오는 것이기 때문에 (찾아보니 복사라고 한다.) 특정 오브젝트와 충돌한 이벤트를 가져오기 위해 other 을 넣고, events 는 이 데이터들이 반환될 List<T> 를 넣어주면 된다.
즉 해당 리스트 공간에 모두 삽입되어 개수를 반환해준다. (원래 배열 형태로 참조시켰으나 가비지 이유 때문인지 Deprecated 되었다.)
이제 foreach 과정에서 ParticleCollisionEvent 의 내부를 살펴보면 colliderComponent, normal, intersection, velocity가 있는데 colliderComponent 는 충돌한 대상 객체의 Collider 컴포넌트를 가져와주고(아무래도 충돌 처리를 하기 때문에 해당 컴포넌트 기반으로 계산하는 듯 싶다. 다만 Plane 모드 일 때는 해당 컴포넌트와 관련이 있는지는 모르겠다. World 전역 모드 기준)
normal 은 충돌 교차 지점의 노말(정확히 어떤 법선인지는 모르겠다. 방향 벡터는 노말이 여러개이므로 찾아볼 필요가 있다.)
intersection은 교차점 벡터, velocity 는 해당 파티클의 가속 벡터라고 볼 수 있다.
해당 정보를 통해서 교차한 지점에 대해 가속한 방향으로 Decal 메시를 생성할 수 있다.
데칼 메시의 생성 방법은 어렵지 않다. 미리 데칼 객체를 에디터 상에 만들어두고 Hierarchy 에서 Asset 으로 드래그하면 (즉 게임 오브젝트 인스턴스를 에셋 공간으로 드래그하면) 이를 패키지화 하여 prefab 형태로 압축 파일 처럼 만들어준다.... 이는 GameObject로 취급되기 때문에 해당 스크립트에 Inspector로 넘길 수 있다...
이후 Instantiate 함수를 통해서 어떤 오브젝트를 복제할 것인지 위치, 방향 Quaternion은 무엇인지 지정하면 된다. 나의 경우 방향 벡터에서 -90도 회전을 했는데 .. 내가 만든 데칼 메시가 기본 방향이 앞으로 향할 때 땅에 그려지게끔 구현했기 때문이다.
이런식으로 데칼이 땅에 표시되는 것을 볼 수 있다.
댓글 0개
댓글을 작성하는 경우 댓글 처리 방침에 동의하는 것으로 간주됩니다. 댓글을 작성하면 일회용 인증키가 발급되며, 해당 키를 분실하는 경우 댓글을 제거할 수 없습니다. 댓글을 작성하면 사용자 IP가 영구적으로 기록 및 부분 공개됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.