본문 바로가기

Unity

유니티 C# - Interface 게임에 적용해 보기

반응형

애매모호한 Interface를 이해하기 위한 실사용에서 도움이 될만한 간단한 예제입니다.

우선 게임 속 몬스터가 종류별로 10마리 있다고 하겠습니다.

게임을 진행하면서 플레이어가 공격을 할 때 Collider로 적을 감지해서 10마리의 몬스터중 어떤 몬스터인지

파악을 한 후 해당 몬스터에 대미지를 준다고 가정해 보면

    private void OnTriggerEnter2D(Collider2D other) {
        if (other.CompareTag("Enemy")) {
            switch(other.gameObject.name) {
                case "EnemyA":
                    other.gameObject.GetComponent<EnemyA>().Damage(10);
                    break;
                case "EnemyB":
                    other.gameObject.GetComponent<EnemyB>().Damage(10);
                    break;
                case "EnemyC":
                    other.gameObject.GetComponent<EnemyC>().Damage(10);
                    break;
                .
                .
                .
            }
        }
    }

공격을 가해 Collider 가 해당 몬스터를 감지 후 OnTriggerEnter2D로 해당 GameObject가 어떤 몬스터인지 switch로 찾아서 해당 몬스터에 대미지를 10 주는 코드입니다.

이런 식의 코드를 본다면 몬스터가 10마리라고 했으니 해당 10마리만큼 적용을 해줘야 대미지를 줄 수 있을 겁니다.

10마리 정도는 뭐 그렇다 해도 만약 몬스터가 20마리 아니면 100 마리면 말도 안 되는 중복 작업이죠?

해당 작업을 Interface를 통해 어떻게 적용되는지 살펴보겠습니다.

새로운 c# 파일을 하나 만들고 이름을 IDamage.cs로 주겠습니다.

public interface IDamage 
{
   void Damage(float damage);
}

해당 Interface는 각 몬스터마다 적용해서 몬스터가 공격당했을 경우 해당 대미지만큼 생명력을 빼며 또한 죽음 등을 처리하는 코드가 포함될 것입니다.

이제 첫 번째 몬스터 EnemyA.cs 에 IDamage 인터페이스를 구현해 줍니다.

public class EnemyA : MonoBehaviour, IDamage
{
    // IDamage의 인터페이스 구현
    public void Damage(float playerAtkDamage) {
        enemyHealth -= playerAtkDamage;

        if (enemyHealth <= 0) {
            // 몬스터 죽음 처리
        } 
    }
}

playerAtkDamage라는 float 변수 값을 받아 해당 몬스터의 생명력을 공격받은 값만큼 빼며 만약 생명력이 0이면 죽음 처리를 하는 코드입니다.

이런 식으로 각 몬스터마다 해당 인터페이스를 구현해 주며 모든 몬스터들이 해당 IDamage라는 Interface를 가지고 있습니다.

이제 플레이어가 공격 시 몬스터마다 적용된 Interface를 확인 후 어떻게 대미지를 주는지 살펴보겠습니다.

   private void OnTriggerEnter2D(Collider2D other) {
        IDamage damage = other.GetComponent<IDamage>();

        if (damage != null) {
            damage.Damage(10);
        }
    }

IDamage damage = other.GetComponent();

플레이어가 몬스터 공격 시 Collider가 해당 몬스터를 감지하면 IDamage damage에 Collider에서 감지된 몬스터의 인터페이스를 가져옵니다.

if (damage != null)

해당 몬스터가 인터페이스를 가지고 있다면

damage.Damage(10);

해당 몬스터에 구현된 인터페이스 Damage함수에 10이라는 값을 전달합니다. (해당 몬스터에 10만큼 피해를 줍니다)

* damage.Damage(데미지 값); -> 코드에선 편의상 10을 주었지만 해당 값에는 플레이어에 설정된 공격력 값을 주시면 됩니다.

이렇게 하면 몬스터가 10마리가 있던 100마리가 있던 관계없이 처리 가능하게 됩니다.

Interface를 구현하기 전 사용한 switch문과 비교하면 왜 Interface를 사용해야 하는지 알 수가 있습니다.

몬스터를 예로 들었지만 여러 종류의 아이템들 역시 클릭된 아이템이 어떤 아이템인지 구분할 필요 없이

그 아이템이 가지고 있는 Interface만 가져와서 기능을 실행시켜 주면 됩니다.

이상 Interface를 이해하는데 조금이라도 도움이 되었음 합니다.

 

반응형