DDD-43 코드 리팩토링
This commit is contained in:
parent
4a06cc0565
commit
ef384bf59c
@ -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
|
||||
|
@ -2,178 +2,208 @@ using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 플레이어 배의 움직임을 제어하는 컴포넌트
|
||||
/// 속도, 회전, 틸트, 파도 효과 등을 관리합니다.
|
||||
/// 플레이어 배의 기본 이동과 회전을 처리하는 컴포넌트
|
||||
/// </summary>
|
||||
[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<Vector2>();
|
||||
}
|
||||
#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<Vector2>();
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -3,176 +3,180 @@ using UnityEngine;
|
||||
namespace Voyage
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(VoyagePlayerShipMovement)), RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
|
||||
/// <summary>
|
||||
/// 배의 움직임을 시각적으로 디버깅하기 위한 컴포넌트
|
||||
/// </summary>
|
||||
[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<VoyagePlayerShipMovement>();
|
||||
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
|
||||
|
||||
InitializeDebugVisuals();
|
||||
InitializeComponents();
|
||||
InitializeDebugLines();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!showDebugVisuals) return;
|
||||
UpdateDebugVisuals();
|
||||
if (!settings.showDebugVisuals) return;
|
||||
UpdateAllDebugLines();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
private void InitializeComponents()
|
||||
{
|
||||
movement = GetComponent<VoyagePlayerShipMovement>();
|
||||
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
|
||||
}
|
||||
|
||||
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<LineRenderer>();
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user