using System; using System.Collections; using Sirenix.OdinInspector; using UnityEngine; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class ItemController : MonoBehaviour { [Title("아이템")] [SerializeField] private Item item; [SerializeField] private GameObject itemUiPrefab; [SerializeField] private GameObject pointingArrowUiPrefab; [ShowIf("@pointingArrowUiPrefab")] [SerializeField] private float arrowOffset = 10f; [Title("자동 파괴")] [SerializeField] private bool useAutoDestroy = true; [ShowIf("@useAutoDestroy")] [SerializeField] private float autoDestroyTime = 30f; [Title("획득")] [SerializeField] private bool drawGizmos = true; [SerializeField] private float radius = 5f; [SerializeField] private float acquisitionTime = 1f; [SerializeField] private LayerMask targetLayer; private Collider[] hitColliders = new Collider[1]; private Collider targetCollider; private WaitForSeconds lootCoroutineTime = new(0.5f); private AudioSource audioSource; private ItemUiController itemLootUi; private Transform pointingArrowUi; private void OnDrawGizmosSelected() { if (!drawGizmos) return; Gizmos.DrawWireSphere(transform.position, radius); } public void Init(Item newItem) { item = newItem; var myPos = transform.position; var screenPos = CameraManager.Inst.MainCam.WorldToScreenPoint(myPos); itemLootUi = Instantiate(itemUiPrefab, screenPos, Quaternion.identity, UiManager.Inst.OceanUi.ItemsLoot).GetComponent(); if (pointingArrowUiPrefab) { pointingArrowUi = Instantiate(pointingArrowUiPrefab, screenPos, Quaternion.identity, UiManager.Inst.OceanUi.InstantiateUi).transform; pointingArrowUi.gameObject.SetActive(false); } itemLootUi.Init(transform); } private void Awake() { audioSource = transform.parent.Find("Audio").GetComponent(); } private void Start() { if (useAutoDestroy) { Destroy(transform.parent.gameObject, autoDestroyTime); Destroy(itemLootUi.gameObject, autoDestroyTime); } StartCoroutine(LootCoroutine()); } private void LateUpdate() { PointingArrowUi(); } private IEnumerator LootCoroutine() { while (true) { var maxSize = Physics.OverlapSphereNonAlloc(transform.position, radius, hitColliders, targetLayer); if (maxSize > 0) { targetCollider = hitColliders[0]; itemLootUi.ItemAcquisition(); break; } yield return lootCoroutineTime; } var startPosition = transform.position; var elapsedTime = 0f; while (elapsedTime < acquisitionTime) { elapsedTime += Time.deltaTime; var t = elapsedTime / acquisitionTime; t = Mathf.SmoothStep(0f, 1f, t); transform.position = Vector3.Lerp(startPosition, targetCollider.transform.position, t); yield return null; } item.Acquire(); itemLootUi.gameObject.SetActive(false); UiManager.Inst.OceanUi.DropItemGroupController.ShowDropItemInfoUi(item); if (audioSource && audioSource.resource) { audioSource.Play(); } yield return new WaitForSeconds(audioSource.clip.length); Destroy(transform.parent.gameObject); Destroy(itemLootUi.gameObject); } private void PointingArrowUi() { if (!itemLootUi || !pointingArrowUi) return; var planes = GeometryUtility.CalculateFrustumPlanes(CameraManager.Inst.MainCam); var centerPosition = GameManager.Inst.ShipPlayer.transform.position; var direction = transform.position - centerPosition; var ray = new Ray(centerPosition, direction); var rayMinDistance = Mathf.Infinity; for (var i = 0; i < 4; i++) { if (planes[i].Raycast(ray, out var distance) && distance < rayMinDistance) { rayMinDistance = distance; } } rayMinDistance = Mathf.Clamp(rayMinDistance, 0f, direction.magnitude); pointingArrowUi.gameObject.SetActive(direction.magnitude > rayMinDistance); var angle = Mathf.Atan2(direction.normalized.z, direction.normalized.x) * Mathf.Rad2Deg; pointingArrowUi.transform.rotation = Quaternion.Euler(0, 0, angle + 90f); var screenPosition = CameraManager.Inst.MainCam.WorldToScreenPoint(ray.GetPoint(rayMinDistance)); screenPosition.x = Mathf.Clamp(screenPosition.x, arrowOffset, Screen.width - arrowOffset); screenPosition.y = Mathf.Clamp(screenPosition.y, arrowOffset, Screen.height - arrowOffset); pointingArrowUi.transform.position = screenPosition; } } }