DDD-43 코드 리팩토링
This commit is contained in:
parent
4a06cc0565
commit
ef384bf59c
@ -14,6 +14,7 @@ GameObject:
|
|||||||
- component: {fileID: -1082383067592254908}
|
- component: {fileID: -1082383067592254908}
|
||||||
- component: {fileID: 7722456790212551628}
|
- component: {fileID: 7722456790212551628}
|
||||||
- component: {fileID: 3140672700990605547}
|
- component: {fileID: 3140672700990605547}
|
||||||
|
- component: {fileID: 66612183539046142}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: PlayerShip
|
m_Name: PlayerShip
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@ -107,13 +108,15 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3}
|
m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
movementSettings:
|
||||||
maxSpeed: 20
|
maxSpeed: 20
|
||||||
accelerationRate: 1
|
accelerationRate: 1
|
||||||
dragFactor: 0.98
|
dragFactor: 0.98
|
||||||
minSpeedThreshold: 0.1
|
minSpeedThreshold: 0.1
|
||||||
rotationSpeed: 270
|
rotationSettings:
|
||||||
|
maxRotationSpeed: 270
|
||||||
minRotationSpeed: 90
|
minRotationSpeed: 90
|
||||||
rotationAccelerationRate: 5
|
accelerationRate: 5
|
||||||
turnSpeedPenalty: 0.5
|
turnSpeedPenalty: 0.5
|
||||||
maxTurnAngle: 180
|
maxTurnAngle: 180
|
||||||
--- !u!114 &7722456790212551628
|
--- !u!114 &7722456790212551628
|
||||||
@ -157,9 +160,43 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 3d5c5f51b32b4633b887d096554c6cd9, type: 3}
|
m_Script: {fileID: 11500000, guid: 3d5c5f51b32b4633b887d096554c6cd9, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
settings:
|
||||||
showDebugVisuals: 1
|
showDebugVisuals: 1
|
||||||
debugLineLength: 5
|
lineLength: 5
|
||||||
debugLineWidth: 0.1
|
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
|
--- !u!1 &6407855916708530114
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -2,178 +2,208 @@ using UnityEngine;
|
|||||||
using UnityEngine.InputSystem;
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 플레이어 배의 움직임을 제어하는 컴포넌트
|
/// 플레이어 배의 기본 이동과 회전을 처리하는 컴포넌트
|
||||||
/// 속도, 회전, 틸트, 파도 효과 등을 관리합니다.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(Rigidbody))]
|
||||||
public class VoyagePlayerShipMovement : MonoBehaviour
|
public class VoyagePlayerShipMovement : MonoBehaviour
|
||||||
{
|
{
|
||||||
#region Inspector Fields
|
#region Settings
|
||||||
|
[System.Serializable]
|
||||||
[Header("기본 이동 설정")]
|
public class MovementSettings
|
||||||
|
{
|
||||||
[Tooltip("배의 최대 이동 속도")]
|
[Tooltip("배의 최대 이동 속도")]
|
||||||
[SerializeField] private float maxSpeed = 20f;
|
public float maxSpeed = 20f;
|
||||||
[SerializeField] private float accelerationRate = 1f;
|
public float accelerationRate = 1f;
|
||||||
[SerializeField] private float dragFactor = 0.98f;
|
public float dragFactor = 0.98f;
|
||||||
[SerializeField] private float minSpeedThreshold = 0.1f;
|
public float minSpeedThreshold = 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
[Header("회전 설정")]
|
[System.Serializable]
|
||||||
[SerializeField] private float rotationSpeed = 270f;
|
public class RotationSettings
|
||||||
[SerializeField] private float minRotationSpeed = 90f;
|
{
|
||||||
[SerializeField] private float rotationAccelerationRate = 5f;
|
public float maxRotationSpeed = 270f;
|
||||||
[SerializeField] private float turnSpeedPenalty = 0.5f;
|
public float minRotationSpeed = 90f;
|
||||||
[SerializeField] private float maxTurnAngle = 180f;
|
public float accelerationRate = 5f;
|
||||||
|
[Tooltip("선회 시 감속 정도 (0: 감속 없음, 1: 완전 정지)")]
|
||||||
|
public float turnSpeedPenalty = 0.5f;
|
||||||
|
[Tooltip("최대 감속이 적용되는 각도")]
|
||||||
|
public float maxTurnAngle = 180f;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Inspector Fields
|
||||||
|
[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
|
#endregion
|
||||||
|
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private Vector3 currentVelocity;
|
private Vector3 currentVelocity;
|
||||||
private Vector2 currentInput;
|
private Vector2 currentInput;
|
||||||
public Vector2 CurrentInput => currentInput;
|
|
||||||
private float currentRotationSpeed;
|
private float currentRotationSpeed;
|
||||||
public float CurrentRotationSpeed => currentRotationSpeed;
|
|
||||||
private float targetSpeed;
|
private float targetSpeed;
|
||||||
private float currentSpeed;
|
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
|
#endregion
|
||||||
|
|
||||||
#region Unity Messages
|
#region Unity Messages
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
UpdateMovement();
|
UpdateShipMovement();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
public void OnMove(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
currentInput = context.ReadValue<Vector2>();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Movement Methods
|
#region Movement Methods
|
||||||
private void UpdateMovement()
|
private void UpdateShipMovement()
|
||||||
{
|
{
|
||||||
if (IsMoving())
|
if (IsMoving())
|
||||||
{
|
{
|
||||||
HandleMovement();
|
UpdateMovementWithInput();
|
||||||
HandleRotation();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DecelerateMovement();
|
DecelerateShip();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyDrag();
|
ApplyDragForce();
|
||||||
ApplyMovement();
|
ApplyFinalMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsMoving()
|
private void UpdateMovementWithInput()
|
||||||
{
|
{
|
||||||
return currentInput.magnitude > minSpeedThreshold;
|
UpdateSpeed();
|
||||||
|
UpdateRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMovement()
|
private void UpdateSpeed()
|
||||||
{
|
{
|
||||||
float baseTargetSpeed = CalculateBaseTargetSpeed();
|
float baseTargetSpeed = CalculateBaseTargetSpeed();
|
||||||
float turnPenaltyFactor = CalculateTurnPenaltyFactor();
|
float turnPenaltyFactor = CalculateTurnPenaltyFactor();
|
||||||
|
|
||||||
targetSpeed = baseTargetSpeed * turnPenaltyFactor;
|
targetSpeed = baseTargetSpeed * turnPenaltyFactor;
|
||||||
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, accelerationRate * Time.fixedDeltaTime);
|
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed,
|
||||||
|
movementSettings.accelerationRate * Time.fixedDeltaTime);
|
||||||
|
|
||||||
if (ShouldStop())
|
if (ShouldStop())
|
||||||
{
|
{
|
||||||
currentSpeed = 0f;
|
StopShip();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateVelocityVector();
|
UpdateVelocityVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleRotation()
|
private void UpdateRotation()
|
||||||
{
|
{
|
||||||
if (IsMoving())
|
if (!IsMoving()) return;
|
||||||
{
|
|
||||||
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
|
||||||
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
|
||||||
|
|
||||||
// 회전 속도를 현재 속도에 비례하도록 설정
|
Quaternion targetRotation = CalculateTargetRotation();
|
||||||
float desiredRotationSpeed = rotationSpeed * (currentSpeed / maxSpeed);
|
float rotationSpeed = CalculateRotationSpeed();
|
||||||
desiredRotationSpeed = Mathf.Max(desiredRotationSpeed, minRotationSpeed);
|
|
||||||
currentRotationSpeed = Mathf.Lerp(currentRotationSpeed, desiredRotationSpeed,
|
|
||||||
rotationAccelerationRate * Time.fixedDeltaTime);
|
|
||||||
|
|
||||||
// 기본 회전 적용 (오브젝트 전체)
|
ApplyRotation(targetRotation, rotationSpeed);
|
||||||
transform.rotation = Quaternion.RotateTowards(
|
|
||||||
transform.rotation,
|
|
||||||
targetRotation,
|
|
||||||
currentRotationSpeed * Time.fixedDeltaTime
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helper Methods
|
||||||
|
private bool IsMoving()
|
||||||
|
{
|
||||||
|
return currentInput.magnitude > movementSettings.minSpeedThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float CalculateBaseTargetSpeed()
|
private float CalculateBaseTargetSpeed()
|
||||||
{
|
{
|
||||||
return Mathf.Clamp01(currentInput.magnitude) * maxSpeed;
|
return Mathf.Clamp01(currentInput.magnitude) * movementSettings.maxSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float CalculateTurnPenaltyFactor()
|
private float CalculateTurnPenaltyFactor()
|
||||||
{
|
{
|
||||||
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);
|
||||||
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()
|
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()
|
private void UpdateVelocityVector()
|
||||||
{
|
{
|
||||||
currentVelocity = transform.forward * currentSpeed;
|
currentVelocity = transform.forward * currentSpeed;
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void ApplyDrag()
|
private void DecelerateShip()
|
||||||
{
|
{
|
||||||
currentSpeed *= dragFactor;
|
currentSpeed = Mathf.Lerp(currentSpeed, 0f,
|
||||||
|
movementSettings.accelerationRate * Time.fixedDeltaTime);
|
||||||
// 최소 속도 이하면 완전히 정지
|
currentRotationSpeed = 0f;
|
||||||
if (currentSpeed < minSpeedThreshold)
|
|
||||||
{
|
|
||||||
currentSpeed = 0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 방향으로 감속된 속도 적용
|
private void ApplyDragForce()
|
||||||
currentVelocity = transform.forward * currentSpeed;
|
{
|
||||||
|
currentSpeed *= movementSettings.dragFactor;
|
||||||
|
if (currentSpeed < movementSettings.minSpeedThreshold)
|
||||||
|
{
|
||||||
|
StopShip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateVelocityVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyMovement()
|
private void ApplyFinalMovement()
|
||||||
{
|
{
|
||||||
transform.position += currentVelocity * Time.fixedDeltaTime;
|
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
|
#endregion
|
||||||
}
|
}
|
@ -3,176 +3,180 @@ using UnityEngine;
|
|||||||
namespace Voyage
|
namespace Voyage
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEngine;
|
/// <summary>
|
||||||
|
/// 배의 움직임을 시각적으로 디버깅하기 위한 컴포넌트
|
||||||
[RequireComponent(typeof(VoyagePlayerShipMovement)), RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(VoyagePlayerShipMovement))]
|
||||||
|
[RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
|
||||||
public class VoyagePlayerShipDebug : MonoBehaviour
|
public class VoyagePlayerShipDebug : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Debug Visualization")]
|
#region Debug Settings
|
||||||
[SerializeField] private bool showDebugVisuals = true;
|
[System.Serializable]
|
||||||
[SerializeField] private float debugLineLength = 5f;
|
public class DebugSettings
|
||||||
[SerializeField] private float debugLineWidth = 0.1f;
|
{
|
||||||
|
public bool showDebugVisuals = true;
|
||||||
|
public float lineLength = 5f;
|
||||||
|
public float lineWidth = 0.1f;
|
||||||
|
|
||||||
private LineRenderer _speedLineRenderer;
|
[Header("라인 색상")]
|
||||||
private LineRenderer _rotationSpeedLineRenderer;
|
public Color speedLineColor = Color.green;
|
||||||
private LineRenderer _rotationDeltaLineRenderer;
|
public Color rotationSpeedLineColor = Color.magenta;
|
||||||
private LineRenderer _TiltLineRenderer;
|
public Color rotationDeltaLineColor = Color.yellow;
|
||||||
private LineRenderer _waveHeightLineRenderer;
|
public Color tiltLineColor = Color.red;
|
||||||
private LineRenderer _wavePatternLineRenderer;
|
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 VoyagePlayerShipMovement movement;
|
||||||
private VoyagePlayerShipMovementVisual movementVisual;
|
private VoyagePlayerShipMovementVisual movementVisual;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Unity Messages
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
if (!showDebugVisuals) return;
|
if (!settings.showDebugVisuals) return;
|
||||||
|
|
||||||
movement = GetComponent<VoyagePlayerShipMovement>();
|
InitializeComponents();
|
||||||
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
|
InitializeDebugLines();
|
||||||
|
|
||||||
InitializeDebugVisuals();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (!showDebugVisuals) return;
|
if (!settings.showDebugVisuals) return;
|
||||||
UpdateDebugVisuals();
|
UpdateAllDebugLines();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Initialization
|
||||||
|
private void InitializeComponents()
|
||||||
|
{
|
||||||
|
movement = GetComponent<VoyagePlayerShipMovement>();
|
||||||
|
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeDebugVisuals()
|
private void InitializeDebugLines()
|
||||||
{
|
{
|
||||||
if (!showDebugVisuals) return;
|
lines.Speed = CreateLineRenderer("SpeedLine", settings.speedLineColor);
|
||||||
|
lines.RotationSpeed = CreateLineRenderer("RotationSpeedLine", settings.rotationSpeedLineColor);
|
||||||
// 속도 표시
|
lines.RotationDelta = CreateLineRenderer("RotationDeltaLine", settings.rotationDeltaLineColor);
|
||||||
_speedLineRenderer = CreateLineRenderer("SpeedLine", Color.green);
|
lines.Tilt = CreateLineRenderer("TiltLine", settings.tiltLineColor);
|
||||||
// 회전 방향 표시
|
lines.WaveHeight = CreateLineRenderer("WaveHeightLine", settings.waveHeightLineColor);
|
||||||
_rotationSpeedLineRenderer = CreateLineRenderer("RotationSpeedLine", Color.magenta);
|
lines.WavePattern = CreateLineRenderer("WavePatternLine", settings.wavePatternLineColor, 50);
|
||||||
// 회전 방향 표시
|
|
||||||
_rotationDeltaLineRenderer = CreateLineRenderer("RotationDeltaLine", Color.yellow);
|
|
||||||
// 틸트 표시
|
|
||||||
_TiltLineRenderer = CreateLineRenderer("TiltLine", Color.red);
|
|
||||||
// 파도 높이 표시
|
|
||||||
_waveHeightLineRenderer = CreateLineRenderer("WaveHeightLine", Color.blue);
|
|
||||||
// 파도 패턴 표시
|
|
||||||
_wavePatternLineRenderer = CreateLineRenderer("WavePatternLine", Color.cyan);
|
|
||||||
_wavePatternLineRenderer.positionCount = 50; // 파도 패턴을 위한 더 많은 점
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
private void UpdateDebugVisuals()
|
#region Line Updates
|
||||||
|
private void UpdateAllDebugLines()
|
||||||
{
|
{
|
||||||
if (!showDebugVisuals) return;
|
|
||||||
|
|
||||||
// 속도 벡터 표시
|
|
||||||
UpdateSpeedLine();
|
UpdateSpeedLine();
|
||||||
|
UpdateRotationLines();
|
||||||
// 회전 방향 및 각속도 표시
|
|
||||||
UpdateRotationSpeedLine();
|
|
||||||
UpdateRotationDeltaLine();
|
|
||||||
// 회전 틸트 표시
|
|
||||||
UpdateTiltLine();
|
UpdateTiltLine();
|
||||||
// 파도 높이와 패턴 표시
|
|
||||||
UpdateWaveVisualization();
|
UpdateWaveVisualization();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetCurrentSpeed() => movement.CurrentSpeed;
|
|
||||||
private float GetMaxSpeed() => movement.MaxSpeed;
|
|
||||||
private float GetRotationSpeed() => movement.CurrentRotationSpeed;
|
|
||||||
private Vector2 GetCurrentInput() => movement.CurrentInput;
|
|
||||||
|
|
||||||
private void UpdateSpeedLine()
|
private void UpdateSpeedLine()
|
||||||
{
|
{
|
||||||
Vector3 start = transform.position + Vector3.up * 1.5f;
|
Vector3 start = GetDebugLineStart(1.5f);
|
||||||
Vector3 end = start + transform.forward * ((GetCurrentSpeed() / GetMaxSpeed()) * debugLineLength * 2);
|
Vector3 direction = transform.forward * (movement.CurrentSpeed / movement.MaxSpeed);
|
||||||
DrawLine(_speedLineRenderer, start, end);
|
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;
|
UpdateRotationSpeedArc();
|
||||||
// 각속도를 호로 표현
|
UpdateRotationDeltaArc();
|
||||||
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;
|
private void UpdateRotationSpeedArc()
|
||||||
_rotationSpeedLineRenderer.SetPositions(arcPoints);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_rotationSpeedLineRenderer.positionCount = 0;
|
if (Mathf.Abs(movement.CurrentRotationSpeed) <= 0.1f)
|
||||||
}
|
{
|
||||||
|
lines.RotationSpeed.positionCount = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateRotationDeltaLine()
|
DrawArc(lines.RotationSpeed,
|
||||||
{
|
GetDebugLineStart(1.2f),
|
||||||
float deltaAngle = 0f;
|
settings.lineLength,
|
||||||
if (GetCurrentInput().magnitude > 0.1f)
|
movement.CurrentRotationSpeed);
|
||||||
{
|
|
||||||
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;
|
private void UpdateRotationDeltaArc()
|
||||||
// 각속도를 호로 표현
|
|
||||||
if (Mathf.Abs(deltaAngle) > 0.1f)
|
|
||||||
{
|
{
|
||||||
Vector3[] arcPoints = new Vector3[10];
|
if (movement.CurrentInput.magnitude <= 0.1f)
|
||||||
float radius = debugLineLength * 1.05f;
|
|
||||||
float angleStep = deltaAngle * 1f / (arcPoints.Length - 1);
|
|
||||||
|
|
||||||
for (int i = 0; i < arcPoints.Length; i++)
|
|
||||||
{
|
{
|
||||||
float angle = angleStep * i;
|
lines.RotationDelta.positionCount = 0;
|
||||||
Vector3 point = start + Quaternion.Euler(0, angle, 0) * transform.forward * radius;
|
return;
|
||||||
arcPoints[i] = point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_rotationDeltaLineRenderer.positionCount = arcPoints.Length;
|
float deltaAngle = CalculateRotationDeltaAngle();
|
||||||
_rotationDeltaLineRenderer.SetPositions(arcPoints);
|
if (Mathf.Abs(deltaAngle) <= 0.1f)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_rotationDeltaLineRenderer.positionCount = 0;
|
lines.RotationDelta.positionCount = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawArc(lines.RotationDelta,
|
||||||
|
GetDebugLineStart(1.2f),
|
||||||
|
settings.lineLength * 1.05f,
|
||||||
|
deltaAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateTiltLine()
|
private void UpdateTiltLine()
|
||||||
{
|
{
|
||||||
Vector3 start = transform.position + Vector3.up * 1.5f;
|
Vector3 start = GetDebugLineStart(1.5f);
|
||||||
Vector3 tiltDirection = movementVisual.MeshTransform.up;
|
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()
|
private void UpdateWaveVisualization()
|
||||||
|
{
|
||||||
|
UpdateWaveHeightLine();
|
||||||
|
UpdateWavePatternLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWaveHeightLine()
|
||||||
{
|
{
|
||||||
// 현재 파도 높이 표시
|
// 현재 파도 높이 표시
|
||||||
Vector3 waveStart = transform.position + Vector3.up * 1.5f - transform.forward * 1.5f;
|
Vector3 waveStart = transform.position + Vector3.up * 1.5f - transform.forward * 1.5f;
|
||||||
Vector3 waveEnd = waveStart + Vector3.up * (GetCurrentWaveHeight() * debugLineLength);
|
Vector3 waveEnd = waveStart + Vector3.up * (movementVisual.CurrentWaveHeight * settings.lineLength);
|
||||||
DrawLine(_waveHeightLineRenderer, waveStart, waveEnd);
|
DrawLine(lines.WaveHeight, waveStart, waveEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWavePatternLine()
|
||||||
|
{
|
||||||
// 파도 패턴 시각화
|
// 파도 패턴 시각화
|
||||||
Vector3[] wavePoints = new Vector3[_wavePatternLineRenderer.positionCount];
|
Vector3[] wavePoints = new Vector3[lines.WavePattern.positionCount];
|
||||||
float waveLength = debugLineLength * 2f;
|
float waveLength = settings.lineLength * 2f;
|
||||||
|
|
||||||
for (int i = 0; i < wavePoints.Length; i++)
|
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 x = t * waveLength - waveLength * 0.5f;
|
||||||
float currentSpeedByUnit = GetCurrentSpeed() / GetWaveUnitSpeed();
|
float currentSpeedByUnit = movement.CurrentSpeed / movementVisual.WaveUnitSpeed;
|
||||||
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
||||||
float waveHeight = Mathf.Lerp(GetMinSpeedWaveHeight(), GetMaxSpeedWaveHeight(), currentSpeedByUnit);
|
float waveHeight = Mathf.Lerp(movementVisual.MinSpeedWaveHeight, movementVisual.MaxSpeedWaveHeight, currentSpeedByUnit);
|
||||||
float y = Mathf.Sin((GetWaveTime() + x) * GetBaseWaveFrequency()) * waveHeight;
|
float y = Mathf.Sin((movementVisual.WaveTime + x) * movementVisual.BaseWaveFrequency) * waveHeight;
|
||||||
|
|
||||||
wavePoints[i] = transform.position +
|
wavePoints[i] = transform.position +
|
||||||
Vector3.right * x +
|
Vector3.right * x +
|
||||||
@ -180,43 +184,73 @@ namespace Voyage
|
|||||||
wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f;
|
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 CalculateRotationDeltaAngle()
|
||||||
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);
|
Vector3 inputDirection = new Vector3(movement.CurrentInput.x, 0, movement.CurrentInput.y).normalized;
|
||||||
lineObj.transform.SetParent(transform);
|
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
||||||
LineRenderer line = lineObj.AddComponent<LineRenderer>();
|
return Quaternion.Angle(transform.rotation, targetRotation);
|
||||||
|
}
|
||||||
|
|
||||||
line.startWidth = debugLineWidth;
|
private void DrawArc(LineRenderer lineRenderer, Vector3 center, float radius, float totalAngle)
|
||||||
line.endWidth = debugLineWidth;
|
{
|
||||||
|
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.material = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
|
||||||
line.startColor = color;
|
line.startColor = line.endColor = color;
|
||||||
line.endColor = color;
|
line.positionCount = pointCount;
|
||||||
line.positionCount = 2;
|
|
||||||
|
|
||||||
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||||
line.receiveShadows = false;
|
line.receiveShadows = false;
|
||||||
line.material.color = color;
|
line.material.color = color;
|
||||||
|
|
||||||
return line;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawLine(LineRenderer line, Vector3 start, Vector3 end)
|
private void DrawLine(LineRenderer line, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
if (line is null) return;
|
if (line is null) return;
|
||||||
|
|
||||||
line.positionCount = 2;
|
line.positionCount = 2;
|
||||||
line.SetPosition(0, start);
|
line.SetPosition(0, start);
|
||||||
line.SetPosition(1, end);
|
line.SetPosition(1, end);
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user