Unity Enemy와 Player의 공통 Skill 구현

이시율·2025년 7월 8일

Enemy와 Player가 똑같은 스킬을 사용할 때 반응이 다르도록 구현을 목표로 하였다.

스킬에 변화를 주는 Rune에는 bool값을 추가하여 누가 사용하는지 알 수있도록 추가 하였으며

public abstract class Rune : ScriptableObject
{
    public string runeName;
    public string description;
    public bool enemy;
    public abstract void Apply(Skill skill);
}

Skill에도 Enemy 전용 Use 메서드를 추가.

public GameObject EnemyUse(float enemyDamage, GameObject enemyObj) // 몬스터 스킬 사용
    {
        if (ObjectPoolManager.Instance.pools != null && ObjectPoolManager.Instance.pools.ContainsKey("Enemy" + obj.name))
        {

        }
        else  // 풀 없으면 생성
        {
            ObjectPoolManager.Instance.CreatePool("Enemy" + skillComponent.Name, obj, 1);
        }
        
        enemyPool = ObjectPoolManager.Instance.Get("Enemy" + obj.name);
        enemySkillAction = enemyPool.GetComponent<SkillAction>();

        enemySkillAction.enemy = true;
        enemySkillAction.onEnemy = setEnemy;
        enemySkillAction.damage = enemyDamage;
        enemySkillAction.caster = enemyObj;

        enemyPool.transform.position = enemyObj.transform.position;
        enemySkillAction.EnemyInit();

        return enemyPool;
    }

Skill을 상속받는 클래스에서도 OnTriggerEnter나 Init 부분을 다르게 처리하였다.

 public void EnemyInit()
    {
        duration = 5f;

        /*
        Vector2 direction = (PlayerSkillManager.Instance.transform.position - transform.position).normalized;

        // 방향 벡터로 각도 계산 (라디안 → 도 단위)
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        // 오브젝트 회전 설정 (Z축 회전)
        transform.rotation = Quaternion.Euler(0, 0, angle);
        Rigidbody2D rb = GetComponent<Rigidbody2D>();

        // Rigidbody2D에 방향 * 속도로 속도 설정 → 발사
        rb.velocity = direction * speed;
        */
        onEnemy?.Invoke();
        GetComponent<Animator>().SetInteger("Elemental", (int)elemental);

        cts?.Cancel();
        cts?.Dispose();
        cts = new CancellationTokenSource();
        Return(cts.Token, "EnemyMagicBall").Forget();
    }
    
    void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.layer == LayerMask.NameToLayer("Enemy") && !enemy) // Enemy 적중
        {
            onHit?.Invoke();
            if (!through)
            {
                GetComponent<Animator>().SetInteger("Elemental", -1);
                GetComponent<Rigidbody2D>().velocity = Vector2.zero;
                collision.GetComponent<EnemyController>().OnDamage(damage);
                Invoke(nameof(ReturnToPool), 0.5f);
            }
        }
        else if (collision.CompareTag("Player") && enemy) // Player 적중
        {
            collision.GetComponent<IDamageable>().OnDamage(damage);
            ObjectPoolManager.Instance.Return(this.gameObject, "EnemyMagicBall");
        }
    }

0개의 댓글