Unity3D에서의 Collections 콜렉션 자료형

2013. 7. 4. 18:19게임 개발/OpenGL

 

 

Unity3D에서는 배열을 포함한 콜렉션이라고 불리우는 다양한 자료형들을 지원한다.

 

-       내장형 배열(Built-in Array)

-       JavaScript 배열

-       ArrayList

-       HashTable

-       Generic List

-       Generic Dictionary

-       2차원 배열

 

Unity3D .NET 의 오픈소스 버전인 Mono 에 기반하고 있기 때문에, .NET 에서 지원하는 대부분의 기본적인 자료형을 지원한다. Javascript 배열을 제외하면 위에 열거된 모든 자료형들이 사실 .NET 의 기본 자료형들이다.

 

Javascript 배열은 Unity3D에서 추가한 자료형으로 Unity3D에서 JavaScript를 사용해서 프로그래밍할 때만 사용할 수 있는 자료형을 C#을 사용하는 경우에는 사용할 수 없다.

Javascript 배열은 ArrayList Wrapper 로 이와 크게 다르지 않지만, 기존에 ActionScript 와 같이 Javascript 계열 혹은 이와 유사한 언어에 익숙한 사용자라면 이들의 차이를 이해하고 Unity Javascript가 사실은 Javascript와 유사한 문법만을 가지고 있을 뿐이며 실제 Javascript와 다르다는 것을 숙지하는 것이 중요하다.

 

모든 타입의 자료형들에는 다음과 같은 공통점이 있다.

-       모든 자료형은 객체(Object)를 저장할 수 있고, 이를 꺼내서 읽는 것이 가능하다.

-       자료형의 크기를 알 수 있다.

-       모든 자료형은 아니지만 대부분의 자료형에 대해서는 임의의 위치에 자료형을 삽입하거나 삭제하는 것이 가능하며 정렬하는 것도 가능하다.

-       자료형들은 별도의 루프를 통해서 순회하는 것이 가능하다.

 

다음은 앞에서 언급한 자료형에 대한 설명이다.

 

1. 내장형 배열(Built-in Array)

 

Unity JS C# 에서 모두 사용이 가능한 기본적인 배열 타입의 자료형이 바로 내장형 배열이다.

내장형 배열은 배열을 선언할 때 크기를 함께 설정하기 때문에 고정된 크기를 가지며 매우 빠른 처리가 가능하다. 이 때문에 내장형 배열은 코드에서 빠른 처리를 해야 하고, 자료의 크기(개수)를 알고 있는 경우에는 선택 할 수 있는 가장 좋은 자료형이다.

 

만약 다양한 개수의 아이템들을 저장해야 하는 경우라도 최대 크기를 알고 있거나 결정할 수 있는 경우라면 내장형 배열을 사용하는 것이 좋다.
예를 들어 슈팅 게임에서 총알을 한번에 최대 50개까지만 발사할 수 있다면, 크기가 50인 내장형 내열을 사용해서 사용하지 않는 공간은 null로 채우는 방법을 사용하면 된다.

또한 내장형 배열은 Unity Inspector 윈도우 창에 표시할 수 있다.

때문에 Unity 에디터를 이용해서 편집이 필요한 자료형이라면 내장형 자료형을 사용하는 것이 편리하다.

 

Unity Get… 함수를 통해서 리턴되는 배열형은 모두 내장형 배열이다.
예를 들어 GetComponentInChildren 함수가 리턴하는 컴포넌트 들은 내장형 배열을 사용해서 저장할수 있다.

 

EX) C# 

//declaration

TheType[] myArray = new TheType[lengthOfArray];

 

//declaration example using ints

Int[] myNumbers = new int[10];

 

//declaration example using GameObjects

GameObject[] enemies = new GameObject[16];

 

// get the length of the array

int howBig = myArray.Length;

 

// set a value at position i

myArray[i] = newValue;

 

//get a value from position i

TheType thisValue = myArray[i];

 

 

EX) Javascript 자료형을 var로 변경하는 것 외에 특이사항없이 동일

 

2. Javascript 배열

 

