캐릭터 애니메이션 로직 변경
This commit is contained in:
parent
a3c295285f
commit
1fbbb44f02
@ -46,6 +46,7 @@ GameObject:
|
||||
- component: {fileID: 3365694194251356714}
|
||||
- component: {fileID: 8736963048629680089}
|
||||
- component: {fileID: 127430239903465757}
|
||||
- component: {fileID: 6612028984666579384}
|
||||
- component: {fileID: 3095965496140440094}
|
||||
- component: {fileID: 7606279200344222219}
|
||||
- component: {fileID: 3805557225565208309}
|
||||
@ -158,6 +159,18 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 38cb67223546879468e9c0655893e025, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &6612028984666579384
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5259510642736920361}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3af7fa0aab2d45b19f78c34b028732b3, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &3095965496140440094
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
BIN
Assets/_DDD/_Addressables/So/RestaurantData/DataObjects/RestaurantPlayerData.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_Addressables/So/RestaurantData/DataObjects/RestaurantPlayerData.asset
(Stored with Git LFS)
Binary file not shown.
@ -2,6 +2,7 @@ namespace DDD.Restaurant
|
||||
{
|
||||
public interface IMovementConstraint
|
||||
{
|
||||
|
||||
public bool IsBlockingMovement();
|
||||
public float GetMovementSpeedMultiplier();
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
using DDD.Restaurant;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
|
@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
[RequireComponent(typeof(SpineController))]
|
||||
public class CharacterAnimation : MonoBehaviour
|
||||
@ -15,6 +15,11 @@ protected virtual void Awake()
|
||||
protected virtual void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
|
@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public enum CarriableType
|
||||
{
|
||||
|
@ -5,7 +5,14 @@
|
||||
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public class CharacterInteraction : MonoBehaviour, IInteractor, IEventHandler<RestaurantInteractionEvent>
|
||||
public interface IInteractionStateProvider
|
||||
{
|
||||
bool IsInteracting();
|
||||
float GetMovementSpeedMultiplier();
|
||||
bool IsMovementBlocked();
|
||||
}
|
||||
|
||||
public class CharacterInteraction : MonoBehaviour, IInteractor, IEventHandler<RestaurantInteractionEvent>, IInteractionStateProvider
|
||||
{
|
||||
[EnumToggleButtons, SerializeField] protected InteractionType _availableInteractions;
|
||||
[SerializeField, ReadOnly] protected Collider[] _nearColliders = new Collider[10];
|
||||
@ -142,5 +149,9 @@ protected void InitializeInteractionSolvers(Dictionary<InteractionType, Type> ty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsInteracting() => _interactingTarget != null;
|
||||
public virtual float GetMovementSpeedMultiplier() => 1f;
|
||||
public virtual bool IsMovementBlocked() => false;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public class CharacterMovement : MonoBehaviour
|
||||
{
|
||||
private CharacterMovementConstraint _constraint;
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_constraint = gameObject.AddComponent<CharacterMovementConstraint>();
|
||||
|
||||
}
|
||||
|
||||
public virtual bool CanMove()
|
||||
@ -24,5 +23,19 @@ public virtual bool CanMove()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual float GetMovementSpeedMultiplier()
|
||||
{
|
||||
var constraints = GetComponents<IMovementConstraint>();
|
||||
float minMultiplier = 1f;
|
||||
|
||||
foreach (var constraint in constraints)
|
||||
{
|
||||
float multiplier = constraint.GetMovementSpeedMultiplier();
|
||||
minMultiplier = Mathf.Min(minMultiplier, multiplier);
|
||||
}
|
||||
|
||||
return minMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
[RequireComponent(typeof(CharacterAnimation))]
|
||||
public class CharacterMovementConstraint : MonoBehaviour, IMovementConstraint
|
||||
{
|
||||
private CharacterAnimation _characterAnimation;
|
||||
private IInteractionStateProvider _interactionStateProvider;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_characterAnimation = GetComponent<CharacterAnimation>();
|
||||
_interactionStateProvider = GetComponent<IInteractionStateProvider>();
|
||||
}
|
||||
|
||||
public bool IsBlockingMovement()
|
||||
{
|
||||
if (GetComponent<CharacterAnimation>().IsPlayingAnimation())
|
||||
if (_characterAnimation.IsPlayingAnimation())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_interactionStateProvider != null && _interactionStateProvider.IsMovementBlocked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetMovementSpeedMultiplier()
|
||||
{
|
||||
if (IsBlockingMovement())
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
if (_interactionStateProvider != null)
|
||||
{
|
||||
return _interactionStateProvider.GetMovementSpeedMultiplier();
|
||||
}
|
||||
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using Pathfinding;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
[RequireComponent(typeof(AIPath))]
|
||||
public class NpcMovement : CharacterMovement, IAiMovement, ICurrentDirection
|
||||
|
@ -1,48 +1,186 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public enum PlayerTaskAnimationState
|
||||
{
|
||||
None = 0,
|
||||
Dashing
|
||||
}
|
||||
|
||||
public enum PlayerActionAnimationState
|
||||
{
|
||||
None = 0,
|
||||
CleaningTable = 1,
|
||||
}
|
||||
|
||||
public enum PlayerDefaultAnimationState
|
||||
{
|
||||
None = 0,
|
||||
Idle = 1,
|
||||
Moving = 2,
|
||||
}
|
||||
|
||||
[RequireComponent(typeof(PlayerMovement))]
|
||||
public class PlayerAnimation : CharacterAnimation
|
||||
{
|
||||
private PlayerMovement _playerMovement;
|
||||
private IMovementState _movementState;
|
||||
private PlayerTaskAnimationState _currentTaskAnimationState = PlayerTaskAnimationState.None;
|
||||
private PlayerActionAnimationState _currentActionAnimationState = PlayerActionAnimationState.None;
|
||||
private PlayerDefaultAnimationState _currentDefaultAnimationState = PlayerDefaultAnimationState.None;
|
||||
|
||||
private Dictionary<PlayerTaskAnimationState, string> _taskToAnimation = new()
|
||||
{
|
||||
{ PlayerTaskAnimationState.Dashing, "Dash" },
|
||||
};
|
||||
|
||||
private Dictionary<PlayerActionAnimationState, string> _actionToAnimation = new()
|
||||
{
|
||||
{ PlayerActionAnimationState.CleaningTable, "Cleaning/CleaningTable" },
|
||||
};
|
||||
|
||||
private Dictionary<PlayerDefaultAnimationState, string> _defaultToAnimation = new()
|
||||
{
|
||||
{ PlayerDefaultAnimationState.Idle, "Idle" },
|
||||
{ PlayerDefaultAnimationState.Moving, "RunFast" },
|
||||
};
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
_playerMovement = GetComponent<PlayerMovement>();
|
||||
_movementState = GetComponent<IMovementState>();
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
_playerMovement.OnMoving += OnMove;
|
||||
_playerMovement.OnDashing += OnDash;
|
||||
InitializeTaskAnimations();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
UpdateAnimations();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
if (_playerMovement)
|
||||
|
||||
if (_movementState != null)
|
||||
{
|
||||
_playerMovement.OnMoving -= OnMove;
|
||||
_playerMovement.OnDashing -= OnDash;
|
||||
_movementState.OnDashing -= HandleDashingTask;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMove(bool isMoving)
|
||||
private void InitializeTaskAnimations()
|
||||
{
|
||||
string animationName = isMoving ? RestaurantPlayerAnimationType.Walk : RestaurantPlayerAnimationType.Idle;
|
||||
_spineController.PlayAnimation(animationName, true);
|
||||
_movementState.OnDashing += HandleDashingTask;
|
||||
}
|
||||
|
||||
private void OnDash(float dashTime)
|
||||
|
||||
private void UpdateAnimations()
|
||||
{
|
||||
_spineController.PlayAnimationDuration(RestaurantPlayerAnimationType.Dash, false, duration:dashTime);
|
||||
}
|
||||
// 1순위: Task 애니메이션이 재생 중이면 다른 애니메이션 처리하지 않음
|
||||
if (_currentTaskAnimationState != PlayerTaskAnimationState.None)
|
||||
{
|
||||
_currentActionAnimationState = PlayerActionAnimationState.None;
|
||||
_currentDefaultAnimationState = PlayerDefaultAnimationState.None;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2순위: ActionState 체크
|
||||
var desiredActionState = GetDesiredActionState();
|
||||
if (desiredActionState != PlayerActionAnimationState.None)
|
||||
{
|
||||
if (_currentActionAnimationState != desiredActionState)
|
||||
{
|
||||
_currentDefaultAnimationState = PlayerDefaultAnimationState.None;
|
||||
_currentActionAnimationState = desiredActionState;
|
||||
PlayActionAnimation(_currentActionAnimationState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 3순위: 기본 AnimationState 처리
|
||||
var desiredADefaultState = GetDesiredADefaultState();
|
||||
if (_currentDefaultAnimationState != desiredADefaultState)
|
||||
{
|
||||
_currentDefaultAnimationState = desiredADefaultState;
|
||||
PlayStateAnimation(_currentDefaultAnimationState);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDashingTask(float duration)
|
||||
{
|
||||
_ = PlayTaskAnimation(PlayerTaskAnimationState.Dashing, duration);
|
||||
}
|
||||
|
||||
private async Task PlayTaskAnimation(PlayerTaskAnimationState state, float duration = 0f)
|
||||
{
|
||||
_currentTaskAnimationState = state;
|
||||
|
||||
if (_taskToAnimation.TryGetValue(state, out string animationName))
|
||||
{
|
||||
if (duration > 0f)
|
||||
{
|
||||
_spineController.PlayAnimationDuration(animationName, false, duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
_spineController.PlayAnimation(animationName, false);
|
||||
}
|
||||
}
|
||||
|
||||
await Awaitable.WaitForSecondsAsync(duration);
|
||||
_currentTaskAnimationState = PlayerTaskAnimationState.None;
|
||||
}
|
||||
|
||||
private PlayerActionAnimationState GetDesiredActionState()
|
||||
{
|
||||
// 여기서 현재 액션 상태를 확인하는 로직 구현
|
||||
// 예: 상호작용 컴포넌트에서 상태 가져오기
|
||||
|
||||
return PlayerActionAnimationState.None;
|
||||
}
|
||||
|
||||
private void PlayActionAnimation(PlayerActionAnimationState actionAnimationState)
|
||||
{
|
||||
if (_actionToAnimation.TryGetValue(actionAnimationState, out string animationName))
|
||||
{
|
||||
_spineController.PlayAnimation(animationName, true);
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerDefaultAnimationState GetDesiredADefaultState()
|
||||
{
|
||||
if (_movementState.IsMoving())
|
||||
{
|
||||
return PlayerDefaultAnimationState.Moving;
|
||||
}
|
||||
|
||||
return PlayerDefaultAnimationState.Idle;
|
||||
}
|
||||
|
||||
private void PlayStateAnimation(PlayerDefaultAnimationState state)
|
||||
{
|
||||
if (_defaultToAnimation.TryGetValue(state, out string animationName))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PlayerDefaultAnimationState.None:
|
||||
break;
|
||||
case PlayerDefaultAnimationState.Idle:
|
||||
case PlayerDefaultAnimationState.Moving:
|
||||
_spineController.PlayAnimation(animationName, true);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(state), state, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
@ -12,6 +11,7 @@ public class PlayerInteraction : CharacterInteraction
|
||||
|
||||
private float _interactHeldTime;
|
||||
private bool _isInteracting;
|
||||
private float _interactionStartTime = -1f;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
@ -68,7 +68,7 @@ protected virtual void Update()
|
||||
if (_nearestInteractable != _previousInteractable)
|
||||
{
|
||||
_previousInteractable = _nearestInteractable;
|
||||
OnNearestInteractableChanged(_nearestInteractable);
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), 0f);
|
||||
}
|
||||
|
||||
if (_isInteracting)
|
||||
@ -90,13 +90,17 @@ protected virtual void Update()
|
||||
OnInteractionCompleted();
|
||||
|
||||
ResetInteractionState();
|
||||
OnInteractionHoldProgress(0f);
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnInteractionHoldProgress(ratio);
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), ratio);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), 0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -120,28 +124,9 @@ private void OnInteractPerformed(InputAction.CallbackContext context)
|
||||
|
||||
private void OnInteractCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
OnInteractionHoldProgress(0f);
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), 0f);
|
||||
ResetInteractionState();
|
||||
}
|
||||
|
||||
protected void OnNearestInteractableChanged(IInteractable newTarget)
|
||||
{
|
||||
if (newTarget != null)
|
||||
{
|
||||
BroadcastShowUi(newTarget, CanInteractTo(newTarget), 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
EventBus.Broadcast(GameEvents.HideInteractionUiEvent);
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnInteractionHoldProgress(float ratio)
|
||||
{
|
||||
if (_interactingTarget != null)
|
||||
{
|
||||
BroadcastShowUi(_interactingTarget, CanInteractTo(_interactingTarget), ratio);
|
||||
}
|
||||
_interactionStartTime = -1f;
|
||||
}
|
||||
|
||||
protected override void OnInteractionCompleted()
|
||||
@ -149,8 +134,14 @@ protected override void OnInteractionCompleted()
|
||||
|
||||
}
|
||||
|
||||
private void BroadcastShowUi(IInteractable interactable, bool canInteract, float ratio)
|
||||
private void BroadcastInteractionUi(IInteractable interactable, bool canInteract, float ratio)
|
||||
{
|
||||
if (interactable == null)
|
||||
{
|
||||
EventBus.Broadcast(GameEvents.HideInteractionUiEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
var displayParameters = interactable.GetDisplayParameters();
|
||||
var evt = GameEvents.ShowInteractionUiEvent;
|
||||
evt.CanInteract = canInteract;
|
||||
@ -167,7 +158,7 @@ protected void ResetInteractionState()
|
||||
_isInteracting = false;
|
||||
_interactingTarget = null;
|
||||
_interactHeldTime = 0f;
|
||||
OnInteractionHoldProgress(0f);
|
||||
BroadcastInteractionUi(_nearestInteractable, CanInteractTo(_nearestInteractable), 0f);
|
||||
}
|
||||
|
||||
protected IInteractable GetNearestInteractable()
|
||||
@ -206,5 +197,26 @@ public override bool FetchSolverTypeForInteraction(InteractionType type, out Typ
|
||||
|
||||
return base.FetchSolverTypeForInteraction(type, out solverType);
|
||||
}
|
||||
|
||||
public override bool IsInteracting() => _isInteracting;
|
||||
|
||||
public override float GetMovementSpeedMultiplier()
|
||||
{
|
||||
if (_isInteracting == false)
|
||||
{
|
||||
_interactionStartTime = -1f;
|
||||
return 1f;
|
||||
}
|
||||
|
||||
if (_interactionStartTime < 0f)
|
||||
{
|
||||
_interactionStartTime = Time.time;
|
||||
}
|
||||
|
||||
float elapsed = Time.time - _interactionStartTime;
|
||||
float normalizedTime = Mathf.Clamp01(elapsed / _restaurantPlayerDataSo.DecelerationTime);
|
||||
|
||||
return Mathf.Clamp01(_restaurantPlayerDataSo.InteractionDecelerationCurve.Evaluate(normalizedTime));
|
||||
}
|
||||
}
|
||||
}
|
@ -7,27 +7,32 @@
|
||||
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public interface IMovementState
|
||||
{
|
||||
bool IsMoving();
|
||||
bool IsDashing();
|
||||
Action<float> OnDashing { get; set; }
|
||||
}
|
||||
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
[RequireComponent(typeof(BoxCollider))]
|
||||
public class PlayerMovement : CharacterMovement, ICurrentDirection
|
||||
public class PlayerMovement : CharacterMovement, ICurrentDirection, IMovementState
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private Rigidbody _rigidbody;
|
||||
private BoxCollider _boxCollider;
|
||||
private RestaurantPlayerData _playerDataSo;
|
||||
|
||||
private Vector3 _inputDirection;
|
||||
private Vector3 _currentDirection;
|
||||
private Vector3 _currentVelocity;
|
||||
|
||||
private bool _isInputtedMovement;
|
||||
private bool _isMoving;
|
||||
private bool _isDashing;
|
||||
private bool _isDashCooldown;
|
||||
private bool _isInitialized;
|
||||
|
||||
public Action<bool> OnMoving;
|
||||
public Action<float> OnDashing;
|
||||
|
||||
public Action<float> OnDashing { get; set; }
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private MovementDebugVisualizer _debugVisualizer;
|
||||
@ -44,15 +49,13 @@ protected override void Awake()
|
||||
InitializeComponents();
|
||||
}
|
||||
|
||||
private async void Start()
|
||||
private void Start()
|
||||
{
|
||||
await InitializePlayerData();
|
||||
SubscribeToInputEvents();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
|
||||
HandleMovement();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@ -69,6 +72,8 @@ private void OnDestroy()
|
||||
|
||||
#region Initialization
|
||||
|
||||
private RestaurantPlayerData GetPlayerData() => RestaurantData.Instance.PlayerData;
|
||||
|
||||
private void InitializeComponents()
|
||||
{
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
@ -79,46 +84,30 @@ private void InitializeComponents()
|
||||
#endif
|
||||
}
|
||||
|
||||
private System.Threading.Tasks.Task InitializePlayerData()
|
||||
{
|
||||
try
|
||||
{
|
||||
_playerDataSo = RestaurantData.Instance.PlayerData;
|
||||
SubscribeToInputEvents();
|
||||
_isInitialized = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Player data load failed\n{e}");
|
||||
}
|
||||
|
||||
return System.Threading.Tasks.Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void SubscribeToInputEvents()
|
||||
{
|
||||
_playerDataSo.MoveAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Move));
|
||||
_playerDataSo.DashAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Dash));
|
||||
GetPlayerData().MoveAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Move));
|
||||
GetPlayerData().DashAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Dash));
|
||||
|
||||
_playerDataSo.MoveAction.performed += OnMove;
|
||||
_playerDataSo.MoveAction.canceled += OnMove;
|
||||
_playerDataSo.DashAction.performed += OnDash;
|
||||
GetPlayerData().MoveAction.performed += OnMove;
|
||||
GetPlayerData().MoveAction.canceled += OnMove;
|
||||
GetPlayerData().DashAction.performed += OnDash;
|
||||
}
|
||||
|
||||
private void UnsubscribeFromInputEvents()
|
||||
{
|
||||
if (!_playerDataSo) return;
|
||||
if (GetPlayerData() == null) return;
|
||||
|
||||
_playerDataSo.MoveAction.performed -= OnMove;
|
||||
_playerDataSo.MoveAction.canceled -= OnMove;
|
||||
_playerDataSo.DashAction.performed -= OnDash;
|
||||
GetPlayerData().MoveAction.performed -= OnMove;
|
||||
GetPlayerData().MoveAction.canceled -= OnMove;
|
||||
GetPlayerData().DashAction.performed -= OnDash;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Movement
|
||||
|
||||
private void HandleMovement()
|
||||
private void HandleMovement()
|
||||
{
|
||||
if (CanMove())
|
||||
{
|
||||
@ -128,7 +117,7 @@ private void HandleMovement()
|
||||
|
||||
public override bool CanMove()
|
||||
{
|
||||
return base.CanMove() && _playerDataSo.IsMoveEnabled && !_isDashing;
|
||||
return base.CanMove() && GetPlayerData().IsMoveEnabled && !_isDashing;
|
||||
}
|
||||
|
||||
private void Move()
|
||||
@ -141,23 +130,25 @@ private void Move()
|
||||
|
||||
private void UpdateMovementState()
|
||||
{
|
||||
_isMoving = _inputDirection != Vector3.zero;
|
||||
OnMoving?.Invoke(_isMoving);
|
||||
_isInputtedMovement = _inputDirection != Vector3.zero;
|
||||
_isMoving = _isInputtedMovement && _currentVelocity != Vector3.zero;
|
||||
}
|
||||
|
||||
private void UpdateVelocity()
|
||||
{
|
||||
if (_isMoving)
|
||||
float speedMultiplier = GetMovementSpeedMultiplier();
|
||||
|
||||
if (_isInputtedMovement)
|
||||
{
|
||||
Vector3 slideDirection = GetSlideAdjustedDirection(_inputDirection.normalized);
|
||||
Vector3 targetVelocity = slideDirection * _playerDataSo.MoveSpeed;
|
||||
Vector3 targetVelocity = slideDirection * (GetPlayerData().MoveSpeed * speedMultiplier);
|
||||
_currentVelocity = Vector3.MoveTowards(_currentVelocity, targetVelocity,
|
||||
_playerDataSo.Acceleration * Time.fixedDeltaTime);
|
||||
GetPlayerData().Acceleration * Time.fixedDeltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentVelocity = Vector3.MoveTowards(_currentVelocity, Vector3.zero,
|
||||
_playerDataSo.Deceleration * Time.fixedDeltaTime);
|
||||
GetPlayerData().Deceleration * Time.fixedDeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,14 +169,14 @@ private void OnDash(InputAction.CallbackContext context)
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanDash() => _playerDataSo.IsDashEnabled && !_isDashing && !_isDashCooldown;
|
||||
private bool CanDash() => GetPlayerData().IsDashEnabled && !_isDashing && !_isDashCooldown;
|
||||
|
||||
private IEnumerator DashCoroutine()
|
||||
{
|
||||
StartDash();
|
||||
yield return new WaitForSeconds(_playerDataSo.DashTime);
|
||||
yield return new WaitForSeconds(GetPlayerData().DashTime);
|
||||
EndDash();
|
||||
yield return new WaitForSeconds(_playerDataSo.DashCooldown);
|
||||
yield return new WaitForSeconds(GetPlayerData().DashCooldown);
|
||||
ResetDashCooldown();
|
||||
}
|
||||
|
||||
@ -193,10 +184,10 @@ private void StartDash()
|
||||
{
|
||||
_isDashing = true;
|
||||
_isDashCooldown = true;
|
||||
OnDashing?.Invoke(_playerDataSo.DashTime);
|
||||
OnDashing?.Invoke(GetPlayerData().DashTime);
|
||||
|
||||
Vector3 slideDashDirection = GetSlideAdjustedDirection(_currentDirection.normalized);
|
||||
_rigidbody.linearVelocity = slideDashDirection * _playerDataSo.DashSpeed;
|
||||
_rigidbody.linearVelocity = slideDashDirection * GetPlayerData().DashSpeed;
|
||||
}
|
||||
|
||||
private void EndDash()
|
||||
@ -245,7 +236,7 @@ private Vector3 GetSlideAdjustedDirection(Vector3 inputDirection)
|
||||
Vector3 slide = Vector3.ProjectOnPlane(inputDirection, hit.normal).normalized;
|
||||
float slideFactor = CalculateSlideFactor(inputDirection, hit.normal);
|
||||
|
||||
return slideFactor < _playerDataSo.MinSlideFactorThreshold ? Vector3.zero : slide * slideFactor;
|
||||
return slideFactor < GetPlayerData().MinSlideFactorThreshold ? Vector3.zero : slide * slideFactor;
|
||||
}
|
||||
|
||||
private bool TryGetCollisionInfo(Vector3 direction, out RaycastHit hit)
|
||||
@ -253,16 +244,16 @@ private bool TryGetCollisionInfo(Vector3 direction, out RaycastHit hit)
|
||||
Vector3 origin = _boxCollider.bounds.center;
|
||||
Vector3 halfExtents = _boxCollider.bounds.extents;
|
||||
float distance = Mathf.Min(_boxCollider.bounds.size.x, _boxCollider.bounds.size.z);
|
||||
int layerMask = ~_playerDataSo.IgnoreSlidingLayerMask;
|
||||
int layerMask = ~GetPlayerData().IgnoreSlidingLayerMask;
|
||||
|
||||
return Physics.BoxCast(origin, halfExtents * _playerDataSo.BoxCastExtentScale,
|
||||
return Physics.BoxCast(origin, halfExtents * GetPlayerData().BoxCastExtentScale,
|
||||
direction, out hit, transform.rotation, distance, layerMask, QueryTriggerInteraction.Ignore);
|
||||
}
|
||||
|
||||
private float CalculateSlideFactor(Vector3 direction, Vector3 normal)
|
||||
{
|
||||
float dot = Vector3.Dot(direction.normalized, normal);
|
||||
return Mathf.Pow(1f - Mathf.Abs(dot), _playerDataSo.SlidingThreshold);
|
||||
return Mathf.Pow(1f - Mathf.Abs(dot), GetPlayerData().SlidingThreshold);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -270,13 +261,22 @@ private float CalculateSlideFactor(Vector3 direction, Vector3 normal)
|
||||
#if UNITY_EDITOR
|
||||
private void HandleDebugVisualization()
|
||||
{
|
||||
if (_playerDataSo.IsDrawLineDebug)
|
||||
if (GetPlayerData().IsDrawLineDebug)
|
||||
{
|
||||
_debugVisualizer.UpdateVisualization(transform.position, _inputDirection,
|
||||
_currentVelocity, _playerDataSo);
|
||||
_currentVelocity, GetPlayerData());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
public bool IsMoving()
|
||||
{
|
||||
return _isMoving;
|
||||
}
|
||||
|
||||
public bool IsDashing()
|
||||
{
|
||||
return _isDashing;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
@ -33,6 +33,9 @@ public class RestaurantPlayerData : ScriptableObject
|
||||
public float InteractionRadius = 1f;
|
||||
public LayerMask InteractionLayerMask;
|
||||
|
||||
public AnimationCurve InteractionDecelerationCurve;
|
||||
public float DecelerationTime = 0.3f;
|
||||
|
||||
// 디버그
|
||||
public int InputLineSortingOrder = 10;
|
||||
public int VelocityLineSortingOrder = 9;
|
||||
|
@ -10,13 +10,6 @@ public static class CommonConstants
|
||||
public const string BlockImage = "BlockImage";
|
||||
}
|
||||
|
||||
public static class RestaurantPlayerAnimationType
|
||||
{
|
||||
public const string Idle = "Idle";
|
||||
public const string Walk = "RunFast";
|
||||
public const string Dash = "Dash";
|
||||
}
|
||||
|
||||
public static class PathConstants
|
||||
{
|
||||
public const string RawSpritesPathUpper = "ASSETS/_DDD/_RAW/SPRITES/";
|
||||
|
Loading…
Reference in New Issue
Block a user