플레이어 가속, 감속, 충돌 슬라이딩 기능 추가
This commit is contained in:
parent
d5f4b54e6b
commit
ba2ef76e32
@ -6,13 +6,23 @@ namespace DDD
|
||||
[CreateAssetMenu(fileName = "RestaurantPlayerDataSo", menuName = "ScriptableObjects/RestaurantPlayerDataSo")]
|
||||
public class RestaurantPlayerDataSo : ScriptableObject
|
||||
{
|
||||
public bool IsDrawLineDebug = true;
|
||||
|
||||
public bool IsMoveEnabled = true;
|
||||
public float MoveSpeed = 7f;
|
||||
public float Acceleration = 70f;
|
||||
public float Deceleration = 350f;
|
||||
|
||||
public bool IsDashEnabled = true;
|
||||
public float DashSpeed = 20f;
|
||||
public float DashTime = 0.2f;
|
||||
public float DashCooldown = 2f;
|
||||
|
||||
[Tooltip("슬라이딩이 적용되지 않는 충돌체 레이어 (Ground 등)")]
|
||||
public LayerMask IgnoreSlidingLayerMask;
|
||||
|
||||
[Range(0f, 3f), Tooltip("슬라이딩 보정 제곱\n낮을수록 슬라이딩이 잘 됨")]
|
||||
public float SlidingThreshold = 0.5f;
|
||||
|
||||
public string WalkingSfxName;
|
||||
public string DashSfxName;
|
||||
|
@ -2,17 +2,23 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Vector2 = UnityEngine.Vector2;
|
||||
using Vector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
||||
{
|
||||
private Rigidbody _rigidbody;
|
||||
private BoxCollider _boxCollider;
|
||||
|
||||
private RestaurantPlayerDataSo _playerData;
|
||||
private RestaurantPlayerDataSo _playerDataSo;
|
||||
|
||||
private LineRenderer _inputLineRenderer;
|
||||
private LineRenderer _velocityLineRenderer;
|
||||
private Vector3 _inputDirection;
|
||||
private Vector3 _currentDirection;
|
||||
private Vector3 _currentVelocity;
|
||||
private bool _isMoving;
|
||||
private bool _isDashing;
|
||||
private bool _isDashCooldown;
|
||||
@ -24,17 +30,18 @@ public class RestaurantPlayerMovement : RestaurantCharacterMovement
|
||||
private void Awake()
|
||||
{
|
||||
_rigidbody = GetComponent<Rigidbody>();
|
||||
_boxCollider = GetComponent<BoxCollider>();
|
||||
}
|
||||
|
||||
private async void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
_playerData = await AssetManager.LoadAsset<RestaurantPlayerDataSo>(DataConstants.RestaurantPlayerDataSo);
|
||||
_playerDataSo = await AssetManager.LoadAsset<RestaurantPlayerDataSo>(DataConstants.RestaurantPlayerDataSo);
|
||||
|
||||
_playerData.MoveActionReference.action.performed += OnMove;
|
||||
_playerData.MoveActionReference.action.canceled += OnMove;
|
||||
_playerData.DashActionReference.action.performed += OnDash;
|
||||
_playerDataSo.MoveActionReference.action.performed += OnMove;
|
||||
_playerDataSo.MoveActionReference.action.canceled += OnMove;
|
||||
_playerDataSo.DashActionReference.action.performed += OnDash;
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
@ -52,18 +59,96 @@ private void FixedUpdate()
|
||||
{
|
||||
Move();
|
||||
}
|
||||
|
||||
if (_playerDataSo.IsDrawLineDebug)
|
||||
{
|
||||
DrawLineDebug();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_playerData)
|
||||
if (_playerDataSo)
|
||||
{
|
||||
_playerData.MoveActionReference.action.performed -= OnMove;
|
||||
_playerData.MoveActionReference.action.canceled -= OnMove;
|
||||
_playerData.DashActionReference.action.performed -= OnDash;
|
||||
_playerDataSo.MoveActionReference.action.performed -= OnMove;
|
||||
_playerDataSo.MoveActionReference.action.canceled -= OnMove;
|
||||
_playerDataSo.DashActionReference.action.performed -= OnDash;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLineDebug()
|
||||
{
|
||||
Vector3 origin = transform.position;
|
||||
|
||||
if (_inputDirection != Vector3.zero)
|
||||
{
|
||||
Vector3 target = origin + _inputDirection.normalized * 1.5f;
|
||||
if (_inputLineRenderer == null)
|
||||
{
|
||||
_inputLineRenderer = CreateOrGetDebugLineRenderer("DebugLine_Input", 10, 0.1f, Color.blue);
|
||||
}
|
||||
|
||||
UpdateLineRenderer(_inputLineRenderer, origin, target);
|
||||
_inputLineRenderer.enabled = true;
|
||||
}
|
||||
else if (_inputLineRenderer != null)
|
||||
{
|
||||
_inputLineRenderer.enabled = false;
|
||||
}
|
||||
|
||||
float speed = _currentVelocity.magnitude;
|
||||
if (speed > 0.01f)
|
||||
{
|
||||
Vector3 target = origin + _currentVelocity.normalized * (speed * 0.5f);
|
||||
|
||||
if (_velocityLineRenderer == null)
|
||||
{
|
||||
_velocityLineRenderer = CreateOrGetDebugLineRenderer("DebugLine_Velocity", 9, 0.2f, Color.red);
|
||||
}
|
||||
|
||||
UpdateLineRenderer(_velocityLineRenderer, origin, target);
|
||||
_velocityLineRenderer.enabled = true;
|
||||
}
|
||||
else if (_velocityLineRenderer != null)
|
||||
{
|
||||
_velocityLineRenderer.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private LineRenderer CreateOrGetDebugLineRenderer(string name, int sortingIndex, float width, Color color)
|
||||
{
|
||||
Transform existing = transform.Find(name);
|
||||
if (existing != null)
|
||||
{
|
||||
var lr = existing.GetComponent<LineRenderer>();
|
||||
if (lr != null)
|
||||
{
|
||||
lr.startColor = lr.endColor = color;
|
||||
return lr;
|
||||
}
|
||||
}
|
||||
|
||||
var newGameObject = new GameObject(name);
|
||||
newGameObject.transform.SetParent(transform);
|
||||
newGameObject.transform.localPosition = Vector3.zero;
|
||||
|
||||
var lineRenderer = newGameObject.AddComponent<LineRenderer>();
|
||||
lineRenderer.positionCount = 2;
|
||||
lineRenderer.material = new Material(Shader.Find("Sprites/Default")); // URP 호환
|
||||
lineRenderer.sortingOrder = sortingIndex;
|
||||
lineRenderer.startWidth = lineRenderer.endWidth = width;
|
||||
lineRenderer.startColor = lineRenderer.endColor = color;
|
||||
lineRenderer.useWorldSpace = true;
|
||||
|
||||
return lineRenderer;
|
||||
}
|
||||
|
||||
private void UpdateLineRenderer(LineRenderer lr, Vector3 start, Vector3 end)
|
||||
{
|
||||
lr.SetPosition(0, start);
|
||||
lr.SetPosition(1, end);
|
||||
}
|
||||
|
||||
public void SetCurrentDirection(Vector3 normalDirection)
|
||||
{
|
||||
if (_inputDirection == Vector3.zero) return;
|
||||
@ -79,7 +164,7 @@ private void OnMove(InputAction.CallbackContext context)
|
||||
|
||||
private bool CanMove()
|
||||
{
|
||||
return _playerData.IsMoveEnabled && _isDashing == false;
|
||||
return _playerDataSo.IsMoveEnabled && _isDashing == false;
|
||||
}
|
||||
|
||||
private void Move()
|
||||
@ -88,9 +173,44 @@ private void Move()
|
||||
|
||||
_isMoving = _inputDirection != Vector3.zero;
|
||||
OnMoving?.Invoke(_isMoving);
|
||||
|
||||
if (_isMoving)
|
||||
{
|
||||
Vector3 slideDirection = GetSlideAdjustedDirection(_inputDirection.normalized);
|
||||
Vector3 targetVelocity = slideDirection * _playerDataSo.MoveSpeed;
|
||||
_currentVelocity = Vector3.MoveTowards(_currentVelocity, targetVelocity, _playerDataSo.Acceleration * Time.fixedDeltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentVelocity = Vector3.MoveTowards(_currentVelocity, Vector3.zero, _playerDataSo.Deceleration * Time.fixedDeltaTime);
|
||||
}
|
||||
|
||||
Vector3 finalVelocity = _inputDirection * _playerData.MoveSpeed;
|
||||
_rigidbody.linearVelocity = finalVelocity;
|
||||
_rigidbody.linearVelocity = _currentVelocity;
|
||||
}
|
||||
|
||||
private Vector3 GetSlideAdjustedDirection(Vector3 inputDirection)
|
||||
{
|
||||
Vector3 origin = _boxCollider.bounds.center;
|
||||
Vector3 halfExtents = _boxCollider.bounds.extents;
|
||||
Quaternion rotation = transform.rotation;
|
||||
float distance = _boxCollider.bounds.size.x <= _boxCollider.bounds.size.z
|
||||
? _boxCollider.bounds.size.x
|
||||
: _boxCollider.bounds.size.z;
|
||||
int layerMask = ~_playerDataSo.IgnoreSlidingLayerMask;
|
||||
|
||||
if (Physics.BoxCast(origin, halfExtents * 0.95f, inputDirection, out RaycastHit hit, rotation, distance, layerMask))
|
||||
{
|
||||
Vector3 slide = Vector3.ProjectOnPlane(inputDirection, hit.normal).normalized;
|
||||
|
||||
float dot = Vector3.Dot(inputDirection.normalized, hit.normal);
|
||||
float slideFactor = Mathf.Pow(1f - Mathf.Abs(dot), _playerDataSo.SlidingThreshold);
|
||||
|
||||
if (slideFactor < 0.05f) return Vector3.zero;
|
||||
|
||||
return slide * slideFactor;
|
||||
}
|
||||
|
||||
return inputDirection;
|
||||
}
|
||||
|
||||
private void OnDash(InputAction.CallbackContext context)
|
||||
@ -103,7 +223,7 @@ private void OnDash(InputAction.CallbackContext context)
|
||||
|
||||
private bool CanDash()
|
||||
{
|
||||
return _playerData.IsDashEnabled && _isDashing == false && _isDashCooldown == false;
|
||||
return _playerDataSo.IsDashEnabled && _isDashing == false && _isDashCooldown == false;
|
||||
}
|
||||
|
||||
private IEnumerator DashCoroutine()
|
||||
@ -111,16 +231,19 @@ private IEnumerator DashCoroutine()
|
||||
_isDashing = true;
|
||||
_isDashCooldown = true;
|
||||
|
||||
OnDashing?.Invoke(_playerData.DashTime);
|
||||
OnDashing?.Invoke(_playerDataSo.DashTime);
|
||||
|
||||
Vector3 dashVelocity = _currentDirection.normalized * _playerData.DashSpeed;
|
||||
Vector3 currentDirection = _currentDirection.normalized;
|
||||
Vector3 slideDashDirection = GetSlideAdjustedDirection(currentDirection);
|
||||
|
||||
Vector3 dashVelocity = slideDashDirection * _playerDataSo.DashSpeed;
|
||||
_rigidbody.linearVelocity = dashVelocity;
|
||||
|
||||
yield return new WaitForSeconds(_playerData.DashTime);
|
||||
yield return new WaitForSeconds(_playerDataSo.DashTime);
|
||||
|
||||
_isDashing = false;
|
||||
|
||||
yield return new WaitForSeconds(_playerData.DashCooldown);
|
||||
yield return new WaitForSeconds(_playerDataSo.DashCooldown);
|
||||
_isDashCooldown = false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user