diff --git a/Assets/0_Voyage/Ship/Player/PlayerShip.prefab b/Assets/0_Voyage/Ship/Player/PlayerShip.prefab
index e104f8cec..86f046578 100644
--- a/Assets/0_Voyage/Ship/Player/PlayerShip.prefab
+++ b/Assets/0_Voyage/Ship/Player/PlayerShip.prefab
@@ -14,6 +14,7 @@ GameObject:
- component: {fileID: -1082383067592254908}
- component: {fileID: 7722456790212551628}
- component: {fileID: 3140672700990605547}
+ - component: {fileID: 66612183539046142}
m_Layer: 0
m_Name: PlayerShip
m_TagString: Untagged
@@ -107,15 +108,17 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3}
m_Name:
m_EditorClassIdentifier:
- maxSpeed: 20
- accelerationRate: 1
- dragFactor: 0.98
- minSpeedThreshold: 0.1
- rotationSpeed: 270
- minRotationSpeed: 90
- rotationAccelerationRate: 5
- turnSpeedPenalty: 0.5
- maxTurnAngle: 180
+ movementSettings:
+ maxSpeed: 20
+ accelerationRate: 1
+ dragFactor: 0.98
+ minSpeedThreshold: 0.1
+ rotationSettings:
+ maxRotationSpeed: 270
+ minRotationSpeed: 90
+ accelerationRate: 5
+ turnSpeedPenalty: 0.5
+ maxTurnAngle: 180
--- !u!114 &7722456790212551628
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -157,9 +160,43 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3d5c5f51b32b4633b887d096554c6cd9, type: 3}
m_Name:
m_EditorClassIdentifier:
- showDebugVisuals: 1
- debugLineLength: 5
- debugLineWidth: 0.1
+ settings:
+ showDebugVisuals: 1
+ lineLength: 5
+ lineWidth: 0.1
+ speedLineColor: {r: 0, g: 1, b: 0, a: 1}
+ rotationSpeedLineColor: {r: 1, g: 0, b: 1, a: 1}
+ rotationDeltaLineColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+ tiltLineColor: {r: 1, g: 0, b: 0, a: 1}
+ waveHeightLineColor: {r: 0, g: 0, b: 1, a: 1}
+ wavePatternLineColor: {r: 0, g: 1, b: 1, a: 1}
+--- !u!54 &66612183539046142
+Rigidbody:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1553910019582315619}
+ serializedVersion: 4
+ m_Mass: 1
+ m_Drag: 0
+ m_AngularDrag: 0.05
+ m_CenterOfMass: {x: 0, y: 0, z: 0}
+ m_InertiaTensor: {x: 1, y: 1, z: 1}
+ m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ImplicitCom: 1
+ m_ImplicitTensor: 1
+ m_UseGravity: 0
+ m_IsKinematic: 0
+ m_Interpolate: 0
+ m_Constraints: 0
+ m_CollisionDetection: 0
--- !u!1 &6407855916708530114
GameObject:
m_ObjectHideFlags: 0
diff --git a/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs b/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs
index 3096a1231..a745566a9 100644
--- a/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs
+++ b/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs
@@ -2,178 +2,208 @@ using UnityEngine;
using UnityEngine.InputSystem;
///
-/// 플레이어 배의 움직임을 제어하는 컴포넌트
-/// 속도, 회전, 틸트, 파도 효과 등을 관리합니다.
+/// 플레이어 배의 기본 이동과 회전을 처리하는 컴포넌트
///
+[RequireComponent(typeof(Rigidbody))]
public class VoyagePlayerShipMovement : MonoBehaviour
{
+ #region Settings
+ [System.Serializable]
+ public class MovementSettings
+ {
+ [Tooltip("배의 최대 이동 속도")]
+ public float maxSpeed = 20f;
+ public float accelerationRate = 1f;
+ public float dragFactor = 0.98f;
+ public float minSpeedThreshold = 0.1f;
+ }
+
+ [System.Serializable]
+ public class RotationSettings
+ {
+ public float maxRotationSpeed = 270f;
+ public float minRotationSpeed = 90f;
+ public float accelerationRate = 5f;
+ [Tooltip("선회 시 감속 정도 (0: 감속 없음, 1: 완전 정지)")]
+ public float turnSpeedPenalty = 0.5f;
+ [Tooltip("최대 감속이 적용되는 각도")]
+ public float maxTurnAngle = 180f;
+ }
+ #endregion
+
#region Inspector Fields
-
- [Header("기본 이동 설정")]
- [Tooltip("배의 최대 이동 속도")]
- [SerializeField] private float maxSpeed = 20f;
- [SerializeField] private float accelerationRate = 1f;
- [SerializeField] private float dragFactor = 0.98f;
- [SerializeField] private float minSpeedThreshold = 0.1f;
-
- [Header("회전 설정")]
- [SerializeField] private float rotationSpeed = 270f;
- [SerializeField] private float minRotationSpeed = 90f;
- [SerializeField] private float rotationAccelerationRate = 5f;
- [SerializeField] private float turnSpeedPenalty = 0.5f;
- [SerializeField] private float maxTurnAngle = 180f;
+ [SerializeField]
+ private MovementSettings movementSettings = new();
+ [SerializeField]
+ private RotationSettings rotationSettings = new();
+ #endregion
+
+ #region Properties
+ public Vector2 CurrentInput => currentInput;
+ public float CurrentRotationSpeed => currentRotationSpeed;
+ public float CurrentSpeed => currentSpeed;
+ public float MaxSpeed => movementSettings.maxSpeed;
+ public Vector3 CurrentVelocity => currentVelocity;
#endregion
#region Private Fields
-
private Vector3 currentVelocity;
private Vector2 currentInput;
- public Vector2 CurrentInput => currentInput;
private float currentRotationSpeed;
- public float CurrentRotationSpeed => currentRotationSpeed;
private float targetSpeed;
private float currentSpeed;
- public float CurrentSpeed => currentSpeed;
- public float MaxSpeed => maxSpeed;
-
- // 회전 틸트 관련
- private float currentRotationTilt;
- private float lastRotationY;
- private float currentAngularVelocity;
-
- // 가속 틸트 관련
- private float currentAccelTilt;
- private float accelTiltVelocity;
- private float prevSpeed;
-
- // 파도 효과 관련
- private float waveTime;
- private float waveRandomOffset;
- private float currentWaveHeight;
-
#endregion
#region Unity Messages
private void FixedUpdate()
{
- UpdateMovement();
+ UpdateShipMovement();
+ }
+ #endregion
+
+ #region Public Methods
+ public void OnMove(InputAction.CallbackContext context)
+ {
+ currentInput = context.ReadValue();
}
#endregion
#region Movement Methods
- private void UpdateMovement()
+ private void UpdateShipMovement()
{
if (IsMoving())
{
- HandleMovement();
- HandleRotation();
+ UpdateMovementWithInput();
}
else
{
- DecelerateMovement();
+ DecelerateShip();
}
- ApplyDrag();
- ApplyMovement();
+ ApplyDragForce();
+ ApplyFinalMovement();
}
- private bool IsMoving()
+ private void UpdateMovementWithInput()
{
- return currentInput.magnitude > minSpeedThreshold;
+ UpdateSpeed();
+ UpdateRotation();
}
- private void HandleMovement()
+ private void UpdateSpeed()
{
float baseTargetSpeed = CalculateBaseTargetSpeed();
float turnPenaltyFactor = CalculateTurnPenaltyFactor();
targetSpeed = baseTargetSpeed * turnPenaltyFactor;
- currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, accelerationRate * Time.fixedDeltaTime);
+ currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed,
+ movementSettings.accelerationRate * Time.fixedDeltaTime);
if (ShouldStop())
{
- currentSpeed = 0f;
+ StopShip();
}
UpdateVelocityVector();
}
- private void HandleRotation()
+ private void UpdateRotation()
{
- if (IsMoving())
- {
- Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
- Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
+ if (!IsMoving()) return;
- // 회전 속도를 현재 속도에 비례하도록 설정
- float desiredRotationSpeed = rotationSpeed * (currentSpeed / maxSpeed);
- desiredRotationSpeed = Mathf.Max(desiredRotationSpeed, minRotationSpeed);
- currentRotationSpeed = Mathf.Lerp(currentRotationSpeed, desiredRotationSpeed,
- rotationAccelerationRate * Time.fixedDeltaTime);
-
- // 기본 회전 적용 (오브젝트 전체)
- transform.rotation = Quaternion.RotateTowards(
- transform.rotation,
- targetRotation,
- currentRotationSpeed * Time.fixedDeltaTime
- );
- }
+ Quaternion targetRotation = CalculateTargetRotation();
+ float rotationSpeed = CalculateRotationSpeed();
+
+ ApplyRotation(targetRotation, rotationSpeed);
}
-
+ #endregion
+
+ #region Helper Methods
+ private bool IsMoving()
+ {
+ return currentInput.magnitude > movementSettings.minSpeedThreshold;
+ }
+
private float CalculateBaseTargetSpeed()
{
- return Mathf.Clamp01(currentInput.magnitude) * maxSpeed;
+ return Mathf.Clamp01(currentInput.magnitude) * movementSettings.maxSpeed;
}
private float CalculateTurnPenaltyFactor()
{
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
float angleDifference = Vector3.Angle(transform.forward, inputDirection);
- return Mathf.Clamp01(1f - (angleDifference / maxTurnAngle * turnSpeedPenalty));
+ float penaltyFactor = angleDifference / rotationSettings.maxTurnAngle * rotationSettings.turnSpeedPenalty;
+
+ return Mathf.Clamp01(1f - penaltyFactor);
+ }
+
+ private Quaternion CalculateTargetRotation()
+ {
+ Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
+ return Quaternion.LookRotation(inputDirection, Vector3.up);
+ }
+
+ private float CalculateRotationSpeed()
+ {
+ float speedBasedRotation = rotationSettings.maxRotationSpeed * (currentSpeed / movementSettings.maxSpeed);
+ float desiredRotationSpeed = Mathf.Max(speedBasedRotation, rotationSettings.minRotationSpeed);
+
+ return Mathf.Lerp(currentRotationSpeed, desiredRotationSpeed,
+ rotationSettings.accelerationRate * Time.fixedDeltaTime);
+ }
+
+ private void ApplyRotation(Quaternion targetRotation, float rotationSpeed)
+ {
+ currentRotationSpeed = rotationSpeed;
+ transform.rotation = Quaternion.RotateTowards(
+ transform.rotation,
+ targetRotation,
+ rotationSpeed * Time.fixedDeltaTime
+ );
}
private bool ShouldStop()
{
- return currentSpeed < minSpeedThreshold && targetSpeed < minSpeedThreshold;
+ return currentSpeed < movementSettings.minSpeedThreshold &&
+ targetSpeed < movementSettings.minSpeedThreshold;
+ }
+
+ private void StopShip()
+ {
+ currentSpeed = 0f;
+ currentVelocity = Vector3.zero;
}
private void UpdateVelocityVector()
{
currentVelocity = transform.forward * currentSpeed;
}
- #endregion
-
- private void ApplyDrag()
+
+ private void DecelerateShip()
{
- currentSpeed *= dragFactor;
-
- // 최소 속도 이하면 완전히 정지
- if (currentSpeed < minSpeedThreshold)
- {
- currentSpeed = 0f;
- }
-
- // 현재 방향으로 감속된 속도 적용
- currentVelocity = transform.forward * currentSpeed;
+ currentSpeed = Mathf.Lerp(currentSpeed, 0f,
+ movementSettings.accelerationRate * Time.fixedDeltaTime);
+ currentRotationSpeed = 0f;
}
- private void ApplyMovement()
+ private void ApplyDragForce()
+ {
+ currentSpeed *= movementSettings.dragFactor;
+ if (currentSpeed < movementSettings.minSpeedThreshold)
+ {
+ StopShip();
+ }
+ else
+ {
+ UpdateVelocityVector();
+ }
+ }
+
+ private void ApplyFinalMovement()
{
transform.position += currentVelocity * Time.fixedDeltaTime;
}
-
- private void DecelerateMovement()
- {
- // 입력이 없을 때는 서서히 감속
- currentSpeed = Mathf.Lerp(currentSpeed, 0f, accelerationRate * Time.fixedDeltaTime);
- currentRotationSpeed = 0;
- }
-
- #region Input Handling
- public void OnMove(InputAction.CallbackContext context)
- {
- currentInput = context.ReadValue();
- }
#endregion
}
\ No newline at end of file
diff --git a/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs b/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
index 58d3e2ceb..caaca336a 100644
--- a/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
+++ b/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
@@ -3,176 +3,180 @@ using UnityEngine;
namespace Voyage
{
#if UNITY_EDITOR
- using UnityEngine;
-
- [RequireComponent(typeof(VoyagePlayerShipMovement)), RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
+ ///
+ /// 배의 움직임을 시각적으로 디버깅하기 위한 컴포넌트
+ ///
+ [RequireComponent(typeof(VoyagePlayerShipMovement))]
+ [RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
public class VoyagePlayerShipDebug : MonoBehaviour
{
- [Header("Debug Visualization")]
- [SerializeField] private bool showDebugVisuals = true;
- [SerializeField] private float debugLineLength = 5f;
- [SerializeField] private float debugLineWidth = 0.1f;
+ #region Debug Settings
+ [System.Serializable]
+ public class DebugSettings
+ {
+ public bool showDebugVisuals = true;
+ public float lineLength = 5f;
+ public float lineWidth = 0.1f;
+
+ [Header("라인 색상")]
+ public Color speedLineColor = Color.green;
+ public Color rotationSpeedLineColor = Color.magenta;
+ public Color rotationDeltaLineColor = Color.yellow;
+ public Color tiltLineColor = Color.red;
+ public Color waveHeightLineColor = Color.blue;
+ public Color wavePatternLineColor = Color.cyan;
+ }
- private LineRenderer _speedLineRenderer;
- private LineRenderer _rotationSpeedLineRenderer;
- private LineRenderer _rotationDeltaLineRenderer;
- private LineRenderer _TiltLineRenderer;
- private LineRenderer _waveHeightLineRenderer;
- private LineRenderer _wavePatternLineRenderer;
+ [SerializeField] private DebugSettings settings = new();
+ #endregion
+ #region Line Renderers
+ private class DebugLines
+ {
+ public LineRenderer Speed { get; set; }
+ public LineRenderer RotationSpeed { get; set; }
+ public LineRenderer RotationDelta { get; set; }
+ public LineRenderer Tilt { get; set; }
+ public LineRenderer WaveHeight { get; set; }
+ public LineRenderer WavePattern { get; set; }
+ }
+
+ private DebugLines lines = new();
+ #endregion
+
+ #region Components
private VoyagePlayerShipMovement movement;
private VoyagePlayerShipMovementVisual movementVisual;
+ #endregion
-
+ #region Unity Messages
private void Start()
{
- if (!showDebugVisuals) return;
+ if (!settings.showDebugVisuals) return;
- movement = GetComponent();
- movementVisual = GetComponent();
-
- InitializeDebugVisuals();
+ InitializeComponents();
+ InitializeDebugLines();
}
private void Update()
{
- if (!showDebugVisuals) return;
- UpdateDebugVisuals();
+ if (!settings.showDebugVisuals) return;
+ UpdateAllDebugLines();
+ }
+ #endregion
+
+ #region Initialization
+ private void InitializeComponents()
+ {
+ movement = GetComponent();
+ movementVisual = GetComponent();
}
- private void InitializeDebugVisuals()
+ private void InitializeDebugLines()
{
- 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; // 파도 패턴을 위한 더 많은 점
+ lines.Speed = CreateLineRenderer("SpeedLine", settings.speedLineColor);
+ lines.RotationSpeed = CreateLineRenderer("RotationSpeedLine", settings.rotationSpeedLineColor);
+ lines.RotationDelta = CreateLineRenderer("RotationDeltaLine", settings.rotationDeltaLineColor);
+ lines.Tilt = CreateLineRenderer("TiltLine", settings.tiltLineColor);
+ lines.WaveHeight = CreateLineRenderer("WaveHeightLine", settings.waveHeightLineColor);
+ lines.WavePattern = CreateLineRenderer("WavePatternLine", settings.wavePatternLineColor, 50);
}
+ #endregion
- private void UpdateDebugVisuals()
+ #region Line Updates
+ private void UpdateAllDebugLines()
{
- if (!showDebugVisuals) return;
-
- // 속도 벡터 표시
UpdateSpeedLine();
-
- // 회전 방향 및 각속도 표시
- UpdateRotationSpeedLine();
- UpdateRotationDeltaLine();
- // 회전 틸트 표시
+ UpdateRotationLines();
UpdateTiltLine();
- // 파도 높이와 패턴 표시
UpdateWaveVisualization();
}
-
- private float GetCurrentSpeed() => movement.CurrentSpeed;
- private float GetMaxSpeed() => movement.MaxSpeed;
- private float GetRotationSpeed() => movement.CurrentRotationSpeed;
- private Vector2 GetCurrentInput() => movement.CurrentInput;
private void UpdateSpeedLine()
{
- Vector3 start = transform.position + Vector3.up * 1.5f;
- Vector3 end = start + transform.forward * ((GetCurrentSpeed() / GetMaxSpeed()) * debugLineLength * 2);
- DrawLine(_speedLineRenderer, start, end);
+ Vector3 start = GetDebugLineStart(1.5f);
+ Vector3 direction = transform.forward * (movement.CurrentSpeed / movement.MaxSpeed);
+ Vector3 end = start + direction * (settings.lineLength * 2f);
+
+ DrawLine(lines.Speed, start, end);
}
- private void UpdateRotationSpeedLine()
+ private void UpdateRotationLines()
{
- Vector3 start = transform.position + Vector3.up * 1.2f;
- // 각속도를 호로 표현
- if (Mathf.Abs(GetRotationSpeed()) > 0.1f)
- {
- Vector3[] arcPoints = new Vector3[10];
- float radius = debugLineLength * 1f;
- float angleStep = GetRotationSpeed() * 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;
- }
+ UpdateRotationSpeedArc();
+ UpdateRotationDeltaArc();
}
- private void UpdateRotationDeltaLine()
+ private void UpdateRotationSpeedArc()
{
- float deltaAngle = 0f;
- if (GetCurrentInput().magnitude > 0.1f)
+ if (Mathf.Abs(movement.CurrentRotationSpeed) <= 0.1f)
{
- Vector3 inputDirection = new Vector3(GetCurrentInput().x, 0, GetCurrentInput().y).normalized;
- Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
- deltaAngle = Quaternion.Angle(transform.rotation, targetRotation);
+ lines.RotationSpeed.positionCount = 0;
+ return;
}
- 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);
+ DrawArc(lines.RotationSpeed,
+ GetDebugLineStart(1.2f),
+ settings.lineLength,
+ movement.CurrentRotationSpeed);
+ }
- 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
+ private void UpdateRotationDeltaArc()
+ {
+ if (movement.CurrentInput.magnitude <= 0.1f)
{
- _rotationDeltaLineRenderer.positionCount = 0;
+ lines.RotationDelta.positionCount = 0;
+ return;
}
+
+ float deltaAngle = CalculateRotationDeltaAngle();
+ if (Mathf.Abs(deltaAngle) <= 0.1f)
+ {
+ lines.RotationDelta.positionCount = 0;
+ return;
+ }
+
+ DrawArc(lines.RotationDelta,
+ GetDebugLineStart(1.2f),
+ settings.lineLength * 1.05f,
+ deltaAngle);
}
private void UpdateTiltLine()
{
- Vector3 start = transform.position + Vector3.up * 1.5f;
+ Vector3 start = GetDebugLineStart(1.5f);
Vector3 tiltDirection = movementVisual.MeshTransform.up;
- DrawLine(_TiltLineRenderer, start, start + tiltDirection * (debugLineLength * 0.4f));
+ DrawLine(lines.Tilt, start, start + tiltDirection * (settings.lineLength * 0.4f));
}
private void UpdateWaveVisualization()
+ {
+ UpdateWaveHeightLine();
+ UpdateWavePatternLine();
+ }
+
+ private void UpdateWaveHeightLine()
{
// 현재 파도 높이 표시
Vector3 waveStart = transform.position + Vector3.up * 1.5f - transform.forward * 1.5f;
- Vector3 waveEnd = waveStart + Vector3.up * (GetCurrentWaveHeight() * debugLineLength);
- DrawLine(_waveHeightLineRenderer, waveStart, waveEnd);
+ Vector3 waveEnd = waveStart + Vector3.up * (movementVisual.CurrentWaveHeight * settings.lineLength);
+ DrawLine(lines.WaveHeight, waveStart, waveEnd);
+ }
+ private void UpdateWavePatternLine()
+ {
// 파도 패턴 시각화
- Vector3[] wavePoints = new Vector3[_wavePatternLineRenderer.positionCount];
- float waveLength = debugLineLength * 2f;
+ Vector3[] wavePoints = new Vector3[lines.WavePattern.positionCount];
+ float waveLength = settings.lineLength * 2f;
for (int i = 0; i < wavePoints.Length; i++)
{
- float t = (float)i / (_wavePatternLineRenderer.positionCount - 1);
+ float t = (float)i / (lines.WavePattern.positionCount - 1);
float x = t * waveLength - waveLength * 0.5f;
- float currentSpeedByUnit = GetCurrentSpeed() / GetWaveUnitSpeed();
+ float currentSpeedByUnit = movement.CurrentSpeed / movementVisual.WaveUnitSpeed;
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
- float waveHeight = Mathf.Lerp(GetMinSpeedWaveHeight(), GetMaxSpeedWaveHeight(), currentSpeedByUnit);
- float y = Mathf.Sin((GetWaveTime() + x) * GetBaseWaveFrequency()) * waveHeight;
+ float waveHeight = Mathf.Lerp(movementVisual.MinSpeedWaveHeight, movementVisual.MaxSpeedWaveHeight, currentSpeedByUnit);
+ float y = Mathf.Sin((movementVisual.WaveTime + x) * movementVisual.BaseWaveFrequency) * waveHeight;
wavePoints[i] = transform.position +
Vector3.right * x +
@@ -180,43 +184,73 @@ namespace Voyage
wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f;
}
- _wavePatternLineRenderer.SetPositions(wavePoints);
+ lines.WavePattern.SetPositions(wavePoints);
+ }
+ #endregion
+
+ #region Helper Methods
+ private Vector3 GetDebugLineStart(float heightOffset)
+ {
+ return transform.position + Vector3.up * heightOffset;
}
- private float GetCurrentWaveHeight() => movementVisual.CurrentWaveHeight;
- private float GetWaveUnitSpeed() => movementVisual.WaveUnitSpeed;
- private float GetMinSpeedWaveHeight() => movementVisual.MinSpeedWaveHeight;
- private float GetMaxSpeedWaveHeight() => movementVisual.MaxSpeedWaveHeight;
- private float GetWaveTime() => movementVisual.WaveTime;
- private float GetBaseWaveFrequency() => movementVisual.BaseWaveFrequency;
-
- private LineRenderer CreateLineRenderer(string name, Color color)
+ private float CalculateRotationDeltaAngle()
{
- GameObject lineObj = new GameObject(name);
+ Vector3 inputDirection = new Vector3(movement.CurrentInput.x, 0, movement.CurrentInput.y).normalized;
+ Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
+ return Quaternion.Angle(transform.rotation, targetRotation);
+ }
+
+ private void DrawArc(LineRenderer lineRenderer, Vector3 center, float radius, float totalAngle)
+ {
+ const int ArcSegments = 10;
+ Vector3[] arcPoints = new Vector3[ArcSegments];
+ float angleStep = totalAngle / (ArcSegments - 1);
+
+ for (int i = 0; i < ArcSegments; i++)
+ {
+ float angle = angleStep * i;
+ Vector3 point = center + Quaternion.Euler(0, angle, 0) * transform.forward * radius;
+ arcPoints[i] = point;
+ }
+
+ lineRenderer.positionCount = ArcSegments;
+ lineRenderer.SetPositions(arcPoints);
+ }
+
+ private LineRenderer CreateLineRenderer(string name, Color color, int pointCount = 2)
+ {
+ GameObject lineObj = new GameObject($"Debug_{name}");
lineObj.transform.SetParent(transform);
+
LineRenderer line = lineObj.AddComponent();
+ InitializeLineRenderer(line, color, pointCount);
+
+ return line;
+ }
- line.startWidth = debugLineWidth;
- line.endWidth = debugLineWidth;
+ private void InitializeLineRenderer(LineRenderer line, Color color, int pointCount)
+ {
+ line.startWidth = settings.lineWidth;
+ line.endWidth = settings.lineWidth;
line.material = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
- line.startColor = color;
- line.endColor = color;
- line.positionCount = 2;
-
+ line.startColor = line.endColor = color;
+ line.positionCount = pointCount;
+
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 is null) return;
+
line.positionCount = 2;
line.SetPosition(0, start);
line.SetPosition(1, end);
}
+ #endregion
}
#endif
}
\ No newline at end of file