Unity2D

Unity) [유니티 2D] 지속(독) 데미지 특수효과 구현

HSH12345 2023. 4. 29. 21:38
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoisonBullet : Relic
{
    public GameObject vfxPoison;
    [System.NonSerialized]
    public Queue<GameObject> vfxPoisonPool;

    public override void Init()
    {
        base.Init();
        this.vfxPoisonPool = new Queue<GameObject>();
    }

    //Monster 스크립트에서 구현
    public bool IsPoison()
    {
        return true;
    }    

    public void ShowVfxPoison(Transform monsterTrans)
    {
        GameObject go;

        if (vfxPoisonPool.Count > 0)
        {
            go = vfxPoisonPool.Dequeue();
            go.SetActive(true);
            go.transform.SetParent(monsterTrans);
        }
        else
        {
            go = Instantiate(this.vfxPoison, monsterTrans);
        }

        go.GetComponent<VfxPoison>().Init();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Monster : MonoBehaviour
{
    public PathFinding pathFinding;
    public AnimationClip deadAnimationClip;

    [System.NonSerialized]
    public int exp = 10;
    [System.NonSerialized]
    public int maxHP = 1000;
    [System.NonSerialized]
    public int hp;
    public bool isSkilldDamaged;
    public bool isDead;

    private MonsterGenerator monsterGenerator;

    //독데미지
    private Coroutine PoisonRoutine;
    private int getPoisonCnt;
    private int maxPoisonCnt;
    private PoisonBullet poisonBullet;

    public void Init(MonsterGenerator monsterGenerator)
    {
        this.monsterGenerator = monsterGenerator;
        this.pathFinding.enabled = true;
        this.pathFinding.gameObject.GetComponent<Rigidbody2D>().simulated = true;
        this.pathFinding.gameObject.GetComponent<Collider2D>().enabled = true;
        this.hp = this.maxHP;
        this.poisonBullet = GameObject.FindObjectOfType<PoisonBullet>()?.GetComponent<PoisonBullet>();
        this.maxPoisonCnt = 7;
    }

    public void OnDisable()
    {
        this.monsterGenerator.monsterPool.Enqueue(this.gameObject);
    }

    public void TakeSkillDamage(int damage, float skillTime)
    {
        this.TakeDamage(damage);
        StartCoroutine(SkillDamagedRoutine(skillTime));
    }

    public IEnumerator SkillDamagedRoutine(float skillTime)
    {
        this.isSkilldDamaged = true;
        yield return new WaitForSeconds(skillTime);
        this.isSkilldDamaged = false;
    }

    public void TakeBulletDamage(int damage)
    {        
        this.TakeDamage(damage);
        if (this.poisonBullet != null) 
        {
            if (this.poisonBullet.IsPoison())
            {
                if (this.PoisonRoutine != null) StopCoroutine(this.PoisonRoutine);
                this.PoisonRoutine = StartCoroutine(this.GetPoisonDamageRoutine());
            }  
        }
    }

    private IEnumerator GetPoisonDamageRoutine()
    {
        while(true)
        {
            if (this.maxPoisonCnt <= this.getPoisonCnt || this.isDead) break;
            if (this.poisonBullet != null) this.poisonBullet.ShowVfxPoison(this.gameObject.transform);
            this.pathFinding.HitPlayerActiveSkill(-this.pathFinding.dir, 1000);
            this.TakeDamage(100);
            yield return new WaitForSeconds(1.2f);
            this.getPoisonCnt++;            
        }
    }
    
    public void TakeDamage(int damage)
    {
        //Debug.Log(this.hp);
        this.hp -= damage;
        if (this.hp <= 0) isDead = true;
        if (isDead)
        {            
            this.pathFinding.enabled = false;
            this.pathFinding.gameObject.GetComponent<Rigidbody2D>().simulated = false;
            this.pathFinding.gameObject.GetComponent<Collider2D>().enabled = false;
            this.gameObject.GetComponent<Animator>().Play("Dead", -1, 0);
            EventDispatcher.Instance.Dispatch(EventDispatcher.EventName.PlayerExpUp, this.exp);

            StartCoroutine(this.MonsterDeadRoutine());
        }
    }

    IEnumerator MonsterDeadRoutine()
    {
        yield return new WaitForSeconds(this.deadAnimationClip.length);
        this.gameObject.SetActive(false);
    }
}

 

 몬스터가 플레이어에게 불렛이나 대시공격으로 공격 당했을 때 해당 능력을 보유하고 있으면 독데미지를 입도록 기능 구현하였습니다. 몬스터의 Init 메서드가 호출될 때 비모노 클래스인 PoisonBullet이 Nuill이 아니라면 해당 효과가 적용됩니다.