OldBlueWater/BlueWater/Assets/02.Scripts/Item/DropItemController.cs
2024-04-30 11:48:52 +09:00

193 lines
6.7 KiB
C#

using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class DropItemController : MonoBehaviour
{
[Title("컴포넌트")]
[SerializeField] private Rigidbody rb;
[SerializeField] private Collider collider;
[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<ItemUiController>();
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;
}
if (rb)
{
rb.isKinematic = true;
rb.useGravity = false;
}
if (collider)
{
collider.enabled = false;
}
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;
}
}
}