using System.Collections; using Sirenix.OdinInspector; using UnityEngine; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class DropItemController : MonoBehaviour { [Title("컴포넌트")] [SerializeField] private SpriteRenderer spriteRenderer; [SerializeField] private AudioSource audioSource; [Title("아이템")] [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 ItemSlot itemSlot; private Collider[] hitColliders = new Collider[1]; private Collider targetCollider; private WaitForSeconds lootCoroutineTime = new(0.5f); private ItemUiController itemLootUi; private Transform pointingArrowUi; private void OnDrawGizmosSelected() { if (!drawGizmos) return; Gizmos.DrawWireSphere(transform.position, radius); } public void Init(ItemSlot itemSlotValue) { itemSlot = itemSlotValue; if (spriteRenderer) { spriteRenderer.sprite = ItemManager.Inst.ItemDictionary[itemSlot.Idx].sprite; } var myPos = transform.position; var screenPos = CameraManager.Inst.MainCam.WorldToScreenPoint(myPos); if (itemUiPrefab) { itemLootUi = Instantiate(itemUiPrefab, screenPos, Quaternion.identity, UiManager.Inst.OceanUi.ItemsLoot).GetComponent(); itemLootUi.Init(transform); } if (pointingArrowUiPrefab) { pointingArrowUi = Instantiate(pointingArrowUiPrefab, screenPos, Quaternion.identity, UiManager.Inst.OceanUi.InstantiateUi).transform; pointingArrowUi.gameObject.SetActive(false); } } 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]; if (itemLootUi) { 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.parent.position = Vector3.Lerp(startPosition, targetCollider.bounds.center, t); yield return null; } ItemManager.Inst.Acquire(itemSlot); if (itemLootUi) { itemLootUi.gameObject.SetActive(false); } if (spriteRenderer) { spriteRenderer.gameObject.SetActive(false); } DropItemGroupController dropItemGroupController = null; if (UiManager.Inst.OceanUi) { dropItemGroupController = UiManager.Inst.OceanUi.DropItemGroupController; } else if (UiManager.Inst.CombatUi) { dropItemGroupController = UiManager.Inst.CombatUi.DropItemGroupController; } dropItemGroupController?.ShowDropItemInfoUi(ItemManager.Inst.ItemDictionary[itemSlot.Idx], itemSlot.Count); if (audioSource && audioSource.resource) { audioSource.Play(); } yield return new WaitForSeconds(audioSource.clip.length); Destroy(transform.parent.gameObject); if (itemLootUi) { 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; } } }