CapersProject/Assets/02.Scripts/Item/Item.cs
Nam Tae Gun 7fb0da5888 #25, #26 아이템 직접 획득 방식 추가 및 선형적인 맵 구조 변경
+ Item관련 Excel, Json, So 수정
+ DropItemTable 로직 수정
+ 아이템 프리팹에서 Enable Interaction 체크하면 직접 룻팅, 해제하면 자동 룻팅
+ 체력회복 아이템 추가
+ 개발자 메뉴 상호작용 "F1" 키를 통해 접근 가능
+ 보스 맵은 마법진을 상호작용하면 보스전 시작
+ 맵 안에서 교전 중일 때, 투명 벽 쉐이더 추가
+ 맵 마다의 통로를 통해서 이동 가능
+ 선형적인 맵 구조에 맞게 리소스 및 위치 수정
+ 타이틀 화면으로 이동할 때 나타나는 오류 수정(CombatUiManager OnDisable 싱글톤 문제)

Closes #25, #26
2024-06-22 07:11:53 +09:00

204 lines
5.9 KiB
C#

using System.Collections;
using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Uis;
using BlueWater.Utility;
using Sirenix.OdinInspector;
using UnityEngine;
namespace BlueWater.Items
{
public class Item : MonoBehaviour, IPlayerInteraction
{
[field: Title("컴포넌트")]
public Transform Transform { get; private set; }
[SerializeField]
protected Rigidbody Rigidbody;
[SerializeField]
protected Collider Collider;
[SerializeField]
protected Transform VisualLook;
[SerializeField]
protected SpriteRenderer SpriteRenderer;
[SerializeField]
protected Canvas Canvas;
[field: Title("드랍 옵션")]
[field: SerializeField, Tooltip("키 입력을 통한 아이템 획득")]
public bool EnableInteraction { get; private set; } = true;
[SerializeField]
protected bool UseAutoDestroy = true;
[SerializeField, ShowIf("@UseAutoDestroy")]
protected float AutoDestroyTime = 30f;
[SerializeField, ShowIf("@!EnableInteraction")]
protected bool DrawGizmos = true;
[SerializeField, ShowIf("@!EnableInteraction")]
protected float Radius = 5f;
[SerializeField, ShowIf("@!EnableInteraction")]
protected float AcquisitionTime = 1f;
[SerializeField]
protected string AcquiredSfxName = "GetItem";
[Title("아이템 데이터")]
[SerializeField]
protected ItemData ItemData;
protected ItemSlot ItemSlot;
protected Collider TargetCollider;
protected Coroutine RootCoroutineInstance;
protected readonly WaitForSeconds LootCoroutineTime = new(0.5f);
private bool _isQuitting;
private void OnDrawGizmosSelected()
{
if (!DrawGizmos) return;
Gizmos.DrawWireSphere(transform.position, Radius);
}
private void Awake()
{
InitializeComponents();
}
private void Start()
{
if (UseAutoDestroy)
{
Destroy(gameObject, AutoDestroyTime);
}
if (EnableInteraction)
{
GameManager.Instance.CurrentCombatPlayer.CombatInput.RegisterPlayerInteraction(this);
}
else
{
Utils.StartUniqueCoroutine(this, ref RootCoroutineInstance, LootCoroutine());
}
}
private void OnApplicationQuit()
{
_isQuitting = true;
}
private void OnDestroy()
{
if (_isQuitting) return;
if (EnableInteraction)
{
GameManager.Instance.CurrentCombatPlayer.CombatInput.UnregisterPlayerInteraction(this);
}
}
public void Initialize(ItemSlot itemSlot)
{
ItemSlot = itemSlot;
ItemData = ItemManager.Instance.GetItemDataByIdx(ItemSlot.Idx);
SpriteRenderer.sprite = ItemData.Sprite;
}
[Button("컴포넌트 초기화")]
private void InitializeComponents()
{
Transform = transform;
Rigidbody = GetComponent<Rigidbody>();
Collider = GetComponent<Collider>();
VisualLook = transform.Find("VisualLook");
SpriteRenderer = VisualLook.GetComponent<SpriteRenderer>();
Canvas = transform.Find("Canvas").GetComponent<Canvas>();
Canvas.GetComponent<Canvas>().worldCamera = Camera.main;
}
protected virtual void OnAcquired()
{
Destroy(gameObject);
AudioManager.Instance.PlaySfx(AcquiredSfxName);
DataManager.Instance.CombatInventory.AddItem(ItemSlot);
CombatUiManager.Instance.ItemLootUi.ShowLootInfoUi(ItemData, ItemSlot.Count);
}
private IEnumerator LootCoroutine()
{
while (true)
{
TargetCollider = GameManager.Instance.CurrentCombatPlayer.CharacterCollider;
if (TargetCollider == null)
{
yield return LootCoroutineTime;
continue;
}
var targetDistance = Vector3.Distance(TargetCollider.transform.position, transform.position);
if (targetDistance <= Radius) break;
yield return LootCoroutineTime;
}
if (Rigidbody)
{
Rigidbody.isKinematic = true;
Rigidbody.useGravity = false;
}
if (Collider)
{
Collider.enabled = false;
}
var startPosition = transform.position;
var elapsedTime = 0f;
while (elapsedTime < AcquisitionTime)
{
if (TargetCollider == null)
{
yield break;
}
elapsedTime += Time.deltaTime;
var t = elapsedTime / AcquisitionTime;
t = Mathf.SmoothStep(0f, 1f, t);
transform.position = Vector3.Lerp(startPosition, TargetCollider.bounds.center, t);
yield return null;
}
OnAcquired();
}
public void AddForce(Vector3 force, ForceMode forceMode) => Rigidbody.AddForce(force, forceMode);
public void Interaction()
{
OnAcquired();
}
public void ShowInteractionUi()
{
if (!Canvas) return;
Canvas.gameObject.SetActive(true);
}
public void HideInteractionUi()
{
if (!Canvas) return;
Canvas.gameObject.SetActive(false);
}
}
}