목표 |
1. 다형성이 무엇인지 알아보고 구현하는 방법을 살펴 보자.
2. 인터페이스 사용법을 알아 보자
이론 |
1. 다형성
플레이어와 적이 있다면 공통적으로 생명체로 동작하게 되며 생명력과 누군가에게 데미지를 입히거나 다른 생명체로 부터 데미지를 얻을 수 있다.
이러한 생명체 클래스는 부모의 구현을 재사용 가능하며 부모클래스 타입으로 일괄 처리가 가능하다.
1. 상속관계에서의 다형성
몬스터가 있고 몬스터의 종류에는 오크와 드래곤이 있다고 가정해 보자.
몬스터의 속성으로는 데미지가 있고 공격을 할 수 있는 능력이 있다고 하면 몬스터 클래스를 다음과 같이 구현 할 수 있다.
public class Monster : MonoBehaviour{
public void Attack(){
Debug.Log("공격");
}
}
테스트 하기 위해 Dragon Warrior를 에셋에서 다운받아서 캐릭터를 하나 추가하자.
2022.05.31 - [응용프로그래밍/유니티기초] - [유니티기초]2-01.에셋스토어에서 2D 이미지 다운받아 적용하기
orc 도 다운받아 캐릭터를 추가하자.(Orc Warrior Cartoon Character)
다음으로 Orc 와 Dragon 을 다음과 같이 Monster 를 상속 받아서 스크립트를 작성하자.
public class Orc : Monster{
public void WarCry(){
Debug.Log("전투함성");
}
}
Orc 는 몬스터를 상속 받아서 WarCry() 메서드를 추가하자
public class Dragon : Monster{
public void Fly(){
Debug.Log("날기");
}
}
Dragon 에는 Fly() 메서드를 추가하자.
각각의 객체에 스크립트를 추가하자.
이렇게 만들게 되면 오크와 드래곤은 Monster를 상속하므로 Monster 타입으로 취급 할 수 있다.
GameManager 에서 다음과 같이 Orc 씬을 찾아서 Monster의 Attack() 을 실행 해 보자.
Orc orc = FindObjectOfType<Orc>(); //씬에서 오크를 찾음
Monster monster = orc; //몬스터 타입의 변수에 오크를 할당
monster.Attack(); //실행가능
monster.WarCry(); //실행 불가능
이 때 monster 의 Attack 는 실행 가능하지만 WarCry 는 실행이 불가능하다. 이것은 Monster 에는 WarCry 가 없기 때문이다.
유니티에서는 객체는 MonoBehaviour 를 상속 받아야 이벤트 처리가 가능 하므로 다중상속을 해야 하는데 C#에서는 다중상속을 지원하지 않는다.
따라서 위의 코드를 유니티에서 실행해 보기 위해서는 Monster 를 인터페이스 형태로 만든 후에 Orc와 Dragon 이 인터페이스를 상속 받을 수 있다.
public interface IMonster
{
public void Attack()
{
Debug.Log("공격");
}
}
public class Orc : MonoBehaviour, IMonster
{
public void WarCry()
{
Debug.Log("전투함성");
}
}
public class Dragon : MonoBehaviour, IMonster
{
public void Fly()
{
Debug.Log("날기");
}
}
위와 같이 코드를 변경 후 게임매니저에서 다음과 같이 호출을 하면 monster의 Attack() 이 호출 되는 것을 확인 할 수 있다.
Orc orc = FindObjectOfType<Orc>(); //씬에서 오크를 찾음
IMonster monster = orc; //몬스터 타입의 변수에 오크를 할당
monster.Attack(); //실행가능
2. 인터페이스
인터페이스로 정의한 메서드는 추상클래스와 비슷한 개념을 가지게 된다.
인터페이스에서 정의한 메서드는 상속 받은 객체 클래스에서 구현을 해 주어야 한다.
위의 예에서 Monster 는 Attack 하는 기능과 Say하는 기능이 있다고 하면 Attack 은 인터페이스에서 구현을 했지만 Say 는 상속 받은 객체에서 구현을 해야 한다고 하면 다음과 같이 구현할 수 있다.
public interface IMonster
{
public void Attack();
public void Say(); //여기서는 정의만 한다.
}
public class Orc : MonoBehaviour,IMonster
{
public void WarCry()
{
Debug.Log("전투함성");
}
public void Attack(){
Debug.Log("Orc가 공격을 합니다.");
};
public void Say(){
Debug.Log("Orc가 말을 합니다.");
};
}
public class Dragon : MonoBehaviour,IMonster
{
public void Fly()
{
Debug.Log("날기");
}
public void Attack(){
Debug.Log("Dragon이 공격을 합니다.");
}
public void Say(){
Debug.Log("Dragon이 말을 합니다.");
}
}
이렇게 하면 IMonster 를 상속 받은 경우 무조건 Attack 과 Say 메서드가 구현 되어 있음이 보장 된다.
그렇다면 Player 와 드래곤이나 오크가 부딪혔을때 몬스터의 기능인 Say() 하는 것을 구현해 봅시다.
PlayMovement 를 다음과 같이 구현 합니다.
private void OnCollisionEnter2D(Collision2D other) {
if(other.gameObject.tag=="bottom"){
//Die();
}
IMonster monster = other.gameObject.GetComponent<IMonster>();
if(monster!=null) monster.Say();
}
이동하여 가까이 갔을때 말을 하는 것을 확인 할 수 있다.
'응용프로그래밍 > 유니티기초' 카테고리의 다른 글
[유니티기초]2-04. 애니메이션 (0) | 2022.06.01 |
---|---|
[유니티기초] 2-03. 두 객체가 부딪혔을 때 밀림 방지 (0) | 2022.05.31 |
[유니티기초] 2-02.싱글턴 패턴 (0) | 2022.05.31 |
[유니티기초]2-01.에셋스토어에서 2D 이미지 다운받아 적용하기 (0) | 2022.05.31 |
[유니티기초]1-10. 카메라 이동 (0) | 2022.05.30 |