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 Transform[] inCameraRadar = new Transform[10]; public Transform target; // 클래스 레벨 변수 private List visibleObjects; [Title("캐논")] public Rigidbody projectilePrefab; public Transform launchPoint; public float timeOfFlight; public Transform predictedPos; public List Canons { get; } = new (GlobalValue.MAX_CANON_COUNT); public bool IsAssaultMode { get; set; } public bool IsInShipMode { get; set; } public bool IsDredgeMode { get; set; } public bool IsTakeAim { get; set; } private void Init() { character = transform.Find("Character").gameObject; rb = GetComponent(); GetComponentsInChildren(Canons); visibleObjects = new List(); } #region Unity Function private void Awake() { Init(); } private void FixedUpdate() { HandleMovement(); } private void Update() { FindInRadarRange(); FilterInCameraObjects(); FindTarget(); LookAtTarget(); } #endregion #region Movement public void OnMove(InputValue value) // WASD { movementInput = value.Get(); } 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() { Vector3 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(); } } #endregion #region AssaultMode/DreadgeMode Switch private void OnAssaultMode(InputValue value) // V { SwitchAssaultMode(!IsAssaultMode); } private void SwitchAssaultMode(bool isOn) { if (isOn) { SwitchTakeAim(false); SwitchInShipMode(false); GameManager.Inst.CameraController.CamAssaultMode(); UiManager.Inst.CardLayoutGroupAnimator.Play(); IsAssaultMode = true; } else if (IsAssaultMode) { GameManager.Inst.CameraController.CamDredgeMode(); UiManager.Inst.CardLayoutGroupAnimator.Reverse(); IsAssaultMode = false; } } #endregion #region Interaction Key private void OnInteractionE(InputValue value) //E { UiManager.Inst.CheckRadarOverlap(); } private void OnInteraction(InputValue value) //F { } private void OnInteractionHold(InputValue value) //F Hold { SwitchInShipMode(!IsInShipMode); } private void SwitchInShipMode(bool isOn) { if (isOn) { SwitchTakeAim(false); SwitchAssaultMode(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); 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() { visibleObjects.Clear(); foreach (var col in radar) { if (col == null) continue; var screenPoint = Camera.main.WorldToViewportPoint(col.transform.position); if (screenPoint.z > 0 && screenPoint.x >= 0 && screenPoint.x <= 1 && screenPoint.y >= 0 && screenPoint.y <= 1) { visibleObjects.Add(col.transform); } } visibleObjects.Sort((a, b) => Vector3.Distance(transform.position, a.position).CompareTo(Vector3.Distance(transform.position, b.position))); } private void FindTarget() { foreach (var trans in visibleObjects) { if (trans.Find("TestTarget") == null) continue; target = trans.Find("TestTarget").transform; break; } } private void LookAtTarget() { if (target == null) return; foreach (var canon in Canons) { canon.predictedPos = target; canon.LookAtTarget(); } } #endregion } }