2D 파티클 효과
[Unit] Player character and movement > [Tutorial] Create Input Actions for player character movement
- 이미지 기본 속성 설정
- Sprite Mode: Multiple (하나의 파일을 여러 조각으로 쪼개기 위해)
- Pixels Per Unit (PPU): 100 (게임 내 크기 단위 표준 확인)
-
Mesh Type: Full Rect (가장 중요!)
이유: 파티클은 사각형 평면에서 돌아가야 하므로, 투명한 여백을 최대한 잘라내는 ‘Tight’ 대신 ‘Full Rect’를 써야 이미지가 찌그러지지 않고 비율이 유지됩니다. 2. 스프라이트 쪼개기 (Slice)
- 버튼 클릭: Apply 적용 후 Sprite Editor 실행
- 작업: Slice 메뉴 -> Type: Grid By Cell Count 선택
- 설정: Column(열): 4, Row(행): 4 입력
- 결과: 전체 이미지가 4x4 (총 16칸)의 격자로 균일하게 잘립니다
- 기본 생성 및 이름 변경
- Hierarchy(계층 구조) 창 > 마우스 우클릭 > Effect > Particle System 선택
- Inspector(인스펙터) 창 최상단 > 이름 수정: SmokeEffect
- 이미지 소스 연결 (Texture Sheet Animation)
파티클의 모양을 ‘기본 사각형’에서 ‘연기 스프라이트’로 교체하는 단계입니다.
- Inspector > Particle System 컴포넌트 > Texture Sheet Animation 모듈 체크 및 확장
- Mode: Sprites로 변경
- (+) 버튼: 클릭하여 슬롯 2개 생성
- Sprite 슬롯: ParticleSpriteAtlas_0 및 ParticleSpriteAtlas_1 할당
- 무작위 모양 설정 (Start Frame)
나오는 연기마다 모양이 다르게 섞여 나오도록 설정합니다.
- Inspector > Particle System 컴포넌트 > Texture Sheet Animation 모듈
- Start Frame: 우측 화살표 클릭 > Random Between Two Constants 선택
- 값 입력: 0 과 2 (생성 시 0번 혹은 1번 이미지 중 하나를 무작위 선택)
- 애니메이션 고정 (Frame over Time)
연기가 날아가면서 모양이 변하지 않고 처음 뽑힌 모양을 유지하게 합니다.
- Inspector > Particle System 컴포넌트
- Frame over Time: 우측 곡선(Curve) 또는 상자 클릭
- 곡선 편집기(하단): 오른쪽 끝에 있는 점(키프레임) 마우스 우클릭 > Delete Key 선택
- 결과: 수평선 형태가 되어 시간이 지나도 이미지가 바뀌지 않음
- 방출 각도 조절 (Angle)
-
위치: Inspector > Particle System 컴포넌트 > Shape
- Angle 5로 설정: 파티클이 퍼지는 범위를 좁혀서 연기가 직선에 가깝게 올라가도록 만듭니다.
- 방출 지점 밀집 (Radius)
- Radius 0으로 설정: 넓은 원 영역이 아니라 정확히 한 점에서 파티클이 생성됩니다.
🔍 파티클 시스템에 무작위성을 더 추가
위치: Inspector > Particle System
-
수명 설정 (Start Lifetime)
연기가 사라지는 시간을 무작위로 설정하여 소멸 지점을 다르게 합니다.
- 속성: Start Lifetime -> 우측 화살표 -> Random Between Two Constants
- 설정 값: 1.5 와 3
- 효과: 어떤 연기는 빨리 사라지고, 어떤 연기는 더 멀리까지 날아갑니다.
- 속도 설정 (Start Speed)
연기가 올라가는 속도에 변화를 줍니다.
- 속성: Start Speed -> 우측 화살표 -> Random Between Two Constants
- 설정 값: 0.5 와 1
- 효과: 연기 덩어리들이 서로 다른 속도로 솟아올라 더 역동적으로 보입니다.
- 크기 설정 (Start Size)
연기 입자의 크기를 불규칙하게 만듭니다.
- 속성: Start Size -> 우측 화살표 -> Random Between Two Constants
- 설정 값: 0.3 과 0.5
- 효과: 큰 연기와 작은 연기가 섞여 나와 획일적인 느낌이 사라집니다.
🔍 연기가 사라지는 디테일 추가
-
투명도 변화 설정 (Color over Lifetime)
연기가 시작 때는 선명했다가, 사라지기 직전에는 투명하게 사라지도록 만듭니다.
- Inspector > Particle System > Color over Lifetime 모듈 체크 및 확장
- 속성: Color 상자 클릭 (그라디언트 편집기 열기)
- 조작: 오른쪽 상단 마커(Alpha 마커) 클릭
- Alpha 값: 0 으로 설정
- 크기 변화 설정 (Size over Lifetime)
연기가 시작 때는 덩어리졌다가 서서히 작아지게 만듭니다.
- Inspector > Particle System > Size over Lifetime 모듈 체크 및 확장
- 속성: Size 상자(그래프) 클릭
- 사전 설정(Preset): 하단 5번째 옵션 선택 (오른쪽 아래로 내려가는 곡선)
- 조작: Ctrl(Cmd)을 누른 채 그래프의 점들을 드래그하여 곡선 모양 조절
- 효과: 처음에는 설정한 크기(Start Size)로 시작했다가, 수명이 다할 때쯤 0이 되어 사라집니다.
🔍 SmokeEffect 프리팹 적용 및 배치 정리
- SmokeEffect 게임 오브젝트를 기반으로 프리팹을 생성 하고 씬에 있는 기존 프리팹을 삭제합니다.
- 프리팹 편집 모드에서 적 프리팹을 엽니다 .
- 프로젝트 창 에서 SmokeEffect 프리팹을 클릭하고 드래그하여 계층 구조 창 에서 Enemy GameObject 위로 놓으면 SmokeEffect 프리팹이 Enemy GameObject 의 자식 GameObject가 됩니다 .
- 씬 뷰 에서 도구 오버레이의 이동 도구를 선택하고 SmokeEffect 게임 오브젝트를 배치하여 연기가 Enemy 게임 오브젝트 의 위쪽에서 나오는 것처럼 보이도록 합니다 .
- 인스펙터 창 에서 파티클 시스템 구성 요소의 기본 모듈 에 있는 시뮬레이션 공간 속성 드롭다운을 열고 월드를 선택합니다 .
- Local : 파티클이 부모의 좌표계에 갇힘연기가 적 머리에 풀로 붙인 듯 따라다님.
- World : 파티클이 생성 후 세계 좌표에 남음. 적이 움직이면 뒤에 연기 꼬리가 생김.
###🔍 적 스크립트 수정
using UnityEngine;
public class EnemyController : MonoBehaviour
{
// Public variables
public float speed;
public bool vertical;
public float changeTime = 3.0f;
public bool isBroken { get { return broken; } }
public ParticleSystem smokeParticleEffect;
// Private variables
Rigidbody2D rigidbody2d;
Animator animator;
float timer;
int direction = 1;
bool broken = true;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
timer = changeTime;
}
// Update is called every frame
void Update()
{
timer -= Time.deltaTime;
if (timer < 0)
{
direction = -direction;
timer = changeTime;
}
}
// FixedUpdate has the same call rate as the physics system
void FixedUpdate()
{
if (!broken)
{
return;
}
Vector2 position = rigidbody2d.position;
if (vertical)
{
position.y = position.y + speed * direction * Time.deltaTime;
animator.SetFloat("Move X", 0); // "Move X"라는 변수 값을 0으로 만듦
animator.SetFloat("Move Y", direction);
}
else
{
position.x = position.x + speed * direction * Time.deltaTime;
animator.SetFloat("Move X", direction);
animator.SetFloat("Move Y", 0);
}
rigidbody2d.MovePosition(position);
}
void OnTriggerEnter2D(Collider2D other)
{
PlayerController player = other.gameObject.GetComponent<PlayerController>();
if (player != null)
{
player.ChangeHealth(-1);
}
}
public void Fix()
{
broken = false;
// 적 게임 오브젝트를 물리 시스템의 충돌 시뮬레이션에서 제외.
// 투사체가 더 이상 적과 충돌하지 않으며 적 캐릭터에게 피해를 못 주게 됨.
rigidbody2d.simulated = false;
animator.SetTrigger("Fixed");
smokeParticleEffect.Stop(); // 고친 후 연기 안 남
}
}
Hierarchy 창 에서 SmokeEffect 자식 GameObject를 클릭하고 드래그하여 Smoke Effect 속성 위로 가져다 놓습니다.