DDD-43 배 가속도 틸팅

This commit is contained in:
Jeonghyeon Ha 2025-07-15 16:20:02 +09:00
parent 2c026cae7b
commit 1b45fab5eb
2 changed files with 95 additions and 31 deletions

View File

@ -105,18 +105,27 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3} m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
maxSpeed: 10 maxSpeed: 20
rotationSpeed: 120 rotationSpeed: 180
accelerationRate: 2 accelerationRate: 1
minSpeedThreshold: 0.1 minSpeedThreshold: 0.1
dragFactor: 0.98 dragFactor: 0.98
turnSpeedPenalty: 0.5 turnSpeedPenalty: 0.5
maxTurnAngle: 180 maxTurnAngle: 180
showDebugLines: 1 showDebugLines: 1
debugLineLength: 4 debugLineLength: 5
debugLineHeightStep: 0.1 debugLineHeightStep: 0.02
maxTiltAngle: 15 maxRotationTiltAngle: 15
tiltSpeed: 5 rotationTiltSpeed: 5
RotationTiltReturnSpeed: 3
angularVelocityMultiplier: 2
maxAccelTiltAngle: 15
accelTiltForce: 15
accelTiltDamping: 0.9
accelTiltSpeed: 10
springStiffness: 30
springDamping: 15
meshObjectName: Ship_Mesh
--- !u!1 &6407855916708530114 --- !u!1 &6407855916708530114
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -158,7 +167,7 @@ MeshFilter:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6407855916708530114} m_GameObject: {fileID: 6407855916708530114}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &9176830315433650152 --- !u!23 &9176830315433650152
MeshRenderer: MeshRenderer:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -1,13 +1,13 @@
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using UnityEngine.Serialization;
public class VoyagePlayerShipMovement : MonoBehaviour public class VoyagePlayerShipMovement : MonoBehaviour
{ {
[Header("Movement Settings")] [Header("Movement Settings")]
[SerializeField] private float maxSpeed = 10f; [SerializeField] private float maxSpeed = 20f;
[SerializeField] private float rotationSpeed = 180f;
[SerializeField] private float rotationSpeed = 120f; [SerializeField] private float accelerationRate = 1f;
[SerializeField] private float accelerationRate = 2f;
[SerializeField] private float minSpeedThreshold = 0.1f; [SerializeField] private float minSpeedThreshold = 0.1f;
[SerializeField] private float dragFactor = 0.98f; [SerializeField] private float dragFactor = 0.98f;
@ -34,18 +34,34 @@ public class VoyagePlayerShipMovement : MonoBehaviour
private float targetSpeed; private float targetSpeed;
private float currentSpeed; private float currentSpeed;
[Header("Tilt Settings")] [Header("Rotation Tilt Settings")]
[SerializeField] private float maxTiltAngle = 15f; [SerializeField] private float maxRotationTiltAngle = 15f;
[SerializeField] private float tiltSpeed = 5f; [SerializeField] private float rotationTiltSpeed = 5f;
[SerializeField] private float returnSpeed = 3f; // 원래 자세로 돌아오는 속도 [SerializeField] private float RotationTiltReturnSpeed = 3f; // 원래 자세로 돌아오는 속도
[SerializeField] private float angularVelocityMultiplier = 2f; // 각속도 영향력 [SerializeField] private float angularVelocityMultiplier = 2f; // 각속도 영향력
[Header("Acceleration Tilt Settings")]
[SerializeField] private float maxAccelTiltAngle = 15f; // 최대 가속 틸트 각도
[SerializeField] private float accelTiltForce = 15f; // 틸트 강도
[SerializeField] private float accelTiltDamping = 0.9f; // 틸트 감쇠 계수
[SerializeField] private float accelTiltSpeed = 10f; // 스프링 보간속도
[SerializeField] private float springStiffness = 30f; // 스프링 강성
[SerializeField] private float springDamping = 15f; // 스프링 감쇠
[Header("Mesh Settings")]
[SerializeField] private string meshObjectName = "Ship_Mesh"; [SerializeField] private string meshObjectName = "Ship_Mesh";
private Transform _meshTransform; private Transform _meshTransform;
private float _currentTilt = 0f; // Rotation Tilt
private float _currentRotationTilt = 0f;
private float _lastRotationY; // 이전 프레임의 Y축 회전값
private float _currentAngularVelocity; // 현재 각속도
// Acceleration Tilt
private float _currentAccelTilt;
private float _accelTiltVelocity;
private float _prevSpeed;
private Quaternion _originalMeshRotation; private Quaternion _originalMeshRotation;
private float _lastRotationY; // 이전 프레임의 Y축 회전값
private float _currentAngularVelocity; // 현재 각속도
private void Start() private void Start()
{ {
@ -73,11 +89,14 @@ public class VoyagePlayerShipMovement : MonoBehaviour
// 입력이 없을 때는 서서히 감속 // 입력이 없을 때는 서서히 감속
currentSpeed = Mathf.Lerp(currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime); currentSpeed = Mathf.Lerp(currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime);
} }
UpdateMeshRotationTilt();
ApplyDrag(); ApplyDrag();
ApplyMovement(); ApplyMovement();
// Cosmetic Mesh Tilting
UpdateMeshRotationTilt();
UpdateAccelerationTilt();
ApplyMeshTilt();
#if UNITY_EDITOR #if UNITY_EDITOR
if (showDebugLines) if (showDebugLines)
{ {
@ -86,7 +105,6 @@ public class VoyagePlayerShipMovement : MonoBehaviour
#endif #endif
} }
private void HandleMovement() private void HandleMovement()
{ {
// 기본 목표 속도 계산 (입력 크기에 비례) // 기본 목표 속도 계산 (입력 크기에 비례)
@ -147,25 +165,64 @@ public class VoyagePlayerShipMovement : MonoBehaviour
// 목표 틸트 각도 계산 // 목표 틸트 각도 계산
float targetTilt = -_currentAngularVelocity * angularVelocityMultiplier; float targetTilt = -_currentAngularVelocity * angularVelocityMultiplier;
targetTilt = Mathf.Clamp(targetTilt, -maxTiltAngle, maxTiltAngle); targetTilt = Mathf.Clamp(targetTilt, -maxRotationTiltAngle, maxRotationTiltAngle);
// 틸트 적용 또는 복귀 // 틸트 적용 또는 복귀
if (Mathf.Abs(_currentAngularVelocity) > 0.1f) if (Mathf.Abs(_currentAngularVelocity) > 0.1f)
{ {
_currentTilt = Mathf.Lerp(_currentTilt, targetTilt, tiltSpeed * Time.fixedDeltaTime); _currentRotationTilt = Mathf.Lerp(_currentRotationTilt, targetTilt, rotationTiltSpeed * Time.fixedDeltaTime);
} }
else else
{ {
// 입력이 없을 때는 원래 자세로 천천히 복귀 // 입력이 없을 때는 원래 자세로 천천히 복귀
_currentTilt = Mathf.Lerp(_currentTilt, 0f, returnSpeed * Time.fixedDeltaTime); _currentRotationTilt = Mathf.Lerp(_currentRotationTilt, 0f, RotationTiltReturnSpeed * Time.fixedDeltaTime);
} }
// 메시에 틸트 적용
_meshTransform.localRotation = _originalMeshRotation * Quaternion.Euler(0, 0, _currentTilt);
_lastRotationY = currentRotationY; _lastRotationY = currentRotationY;
} }
private void UpdateAccelerationTilt()
{
// 가속도 계산
float acceleration = (currentSpeed - _prevSpeed) / Time.fixedDeltaTime;
// 스프링 물리 시스템 구현
float springForce = -springStiffness * _currentAccelTilt; // 복원력
float dampingForce = -springDamping * _accelTiltVelocity; // 감쇠력
float accelerationForce = -acceleration * accelTiltForce; // 가속에 의한 힘
// 전체 힘 계산
float totalForce = springForce + dampingForce + accelerationForce;
// 가속도 계산 (F = ma, 질량은 1로 가정)
float tiltAcceleration = totalForce;
// 속도 업데이트
_accelTiltVelocity += tiltAcceleration;
_accelTiltVelocity *= accelTiltDamping; // 감쇠 적용
_accelTiltVelocity *= Time.fixedDeltaTime;
// 위치(각도) 업데이트
_currentAccelTilt = Mathf.Lerp(_currentAccelTilt, _currentAccelTilt + _accelTiltVelocity, accelTiltSpeed * Time.fixedDeltaTime);
_currentAccelTilt = Mathf.Clamp(_currentAccelTilt, -maxAccelTiltAngle, maxAccelTiltAngle);
_prevSpeed = currentSpeed;
}
private void ApplyMeshTilt()
{
if (_meshTransform is null) return;
// 회전 틸트와 가속 틸트를 조합
// 메시에 최종 틸트 적용
_meshTransform.localRotation = _originalMeshRotation * Quaternion.Euler(
_currentAccelTilt, // X축 (가속 틸트)
0, // Y축
_currentRotationTilt // Z축 (회전 틸트)
);
}
private void ApplyDrag() private void ApplyDrag()
{ {
@ -190,8 +247,6 @@ public class VoyagePlayerShipMovement : MonoBehaviour
public void OnMove(InputAction.CallbackContext context) public void OnMove(InputAction.CallbackContext context)
{ {
currentInput = context.ReadValue<Vector2>(); currentInput = context.ReadValue<Vector2>();
// Debug Log this
Debug.Log(currentInput);
} }
#if UNITY_EDITOR #if UNITY_EDITOR