320 lines
9.6 KiB
C#
320 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Blobcreate.ProjectileToolkit;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
namespace BlueWaterProject
|
|
{
|
|
[SelectionBase]
|
|
public class ShipPlayer : Player
|
|
{
|
|
[Title("쉽의 기본 설정")]
|
|
private Rigidbody rb;
|
|
[Tooltip("최대 스피드")] public float maxSpeed = 10f;
|
|
|
|
[Tooltip("가속 수치")] public float acceleration = 2f;
|
|
[Tooltip("감속 수치")] public float deceleration = 2f;
|
|
[Tooltip("회전 속도")] public float turnSpeed = 10f;
|
|
|
|
[Title("레이더")]
|
|
public Collider[] radar = new Collider[10];
|
|
public List<Transform> inCameraRadar = new(10);
|
|
public Transform target;
|
|
public bool IsTargeting { get; private set; }
|
|
|
|
[Title("캐논")]
|
|
public Rigidbody projectilePrefab;
|
|
public Transform launchPoint;
|
|
public float timeOfFlight;
|
|
public Transform predictedPos;
|
|
[field: SerializeField] public List<Canon> Canons { get; private set; } = new(GlobalValue.MAX_CANON_COUNT);
|
|
|
|
[Title("Interaction")]
|
|
public bool IsIslandInteraction { get; set; }
|
|
private float rayLength;
|
|
private LayerMask groundLayer;
|
|
private Vector3 halfExtents; // 박스 크기의 절반을 나타내는 벡터값을 설정합니다.
|
|
private List<Vector3> directions = new(8);
|
|
|
|
private void Init()
|
|
{
|
|
rb = GetComponent<Rigidbody>();
|
|
GetComponentsInChildren(Canons);
|
|
|
|
rayLength = 15f;
|
|
groundLayer = LayerMask.GetMask("Ground");
|
|
halfExtents = new Vector3(5, 5, 5);
|
|
directions = new List<Vector3>(8)
|
|
{
|
|
transform.forward,
|
|
-transform.forward,
|
|
transform.right,
|
|
-transform.right,
|
|
transform.forward + transform.right,
|
|
transform.forward - transform.right,
|
|
-transform.forward + transform.right,
|
|
-transform.forward - transform.right
|
|
};
|
|
}
|
|
|
|
#region Unity Function
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
RadarDrawGizmo();
|
|
Raycast8DrawGizmo();
|
|
}
|
|
|
|
protected override void Awake()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
protected override void Start()
|
|
{
|
|
GameManager.Inst.SwitchDredgeMode(true);
|
|
}
|
|
|
|
protected override void FixedUpdate()
|
|
{
|
|
HandleMovement();
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
FindInRadarRange();
|
|
FilterInCameraObjects();
|
|
LookAtTarget();
|
|
Raycast8Direction();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Movement
|
|
|
|
private void MoveShipPlayer()
|
|
{
|
|
var desiredVelocity = transform.forward * (movementInput.y * maxSpeed);
|
|
var speedChange = (movementInput.y != 0 ? acceleration : deceleration) * Time.fixedDeltaTime;
|
|
rb.velocity = Vector3.MoveTowards(rb.velocity, desiredVelocity, speedChange);
|
|
}
|
|
|
|
private void RotatePlayer()
|
|
{
|
|
var turn = movementInput.x;
|
|
var turnRotation = Quaternion.Euler(0f, turn * turnSpeed, 0f);
|
|
rb.MoveRotation(rb.rotation * turnRotation);
|
|
}
|
|
|
|
private void HandleMovement()
|
|
{
|
|
if (GameManager.Inst.IsDredgeMode)
|
|
{
|
|
MoveShipPlayer();
|
|
RotatePlayer();
|
|
}
|
|
}
|
|
|
|
private void StopShipMovement()
|
|
{
|
|
rb.velocity = Vector3.zero;
|
|
rb.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region AssaultMode/DreadgeMode Switch
|
|
|
|
private void OnAssaultMode(InputValue value) // V
|
|
{
|
|
//GameManager.Inst.SwitchAssaultMode(!GameManager.Inst.IsAssaultMode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Interaction Key
|
|
|
|
private void OnTargeting(InputValue value) //Q
|
|
{
|
|
if (inCameraRadar.Count == 0) return;
|
|
IsTargeting = true;
|
|
UiManager.Inst.RadarUIOnOff(IsTargeting);
|
|
|
|
FindTarget();
|
|
}
|
|
|
|
private void OnTargetingHold(InputValue value) //Q Hold
|
|
{
|
|
IsTargeting = false;
|
|
UiManager.Inst.RadarUIOnOff(IsTargeting);
|
|
}
|
|
|
|
private void OnInteractionE(InputValue value) //E
|
|
{
|
|
if (IsTargeting) UiManager.Inst.CheckRadarOverlap();
|
|
}
|
|
|
|
private void OnInteraction(InputValue value) //F
|
|
{
|
|
if (!IsIslandInteraction) return;
|
|
GameManager.Inst.SwitchAssaultMode(true);
|
|
UiManager.Inst.DefaultInteractionOnOff(false);
|
|
StopShipMovement();
|
|
}
|
|
|
|
private void OnInteractionHold(InputValue value) //F Hold
|
|
{
|
|
GameManager.Inst.SwitchInShipMode(!GameManager.Inst.IsInShipMode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void OnZkey(InputValue value)
|
|
{
|
|
UiManager.Inst.AssaultCardInit();
|
|
}
|
|
|
|
#region TakeAim
|
|
|
|
private void OnTakeAim(InputValue value) // Space
|
|
{
|
|
//if (GameManager.Inst.CurrentModeState == GlobalValue.PlayerModeState.IN_SHIP) return;
|
|
//GameManager.Inst.SwitchTakeAim(!GameManager.Inst.IsTakeAim);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CanonAndRader
|
|
|
|
private void FindInRadarRange()
|
|
{
|
|
Physics.OverlapSphereNonAlloc(transform.position, GlobalValue.RADAR_RANGE, radar,
|
|
LayerMask.GetMask(GlobalValue.ENEMY_LAYER));
|
|
}
|
|
|
|
private void FilterInCameraObjects()
|
|
{
|
|
inCameraRadar.Clear();
|
|
foreach (var col in radar)
|
|
{
|
|
if (col == null) continue;
|
|
var screenPoint =
|
|
GameManager.Inst.CameraController.MainCam.WorldToViewportPoint(col.transform.position);
|
|
if (screenPoint.z > 0 && screenPoint.x >= 0 && screenPoint.x <= 1 && screenPoint.y >= 0 &&
|
|
screenPoint.y <= 1)
|
|
{
|
|
inCameraRadar.Add(col.transform);
|
|
}
|
|
}
|
|
|
|
inCameraRadar.Sort((a, b) =>
|
|
Vector3.Distance(transform.position, a.position)
|
|
.CompareTo(Vector3.Distance(transform.position, b.position)));
|
|
}
|
|
|
|
private void FindTarget()
|
|
{
|
|
var oldTarget = target;
|
|
|
|
foreach (var trans in inCameraRadar)
|
|
{
|
|
if (trans.Find("TestTarget") == null) continue;
|
|
if (target != null && trans.Find("TestTarget").transform == oldTarget) continue;
|
|
target = trans.Find("TestTarget").transform;
|
|
break;
|
|
}
|
|
|
|
if (target != oldTarget)
|
|
{
|
|
UiManager.Inst.RadarTargetInit();
|
|
}
|
|
}
|
|
|
|
private void LookAtTarget()
|
|
{
|
|
if (target == null) return;
|
|
foreach (var canon in Canons)
|
|
{
|
|
canon.predictedPos = target;
|
|
canon.LookAtTarget();
|
|
UiManager.Inst.UpdateEnemyMarker(target);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Raycast 8 Direction
|
|
|
|
private void Raycast8Direction()
|
|
{
|
|
if (!GameManager.Inst.IsDredgeMode) return;
|
|
|
|
var isOn = false;
|
|
|
|
foreach (Vector3 dir in directions)
|
|
{
|
|
RaycastHit hit;
|
|
|
|
if (Physics.BoxCast(transform.position, halfExtents, dir, out hit, Quaternion.identity, rayLength,
|
|
groundLayer))
|
|
{
|
|
isOn = true;
|
|
|
|
var islandInfo = hit.transform.parent.parent.GetComponent<IslandInfo>();
|
|
|
|
if (GameManager.Inst.CameraController.AssaultCam != islandInfo.IslandCam)
|
|
GameManager.Inst.CameraController.AssaultCam = islandInfo.IslandCam;
|
|
|
|
// 박스가 Ground 레이어에 닿았을 때 빨간색으로 표시
|
|
Debug.DrawRay(transform.position, dir * rayLength, Color.red);
|
|
IsIslandInteraction = true;
|
|
break;
|
|
}
|
|
|
|
// 박스가 Ground 레이어에 닿지 않았을 때 녹색으로 표시
|
|
Debug.DrawRay(transform.position, dir * rayLength, Color.green);
|
|
IsIslandInteraction = false;
|
|
}
|
|
|
|
UiManager.Inst.DefaultInteractionOnOff(isOn);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Gizmos
|
|
|
|
private void Raycast8DrawGizmo()
|
|
{
|
|
Gizmos.color = IsIslandInteraction ? Color.red : Color.green;
|
|
|
|
foreach (Vector3 dir in directions)
|
|
{
|
|
bool isHit = Physics.BoxCast(transform.position, halfExtents, dir, out RaycastHit hitInfo, Quaternion.identity, rayLength, groundLayer);
|
|
|
|
if (isHit)
|
|
{
|
|
// 박스가 Ground 레이어에 닿았을 때 빨간색으로 표시
|
|
Gizmos.DrawWireCube(transform.position + dir.normalized * hitInfo.distance, halfExtents * 2);
|
|
}
|
|
else
|
|
{
|
|
// 박스가 Ground 레이어에 닿지 않았을 때 녹색으로 표시
|
|
Gizmos.DrawWireCube(transform.position + dir.normalized * rayLength, halfExtents * 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RadarDrawGizmo()
|
|
{
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawWireSphere(transform.position, GlobalValue.RADAR_RANGE);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
} |