using System.Collections; using System.Threading; using System.Threading.Tasks; using Unity.VisualScripting; using Unity.VisualScripting.Antlr3.Runtime; using UnityEngine; using UnityEngine.SceneManagement; public class ItemEffectManager : MonoBehaviour { public void OnSceneLoaded(Scene scene, LoadSceneMode mode) { } public void ItemUse(ItemInstance item) { switch(item.Data.ItemEffectType) { case ItemEffectType.RECOVERY_HP: { RecoveryHPHealthEffect(GameManager.Instance.Level.CurrentCharacter.GetComponent(), item.Data.RecoveryHP, item.Data.ItemEffectVisual); } break; case ItemEffectType.INTERVAL_DAMAGE: { IntervalDamageHealthEffect(GameManager.Instance.Level.CurrentCharacter.GetComponent(), item.Data.IntervalDamage, item.Data.IntervalDamageTime, item.Data.ItemEffectVisual); } break; } } public void RecoveryHPHealthEffect(Health health,float recoveryHP,GameObject itemEffectVisual) { PlayerHealth playerHealth = health as PlayerHealth; if (playerHealth != null) { GameObject fx_Visual = Instantiate(itemEffectVisual, playerHealth.transform); // health의 자식으로 이펙트 생성 fx_Visual.transform.localPosition = new Vector3(0, 1.5f, 0); playerHealth.ChangeHP(Mathf.Clamp(playerHealth.CurrentHP + Mathf.FloorToInt(recoveryHP), 0, playerHealth.Pstat.MaxHp)); //소수점 전부 버림 } } public void IntervalDamageHealthEffect(Health health,float damage,float time,GameObject itemEffectVisual) { IntervalDamage(health, damage,time, itemEffectVisual); } //일정 시간 동안 틱대미지 일으키는 함수 public async void IntervalDamage(Health health, float damage,float time, GameObject itemEffectVisual) { // 유니티 오브젝트 자체의 CancellationToken 가져오기 (오브젝트 파괴 시 자동 취소) CancellationToken token = health.destroyCancellationToken; GameObject fx_Visual = Instantiate(itemEffectVisual, health.transform); // health의 자식으로 이펙트 생성 fx_Visual.transform.localPosition = new Vector3(0, 1.5f, 0); float tickDamage = damage / time; try { while (time > 0) { health.ChangeHP(health.CurrentHP - Mathf.FloorToInt(tickDamage)); //소수점 전부 버림 if (health.CurrentHP <= 0) break; time--; await Task.Delay(1000, token); } } catch (System.OperationCanceledException) { Debug.Log("데미지 루프가 취소됨"); } finally { // 정상 종료되든, 취소되든(Exception) 이펙트는 확실히 제거 if (fx_Visual != null) Destroy(fx_Visual); } } }