Unity - 6. 상속과 프리팹

땡구의 개발일지·2025년 4월 27일

Unity마스터

목록 보기
19/78
post-thumbnail

자동차 하나를 유니티에서 만든다고 해보자. 객체지향 프로그래밍에 따라 자동차는 여러 부품들로 이루어진 객체가 하나로 뭉쳐 만들어진다. 거기에 이동, 핸들에 따른 회전 등 여러 기능들도 포함될 것이다. 이러한 완성품을 하나의 설계도를 통해 바로 만들어 주는 기능이 프리팹이다

게임 오브젝트의 상속

  • 유니티에서는 오브젝트에 다른 오브젝트를 추가하는 상속의 개념으로 구현. 하위 객체는 자신의 Local Space, 전체 공간에서의 World Space 위치 정보를 동시에 가지기 때문에, 그룹화 된 오브젝트로서의 동작 제어가 간편함
  • 단, 상속이 깊어질 수록 문제가 생긴다

귀여운 눈사람

  • 하이라키 창에서 부모 오브젝트로 쓸 것에 자식 오브젝트로 쓸 것들을 드래그 & 드롭하면 자동으로 상속이 된다

스크립트로 상속 구현하기

  • 상속이 되어 있지 않은 오브젝트도 상속 시키는 방법을 알아보자
  • 화면과 같이 게임 오브젝트들을 생성한다
  • 먼저, 부모 오브젝트를 위한 스크립트를 작성한다
 public class ParentScript : MonoBehaviour
{
    public GameObject Target;
    public Transform TargetTransform;
    private void Awake()
    {
        Init();
    }
    void Start()
    {
        ChildrenAction();
    }
    private void Init()
    {
        // 자식 오브젝트에 접근해서 컴포넌트 참조
        TargetTransform = Target.GetComponent<Transform>();

        // Target을 자식으로 지정
        TargetTransform.SetParent(transform);
        // 이것과 동일한 코드
        // TargetTransform.parent = transform;
    }
    private void ChildrenAction()
    {
        // 하위 게임 오브젝트들에 포함된 모든 childState 컴포넌트(스클비트)를 불러와 반환
        ChildState[] childState = GetComponentsInChildren<ChildState>();

        // 자신을 배열들의 부모로 지정하기
        for (int i = 0; i < childState.Length; i++)
        {
            childState[i].Parent = gameObject;

            // 자식들의 이름을 설정하고, 부모의 이름을 출력하는 함수 호출
            childState[i].SetName($"Child Object - {i}");
            childState[i].PrintParentName();
        }
    }
}
  • 이어서 자식 오브젝트를 위한 스크립트 작성
 public class ChildState : MonoBehaviour
{
    public GameObject Parent;
    public void SetName(string name)
    {
        gameObject.name = name;
    }
    public void PrintParentName()
    {
        Debug.Log($"{gameObject.name}의 부모 오브젝트는 {Parent.name}");
    }
}
  • 스크립트 작성이 완료되면 부모 오브젝트에는 부모 스크립트를, 자식에는 자식 스크립트를 드래그 & 드롭으로 추가한다
  • 부모빈 오브젝트다 상속을 받지 않은 BodyTarget으로 등록
  • 자식Body는 다음과 같이 스크립트만 추가

  • 게임을 실행시키면, 이렇게 된다

깊은 상속 주의점

  • 복잡도 증가

    • 상속의 관계가 깊어질 수록, 상위 객체와 하위 객체들 간의 접근성이 안좋아짐
    • 코드의 가독성이 떨어짐(최하위 객체가 최상위 객체로 접근하는 과정)
    • 의존성 증가
  • 성능 저하

    • 상속이 깊어 질수록, 하위 오브젝트의 데이터를 얻기 위해 각 오브젝트들을 탐색하다보니 시간이 길어져서 성능 하락이 발생한다
  • 메모리 사용량 증가

    • 하위 객체상위 객체들의 정보도 가지게 된다
    • 상속의 관계가 깊어질 수록 하위 객체가 가지게 되는 정보와 메모리 사용량이 증가

오브젝트의 컴포넌트 참조

// 해당 GameObject에 연결된 타입 T의 컴포넌트를 반환 
// 컴포넌트가 여러 개 있다면, 첫 번째 발견된 컴포넌트를 반환
// 해당 타입의 컴포넌트가 없으면 null을 반환
Component comp = GameObject.GetComponent<T>();