Javascript 배열은 .NET 에서 사용하는 자료형과는 별개로 Unity만의 자료형으로 Unity에서 js로 프로그래밍 할 때 사용할 수 있는 자료형 이다. !!! C# 에서는 사용 할 수 없다.
Javascript
배열은 동적인 크기를 가지기 때문에 자료형에 아이템을 삽입하거나 삭제할 때 이에 따라 자료형의 크기가 변하는 특징을 가지고 있다
.
이러한 동적인 크기 변경의 특징 때문에 Javascript 배열은 내장형 배열에 비해 속도가 떨어지는 단점이 있어서, 주의해야함
.
Javascript,
의 또 다른 단점은 JS가 동적인 형 타입을 지원하기 떄문에 자료형에서 객체를 얻어 올 때 명시적인 형변환을 해야 한다는 점이다.

 

Ex)

// declaration

Var myArray = new Array();
// add an item to the end of the array.

myArray.Add(anItem);

//retrieve an item from position i

Var thisItem = myArray[i];

//removes an item from position i

myArray.RemoveAt(i);

//get the length of the Array

Var howBig = myArray.length;

 

3. ArrayList

 

ArrayList .NET 의 자료형으로 Javascript 배열과 매우 유사하다.
다만 JS 뿐만 아니라 C#에서도 사용이 가능하다, 하지만 크기가 역시 동적이기 때문에 자료의 삽입 및 삭제시 ArrayList의 크기가 변경될 수 있다. 내장형 배열과 비교하면 속도가 떨어진다.

 

Ex) C#
// declaration

ArrayList myArrayList = new ArrayList();
// add an item to the end of the array.

myArrayList.Add(anItem);

//change the value stored at position i

myArrayList[i] = newValue;

//retrieve an item from position i

TheType thisItem = (TheType) myArrayList[i];

//removes an item from position i

myArrayList.RemoveAt(i);

//get the number of items in the ArrayList

Var howBig = myArray.length; 

 


4. Hash Table (
해시 테이블)

 

해시테이블은 각각의 아이템이 KEY VALUE 으로 구성된 자료형으로 빠른 검색이 필요한 경우에 요긴하게 사용할 수 있는 것이 장점이다.
주어진 KEY 로 검색하게 되면 VALUE을 리턴하는 방식이다
.
ArrayList
와 마찬가지로 해쉬테이블 역시 얻어 온 값에 대한 형변환(type casting)이 필요하다.


ex) C#

//declaration

Hashtable myHashtable = new Hashtable();

 

//insert or change the value for the given key

myHashtable[anyKey] = newValue;

 

//retrieve a value for the given key

ValueType thisValue = (valueType)myHashtable[theKey];

 

//get the number of items in the Hashtable

Int howBig = myHashtable.Count;

 

//remove the key & value pair from the Hashtable, for the given key.

myHashtable.Remove(theKey);

 

5.     Generic List (제너릭 리스트)

 

Unity3D엔진은 3.0 버전부터 iOS에서 .NET 의 제너릭 자료형을 지원한다.
또한 3.0 버전부터는 Javascript에서도 이 제너릭 콜렉션을 사용할 수 있게 되었다.

 

제너릭 리스트는 제너릭 콜렉션에 속한 자료형으로 동적인 크기를 가지며, 임의의 위치에 자료형의 삽입과 삭제가 가능하는 점에서 Javascript 배열 및 ArrayList 와 유사하다.
제너릭 리스트와 이들 자료형과의 가장 큰 차이점이라면 제너릭 리스트는 자료형을 선언 할 떄 자료형의 타입을 지정한다는 점이다. 그리고 사용 할 때에는 선언시 지정한 자료형만을 삽입하거나 삭제할 수 있다.

그러므로 다음과 같은 특징을 가지게 된다.

-       명시적인 형변환을 할 필요가 없다.

-       ArrayList 보다 빠르다.

 

이러한 특징을 잘 이해해서 만약에 사용하고자 하는 자료의 형을 미리 알고 있는 경우에는 ArrayList 보다 제너릭 리스트를 사용하는 것이 훨씬 유리하다.

제너릭 리스트는 System.Collections 에 기본적으로 포함되어 있지 않기 때문에 제너릭 리스트를 사용하는 경우에는 명시적으로 using System.Collections.Generic 선언이 필요하다.

 

Ex) C#

//declaration

List<Type> myList = new List<Type>();

//a real-world example of declaring a List of ‘ints’

List<int> someNumbers = new List<int>();

 

//a real-world example of declaring a List of “GameObjects”

List<GameObject> enemies = new List<GameObject>();

 

//add an item to the end of the List.

myList.Add(theItem);

 

//change the value in the List at position i

myList[i] = newItem;

 

//retrieve the item at position i

Type thisItem = List[i];

 

//remove the item from position i

myList.RemoveAt(i);

 

6.     Generic Dictionary (제너릭 딕셔너리)

 

제너릭 리스트와 마찬가지로 Unity 3.0 버전부터 iOS JS에서도 사용이 가능한 제너릭 콜렉션 이다.

제너릭 리스트가 ArrayList와 유사한 반면, 제너릭 딕셔너리는 해쉬테이블과 유사하다고 볼수 있다.
제너릭 리스트 처럼 Generic Dictionary도 선언시 아이템의 타입을 명시적으로 선언해 주어야 하며, 제너릭 리스트가 ArrayList에 비해 빠른 속도를 나타내는 것처럼 제너릭 딕셔너리도 일반 딕셔너리에 비해 동적인 형변환에 드는 시간이 없기 때문에 더욱 빠르게 작동한다.

Using 선언 하는 것은 잊지 말기

 

Ex) C#

 // declaration

Dictionary<KeyType,ValueType> myDictionary = new Dictionary<KeyType,ValueType>();

 

//and a real-world declaration example(where “person” is a custom class);

Dictionary<string,Person> myContacts = new Dictionary<string,Person>();

 

//insert or change the value for the given key

myDictionary[anyKey] = newValue;

//retrieve a value for the given key

ValueType thisValue = myDictionary[theKey];

//get the number of items in the Hashtable

Int howBig = myDictionary.count;

//remove the key & value pair ifrom the Hashtable, for the given key.

myDictionary.Remove(theKey);

 

7.     2차원 배열(2D Array)

 

내장형 배열, Javascript 배열, ArrayList , 제너릭 리스트 및 제너릭 딕셔너리가 1차원인 자료형인 반면에 2차원 배열은 제목 그대로 2차원을 지원하는 배열 자료형이다.

게임에서는 타일 인덱스를 저장하기 위한 레벨의 맵 데이터가 이러한 다차원 배열의 예에 속한다.

다차원 배열은 크게 두 종류로 구분할 수 있다.

첫번째는 말 그대로 다차원 배열이 경우로 이 경우에는 myArray[x][y]에서와 같이 고정된 x y값의 크기가 필요하다.

다른 것으로는 jagged 배열이 있는데, 이 경우에는 실제로는 다차원이 아니지만 일차원의 배열을 다차원처럼 사용하는 방법이다.

myArray[x + y*width];

맵 데이터의 예와 같이 실제 다차원 배열을 사용하는 것이 훨씬 직관적인 경우가 있지만 다차원 배열을 중첩해서 사용하는 등의 경우에는 퍼포먼스에 영향을 미칠 수 있기 때문에 직관적이지 않더라도 퍼포먼스를 고려한다면 일차원 배열을 확장하거나 변형해서 사용하는 편이 좋다.

 

Ex)C#

 //Declaration

//a 16x 4 array of strings
string[,] myArray = new string[16,4];

 

//and a real-world declaration example( where ‘Tile’ is a user-created custom class):

 

//creat an array to hold a map of 32x32 tiles

Tile[,] map = new Tile[32,32];

 

//set the value at a given location in the array
myArray[x,y] = newValue;

 

//retrieve a value from a given location in the array.

ValueType thisValue = myArray[x,y];

 

//get the length of 1st dimension of the array
int width = myArray.GetUpperBound(0);

//get the length of 2nd dimension of the array

Int length = myArray.GetUpperBound(1);