본문 바로가기
유니티/기초

유니티 게임 오브젝트( Game Object )

by 노튜 2020. 11. 2.
728x90

 

1. Game Object

 

게임 오브젝트는 Scene에서 모든 개체의 기본 클래스이다.

 

게임 오브젝트는 모든 개체의 기본 클래스로, 게임 오브젝트에 컴포넌트들을 추가하여, 원하는 형태의 객체를 디자인한다. 게임 오브젝트에 Canvas를 추가하여 UI(User Interface)를 구성하거나, Mesh를 추가하여 형태가 존재하는 물체를 만들거나, Script를 추가하여 동적인 움직임을 구현한다. Unity가 Component-based라고 하는 이유이기도 하다.

 

Unity는 게임 오브젝트를 기반으로 자주 사용하는 형태의 객체를 디자인하여, 제공하고 있다. 

예로, 3D Cube를 들 수 있다.

 

3D Cube를 생성하는 과정은 아래와 같다.

  1. Empty Game Object 생성 
  2. Mesh Filter , Mesh Renderer 추가 : Game Object → Add Component
  3. Mesh 등록 : MeshFilter Mesh Cube
  4. Material 등록 : MeshRenderer  →  Material → Default-Material
  5. Collider 추가 : Game Object  → Add Component

Create Cube

  • 1 : 클릭하여 메쉬 추가
  • 2 : 클릭하여 머터리얼 추가
  • 3 : Mesh Filter, Mesh Renderer, Collider 등의 컴포넌트 추가 

 

2. Game Object의 생성

 

게임 오브젝트를 생성하는 방법은 아래와 같다.

 

  • Top Menu →  GameObject  선택 
  • Scene hierarchy  +  선택

 

3. Game Object 파괴

 

더 이상 필요하지 않은 게임 오브젝트는 Destroy() 함수를 호출해 파괴(메모리 해제)가 가능하다. 

이는 메모리를 효율적으로 관리하는 하나의 수단이다. 그러나 지속적으로 게임 오브젝트를 파괴하는 것은 성능 저하를 초래할 수 있다. 월드에서 게임 오브젝트를 파괴하는 것은 Garbage Collector( GC )을 호출하게 하기 때문이다. 

 

GC는 Heap memory area의 사용하지 않는 메모리의 처리와 해제를 관리하는 시스템이다. GC는 시스템에 의해 관리되며, 자동으로 호출된다. GC는 블록이 더 이상 사용되지 않는지 확인하기 위해 모든 현재 활성화된 참조 변수를 검색한다.

 

※ GC와 관련된 추가적인 내용은 아래 유니티 문서( 참조 )를 확인. 

 

Destroy() 호출로 인해 발생하는 성능 저하를 개선하기 위한 방법으로, 대신 게임 오브젝트의 활성화 상태를 비활성화 상태로 변경하는 방법이 있다. 비활성화 상태에서는 물리적 충돌, 업데이트의 호출 등이 발생하지 않는다. 또한, 다시 필요하다면, 게임 오브젝트를 활성화하여, 재사용할 수 있다. 게임 오브젝트를 재활용하는 방법으로 오브젝트 풀링(Object Pooling)이 있다. 

비활성화 상태는 여전히 메모리가 할당된 상태이다. 프로젝트 상황에 따라 사용할 것을 권장한다.

 

※ 오브젝트 풀링은 다른 글에서 다루도록 한다.  

https://notyu.tistory.com/64

 

유니티 오브젝트 풀링(Object pooling)

1. 오브젝트 풀링(Object pooling) 오브젝트 풀링은 개체를 할당하고 파괴하는 대신, 미리 오브젝트 집합(Object Pool)을 생성하고, 필요할 때에 불러와 사용하고, 사용한 개체를 다시 개체 집합에 반환

notyu.tistory.com

 

  • gameObject.SetActive(false) : 비활성화
  • gameObject.SetActive(true) : 활성화  

 

using UnityEngine;

public class GetComponentExample : MonoBehaviour
{
    public PlayerAI playerAI;
    public GameObject myGameObject;

	void Start( )
	{
    	playerAI.gameobject.trasform.position = transform.position;
        NavMeshAgent navMeshAgent = myGameObject.GetComponent<NavMeshAgent>();
        
	}
    