// 해당 GameObject에 연결된 모든 타입 T의 컴포넌트들을 배열로 반환
// 해당 타입의 컴포넌트가 없으면 빈 배열을 반환
Component[] comps = GameObject.GetComponents<T>();    

// 해당 GameObject와 그 자식들을 순회하며 타입 T의 첫 번째 컴포넌트를 반환
// 컴포넌트가 없으면 null을 반환
Component comp = GameObject.GetComponentInChildren<T>();

// 해당 GameObject와 그 자식들을 순회하며 타입 T의 모든 컴포넌트들을 배열로 반환
// 해당 타입의 컴포넌트가 없으면 빈 배열을 반환
Component[] comps = GameObject.GetComponentsInChildren<T>();

// 해당 GameObject와 그 부모들을 순회하며 타입 T의 첫 번째 컴포넌트를 반환
// 만약 그러한 컴포넌트가 없으면 null을 반환
Component comp = GameObject.GetComponentInParent<T>();    

// 해당 GameObject와 그 부모들을 순회하며 타입 T의 모든 컴포넌트들을 배열로 반환
// 해당 타입의 컴포넌트가 없으면 빈 배열을 반환
Component[] Comps = GameObject.GetComponentsInParent<T>();

프리팹(Prefab)

  • 미리 만들어 놓은 게임 오브젝트, 템플릿, 설계도
  • 프리팹으로 게임 오브젝트를 설정, 저장, 생성 가능
  • 게임 오브젝트 구성 중, 자주 사용하는 것을 프리팹으로 저장해서 사용한다

생성

  • 하이라키 창게임 오브젝트프로젝트 창으로 드래그 & 드롭하여 프리팹 생성
  • 프로젝트 창에서 프리팹 만들기로 가능하다
  • 프리팹에디터 에서만 만들 수 있다

특징

  • 프리셋으로 저장게임 오브젝트
  • 오브젝트의 상태를 저장한 것이다. 게임 오브젝트, 컴포넌트, 스크립트, 변수의 값들이 저장되어 있다
  • 게임 오브젝트의 모든 컴포넌트, 속성 값, 자식 게임 오브젝트를 가지고 있음
  • 에 추가할 경우 프리팹 인스턴스로 생성
  • 프리팹 에셋의 변경사항은 프리팹 인스턴스에게 자동으로 반영
  • 프리팹 인스턴스에 변경사항이 있을 경우, 해당 변경사항은 프리팹 에셋에는 영향을 주지 않음
  • 프리팹 에셋 = 클래스
  • 프리팹 인스턴스 = 클래스 인스턴스

프리팹 런타임 생성

  • 런타임 중 프리팹에셋을 이용하여 프리팹 인스턴스를 생성 가능
    public GameObject gameObjectPrefab;     // 프리팹 참조변수
    public Component componentPrefab;       // 프리팹의 컴포넌트 참조변수
    public void Instantiate()
    {
        // Instantiate을 통해 프리팹인스턴스 런타임 생성
        GameObject instance = Instantiate(gameObjectPrefab, Vector3.zero, Quaternion.identity);
        Component component = Instantiate(componentPrefab, Vector3.zero, Quaternion.identity);
    }

프리팹 인스턴스

  • 프로젝트 창의 프리팹씬 창으로 드래그&드롭만 해도 만들 수 있다

인스턴스 수정 내용 프리팹에 저장

  • 인스펙터 창에서 Overrides를 누르고, Apply All을 누르면 수정 내용이 전부 저장된다
  • Revert All을 누르면 프리팹의 설정을 인스턴스로 가져온다

프리팹 편집

  • 프리팹을 더블 클릭 하면 프리팹 전용 편집 모드로 들어가게 된다
  • 편집 모드를 나갈 때는 변동사항을 저장해야 한다

씬에서 프리팹 편집


  • Open을 누르면 해당 게임 오브젝트만 하이라이트 된다. 수정을 하고 나가면 같은 프리팹에도 모두 수정사항이 적용된다. 프리팹 편집 모드와 동일한 기능

프리팹 풀기

  • Unpack을 누르면 프리팹을 풀 수 있다
profile
개발 박살내자

0개의 댓글