152 lines
5.5 KiB
C#
152 lines
5.5 KiB
C#
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<ItemUiController>();
|
|
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<AudioSource>();
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |