DDD-43 디버그 기능 추가
This commit is contained in:
parent
241a2fc51d
commit
d03a4b7892
@ -90187,8 +90187,8 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 943285313}
|
m_GameObject: {fileID: 943285313}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0.22409342, y: 0, z: 0, w: 0.97456765}
|
m_LocalRotation: {x: 0.25884834, y: 0, z: 0, w: 0.965918}
|
||||||
m_LocalPosition: {x: 0, y: 8.74, z: -18}
|
m_LocalPosition: {x: 0, y: 11.014116, z: -19.074339}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@ -141074,7 +141074,7 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1413354196}
|
m_GameObject: {fileID: 1413354196}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: -0, y: 0.7816503, z: -0, w: 0.62371695}
|
m_LocalRotation: {x: -0, y: 0.4456134, z: -0, w: 0.8952256}
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
@ -152373,8 +152373,8 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 1498712852}
|
- component: {fileID: 1498712852}
|
||||||
- component: {fileID: 1498712855}
|
- component: {fileID: 1498712855}
|
||||||
- component: {fileID: 1498712854}
|
- component: {fileID: 1498712857}
|
||||||
- component: {fileID: 1498712856}
|
- component: {fileID: 1498712858}
|
||||||
m_Layer: 9
|
m_Layer: 9
|
||||||
m_Name: CinemachineCamera_Back
|
m_Name: CinemachineCamera_Back
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@ -152390,32 +152390,13 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1498712851}
|
m_GameObject: {fileID: 1498712851}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0.22409342, y: 0, z: 0, w: 0.97456765}
|
m_LocalRotation: {x: 0.25884834, y: 0, z: 0, w: 0.965918}
|
||||||
m_LocalPosition: {x: 0, y: 8.74, z: -18}
|
m_LocalPosition: {x: 0, y: 11.014116, z: -19.074339}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 1885259736}
|
m_Father: {fileID: 1885259736}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!114 &1498712854
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1498712851}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b617507da6d07e749b7efdb34e1173e1, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
TrackerSettings:
|
|
||||||
BindingMode: 4
|
|
||||||
PositionDamping: {x: 1, y: 1, z: 0}
|
|
||||||
AngularDampingMode: 0
|
|
||||||
RotationDamping: {x: 1, y: 1, z: 1}
|
|
||||||
QuaternionDamping: 1
|
|
||||||
FollowOffset: {x: 0, y: 8.74, z: -18}
|
|
||||||
--- !u!114 &1498712855
|
--- !u!114 &1498712855
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -152459,7 +152440,70 @@ MonoBehaviour:
|
|||||||
BarrelClipping: 0.25
|
BarrelClipping: 0.25
|
||||||
Anamorphism: 0
|
Anamorphism: 0
|
||||||
BlendHint: 0
|
BlendHint: 0
|
||||||
--- !u!114 &1498712856
|
--- !u!114 &1498712857
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1498712851}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 3b5d7c088409d9a40b7b09aa707777f8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
TargetOffset: {x: 0, y: 5, z: 0}
|
||||||
|
TrackerSettings:
|
||||||
|
BindingMode: 4
|
||||||
|
PositionDamping: {x: 1, y: 1, z: 1}
|
||||||
|
AngularDampingMode: 0
|
||||||
|
RotationDamping: {x: 1, y: 1, z: 1}
|
||||||
|
QuaternionDamping: 1
|
||||||
|
OrbitStyle: 0
|
||||||
|
Radius: 20
|
||||||
|
Orbits:
|
||||||
|
Top:
|
||||||
|
Radius: 2
|
||||||
|
Height: 5
|
||||||
|
Center:
|
||||||
|
Radius: 4
|
||||||
|
Height: 2.25
|
||||||
|
Bottom:
|
||||||
|
Radius: 2.5
|
||||||
|
Height: 0.1
|
||||||
|
SplineCurvature: 0.5
|
||||||
|
RecenteringTarget: 2
|
||||||
|
HorizontalAxis:
|
||||||
|
Value: 0
|
||||||
|
Center: 0
|
||||||
|
Range: {x: -180, y: 180}
|
||||||
|
Wrap: 1
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
VerticalAxis:
|
||||||
|
Value: 17.5
|
||||||
|
Center: 17.5
|
||||||
|
Range: {x: -10, y: 45}
|
||||||
|
Wrap: 0
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
RadialAxis:
|
||||||
|
Value: 1
|
||||||
|
Center: 1
|
||||||
|
Range: {x: 1, y: 1}
|
||||||
|
Wrap: 0
|
||||||
|
Recentering:
|
||||||
|
Enabled: 0
|
||||||
|
Wait: 1
|
||||||
|
Time: 2
|
||||||
|
Restrictions: 0
|
||||||
|
--- !u!114 &1498712858
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@ -154945,7 +154989,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 1528083691}
|
m_GameObject: {fileID: 1528083691}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: 8.74, z: -18}
|
m_LocalPosition: {x: 0, y: 20, z: -20}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
|
@ -107,14 +107,13 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
maxSpeed: 20
|
maxSpeed: 20
|
||||||
rotationSpeed: 180
|
rotationSpeed: 180
|
||||||
|
minRotationSpeed: 60
|
||||||
|
rotationAccelerationRate: 5
|
||||||
accelerationRate: 1
|
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
|
|
||||||
debugLineLength: 5
|
|
||||||
debugLineHeightStep: 0.02
|
|
||||||
maxRotationTiltAngle: 15
|
maxRotationTiltAngle: 15
|
||||||
rotationTiltSpeed: 5
|
rotationTiltSpeed: 5
|
||||||
RotationTiltReturnSpeed: 3
|
RotationTiltReturnSpeed: 3
|
||||||
@ -132,6 +131,9 @@ MonoBehaviour:
|
|||||||
randomWaveOffset: 0.5
|
randomWaveOffset: 0.5
|
||||||
waveUnitSpeed: 10
|
waveUnitSpeed: 10
|
||||||
meshObjectName: Ship_Mesh
|
meshObjectName: Ship_Mesh
|
||||||
|
showDebugVisuals: 1
|
||||||
|
debugLineLength: 5
|
||||||
|
debugLineWidth: 0.1
|
||||||
--- !u!1 &6407855916708530114
|
--- !u!1 &6407855916708530114
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -7,31 +7,21 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
[Header("Movement Settings")]
|
[Header("Movement Settings")]
|
||||||
[SerializeField] private float maxSpeed = 20f;
|
[SerializeField] private float maxSpeed = 20f;
|
||||||
[SerializeField] private float rotationSpeed = 180f;
|
[SerializeField] private float rotationSpeed = 180f;
|
||||||
|
[SerializeField] private float minRotationSpeed = 60f;
|
||||||
|
[SerializeField] private float rotationAccelerationRate = 5f;
|
||||||
[SerializeField] private float accelerationRate = 1f;
|
[SerializeField] private float accelerationRate = 1f;
|
||||||
[SerializeField] private float minSpeedThreshold = 0.1f;
|
[SerializeField] private float minSpeedThreshold = 0.1f;
|
||||||
[SerializeField] private float dragFactor = 0.98f;
|
[SerializeField] private float dragFactor = 0.98f;
|
||||||
private Vector3 currentVelocity;
|
private Vector3 _currentVelocity;
|
||||||
private Vector2 currentInput;
|
private Vector2 _currentInput;
|
||||||
private float targetSpeed;
|
private float _currentRotationSpeed;
|
||||||
private float currentSpeed;
|
private float _targetSpeed;
|
||||||
|
private float _currentSpeed;
|
||||||
|
|
||||||
[Header("Turn Settings")]
|
[Header("Turn Settings")]
|
||||||
[SerializeField] private float turnSpeedPenalty = 0.5f; // 선회 시 감속 정도 (0: 감속 없음, 1: 완전 정지)
|
[SerializeField] private float turnSpeedPenalty = 0.5f; // 선회 시 감속 정도 (0: 감속 없음, 1: 완전 정지)
|
||||||
[SerializeField] private float maxTurnAngle = 180f; // 최대 감속이 적용되는 각도
|
[SerializeField] private float maxTurnAngle = 180f; // 최대 감속이 적용되는 각도
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[Header("Debug Settings")]
|
|
||||||
[SerializeField] private bool showDebugLines = true;
|
|
||||||
|
|
||||||
[SerializeField] private float debugLineLength = 4f;
|
|
||||||
[SerializeField] private float debugLineHeightStep = 0.1f;
|
|
||||||
private LineRenderer velocityLine;
|
|
||||||
private LineRenderer forwardDirectionLine;
|
|
||||||
private LineRenderer upDirectionLine;
|
|
||||||
private LineRenderer inputDirectionLine;
|
|
||||||
private bool lineRendererCreated = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Rotation Tilt
|
// Rotation Tilt
|
||||||
[Header("Rotation Tilt Settings")]
|
[Header("Rotation Tilt Settings")]
|
||||||
[SerializeField] private float maxRotationTiltAngle = 15f;
|
[SerializeField] private float maxRotationTiltAngle = 15f;
|
||||||
@ -65,7 +55,7 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
[SerializeField] private float waveUnitSpeed = 10f; // 기준 속력
|
[SerializeField] private float waveUnitSpeed = 10f; // 기준 속력
|
||||||
private float _waveTime;
|
private float _waveTime;
|
||||||
private float _waveRandomOffset;
|
private float _waveRandomOffset;
|
||||||
private float currentWaveHeight;
|
private float _currentWaveHeight;
|
||||||
|
|
||||||
|
|
||||||
[Header("Mesh Settings")]
|
[Header("Mesh Settings")]
|
||||||
@ -91,11 +81,15 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
_lastRotationY = transform.eulerAngles.y;
|
_lastRotationY = transform.eulerAngles.y;
|
||||||
_waveTime = 0f;
|
_waveTime = 0f;
|
||||||
_waveRandomOffset = Random.Range(-randomWaveOffset, randomWaveOffset);
|
_waveRandomOffset = Random.Range(-randomWaveOffset, randomWaveOffset);
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
InitializeDebugVisuals();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
if (currentInput.magnitude > minSpeedThreshold)
|
if (_currentInput.magnitude > minSpeedThreshold)
|
||||||
{
|
{
|
||||||
HandleMovement();
|
HandleMovement();
|
||||||
HandleRotation();
|
HandleRotation();
|
||||||
@ -103,7 +97,8 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 입력이 없을 때는 서서히 감속
|
// 입력이 없을 때는 서서히 감속
|
||||||
currentSpeed = Mathf.Lerp(currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime);
|
_currentSpeed = Mathf.Lerp(_currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime);
|
||||||
|
_currentRotationSpeed = 0;
|
||||||
}
|
}
|
||||||
ApplyDrag();
|
ApplyDrag();
|
||||||
ApplyMovement();
|
ApplyMovement();
|
||||||
@ -117,20 +112,17 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
ApplyMeshOffset();
|
ApplyMeshOffset();
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (showDebugLines)
|
UpdateDebugVisuals();
|
||||||
{
|
|
||||||
UpdateAllDebugLines();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMovement()
|
private void HandleMovement()
|
||||||
{
|
{
|
||||||
// 기본 목표 속도 계산 (입력 크기에 비례)
|
// 기본 목표 속도 계산 (입력 크기에 비례)
|
||||||
float baseTargetSpeed = Mathf.Clamp01(currentInput.magnitude) * maxSpeed;
|
float baseTargetSpeed = Mathf.Clamp01(_currentInput.magnitude) * maxSpeed;
|
||||||
|
|
||||||
// 현재 방향과 목표 방향 사이의 각도 계산
|
// 현재 방향과 목표 방향 사이의 각도 계산
|
||||||
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
Vector3 inputDirection = new Vector3(_currentInput.x, 0, _currentInput.y).normalized;
|
||||||
float angleDifference = Vector3.Angle(transform.forward, inputDirection);
|
float angleDifference = Vector3.Angle(transform.forward, inputDirection);
|
||||||
|
|
||||||
// 각도에 따른 속도 페널티 계산 (각도가 클수록 더 큰 감속)
|
// 각도에 따른 속도 페널티 계산 (각도가 클수록 더 큰 감속)
|
||||||
@ -138,37 +130,38 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
turnPenaltyFactor = Mathf.Clamp01(turnPenaltyFactor);
|
turnPenaltyFactor = Mathf.Clamp01(turnPenaltyFactor);
|
||||||
|
|
||||||
// 최종 목표 속도 계산 (기본 속도에 선회 페널티 적용)
|
// 최종 목표 속도 계산 (기본 속도에 선회 페널티 적용)
|
||||||
targetSpeed = baseTargetSpeed * turnPenaltyFactor;
|
_targetSpeed = baseTargetSpeed * turnPenaltyFactor;
|
||||||
|
|
||||||
// 현재 속도를 목표 속도로 부드럽게 보간
|
// 현재 속도를 목표 속도로 부드럽게 보간
|
||||||
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, accelerationRate * Time.fixedDeltaTime);
|
_currentSpeed = Mathf.Lerp(_currentSpeed, _targetSpeed, accelerationRate * Time.fixedDeltaTime);
|
||||||
|
|
||||||
// 최소 임계값 이하면 완전히 정지
|
// 최소 임계값 이하면 완전히 정지
|
||||||
if (currentSpeed < minSpeedThreshold && targetSpeed < minSpeedThreshold)
|
if (_currentSpeed < minSpeedThreshold && _targetSpeed < minSpeedThreshold)
|
||||||
{
|
{
|
||||||
currentSpeed = 0f;
|
_currentSpeed = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 바라보는 방향으로 속도 벡터 업데이트
|
// 현재 바라보는 방향으로 속도 벡터 업데이트
|
||||||
currentVelocity = transform.forward * currentSpeed;
|
_currentVelocity = transform.forward * _currentSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleRotation()
|
private void HandleRotation()
|
||||||
{
|
{
|
||||||
if (currentInput.magnitude > minSpeedThreshold)
|
if (_currentInput.magnitude > minSpeedThreshold)
|
||||||
{
|
{
|
||||||
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
Vector3 inputDirection = new Vector3(_currentInput.x, 0, _currentInput.y).normalized;
|
||||||
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
||||||
|
|
||||||
// 회전 속도를 현재 속도에 비례하도록 설정
|
// 회전 속도를 현재 속도에 비례하도록 설정
|
||||||
float currentRotationSpeed = rotationSpeed * (currentSpeed / maxSpeed);
|
float desiredRotationSpeed = rotationSpeed * (_currentSpeed / maxSpeed);
|
||||||
currentRotationSpeed = Mathf.Max(currentRotationSpeed, rotationSpeed * 0.3f);
|
desiredRotationSpeed = Mathf.Max(desiredRotationSpeed, minRotationSpeed);
|
||||||
|
_currentRotationSpeed = Mathf.Lerp(_currentRotationSpeed, desiredRotationSpeed, rotationAccelerationRate * Time.fixedDeltaTime);
|
||||||
|
|
||||||
// 기본 회전 적용 (오브젝트 전체)
|
// 기본 회전 적용 (오브젝트 전체)
|
||||||
transform.rotation = Quaternion.RotateTowards(
|
transform.rotation = Quaternion.RotateTowards(
|
||||||
transform.rotation,
|
transform.rotation,
|
||||||
targetRotation,
|
targetRotation,
|
||||||
currentRotationSpeed * Time.fixedDeltaTime
|
_currentRotationSpeed * Time.fixedDeltaTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +196,7 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
private void UpdateAccelerationTilt()
|
private void UpdateAccelerationTilt()
|
||||||
{
|
{
|
||||||
// 가속도 계산
|
// 가속도 계산
|
||||||
float acceleration = (currentSpeed - _prevSpeed) / Time.fixedDeltaTime;
|
float acceleration = (_currentSpeed - _prevSpeed) / Time.fixedDeltaTime;
|
||||||
|
|
||||||
// 스프링 물리 시스템 구현
|
// 스프링 물리 시스템 구현
|
||||||
float springForce = -springStiffness * _currentAccelTilt; // 복원력
|
float springForce = -springStiffness * _currentAccelTilt; // 복원력
|
||||||
@ -225,7 +218,7 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
_currentAccelTilt = Mathf.Lerp(_currentAccelTilt, _currentAccelTilt + _accelTiltVelocity, accelTiltSpeed * Time.fixedDeltaTime);
|
_currentAccelTilt = Mathf.Lerp(_currentAccelTilt, _currentAccelTilt + _accelTiltVelocity, accelTiltSpeed * Time.fixedDeltaTime);
|
||||||
_currentAccelTilt = Mathf.Clamp(_currentAccelTilt, -maxAccelTiltAngle, maxAccelTiltAngle);
|
_currentAccelTilt = Mathf.Clamp(_currentAccelTilt, -maxAccelTiltAngle, maxAccelTiltAngle);
|
||||||
|
|
||||||
_prevSpeed = currentSpeed;
|
_prevSpeed = _currentSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyMeshTilt()
|
private void ApplyMeshTilt()
|
||||||
@ -246,108 +239,48 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
if (_meshTransform is null) return;
|
if (_meshTransform is null) return;
|
||||||
|
|
||||||
// 현재 속도에 비례하여 파도 주기 조절
|
// 현재 속도에 비례하여 파도 주기 조절
|
||||||
float waveSpeedFactor = 1f + (currentSpeed / waveUnitSpeed) * speedWaveMultiplier;
|
float waveSpeedFactor = 1f + (_currentSpeed / waveUnitSpeed) * speedWaveMultiplier;
|
||||||
_waveTime += Time.fixedDeltaTime * baseWaveFrequency * waveSpeedFactor;
|
_waveTime += Time.fixedDeltaTime * baseWaveFrequency * waveSpeedFactor;
|
||||||
float currentSpeedByUnit = currentSpeed / waveUnitSpeed;
|
float currentSpeedByUnit = _currentSpeed / waveUnitSpeed;
|
||||||
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
||||||
float waveHeight = Mathf.Lerp(minSpeedWaveHeight, maxSpeedWaveHeight, currentSpeedByUnit);
|
float waveHeight = Mathf.Lerp(minSpeedWaveHeight, maxSpeedWaveHeight, currentSpeedByUnit);
|
||||||
|
|
||||||
currentWaveHeight = waveHeight * Mathf.Sin(_waveTime + _waveRandomOffset);
|
_currentWaveHeight = waveHeight * Mathf.Sin(_waveTime + _waveRandomOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyMeshOffset()
|
private void ApplyMeshOffset()
|
||||||
{
|
{
|
||||||
if (_meshTransform is null) return;
|
if (_meshTransform is null) return;
|
||||||
|
|
||||||
Vector3 position = _originalMeshPosition + (Vector3.up * currentWaveHeight);
|
Vector3 position = _originalMeshPosition + (Vector3.up * _currentWaveHeight);
|
||||||
_meshTransform.localPosition = position;
|
_meshTransform.localPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyDrag()
|
private void ApplyDrag()
|
||||||
{
|
{
|
||||||
currentSpeed *= dragFactor;
|
_currentSpeed *= dragFactor;
|
||||||
|
|
||||||
// 최소 속도 이하면 완전히 정지
|
// 최소 속도 이하면 완전히 정지
|
||||||
if (currentSpeed < minSpeedThreshold)
|
if (_currentSpeed < minSpeedThreshold)
|
||||||
{
|
{
|
||||||
currentSpeed = 0f;
|
_currentSpeed = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 방향으로 감속된 속도 적용
|
// 현재 방향으로 감속된 속도 적용
|
||||||
currentVelocity = transform.forward * currentSpeed;
|
_currentVelocity = transform.forward * _currentSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ApplyMovement()
|
private void ApplyMovement()
|
||||||
{
|
{
|
||||||
transform.position += currentVelocity * Time.fixedDeltaTime;
|
transform.position += _currentVelocity * Time.fixedDeltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnMove(InputAction.CallbackContext context)
|
public void OnMove(InputAction.CallbackContext context)
|
||||||
{
|
{
|
||||||
currentInput = context.ReadValue<Vector2>();
|
_currentInput = context.ReadValue<Vector2>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
private void UpdateAllDebugLines()
|
|
||||||
{
|
|
||||||
if (lineRendererCreated == false)
|
|
||||||
{
|
|
||||||
lineRendererCreated = true;
|
|
||||||
forwardDirectionLine = CreateLineRenderer("CurrentDirectionLine", Color.green);
|
|
||||||
upDirectionLine = CreateLineRenderer("UpDirectionLine", Color.yellow);
|
|
||||||
inputDirectionLine = CreateLineRenderer("InputDirectionLine", Color.red);
|
|
||||||
velocityLine = CreateLineRenderer("VelocityLine", Color.blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 전방 방향 표시 (기본 높이)
|
|
||||||
DrawDebugLine(forwardDirectionLine, transform.forward, debugLineLength, 0);
|
|
||||||
|
|
||||||
// 메시의 위쪽 방향 표시 (틸팅 반영)
|
|
||||||
if (_meshTransform is not null)
|
|
||||||
{
|
|
||||||
DrawDebugLine(upDirectionLine, _meshTransform.up, debugLineLength, debugLineHeightStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 입력 방향 표시 (두 단계 위)
|
|
||||||
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
|
||||||
DrawDebugLine(inputDirectionLine, inputDirection, debugLineLength * currentInput.magnitude, debugLineHeightStep * 2);
|
|
||||||
|
|
||||||
// 속도 벡터 표시 (세 단계 위)
|
|
||||||
DrawDebugLine(velocityLine, currentVelocity.normalized, currentVelocity.magnitude, debugLineHeightStep * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LineRenderer CreateLineRenderer(string name, Color color)
|
|
||||||
{
|
|
||||||
GameObject lineObj = new GameObject(name);
|
|
||||||
lineObj.transform.SetParent(transform);
|
|
||||||
LineRenderer line = lineObj.AddComponent<LineRenderer>();
|
|
||||||
|
|
||||||
line.startWidth = 0.1f;
|
|
||||||
line.endWidth = 0.1f;
|
|
||||||
line.material = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
|
|
||||||
line.startColor = color;
|
|
||||||
line.endColor = color;
|
|
||||||
line.positionCount = 2;
|
|
||||||
|
|
||||||
// 라인 렌더러가 다른 오브젝트를 가리지 않도록 설정
|
|
||||||
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
|
||||||
line.receiveShadows = false;
|
|
||||||
line.material.color = color;
|
|
||||||
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawDebugLine(LineRenderer renderer, Vector3 direction, float length, float heightOffset)
|
|
||||||
{
|
|
||||||
if (!renderer) return;
|
|
||||||
|
|
||||||
Vector3 position = transform.position + Vector3.up * heightOffset;
|
|
||||||
renderer.SetPosition(0, position);
|
|
||||||
renderer.SetPosition(1, position + direction * length);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
{
|
{
|
||||||
// 에디터에서 메시 오브젝트 이름이 변경될 때 자동으로 찾기
|
// 에디터에서 메시 오브젝트 이름이 변경될 때 자동으로 찾기
|
||||||
@ -356,4 +289,188 @@ public class VoyagePlayerShipMovement : MonoBehaviour
|
|||||||
_meshTransform = transform.Find(meshObjectName);
|
_meshTransform = transform.Find(meshObjectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[Header("Debug Visualization")]
|
||||||
|
[SerializeField] private bool showDebugVisuals = true;
|
||||||
|
[SerializeField] private float debugLineLength = 5f;
|
||||||
|
[SerializeField] private float debugLineWidth = 0.1f;
|
||||||
|
|
||||||
|
private LineRenderer _speedLineRenderer;
|
||||||
|
private LineRenderer _rotationSpeedLineRenderer;
|
||||||
|
private LineRenderer _rotationDeltaLineRenderer;
|
||||||
|
private LineRenderer _TiltLineRenderer;
|
||||||
|
private LineRenderer _waveHeightLineRenderer;
|
||||||
|
private LineRenderer _wavePatternLineRenderer;
|
||||||
|
|
||||||
|
private void InitializeDebugVisuals()
|
||||||
|
{
|
||||||
|
if (!showDebugVisuals) return;
|
||||||
|
|
||||||
|
// 속도 표시
|
||||||
|
_speedLineRenderer = CreateLineRenderer("SpeedLine", Color.green);
|
||||||
|
// 회전 방향 표시
|
||||||
|
_rotationSpeedLineRenderer = CreateLineRenderer("RotationSpeedLine", Color.magenta);
|
||||||
|
// 회전 방향 표시
|
||||||
|
_rotationDeltaLineRenderer = CreateLineRenderer("RotationDeltaLine", Color.yellow);
|
||||||
|
// 틸트 표시
|
||||||
|
_TiltLineRenderer = CreateLineRenderer("TiltLine", Color.red);
|
||||||
|
// 파도 높이 표시
|
||||||
|
_waveHeightLineRenderer = CreateLineRenderer("WaveHeightLine", Color.blue);
|
||||||
|
// 파도 패턴 표시
|
||||||
|
_wavePatternLineRenderer = CreateLineRenderer("WavePatternLine", Color.cyan);
|
||||||
|
_wavePatternLineRenderer.positionCount = 50; // 파도 패턴을 위한 더 많은 점
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDebugVisuals()
|
||||||
|
{
|
||||||
|
if (!showDebugVisuals) return;
|
||||||
|
|
||||||
|
// 속도 벡터 표시
|
||||||
|
UpdateSpeedLine();
|
||||||
|
|
||||||
|
// 회전 방향 및 각속도 표시
|
||||||
|
UpdateRotationSpeedLine();
|
||||||
|
UpdateRotationDeltaLine();
|
||||||
|
// 회전 틸트 표시
|
||||||
|
UpdateTiltLine();
|
||||||
|
// 파도 높이와 패턴 표시
|
||||||
|
UpdateWaveVisualization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpeedLine()
|
||||||
|
{
|
||||||
|
Vector3 start = transform.position + Vector3.up * 1.5f;
|
||||||
|
Vector3 end = start + transform.forward * (_currentSpeed / maxSpeed) * debugLineLength * 2;
|
||||||
|
DrawLine(_speedLineRenderer, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotationSpeedLine()
|
||||||
|
{
|
||||||
|
Vector3 start = transform.position + Vector3.up * 1.2f;
|
||||||
|
// 각속도를 호로 표현
|
||||||
|
if (Mathf.Abs(_currentRotationSpeed) > 0.1f)
|
||||||
|
{
|
||||||
|
Vector3[] arcPoints = new Vector3[10];
|
||||||
|
float radius = debugLineLength * 1f;
|
||||||
|
float angleStep = _currentRotationSpeed * 1f / (arcPoints.Length - 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < arcPoints.Length; i++)
|
||||||
|
{
|
||||||
|
float angle = angleStep * i;
|
||||||
|
Vector3 point = start + Quaternion.Euler(0, angle, 0) * transform.forward * radius;
|
||||||
|
arcPoints[i] = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rotationSpeedLineRenderer.positionCount = arcPoints.Length;
|
||||||
|
_rotationSpeedLineRenderer.SetPositions(arcPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_rotationSpeedLineRenderer.positionCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotationDeltaLine()
|
||||||
|
{
|
||||||
|
float deltaAngle = 0f;
|
||||||
|
if (_currentInput.magnitude > minSpeedThreshold)
|
||||||
|
{
|
||||||
|
Vector3 inputDirection = new Vector3(_currentInput.x, 0, _currentInput.y).normalized;
|
||||||
|
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
||||||
|
deltaAngle = Quaternion.Angle(transform.rotation, targetRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 start = transform.position + Vector3.up * 1.2f;
|
||||||
|
// 각속도를 호로 표현
|
||||||
|
if (Mathf.Abs(deltaAngle) > 0.1f)
|
||||||
|
{
|
||||||
|
Vector3[] arcPoints = new Vector3[10];
|
||||||
|
float radius = debugLineLength * 1.05f;
|
||||||
|
float angleStep = deltaAngle * 1f / (arcPoints.Length - 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < arcPoints.Length; i++)
|
||||||
|
{
|
||||||
|
float angle = angleStep * i;
|
||||||
|
Vector3 point = start + Quaternion.Euler(0, angle, 0) * transform.forward * radius;
|
||||||
|
arcPoints[i] = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rotationDeltaLineRenderer.positionCount = arcPoints.Length;
|
||||||
|
_rotationDeltaLineRenderer.SetPositions(arcPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_rotationDeltaLineRenderer.positionCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTiltLine()
|
||||||
|
{
|
||||||
|
Vector3 start = transform.position + Vector3.up * 1.5f;
|
||||||
|
Vector3 tiltDirection = _meshTransform.up;
|
||||||
|
DrawLine(_TiltLineRenderer, start, start + tiltDirection * debugLineLength * 0.4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWaveVisualization()
|
||||||
|
{
|
||||||
|
// 현재 파도 높이 표시
|
||||||
|
Vector3 waveStart = transform.position + Vector3.up*1.5f - transform.forward*1.5f;
|
||||||
|
Vector3 waveEnd = waveStart + Vector3.up * _currentWaveHeight * debugLineLength;
|
||||||
|
DrawLine(_waveHeightLineRenderer, waveStart, waveEnd);
|
||||||
|
|
||||||
|
// 파도 패턴 시각화
|
||||||
|
Vector3[] wavePoints = new Vector3[_wavePatternLineRenderer.positionCount];
|
||||||
|
float waveLength = debugLineLength * 2f;
|
||||||
|
|
||||||
|
for (int i = 0; i < wavePoints.Length; i++)
|
||||||
|
{
|
||||||
|
float t = (float)i / (_wavePatternLineRenderer.positionCount - 1);
|
||||||
|
float x = t * waveLength - waveLength * 0.5f;
|
||||||
|
float currentSpeedByUnit = _currentSpeed / waveUnitSpeed;
|
||||||
|
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
||||||
|
float waveHeight = Mathf.Lerp(minSpeedWaveHeight, maxSpeedWaveHeight, currentSpeedByUnit);
|
||||||
|
float y = Mathf.Sin((_waveTime + x) * baseWaveFrequency) * waveHeight;
|
||||||
|
|
||||||
|
wavePoints[i] = transform.position +
|
||||||
|
Vector3.right * x +
|
||||||
|
Vector3.up * (y + 2f); // 높이 오프셋
|
||||||
|
wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
_wavePatternLineRenderer.SetPositions(wavePoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineRenderer CreateLineRenderer(string name, Color color)
|
||||||
|
{
|
||||||
|
GameObject lineObj = new GameObject(name);
|
||||||
|
lineObj.transform.SetParent(transform);
|
||||||
|
LineRenderer line = lineObj.AddComponent<LineRenderer>();
|
||||||
|
|
||||||
|
line.startWidth = debugLineWidth;
|
||||||
|
line.endWidth = debugLineWidth;
|
||||||
|
line.material = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
|
||||||
|
line.startColor = color;
|
||||||
|
line.endColor = color;
|
||||||
|
line.positionCount = 2;
|
||||||
|
|
||||||
|
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||||
|
line.receiveShadows = false;
|
||||||
|
line.material.color = color;
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLine(LineRenderer line, Vector3 start, Vector3 end)
|
||||||
|
{
|
||||||
|
if (line == null) return;
|
||||||
|
line.positionCount = 2;
|
||||||
|
line.SetPosition(0, start);
|
||||||
|
line.SetPosition(1, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user