개요
캐릭터가 대시할 때 시각적으로 속도감과 몰입감을 주기 위한 연출로, 잔상 느낌의 이펙트를 구현하였다.
특히 이펙트가 이동 경로를 따라 자연스럽게 생성되도록 개선하는 과정이 핵심이었다.
내용
1. EffectManager 구조 설계
싱글톤 방식으로 관리
PlayEffect(Vector3 position, EffectType type)을 통해 타입별 이펙트 실행
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class EffectManager : Singleton<EffectManager>
{
[SerializeField] private GameObject hitEffectPrefab;
[SerializeField] private GameObject dashEffectPrefab;
[SerializeField] private GameObject attackEffectPrefab;
[SerializeField] private GameObject walkEffectPrefab;
public enum EffectType { Attack, Dash, Hit, Walk }
public void PlayEffect(Vector3 position, EffectType type)
{
GameObject prefab = null;
switch (type)
{
case EffectType.Attack: prefab = attackEffectPrefab; break;
case EffectType.Dash: prefab = dashEffectPrefab; break;
case EffectType.Hit: prefab = hitEffectPrefab; break;
case EffectType.Walk: prefab = walkEffectPrefab; break;
}
if (prefab != null)
Instantiate(prefab, position, Quaternion.identity);
}
protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// TODO: 필요하면 씬 전환 시 이펙트 초기화 처리
}
}
2. 이펙트 위치 문제 해결
처음엔 player.transform.position을 기준으로 생성 → 이펙트가 캐릭터 옆에 뜨는 현상 발생
해결 방법:
- 캐릭터에 DashEffectAnchor라는 빈 오브젝트 추가
- 이 앵커를 기준으로 이펙트를 생성해 정확한 위치 보정
3. 이동 거리 기준 생성 조건 추가
이펙트가 짧은 시간 동안 너무 많이 생성되는 것 방지
Vector3.Distance()로 이전 위치와 현재 위치 비교 → 일정 거리 이상일 때만 생성
private void DoDash()
{
timer += Time.deltaTime;
if (timer < duration)
{
var moveVector = direction * dashSpeed * Time.deltaTime;
player.CharacterController.Move(moveVector);
// 일정 거리 이상 이동 시 이펙트 생성
Vector3 currentEffectAnchorPos = player.DashEffectAnchor.position;
float dist = Vector3.Distance(currentEffectAnchorPos, lastEffectPos);
if (dist >= effectSpacing)
{
Debug.DrawLine(currentEffectAnchorPos, currentEffectAnchorPos + Vector3.up * 1f, Color.green, 1f);
EffectManager.Instance.PlayEffect(currentEffectAnchorPos, EffectManager.EffectType.Dash);
lastEffectPos = currentEffectAnchorPos;
}
}
else
{
EndAction();
}
}
4. 이펙트 프리팹 세팅
Looping 체크 해제, Stop Action을 Destroy로 설정 → 한번만 실행되게 설정
Shape 모듈에서 X축 위치 조절로 중심 정렬
5. 디버깅 과정
Debug.DrawLine()으로 앵커 위치 확인
Debug.DrawLine(currentEffectAnchorPos, currentEffectAnchorPos + Vector3.up * 1f, Color.green, 1f);
회전, 쉐이프 위치 등을 직접 수정하면서 방향 문제 해결
추후 이슈 방지를 위한 EffectManager null 체크 추가
이펙트가 추가되면 변경된 PlayerActionDash.cs의 전체 코드는 아래와 같다.
using UnityEngine;
public class PlayerActionDash : IPlayerAction
{
private PlayerController player;
private float duration = 0.25f;
private float timer;
private Vector3 direction;
private float dashSpeedMultiplier = 3f;
private float dashSpeed;
private Vector3 lastEffectPos;
private float effectSpacing = 0.8f;
public bool IsActive { get; private set; }
public void StartAction(PlayerController player)
{
this.player = player;
IsActive = true;
timer = 0f;
// 조이스틱 입력값 있으면 그 방향, 없으면 캐릭터가 바라보는 방향
direction = player.GetMoveDirectionOrForward().normalized;
// 대시 속도 = 이동 속도 x 배수
dashSpeed = player.moveSpeed * dashSpeedMultiplier;
lastEffectPos = player.DashEffectAnchor.position;
if (EffectManager.Instance == null)
Debug.LogError("이펙트 매니저 인스턴스가 null입니다!");
}
public void UpdateAction()
{
if (!IsActive) return;
DoDash();
}
private void DoDash()
{
timer += Time.deltaTime;
if (timer < duration)
{
var moveVector = direction * dashSpeed * Time.deltaTime;
player.CharacterController.Move(moveVector);
// 일정 거리 이상 이동 시 이펙트 생성
Vector3 currentEffectAnchorPos = player.DashEffectAnchor.position;
float dist = Vector3.Distance(currentEffectAnchorPos, lastEffectPos);
if (dist >= effectSpacing)
{
Debug.DrawLine(currentEffectAnchorPos, currentEffectAnchorPos + Vector3.up * 1f, Color.green, 1f);
EffectManager.Instance.PlayEffect(currentEffectAnchorPos, EffectManager.EffectType.Dash);
lastEffectPos = currentEffectAnchorPos;
}
}
else
{
EndAction();
}
}
public void EndAction()
{
IsActive = false;
player.OnActionEnded(this);
player = null;
}
}
결과물은 아래와 같다.
느낀 점
이번에 파티클 시스템을 어떤식으로 수정할지 테스트하면서 수정하는 게 이렇게 해도 되나 살짝 아리송하면서도 재밌었다. 확실히 이펙트가 생기니까 움직임이 달라보여서 좋았다. 내일 남은 이펙트 작업 이어가야겠다.
'공부 > [TIL] Game Bootcamp' 카테고리의 다른 글
[TIL] #12. 통합 후 카메라 흔들림 버그 수정 : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (0) | 2025.05.09 |
---|---|
[TIL] #11. 공격, 피격 이펙트 : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (1) | 2025.05.08 |
[TIL] #9. 플레이어 공격, 피격까지(대시는 덤) : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (0) | 2025.05.02 |
[TIL] #7. 플레이어 피격 : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (1) | 2025.04.29 |
[TIL] #6. Animation event 작동 안함(뭔가 만들었다면 꼭 초기화를 하자) : 멋쟁이사자처럼부트캠프 Unity 게임 개발 3기 (0) | 2025.04.25 |