OldBlueWater/BlueWater/Assets/02.Scripts/Player/Player.cs

427 lines
13 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2023-08-31 06:46:13 +00:00
using Blobcreate.ProjectileToolkit;
using Sirenix.OdinInspector;
2023-08-03 01:03:08 +00:00
using UnityEngine;
using UnityEngine.InputSystem;
2023-08-31 06:46:13 +00:00
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
2023-08-03 01:03:08 +00:00
{
2023-08-10 13:33:10 +00:00
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(PlayerInput))]
2023-09-20 09:06:45 +00:00
[SelectionBase]
2023-08-03 01:03:08 +00:00
public class Player : MonoBehaviour
{
2023-09-20 09:06:45 +00:00
[Title("Component")]
2023-08-15 08:29:24 +00:00
private Rigidbody rb;
private Vector2 movementInput;
2023-09-20 09:06:45 +00:00
[Title("쉽의 기본 설정")]
[Tooltip("최대 스피드")] public float maxSpeed = 10f;
[Tooltip("가속 수치")] public float acceleration = 2f;
[Tooltip("감속 수치")] public float deceleration = 2f;
[Tooltip("회전 속도")] public float turnSpeed = 10f;
[Title("캐릭터의 기본 설정")]
private GameObject character;
2023-09-20 09:06:45 +00:00
[Tooltip("캐릭터의 이동 속도")] public float characterSpeed = 10f;
[Title("레이더")]
2023-08-31 06:46:13 +00:00
public Collider[] radar = new Collider[10];
2023-09-20 09:06:45 +00:00
public List<Transform> inCameraRadar = new(10);
2023-08-31 06:46:13 +00:00
public Transform target;
public bool IsTargeting { get; private set; }
2023-09-20 09:06:45 +00:00
[Title("캐논")]
public Rigidbody projectilePrefab;
public Transform launchPoint;
public float timeOfFlight;
public Transform predictedPos;
2023-09-20 09:06:45 +00:00
[field: SerializeField] public List<Canon> Canons { get; private set; } = new(GlobalValue.MAX_CANON_COUNT);
2023-09-19 16:58:52 +00:00
[field: Title("Mode")]
2023-09-20 09:06:45 +00:00
[field: SerializeField]
public bool IsAssaultMode { get; set; }
2023-09-19 16:58:52 +00:00
[field: SerializeField] public bool IsInShipMode { get; set; }
[field: SerializeField] public bool IsDredgeMode { get; set; }
[field: SerializeField] public bool IsTakeAim { get; set; }
2023-09-20 09:06:45 +00:00
[Title("Interaction")]
2023-09-19 16:58:52 +00:00
public bool IsIslandInteraction { get; set; }
private float rayLength;
private LayerMask groundLayer;
2023-09-20 09:06:45 +00:00
private Vector3 halfExtents; // 박스 크기의 절반을 나타내는 벡터값을 설정합니다.
private List<Vector3> directions = new(8);
2023-08-03 01:03:08 +00:00
2023-08-15 08:29:24 +00:00
private void Init()
2023-08-03 01:03:08 +00:00
{
2023-08-15 08:29:24 +00:00
character = transform.Find("Character").gameObject;
2023-08-03 01:03:08 +00:00
rb = GetComponent<Rigidbody>();
2023-09-11 05:15:18 +00:00
GetComponentsInChildren(Canons);
2023-09-19 16:58:52 +00:00
rayLength = 15f;
groundLayer = LayerMask.GetMask("Ground");
2023-09-20 09:06:45 +00:00
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
};
2023-08-03 01:03:08 +00:00
}
2023-08-15 08:29:24 +00:00
2023-08-17 03:42:12 +00:00
#region Unity Function
2023-09-20 09:06:45 +00:00
2023-09-19 16:58:52 +00:00
private void OnDrawGizmosSelected()
{
2023-09-20 09:06:45 +00:00
RadarDrawGizmo();
Raycast8DrawGizmo();
2023-09-19 16:58:52 +00:00
}
2023-08-17 03:42:12 +00:00
2023-08-15 08:29:24 +00:00
private void Awake()
{
Init();
}
2023-09-19 16:58:52 +00:00
private void Start()
{
SwitchDredgeMode(true);
}
2023-09-11 05:15:18 +00:00
private void FixedUpdate()
{
2023-09-11 05:15:18 +00:00
HandleMovement();
}
2023-09-11 05:15:18 +00:00
private void Update()
2023-08-08 07:08:41 +00:00
{
2023-09-11 05:15:18 +00:00
FindInRadarRange();
FilterInCameraObjects();
LookAtTarget();
2023-09-19 16:58:52 +00:00
Raycast8Direction();
2023-08-08 07:08:41 +00:00
}
2023-08-17 03:42:12 +00:00
#endregion
2023-09-20 09:06:45 +00:00
2023-08-11 16:21:26 +00:00
#region Movement
2023-09-20 09:06:45 +00:00
2023-08-23 07:32:24 +00:00
public void OnMove(InputValue value) // WASD
2023-08-11 16:21:26 +00:00
{
movementInput = value.Get<Vector2>();
}
2023-09-20 09:06:45 +00:00
2023-08-15 08:29:24 +00:00
private void MoveShipPlayer()
2023-08-11 16:21:26 +00:00
{
2023-08-16 01:38:47 +00:00
var desiredVelocity = transform.forward * (movementInput.y * maxSpeed);
2023-08-11 16:21:26 +00:00
var speedChange = (movementInput.y != 0 ? acceleration : deceleration) * Time.fixedDeltaTime;
rb.velocity = Vector3.MoveTowards(rb.velocity, desiredVelocity, speedChange);
}
2023-08-08 07:08:41 +00:00
2023-08-11 16:21:26 +00:00
private void RotatePlayer()
{
var turn = movementInput.x;
var turnRotation = Quaternion.Euler(0f, turn * turnSpeed, 0f);
rb.MoveRotation(rb.rotation * turnRotation);
}
2023-08-15 08:29:24 +00:00
private void MoveCharacterPlayer()
{
2023-09-20 09:06:45 +00:00
var movement = character.transform.rotation * new Vector3(-movementInput.y, 0, movementInput.x) *
(characterSpeed * Time.deltaTime);
2023-08-15 08:29:24 +00:00
character.transform.position += movement;
}
2023-09-20 09:06:45 +00:00
2023-09-11 05:15:18 +00:00
private void HandleMovement()
{
if (IsInShipMode)
{
MoveCharacterPlayer();
}
else
{
MoveShipPlayer();
RotatePlayer();
}
}
2023-09-20 09:06:45 +00:00
2023-09-19 16:58:52 +00:00
private void StopShipMovement()
{
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
2023-09-20 09:06:45 +00:00
2023-08-11 16:21:26 +00:00
#endregion
2023-09-20 09:06:45 +00:00
2023-08-08 07:08:41 +00:00
#region AssaultMode/DreadgeMode Switch
2023-08-23 07:32:24 +00:00
private void OnAssaultMode(InputValue value) // V
2023-08-08 07:08:41 +00:00
{
2023-08-29 04:23:27 +00:00
SwitchAssaultMode(!IsAssaultMode);
}
2023-09-20 09:06:45 +00:00
2023-08-29 04:23:27 +00:00
private void SwitchAssaultMode(bool isOn)
{
if (isOn)
2023-08-08 07:08:41 +00:00
{
2023-08-29 04:23:27 +00:00
SwitchTakeAim(false);
SwitchInShipMode(false);
2023-09-19 16:58:52 +00:00
SwitchDredgeMode(false);
2023-08-29 04:23:27 +00:00
GameManager.Inst.CameraController.CamAssaultMode();
UiManager.Inst.CardLayoutGroupAnimator.Play();
IsAssaultMode = true;
2023-08-08 07:08:41 +00:00
}
2023-08-29 04:23:27 +00:00
else if (IsAssaultMode)
2023-08-08 07:08:41 +00:00
{
2023-08-29 04:23:27 +00:00
GameManager.Inst.CameraController.CamDredgeMode();
UiManager.Inst.CardLayoutGroupAnimator.Reverse();
IsAssaultMode = false;
2023-08-08 07:08:41 +00:00
}
}
2023-09-20 09:06:45 +00:00
2023-09-19 16:58:52 +00:00
private void SwitchDredgeMode(bool isOn)
{
if (isOn)
{
SwitchTakeAim(false);
SwitchAssaultMode(false);
SwitchInShipMode(false);
GameManager.Inst.CameraController.CamDredgeMode();
IsDredgeMode = true;
}
else if (IsDredgeMode)
{
IsDredgeMode = false;
}
}
2023-08-08 07:08:41 +00:00
#endregion
2023-08-11 16:21:26 +00:00
#region Interaction Key
2023-09-20 09:06:45 +00:00
private void OnTargeting(InputValue value) //Q
{
2023-09-20 09:06:45 +00:00
if (inCameraRadar.Count == 0) return;
IsTargeting = true;
UiManager.Inst.RadarUIOnOff(IsTargeting);
2023-09-20 09:06:45 +00:00
FindTarget();
}
2023-09-20 09:06:45 +00:00
private void OnTargetingHold(InputValue value) //Q Hold
{
IsTargeting = false;
UiManager.Inst.RadarUIOnOff(IsTargeting);
}
2023-08-11 16:21:26 +00:00
2023-09-11 05:15:18 +00:00
private void OnInteractionE(InputValue value) //E
2023-09-04 03:20:01 +00:00
{
2023-09-20 09:06:45 +00:00
if (IsTargeting) UiManager.Inst.CheckRadarOverlap();
2023-09-04 03:20:01 +00:00
}
2023-08-23 07:32:24 +00:00
private void OnInteraction(InputValue value) //F
2023-08-03 01:03:08 +00:00
{
2023-09-19 16:58:52 +00:00
if (!IsIslandInteraction) return;
SwitchAssaultMode(true);
UiManager.Inst.DefaultInteractionOnOff(false);
StopShipMovement();
2023-08-03 01:03:08 +00:00
}
2023-09-20 09:06:45 +00:00
2023-08-23 07:32:24 +00:00
private void OnInteractionHold(InputValue value) //F Hold
2023-08-03 01:03:08 +00:00
{
2023-08-29 04:23:27 +00:00
SwitchInShipMode(!IsInShipMode);
}
private void SwitchInShipMode(bool isOn)
{
if (isOn)
2023-08-11 16:21:26 +00:00
{
2023-08-29 04:23:27 +00:00
SwitchTakeAim(false);
SwitchAssaultMode(false);
2023-09-19 16:58:52 +00:00
SwitchDredgeMode(false);
2023-08-11 16:21:26 +00:00
GameManager.Inst.CameraController.CamInShipMode();
IsInShipMode = true;
2023-08-29 04:23:27 +00:00
}
else if (IsInShipMode)
{
GameManager.Inst.CameraController.CamDredgeMode();
IsInShipMode = false;
2023-08-11 16:21:26 +00:00
}
2023-08-08 07:08:41 +00:00
}
2023-08-03 01:03:08 +00:00
2023-08-08 07:08:41 +00:00
#endregion
2023-09-20 09:06:45 +00:00
2023-08-17 03:42:12 +00:00
private void OnZkey(InputValue value)
{
2023-09-20 09:06:45 +00:00
UiManager.Inst.AssaultCardInit();
2023-08-17 03:42:12 +00:00
}
2023-09-11 05:15:18 +00:00
#region TakeAim
2023-08-23 07:32:24 +00:00
private void OnTakeAim(InputValue value) // Space
{
2023-08-29 04:23:27 +00:00
SwitchTakeAim(!IsTakeAim);
}
2023-09-20 09:06:45 +00:00
2023-08-29 04:23:27 +00:00
private void SwitchTakeAim(bool isOn)
{
if (isOn)
{
SwitchAssaultMode(false);
SwitchInShipMode(false);
2023-09-19 16:58:52 +00:00
SwitchDredgeMode(false);
2023-08-29 04:23:27 +00:00
GameManager.Inst.CameraController.CamTakeAim(true);
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
IsTakeAim = true;
}
else if (IsTakeAim)
{
GameManager.Inst.CameraController.CamTakeAim(false);
Cursor.visible = true;
Cursor.lockState = CursorLockMode.Confined;
IsTakeAim = false;
}
2023-09-20 09:06:45 +00:00
2023-08-29 04:23:27 +00:00
UiManager.Inst.AimOnOff(isOn);
}
2023-08-30 05:17:26 +00:00
#endregion
2023-09-11 05:15:18 +00:00
#region CanonAndRader
private void FindInRadarRange()
2023-08-30 05:17:26 +00:00
{
2023-09-20 09:06:45 +00:00
Physics.OverlapSphereNonAlloc(transform.position, GlobalValue.RADAR_RANGE, radar,
LayerMask.GetMask(GlobalValue.ENEMY_LAYER));
2023-09-11 05:15:18 +00:00
}
private void FilterInCameraObjects()
{
inCameraRadar.Clear();
2023-09-11 05:15:18 +00:00
foreach (var col in radar)
{
if (col == null) continue;
2023-09-20 09:06:45 +00:00
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)
2023-09-11 05:15:18 +00:00
{
inCameraRadar.Add(col.transform);
2023-09-11 05:15:18 +00:00
}
}
2023-09-20 09:06:45 +00:00
inCameraRadar.Sort((a, b) =>
Vector3.Distance(transform.position, a.position)
.CompareTo(Vector3.Distance(transform.position, b.position)));
2023-09-11 05:15:18 +00:00
}
private void FindTarget()
{
var oldTarget = target;
foreach (var trans in inCameraRadar)
2023-09-11 05:15:18 +00:00
{
if (trans.Find("TestTarget") == null) continue;
if (target != null && trans.Find("TestTarget").transform == oldTarget) continue;
2023-09-20 09:06:45 +00:00
target = trans.Find("TestTarget").transform;
break;
}
if (target != oldTarget)
{
UiManager.Inst.RadarTargetInit();
2023-09-11 05:15:18 +00:00
}
2023-08-30 05:17:26 +00:00
}
2023-09-11 05:15:18 +00:00
private void LookAtTarget()
{
if (target == null) return;
foreach (var canon in Canons)
{
canon.predictedPos = target;
canon.LookAtTarget();
UiManager.Inst.UpdateEnemyMarker(target);
2023-09-11 05:15:18 +00:00
}
}
#endregion
2023-09-19 16:58:52 +00:00
#region Raycast 8 Direction
private void Raycast8Direction()
{
if (!IsDredgeMode) return;
var isOn = false;
foreach (Vector3 dir in directions)
{
RaycastHit hit;
2023-09-20 09:06:45 +00:00
if (Physics.BoxCast(transform.position, halfExtents, dir, out hit, Quaternion.identity, rayLength,
groundLayer))
2023-09-19 16:58:52 +00:00
{
isOn = true;
2023-09-20 09:06:45 +00:00
2023-09-19 16:58:52 +00:00
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;
}
2023-09-20 09:06:45 +00:00
2023-09-19 16:58:52 +00:00
// 박스가 Ground 레이어에 닿지 않았을 때 녹색으로 표시
Debug.DrawRay(transform.position, dir * rayLength, Color.green);
IsIslandInteraction = false;
}
UiManager.Inst.DefaultInteractionOnOff(isOn);
}
#endregion
2023-09-20 09:06:45 +00:00
#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
2023-08-03 01:03:08 +00:00
}
2023-08-03 02:54:21 +00:00
}