CapersProject/Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
2025-07-15 20:10:46 +09:00

256 lines
9.0 KiB
C#

using UnityEngine;
namespace Voyage
{
#if UNITY_EDITOR
/// <summary>
/// 배의 움직임을 시각적으로 디버깅하기 위한 컴포넌트
/// </summary>
[RequireComponent(typeof(VoyagePlayerShipMovement))]
[RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
public class VoyagePlayerShipDebug : MonoBehaviour
{
#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;
}
[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 (!settings.showDebugVisuals) return;
InitializeComponents();
InitializeDebugLines();
}
private void Update()
{
if (!settings.showDebugVisuals) return;
UpdateAllDebugLines();
}
#endregion
#region Initialization
private void InitializeComponents()
{
movement = GetComponent<VoyagePlayerShipMovement>();
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
}
private void InitializeDebugLines()
{
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
#region Line Updates
private void UpdateAllDebugLines()
{
UpdateSpeedLine();
UpdateRotationLines();
UpdateTiltLine();
UpdateWaveVisualization();
}
private void UpdateSpeedLine()
{
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 UpdateRotationLines()
{
UpdateRotationSpeedArc();
UpdateRotationDeltaArc();
}
private void UpdateRotationSpeedArc()
{
if (Mathf.Abs(movement.CurrentRotationSpeed) <= 0.1f)
{
lines.RotationSpeed.positionCount = 0;
return;
}
DrawArc(lines.RotationSpeed,
GetDebugLineStart(1.2f),
settings.lineLength,
movement.CurrentRotationSpeed);
}
private void UpdateRotationDeltaArc()
{
if (movement.CurrentInput.magnitude <= 0.1f)
{
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 = GetDebugLineStart(1.5f);
Vector3 tiltDirection = movementVisual.MeshTransform.up;
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 * (movementVisual.CurrentWaveHeight * settings.lineLength);
DrawLine(lines.WaveHeight, waveStart, waveEnd);
}
private void UpdateWavePatternLine()
{
// 파도 패턴 시각화
Vector3[] wavePoints = new Vector3[lines.WavePattern.positionCount];
float waveLength = settings.lineLength * 2f;
for (int i = 0; i < wavePoints.Length; i++)
{
float t = (float)i / (lines.WavePattern.positionCount - 1);
float x = t * waveLength - waveLength * 0.5f;
float currentSpeedByUnit = movement.CurrentSpeed / movementVisual.WaveUnitSpeed;
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
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 +
Vector3.up * (y + 2f); // 높이 오프셋
wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f;
}
lines.WavePattern.SetPositions(wavePoints);
}
#endregion
#region Helper Methods
private Vector3 GetDebugLineStart(float heightOffset)
{
return transform.position + Vector3.up * heightOffset;
}
private float CalculateRotationDeltaAngle()
{
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<LineRenderer>();
InitializeLineRenderer(line, color, pointCount);
return line;
}
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 = line.endColor = color;
line.positionCount = pointCount;
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
line.receiveShadows = false;
line.material.color = color;
}
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
}