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_Name:
m_EditorClassIdentifier:
maxSpeed: 10
rotationSpeed: 120
accelerationRate: 2
maxSpeed: 20
rotationSpeed: 180
accelerationRate: 1
minSpeedThreshold: 0.1
dragFactor: 0.98
turnSpeedPenalty: 0.5
maxTurnAngle: 180
showDebugLines: 1
debugLineLength: 4
debugLineHeightStep: 0.1
maxTiltAngle: 15
tiltSpeed: 5
debugLineLength: 5
debugLineHeightStep: 0.02
maxRotationTiltAngle: 15
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
GameObject:
m_ObjectHideFlags: 0
@ -158,7 +167,7 @@ MeshFilter:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6407855916708530114}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &9176830315433650152
MeshRenderer:
m_ObjectHideFlags: 0

View File

@ -1,13 +1,13 @@
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;
public class VoyagePlayerShipMovement : MonoBehaviour
{
[Header("Movement Settings")]
[SerializeField] private float maxSpeed = 10f;
[SerializeField] private float rotationSpeed = 120f;
[SerializeField] private float accelerationRate = 2f;
[SerializeField] private float maxSpeed = 20f;
[SerializeField] private float rotationSpeed = 180f;
[SerializeField] private float accelerationRate = 1f;
[SerializeField] private float minSpeedThreshold = 0.1f;
[SerializeField] private float dragFactor = 0.98f;
@ -34,18 +34,34 @@ public class VoyagePlayerShipMovement : MonoBehaviour
private float targetSpeed;
private float currentSpeed;
[Header("Tilt Settings")]
[SerializeField] private float maxTiltAngle = 15f;
[SerializeField] private float tiltSpeed = 5f;
[SerializeField] private float returnSpeed = 3f; // 원래 자세로 돌아오는 속도
[Header("Rotation Tilt Settings")]
[SerializeField] private float maxRotationTiltAngle = 15f;
[SerializeField] private float rotationTiltSpeed = 5f;
[SerializeField] private float RotationTiltReturnSpeed = 3f; // 원래 자세로 돌아오는 속도
[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";
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 float _lastRotationY; // 이전 프레임의 Y축 회전값
private float _currentAngularVelocity; // 현재 각속도
private void Start()
{
@ -73,11 +89,14 @@ public class VoyagePlayerShipMovement : MonoBehaviour
// 입력이 없을 때는 서서히 감속
currentSpeed = Mathf.Lerp(currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime);
}
UpdateMeshRotationTilt();
ApplyDrag();
ApplyMovement();
// Cosmetic Mesh Tilting
UpdateMeshRotationTilt();
UpdateAccelerationTilt();
ApplyMeshTilt();
#if UNITY_EDITOR
if (showDebugLines)
{
@ -86,7 +105,6 @@ public class VoyagePlayerShipMovement : MonoBehaviour
#endif
}
private void HandleMovement()
{
// 기본 목표 속도 계산 (입력 크기에 비례)
@ -147,25 +165,64 @@ public class VoyagePlayerShipMovement : MonoBehaviour
// 목표 틸트 각도 계산
float targetTilt = -_currentAngularVelocity * angularVelocityMultiplier;
targetTilt = Mathf.Clamp(targetTilt, -maxTiltAngle, maxTiltAngle);
targetTilt = Mathf.Clamp(targetTilt, -maxRotationTiltAngle, maxRotationTiltAngle);
// 틸트 적용 또는 복귀
if (Mathf.Abs(_currentAngularVelocity) > 0.1f)
{
_currentTilt = Mathf.Lerp(_currentTilt, targetTilt, tiltSpeed * Time.fixedDeltaTime);
_currentRotationTilt = Mathf.Lerp(_currentRotationTilt, targetTilt, rotationTiltSpeed * Time.fixedDeltaTime);
}
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;
}
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()
{
@ -190,8 +247,6 @@ public class VoyagePlayerShipMovement : MonoBehaviour
public void OnMove(InputAction.CallbackContext context)
{
currentInput = context.ReadValue<Vector2>();
// Debug Log this
Debug.Log(currentInput);
}
#if UNITY_EDITOR