유니티에서 스크립을 하나 생성하면 기본적으로
이런 클래스에 MonoBehaviour이 상속되는 형태로 생성됩니다.
이번엔 이런 클래스가 정확히 무엇인지, 어떻게 사용하는지도 알아보겠습니다.
클래스를 알아보기 전에 객체 지향 프로그래밍에 대해서 정리해 보겠습니다.
객체 지향 프로그래밍?
객체 지향 프로그래밍은 객체(=오브젝트)를 이용하여 프로그램을 처리하도록 프로그래밍하는 기법으로
코드를 객체/ 블록단위로 구성하여 설계/구현하는 방법입니다.
객체 지향 프로그래밍을 사용하는 이유로는 아래와 같은 점들이 있습니다.
1. 캡슐화 : 객체내부의 데이터를 외부에서 직접적으로 접근할 수 없도록 막을 수 있다.
2. 상속 : 코드상 이미 구현된 내용을 상속을 통해 쉽게 재사용할 수 있다.
3. 다형성 : 동일한 이름의 객체라도 Override를 통해 다양하게 사용 가능하다
객체지향 프로그래밍... 여기까지만 보면 쉽지 않아 보입니다.. 하지만 유니티에서 가장 쉬운 예가 있습니다.
바로 컴포넌트!
유니티에서 하나의 오브젝트에 여러 개의 컴포넌트들을 추가하여 사용하는데
컴포넌트는 스크립 내부의 변수에 대해 숨길 수 도 있고 (캡슐화)
각각의 오브젝트에 추가가 가능하며 (상속)
오브젝트에 따라 다르게 행동하도록 프로그래밍하여 결합 가능합니다.(다형성)
이 부분을 객체 지향 프로그래밍이라고 볼 수 있습니다!
이뿐만 아니라 c# 코드상에서도 여러 객체들을 연결하여 사용하는 부분을 볼 수 있는데 대부분
"클래스"들을 연결, 상속하여 사용하는 점을 볼 수 있습니다.
이제 본론으로 들어가서
클래스란?
코드 상에서 객체를 만들거나/ 컨트롤하기 위해 만들어진 사용자 정의 데이터 형으로
다른 클래스에 상속하여 결합 가능하고, 여러 스크립에서 사용가능한,
객체지향 프로그래밍에서의 기본이 되는 부분입니다.
이제 다시 처음으로 돌아가 기본 코드상의 클래스를 확인해 봅시다.
시작하자마자 MonoBehaviour라는 클래스를 상속받고 있는 것을 알 수 있습니다.
MonoBehaviour? >>> 유니티에서 오브젝트에 컴포넌트로 추가하기 위해 제공되는 클래스
만약 클래스의 상속기능이 없었다면 지금처럼 쉽게 컴포넌트에 추가하는 것이 불가능했겠죠....
(직접 구현하려면... 허..)
이 처럼 클래스는 코드의 개발성을 늘리고, 코드와 메모리의 중복을 줄여주는 아주 중요한 역할을 수행합니다.
클래스의 사용법
클래스를 선언하는 방법은 아래와 같습니다.
class 클래스 이름 : 상속 받을 클래스
{
/// 내부 메서드 , 변수 선언~~
}
여기서 주의할 점은 일반적인 클래스는 하나당 하나씩만 상속 가능합니다.
(정확히는 다중 상속이 가능한 언어도 존재하나 c#에서는 단일 상속만 지원합니다!
유니티에서 인터페이스(Interface)를 이용하여 다중 상속을 구현할 순 있으나 이 부분은 나중에!)
그렇다면 상속만 하면 끝인가?
>> 단순한 기능에선 상속만으로 끝날 수도 있지만 대부분 그렇지 않습니다.
만약 A와 B라는 오브젝트를 움직인다 할 때 아래처럼 코드를 구성해 줍시다.
부모 클래스
public class ClassEX : MonoBehaviour
{
public void moveActor()
{
this.transform.position =
new Vector3(this.transform.position.x, this.transform.position.y + 1*Time.deltaTime, this.transform.position.z);
}
}
자식 클래스에서 ClassEX를 상속
public class Move : ClassEX
{
// Update is called once per frame
void Update()
{
moveActor();
}
}
그리고 Move 스크립트를 각각의 오브젝트에 추가해 주고 실행하면
이런 식으로 같이 moveActor() 함수로 인해 이동하는 것을 볼 수 있습니다.
하지만 두 오브젝트를 다르게 이동하고 싶다면??
물론 서로 다른 함수를 실행하면 되겠지만....
기존의 함수를 실행하면서 약간의 변경을 원한다면 아래처럼 코드를 구성해 보자
부모 클래스
public class ClassEX : MonoBehaviour
{
public virtual void moveActor()
{
this.transform.position =
new Vector3(this.transform.position.x, this.transform.position.y + 1*Time.deltaTime, this.transform.position.z);
}
}
자식 클래스
public class Move : ClassEX
{
public bool check=false;
// Update is called once per frame
void Update()
{
moveActor();
}
public override void moveActor()
{
base.moveActor();
if (check)
{
this.transform.position =
new Vector3(this.transform.position.x + 1 * Time.deltaTime, this.transform.position.y, this.transform.position.z);
}
}
}
check변수에 따라 이동 방향이 달라진 걸 확인할 수 있습니다.
무엇이 바뀌었을까??
가장 먼저 부모클래스에서는
아래처럼 virtual 이 추가되었고
public void moveActor() >> public virtual void moveActor()
자식 함수에서는 아래와 같은 함수가 생성되었습니다.
public override void moveActor()
Virtual?
상속관계에서 메서드 오버라이딩을 위해 부모에서 선언하는 키워드입니다.
이 키워드를 사용하면 부모에서 사용한 moveActor()을 override moveActor()로 다시 선언할 수 있게 됩니다!
base. 함수~();
상속받은 부모의 함수를 불러오는 명령어입니다.
(최상위 부모가 아닌 상속받은 부모의 함수)
지금까지는 부모 - 자식까지의 상속을 구현해 보았는데
이번엔 부모 - 자식 -자식까지의 상속을 만들어 보겠습니다.
최상위 부모
public class ClassEX : MonoBehaviour
{
public virtual void moveActor()
{
this.transform.position =
new Vector3(this.transform.position.x, this.transform.position.y + 1*Time.deltaTime, this.transform.position.z);
}
}
의 자식
public class Move : ClassEX
{
public bool checkMove = false;
public override void moveActor()
{
base.moveActor();
if (checkMove)
{
this.transform.position =
new Vector3(this.transform.position.x, this.transform.position.y + 1 * Time.deltaTime, this.transform.position.z);
}
}
}
의 마지막 자식
public class MoreMove : Move
{
public bool checkMoreMove = false;
void Update()
{
moveActor();
}
public override void moveActor()
{
base.moveActor();
if (checkMoreMove)
{
this.transform.position =
new Vector3(this.transform.position.x, this.transform.position.y + 1 * Time.deltaTime, this.transform.position.z);
}
}
}
이렇게 구성해 주었습니다.
변수 또한 상속받기에
이런 식으로 2개 모두 사용할 수 있고
1번 오브젝트는 둘 다 체크해제
2번은 CheckMove만 체크하고
3번은 둘다 체크했습니다.
결과는!
굳굳 왼쪽부터 y축으로의 속력차이가 보이네요
여기까지 클래스의 상속과 클래스 내부 메서드에 대한 Virtual / Override에 대해 알아보았습니다.
더 많은 기능들이 있겠지만 기본적인 기능만 정리해 보았습니다.
추가적으로 중요해 보이는 기능을 만나게 되면 추후에 수정하도록 하겠습니다!
틀린 점이 있다면 댓 달아주세요!
'유니티 최고 > 유니티 개념' 카테고리의 다른 글
유니티(Unity) 접근 제한자와 프로퍼티에 대해서 (0) | 2023.06.13 |
---|---|
유니티(Unity) 인스펙터창 관리 / [HideInInspector] ? , [SerializeField] ? (1) | 2023.06.08 |
유니티(Unity) async await이란 & 동기식, 비동기식 작업 (0) | 2023.06.01 |
유니티(Unity) 코루틴(Coroutine) 이란 & 사용해보기 (1) | 2023.05.30 |
유니티(Unity) 싱글톤(Singleton) 이란 & 사용해보기 (씬이동시 데이터 유지방식) (0) | 2023.05.25 |
댓글