DEG-61 [FEAT] 플레이어 이펙트 추가

This commit is contained in:
Jay 2025-05-08 17:28:44 +09:00
parent b05ee73207
commit 180220a98d
10 changed files with 43 additions and 15 deletions

BIN
Assets/JAY/Prefabs/ef_6.prefab (Stored with Git LFS)

Binary file not shown.

BIN
Assets/JAY/Prefabs/ef_9.prefab (Stored with Git LFS)

Binary file not shown.

BIN
Assets/JAY/Prefabs/ef_9_root.prefab (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: e1c992841fb286344abd60f364376eaa guid: 1d3a4e169aaf82a4697f426f27653a99
PrefabImporter: PrefabImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@ -26,7 +26,7 @@ public class EffectManager : Singleton<EffectManager>
Instantiate(prefab, position, Quaternion.identity); Instantiate(prefab, position, Quaternion.identity);
} }
public void PlayEffect(Vector3 position, Quaternion rotation, EffectType type) public GameObject PlayEffect(Vector3 pos, Quaternion rot, EffectType type)
{ {
GameObject prefab = null; GameObject prefab = null;
@ -38,10 +38,13 @@ public class EffectManager : Singleton<EffectManager>
} }
if (prefab != null) if (prefab != null)
Instantiate(prefab, position, rotation); return Instantiate(prefab, pos, rot);
return null;
} }
protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode) protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{ {
// TODO: 필요하면 씬 전환 시 이펙트 초기화 처리 // TODO: 필요하면 씬 전환 시 이펙트 초기화 처리

View File

@ -6,6 +6,8 @@ public class PlayerActionAttack : IPlayerAction {
private int comboStep = 1; private int comboStep = 1;
private bool comboQueued = false; private bool comboQueued = false;
private bool canReceiveCombo = false; private bool canReceiveCombo = false;
public int CurrentComboStep => comboStep;
public bool IsActive { get; private set; } public bool IsActive { get; private set; }

View File

@ -51,7 +51,6 @@ public class PlayerActionDash : IPlayerAction
float dist = Vector3.Distance(currentEffectAnchorPos, lastEffectPos); float dist = Vector3.Distance(currentEffectAnchorPos, lastEffectPos);
if (dist >= effectSpacing) if (dist >= effectSpacing)
{ {
Debug.DrawLine(currentEffectAnchorPos, currentEffectAnchorPos + Vector3.up * 1f, Color.green, 1f);
EffectManager.Instance.PlayEffect(currentEffectAnchorPos, EffectManager.EffectType.Dash); EffectManager.Instance.PlayEffect(currentEffectAnchorPos, EffectManager.EffectType.Dash);
lastEffectPos = currentEffectAnchorPos; lastEffectPos = currentEffectAnchorPos;
} }

View File

@ -294,6 +294,7 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함 if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함
if (_currentAction == _attackAction) { if (_currentAction == _attackAction) {
Debug.Log("공격 시작!");
_attackAction.EnableCombo(); _attackAction.EnableCombo();
_weaponController.AttackStart(); _weaponController.AttackStart();
} }
@ -302,6 +303,7 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
public void SetAttackComboFalse() public void SetAttackComboFalse()
{ {
if (_currentAction == _attackAction) { if (_currentAction == _attackAction) {
Debug.Log("공격 종료@");
// 이벤트 중복 호출? 공격 종료 시 SetAttackComboFalse가 아니라 ~True로 끝나서 오류 발생. (공격 안하는 상태여도 공격으로 판정됨) // 이벤트 중복 호출? 공격 종료 시 SetAttackComboFalse가 아니라 ~True로 끝나서 오류 발생. (공격 안하는 상태여도 공격으로 판정됨)
_attackAction.DisableCombo(); _attackAction.DisableCombo();
_weaponController.AttackEnd(); // IsAttacking = false로 변경 _weaponController.AttackEnd(); // IsAttacking = false로 변경
@ -310,12 +312,31 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
public void PlayAttackEffect() public void PlayAttackEffect()
{ {
if (_weaponController != null && _weaponController.AttackEffectAnchor != null) if (_attackAction == null) return;
{
Vector3 pos = _weaponController.AttackEffectAnchor.position;
Quaternion rot = _weaponController.AttackEffectAnchor.rotation;
EffectManager.Instance.PlayEffect(pos, rot, EffectManager.EffectType.Attack); // 현재 콤보 단계 (1~4)
int comboStep = _attackAction.CurrentComboStep;
// 홀수면 기본 방향 (오→왼), 짝수면 반전 (왼→오)
bool isMirror = comboStep % 2 != 0;
Vector3 basePos = CharacterController.transform.position;
Vector3 forward = CharacterController.transform.forward;
float forwardPos = CurrentState == PlayerState.Move ? 1f : 0.2f;
// 이펙트 위치: 위로 0.5 + 앞으로 약간
Vector3 pos = basePos + Vector3.up * 0.5f + forward * forwardPos;
Quaternion rot = Quaternion.LookRotation(forward, Vector3.up) * Quaternion.Euler(0, 90, 0);
GameObject effect = EffectManager.Instance.PlayEffect(pos, rot, EffectManager.EffectType.Attack);
// 반전이 필요한 경우, X축 스케일 -1
if (isMirror && effect != null)
{
Vector3 scale = effect.transform.localScale;
scale.z *= -1;
effect.transform.localScale = scale;
} }
} }

View File

@ -19,6 +19,9 @@ public class PlayerStateHit : IPlayerState
// 이펙트 및 카메라 흔들림 // 이펙트 및 카메라 흔들림
_playerController.PlayHitEffect(); _playerController.PlayHitEffect();
_playerController.ShakeCamera(); _playerController.ShakeCamera();
Vector3 pos = _playerController.CharacterController.transform.position + Vector3.up * 0.5f;
EffectManager.Instance.PlayEffect(pos, EffectManager.EffectType.Hit);
// 타이머 초기화 // 타이머 초기화
timer = 0f; timer = 0f;

View File

@ -37,7 +37,7 @@ public class Animation_seq : MonoBehaviour
} }
else else
{ {
Destroy(gameObject); // 애니메이션 끝나면 제거 Destroy(transform.root.gameObject); // 최상위 부모 삭제
} }
} }
} }