OldBlueWater/BlueWater/Assets/02.Scripts/Player/Player.cs
2023-09-20 01:58:52 +09:00

389 lines
12 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
{
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(PlayerInput))]
public class Player : MonoBehaviour
{
[Title("Component")]
private Rigidbody rb;
private Vector2 movementInput;
[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;
[Tooltip("캐릭터의 이동 속도")]
public float characterSpeed = 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);
[field: Title("Mode")]
[field: SerializeField] public bool IsAssaultMode { get; set; }
[field: SerializeField] public bool IsInShipMode { get; set; }
[field: SerializeField] public bool IsDredgeMode { get; set; }
[field: SerializeField] public bool IsTakeAim { get; set; }
[Title("Interaction")]
public bool IsIslandInteraction { get; set; }
private float rayLength;
private LayerMask groundLayer;
private void Init()
{
character = transform.Find("Character").gameObject;
rb = GetComponent<Rigidbody>();
GetComponentsInChildren(Canons);
rayLength = 15f;
groundLayer = LayerMask.GetMask("Ground");
}
#region Unity Function
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, GlobalValue.RADAR_RANGE);
}
private void Awake()
{
Init();
}
private void Start()
{
SwitchDredgeMode(true);
}
private void FixedUpdate()
{
HandleMovement();
}
private void Update()
{
FindInRadarRange();
FilterInCameraObjects();
LookAtTarget();
Raycast8Direction();
}
#endregion
#region Movement
public void OnMove(InputValue value) // WASD
{
movementInput = value.Get<Vector2>();
}
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 MoveCharacterPlayer()
{
var movement = character.transform.rotation * new Vector3(-movementInput.y, 0, movementInput.x) * (characterSpeed * Time.deltaTime);
character.transform.position += movement;
}
private void HandleMovement()
{
if (IsInShipMode)
{
MoveCharacterPlayer();
}
else
{
MoveShipPlayer();
RotatePlayer();
}
}
private void StopShipMovement()
{
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
#endregion
#region AssaultMode/DreadgeMode Switch
private void OnAssaultMode(InputValue value) // V
{
SwitchAssaultMode(!IsAssaultMode);
}
private void SwitchAssaultMode(bool isOn)
{
if (isOn)
{
SwitchTakeAim(false);
SwitchInShipMode(false);
SwitchDredgeMode(false);
GameManager.Inst.CameraController.CamAssaultMode();
UiManager.Inst.CardLayoutGroupAnimator.Play();
IsAssaultMode = true;
}
else if (IsAssaultMode)
{
GameManager.Inst.CameraController.CamDredgeMode();
UiManager.Inst.CardLayoutGroupAnimator.Reverse();
IsAssaultMode = false;
}
}
private void SwitchDredgeMode(bool isOn)
{
if (isOn)
{
SwitchTakeAim(false);
SwitchAssaultMode(false);
SwitchInShipMode(false);
GameManager.Inst.CameraController.CamDredgeMode();
IsDredgeMode = true;
}
else if (IsDredgeMode)
{
IsDredgeMode = false;
}
}
#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;
SwitchAssaultMode(true);
UiManager.Inst.DefaultInteractionOnOff(false);
StopShipMovement();
}
private void OnInteractionHold(InputValue value) //F Hold
{
SwitchInShipMode(!IsInShipMode);
}
private void SwitchInShipMode(bool isOn)
{
if (isOn)
{
SwitchTakeAim(false);
SwitchAssaultMode(false);
SwitchDredgeMode(false);
GameManager.Inst.CameraController.CamInShipMode();
IsInShipMode = true;
}
else if (IsInShipMode)
{
GameManager.Inst.CameraController.CamDredgeMode();
IsInShipMode = false;
}
}
#endregion
private void OnZkey(InputValue value)
{
UiManager.Inst.AddCard();
}
#region TakeAim
private void OnTakeAim(InputValue value) // Space
{
SwitchTakeAim(!IsTakeAim);
}
private void SwitchTakeAim(bool isOn)
{
if (isOn)
{
SwitchAssaultMode(false);
SwitchInShipMode(false);
SwitchDredgeMode(false);
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;
}
UiManager.Inst.AimOnOff(isOn);
}
#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; // Set new target
break; // Exit the loop
}
// Check if target has changed
if (target != oldTarget)
{
// Call some method if target has changed
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 (!IsDredgeMode) return;
Vector3[] directions =
{
transform.forward,
-transform.forward,
transform.right,
-transform.right,
transform.forward + transform.right,
transform.forward - transform.right,
-transform.forward + transform.right,
-transform.forward - transform.right
};
Vector3 halfExtents = new Vector3(5, 5, 5); // 박스 크기의 절반을 나타내는 벡터값을 설정합니다.
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
}
}