    void Update(){
    
      if(Input.GetKey("q")){
         Destroy(myGameObject); // 파괴
         myGameObject.SetActive(false);
      }
    
    }
}

 

 

4. Game Object 접근

4.1 public 멤버 변수

 

public으로 멤버 변수를 선언하고, 대상 게임 오브젝트를 드래그하여 추가한다.

 

using UnityEngine;

public class GetComponentExample : MonoBehaviour
{
    public PlayerAI playerAI;
    public GameObject myGameObject;

	void Start( )
	{
    	playerAI.gameobject.trasform.position = transform.position;
        NavMeshAgent navMeshAgent = myGameObject.GetComponent<NavMeshAgent>();
        
	}
}

 

4.2 GameObject.Find("Name")

 

유니티는 월드상에 있는 특정한 게임 오브젝트에도 접근이 가능한 Find() 함수를 제공한다.

Find() 함수는 언제 어디서든 원하는 게임 오브젝트에 쉽게 접근할 수 있다는 장점이 있다.

 

그러나, Find() 함수는 Scene상에 존재하는 모든 오브젝트를 순회하여, 대상을 찾는다. 이는 검색하는데 상당한 시간이 소요될 수도 있다는 것을 의미한다. Scene에 게임 오브젝트가 적다면 괜찮지만, 게임 오브젝트가 많이 있는 거대한 Scene에서는 시스템에 상당한 부담을 줄 것이다. 즉, 성능 저하의 원인이 되는 결과를 초래한다.

따라서 GameObject.Find()의 반복적인 사용은 자제를 권한다.

 

Name 이외에도, Tag, ObjectType으로도 검색이 가능하다. 

 

using UnityEngine;

public class FindExample : MonoBehaviour
{
    GameObject myGameObject;

	void Start( )
	{
    	myGameObject = GameObject.Find("MyGameObject");
        
	}
}

 

5. Game Object의 컴포넌트 접근 

 

게임 오브젝트에 연결된 컴포넌트는 gameobject.GetComponent() 함수를 이용해 접근이 가능하다. 

하지만 GetComponent()는 대상 컴포넌트가 게임 오브젝트의 동일한 계층 구조에 있을 때, 접근이 가능하다. 

동일한 종류의 컴포넌트가 여러 개 존재할 때에는 실제 원하는 컴포넌트인지 확실하지가 않다.

이러한 문제로 인해, 유니티는 다양한 GetComponent() 함수들을 제공하고 있다.

 

  • GetComponent <Type>() :  동일한 계층구조에서 대상
  • GetComponents <Type>() : 동일한 계층구조에서 대상들
  • GetComponentInChildren <Type>() : 하위 계층에서 대상
  • GetComponentInParent <Type>() : 상위 계층에서 대상 
  • ...

 

using UnityEngine;

public class GetComponentExample : MonoBehaviour
{
    public PlayerAI playerAI;
    private NavMeshAgent navMeshAgent;
    private Animator animator;
    private SphereCollider findConllider;
    
    void Start( )
    {
    animator = GetComponentInChildren<Animator>();
    navMeshAgent = GetComponent<NavMeshAgent>();
    findConllider = GetComponentInParent<SphereCollider>();
    }
}

 

6.  GameObject  컴포넌트 추가  

 

게임 오브젝트에 연결된 컴포넌트에 접근하는 것뿐만 아니라, 실시간으로 게임 오브젝트에 AddComponent <Type>()를 사용하여 컴포넌트를 추가할 수 있다.

using UnityEngine;

public class AddComponentExample : MonoBehaviour
{

    private SphereCollider myCollider;
    public float radius;
	void Start( )
	{
         myCollider = gameObject.AddComponent<SphereCollider>();
         myCollider.radius = radius;
	}
}

 

 

참조 

 

Garbage Collector(GC)

 

docs.unity3d.com/kr/530/Manual/UnderstandingAutomaticMemoryManagement.html

 

유니티 - 매뉴얼: 자동 메모리 관리를 이해하기

이벤트 함수의 실행 순서 플랫폼 의존 컴파일 자동 메모리 관리를 이해하기 When an object, string or array is created, the memory required to store it is allocated from a central pool called the heap. When the item is no longer in

docs.unity3d.com

 

728x90