2026-04-01 상호작용

This commit is contained in:
2026-04-01 18:05:42 +09:00
parent 902b1b76fb
commit 4cbd9787b8
11 changed files with 89 additions and 17 deletions

Binary file not shown.

View File

@@ -31,7 +31,7 @@ public void InteractClose()
public void InteractExec(PlayerCharacterController player) public void InteractExec(PlayerCharacterController player)
{ {
player.transform.position = gameObject.transform.position; player.PointSitAction(this.transform);
player.transform.rotation = gameObject.transform.rotation; GameManager.Instance.InGameUI.InteractionVisible(false);
} }
} }

View File

@@ -16,6 +16,11 @@ public void VisibleCrossHair(bool isOn)
_crosshairRoot.SetActive(isOn); _crosshairRoot.SetActive(isOn);
} }
public void InteractionVisible(bool isOn)
{
Interaction.gameObject.SetActive(isOn);
}
public SplitWindowUI GetSplitWindowUI() public SplitWindowUI GetSplitWindowUI()
{ {
return SplitWindow; return SplitWindow;

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using Unity.Cinemachine; using Unity.Cinemachine;
using Unity.VisualScripting; using Unity.VisualScripting;
@@ -79,6 +80,7 @@ public enum PlayerRotationMode {CameraCoupled, CameraDecoupled}
//상호작용 //상호작용
public SphereCollider InteractionCollider; public SphereCollider InteractionCollider;
public List<IInteractable> InteractionTargets = new List<IInteractable>(); public List<IInteractable> InteractionTargets = new List<IInteractable>();
private bool _actionExitRequested = false;
//무기 //무기
//[SerializeField] private Weapon _weapon; //[SerializeField] private Weapon _weapon;
@@ -150,6 +152,18 @@ private void PlayerDebug()
#region #region
private void StateUpdate() private void StateUpdate()
{ {
if (_stateMachine.CurrentState == PlayerState.Trans) return;
if (_stateMachine.CurrentState == PlayerState.Action)
{
// Action 중 탈출 입력 감지
if (_moveInput.sqrMagnitude > Mathf.Epsilon || _actionExitRequested)
{
EndAction();
_actionExitRequested = false;
}
return;
}
if (_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer > 0f) if (_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer > 0f)
return; // 관성상태면 상태변환 안함 return; // 관성상태면 상태변환 안함
else if(_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer <= 0f) else if(_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer <= 0f)
@@ -241,7 +255,8 @@ private void WorkGravity()
#region #region
private void Movement() private void Movement()
{ {
if (_stateMachine.CurrentState == PlayerState.Action) return;
if (_stateMachine.CurrentState == PlayerState.Trans) return;
if (_stateMachine.CurrentState == PlayerState.Inertia) return; if (_stateMachine.CurrentState == PlayerState.Inertia) return;
//구르기중일때 전용 로직 //구르기중일때 전용 로직
@@ -378,6 +393,12 @@ private void OnAnimatorMove()
{ {
_rootMotionVelocity = _anim.deltaPosition / Time.deltaTime; _rootMotionVelocity = _anim.deltaPosition / Time.deltaTime;
} }
if (_stateMachine.CurrentState == PlayerState.Action || _stateMachine.CurrentState == PlayerState.Trans)
{
_cController.Move(_anim.deltaPosition);
transform.rotation *= _anim.deltaRotation;
}
} }
private void ApplyMove() private void ApplyMove()
{ {
@@ -403,10 +424,38 @@ private void JumpAction()
} }
#endregion #endregion
#region #region
private void PointSitAction() public void PointSitAction(Transform trn)
{ {
_cController.enabled = false;
_stateMachine.ChangeState(PlayerState.Action);
transform.position = trn.position;
transform.rotation = trn.rotation;
_cController.enabled = true;
_anim.SetBool("IsSit",true);
}
#endregion
#region
public void EndAction()
{
if (_stateMachine.CurrentState != PlayerState.Action) return;
_anim.SetBool("IsSit", false);
float FreezeTime = 2f;
_stateMachine.ChangeState(PlayerState.Trans);
_moveCutTimer = FreezeTime;
_ = Util.RunDelayed(FreezeTime, () => {
_stateMachine.ChangeState(PlayerState.Idle);
RotationMode = PlayerRotationMode.CameraCoupled;
GameManager.Instance.InGameUI.InteractionVisible(true);
}, default);
} }
#endregion #endregion
@@ -438,6 +487,7 @@ public void SprintInput(InputState inputState)
} }
public void JumpInput(InputState inputState) public void JumpInput(InputState inputState)
{ {
if (ActionExitCheck()) return;
if (_stateMachine.CanJump()) if (_stateMachine.CanJump())
{ {
if (inputState == InputState.Started) if (inputState == InputState.Started)
@@ -533,10 +583,14 @@ public void AimToggleInput(InputState inputState)
public void InteractInput() public void InteractInput()
{ {
if (ActionExitCheck()) return;
if (InteractionTargets.Count > 0) if (InteractionTargets.Count > 0)
{ {
IInteractable target = InteractionTargets[0]; IInteractable target = InteractionTargets[0];
target.InteractExec(this); // 실제 상호작용 실행 target.InteractExec(this); // 실제 상호작용 실행
RotationMode = PlayerRotationMode.CameraDecoupled;
} }
} }
@@ -587,6 +641,14 @@ public void SetCursorLockState(bool isLocked)
} }
#endregion #endregion
private bool ActionExitCheck()
{
if (_stateMachine.CurrentState == PlayerState.Action)
_actionExitRequested = true;
return _actionExitRequested;
}
private void OnTriggerEnter(Collider other) private void OnTriggerEnter(Collider other)
{ {
// 상호작용 객체인지 확인 // 상호작용 객체인지 확인

View File

@@ -1 +1 @@
public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Hit, Dead, Inertia, None } public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Hit, Dead, Inertia, Action, Trans, None }

View File

@@ -57,13 +57,13 @@ public void SetMaxJumpCount(int maxCount)
#region #region
//지상 이동이 가능한가? //지상 이동이 가능한가?
public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia); public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia && CurrentState != PlayerState.Action && CurrentState != PlayerState.Trans);
//점프가 가능한 상태인가? //점프가 가능한 상태인가?
public bool CanJump() public bool CanJump()
{ {
bool jumpAlreadyMax = (_maxJumpCount <= _jumpCount); bool jumpAlreadyMax = (_maxJumpCount <= _jumpCount);
return IsGrounded && !IsMoveCut && !jumpAlreadyMax && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia); return IsGrounded && !IsMoveCut && !jumpAlreadyMax && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia && CurrentState != PlayerState.Action && CurrentState != PlayerState.Trans);
} }
//대쉬가 가능한 상태인가? //대쉬가 가능한 상태인가?
public bool CanDodge() public bool CanDodge()
@@ -79,6 +79,8 @@ public bool CanDodge()
if (IsMoveCut) return false; if (IsMoveCut) return false;
if (CurrentState == PlayerState.Inertia) return false; if (CurrentState == PlayerState.Inertia) return false;
if (CurrentState == PlayerState.Action) return false;
if (CurrentState == PlayerState.Trans) return false;
// 스태미나 시스템이 있다면 체크 // 스태미나 시스템이 있다면 체크
// if (CurrentStamina < DodgeCost) return false; // if (CurrentStamina < DodgeCost) return false;
@@ -86,7 +88,7 @@ public bool CanDodge()
return true; return true;
} }
//공중에서 조작 가능한 상태인가? //공중에서 조작 가능한 상태인가?
public bool CanControlInAir() => !IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Jump || CurrentState == PlayerState.Fall) && (CurrentState != PlayerState.Inertia); public bool CanControlInAir() => !IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Jump || CurrentState == PlayerState.Fall) && (CurrentState != PlayerState.Inertia && CurrentState != PlayerState.Action && CurrentState != PlayerState.Trans);
//공격이 가능한 상태인가? //공격이 가능한 상태인가?
public bool CanAttack() public bool CanAttack()
{ {
@@ -101,6 +103,9 @@ public bool CanAttack()
if (CurrentState == PlayerState.Dodge || CurrentState == PlayerState.Inertia) if (CurrentState == PlayerState.Dodge || CurrentState == PlayerState.Inertia)
return false; return false;
if (CurrentState == PlayerState.Action || CurrentState == PlayerState.Trans)
return false;
// (Idle, Walk, Run, Jump, Fall 상태에서 공격 가능) // (Idle, Walk, Run, Jump, Fall 상태에서 공격 가능)
return true; return true;
} }

View File

@@ -387,7 +387,7 @@ AnimatorStateTransition:
serializedVersion: 3 serializedVersion: 3
m_TransitionDuration: 0.25 m_TransitionDuration: 0.25
m_TransitionOffset: 0 m_TransitionOffset: 0
m_ExitTime: 0.8 m_ExitTime: 0.5
m_HasExitTime: 1 m_HasExitTime: 1
m_HasFixedDuration: 1 m_HasFixedDuration: 1
m_InterruptionSource: 0 m_InterruptionSource: 0