using UnityEngine; namespace Voyage { #if UNITY_EDITOR using UnityEngine; [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; private LineRenderer _speedLineRenderer; private LineRenderer _rotationSpeedLineRenderer; private LineRenderer _rotationDeltaLineRenderer; private LineRenderer _TiltLineRenderer; private LineRenderer _waveHeightLineRenderer; private LineRenderer _wavePatternLineRenderer; private VoyagePlayerShipMovement movement; private VoyagePlayerShipMovementVisual movementVisual; private void Start() { if (!showDebugVisuals) return; movement = GetComponent(); movementVisual = GetComponent(); InitializeDebugVisuals(); } private void Update() { if (!showDebugVisuals) return; UpdateDebugVisuals(); } 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 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); } private void UpdateRotationSpeedLine() { 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; } } private void UpdateRotationDeltaLine() { float deltaAngle = 0f; if (GetCurrentInput().magnitude > 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); } 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 = movementVisual.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 * (GetCurrentWaveHeight() * 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 = GetCurrentSpeed() / GetWaveUnitSpeed(); currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit); float waveHeight = Mathf.Lerp(GetMinSpeedWaveHeight(), GetMaxSpeedWaveHeight(), currentSpeedByUnit); float y = Mathf.Sin((GetWaveTime() + x) * GetBaseWaveFrequency()) * waveHeight; wavePoints[i] = transform.position + Vector3.right * x + Vector3.up * (y + 2f); // 높이 오프셋 wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f; } _wavePatternLineRenderer.SetPositions(wavePoints); } 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) { GameObject lineObj = new GameObject(name); lineObj.transform.SetParent(transform); LineRenderer line = lineObj.AddComponent(); 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 is null) return; line.positionCount = 2; line.SetPosition(0, start); line.SetPosition(1, end); } } #endif }