리소스 준비
아래의 화면 갈무리와 같이 리소스를 준비합니다. 화면에 표시될 이미지 파일들과 Label에서 사용할 폰트 파일입니다. 이 예제에서는 Label에서 사용할 폰트를 `나눔고딕`체로 사용하기 위하여 `다이나믹 폰트` 기능도 함께 사용하고 있습니다. 폰트 파일은 네이버를 통해서 다운받을 수 있습니다.
스크롤 뷰 구조 구성하기
스크롤 뷰의 오브젝트 구조를 만들기 위하여 가장 먼저 NGUI의 2D UI를 준비합니다.
여기에서는 모바일 장치에 맞는 화면 크기를 기준으로 삼고 있습니다. 그래서 NGUI의 `UI Root`에 대한 `Scaling Style` 속성을 `FixedSizeOnMobiles`로 변경하고 `Manual Height`값을 800으로 설정합니다.
`UI Root` 하위에 `Scroll View` 오브젝트를 생성합니다.
`Scroll View`의 가로 크기를 700으로 설정합니다. 핸드폰 장치에서 가로뷰 형태로 진행되는 게임이라고 가정했을 때, 전체 크기가 800이므로 스크롤 영역을 700으로 지정하면 화면의 약 87% 정도를 차지하는 면적이 될 것입니다.
`Scroll View` 하위에 `Grid` 오브젝트를 생성합니다. 이 안에 각각의 아이템들이 배치되게 됩니다.
`Grid`에서 한 칸의 크기를 120x200으로 설정하기 위하여 `Cell Width` 속성과 `Cell Height` 속성을 설정합니다. 그리고 스크롤 시에 부드러운 애니메이션 처리를 위하여 `Smooth Tween` 속성을 체크합니다.
`Grid`를 선택하고 `Inspector` 창에서 `Add Component` 버튼을 누릅니다.
"NGUI > Interaction > Center Scroll View On Child" 항목을 선택하여 스크립트 컴포넌트를 추가합니다.
아이템 항목 만들기
일반적으로 `Grid`안에 포함될 아이템 항목은 여러 개의 오브젝트가 하나로 묶인 형태가 될 것입니다. 여러 개의 오브젝트에 대한 컨테이너의 역할을 할 빈 오브젝트를 씬에 추가합니다.
추가된 `GameObject`를 "UI Root > Scroll View > Grid > ... "의 하위로 위치하도록 드래그하여 배치합니다.
이 오브젝트의 이름을 `Item`으로 설정해 주고, Scale 속성을 모두 1로 초기화 합니다. Main Camera와 NGUI의 카메라가 서로 비율이 다르기 때문에 이 오브젝트가 Grid의 하위로 이동하는 순간 Scale의 비율이 변하게 됩니다.
또한 이 요소는 NGUI의 영향을 받아야 하므로, NGUI 요소들이 공통적으로 소속되는 `UI`레이어로 변경해 주어야 합니다.
이렇게 준비된 `Item` 오브젝트에게 `Drag Scroll View` 컴포넌트를 추가합니다. 이 컴포넌트는 "NGUI > Interaction" 하위에 존재합니다. 이 스크립트가 드래그 했을 때, 스크롤이 되도록 처리하는 역할을 합니다.
같은 방식으로 `Center Scroll View on Click` 스크립트를 추가합니다. 이 스크립트의 기능은 특정 항목을 클릭(터치) 했을 경우 그 요소가 Scroll View의 중앙으로 오도록 합니다. 이 기능을 원치 않는다면 이 과정을 생략해도 됩니다.
Item의 하위에 포함될 이미지를 표시하기 위하여 `Texture`를 추가합니다. 여기에서는 스크립트를 통하여 이미지를 지정해 줄 것이므로 오브젝트를 추가하기만 합니다.
이번에는 `Item`의 하위에 Label 요소를 추가합니다. 이 오브젝트는 이미지 하단에 텍스트를 표시하는 역할을 하게 됩니다.
아래의 화면 갈무리를 참고하여 Label에 나눔고딕 폰트를 연결해 줍니다.
Label의 Y축 Position을 -65로 설정하여 이미지 아래에 위치하도록 지정하여 줍니다. 다이나믹 폰트를 사용할 경우 그라디언트 처리는 오히려 텍스트를 흐릿하게 보이게 하므로 `Gradient` 속성의 체크를 해제하고, `Effect` 속성을 `Outline`으로 설정합니다. 이 속성을 사용하면 텍스트에 외각선이 그려집니다.
이 과정이 매우 중요합니다. Scroll View 하위에 포함된 요소들은 스크롤되기 위하여 사용자가 터치해서 이동시키게 될 것입니다. 이 때, 각 아이템의 항목에 대한 터치 좌표를 인지하기 위한 `Collider`가 반드시 추가되어야 합니다.
Hierachy 뷰에서 `Item` 오브젝트를 선택한 상태로 "NGUI > Attach > Collider" 항목을 선택합니다.
우리는 앞서 Gird에서 Cell Width를 120으로 설정 하였습니다. 한 칸 안에서 터치 영역의 크기도 Cell Width와 동일하게 맞춰 줍니다. 그 밖에 Scene 뷰를 보면서 Collider가 이미지와 텍스트를 온전하게 감쌀 수 있도록 Center 속성도 수정합니다.
이제 완성된 Item을 프리팹으로 등록하기 위하여 Project 뷰에 드래그 해서 넣고, Hierarch 뷰의 Item은 삭제합니다.
동적 구성을 위한 스크립트 작성
Item 프리팹을 참조하여 객체를 동적으로 생성하고 Grid에 추가하기 위한 스크립트를 다음과 같이 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | using UnityEngine; using System.Collections; public class Grid : MonoBehaviour { // `Item` 프리팹이 연결될 객체 public GameObject item; // Grid 에서 표시하고자 하는 이미지들이 저장될 Texture 배열 public Texture[] images; /** 처음 객체가 로딩될 때, 초기화 함수 호출 */ void Start () { InitItem(); } /** Grid 초기화 */ void InitItem() { // 이미지의 수 만큼 반복합니다. for ( int i = 0; i < images.Length; i++) { //일단 생성합니다. 무조건... GameObject obj = Instantiate(item, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject; //생성된 GameObject의 부모가 누구인지 명확히 알려줍니다. (내가 니 애비다!!) obj.transform.parent = this .transform; //NGUI는 자동이 너무많이 짜증나니 수동으로 Scale을 조정해줍니다. obj.transform.localScale = new Vector3(1f, 1f, 1f); // Item 하위의 자식 요소들에 대한 객체를 얻어냅니다. UITexture texture = GetChildObj (obj, "Texture" ).GetComponent<UITexture>(); UILabel label = GetChildObj (obj, "Label" ).GetComponent<UILabel>(); // 자식 객체들에게 이미지와 텍스트를 출력. texture.mainTexture = images[i]; label.text = (i+1).ToString(); } //Prefab을 생성한 이후에 Position이 모두 같아서 겹쳐지므로 Reposition시키도록 합니다. GetComponent<UIGrid>().Reposition(); } /** 객체의 이름을 통하여 자식 요소를 찾아서 리턴하는 함수 */ GameObject GetChildObj( GameObject source, string strName ) { Transform[] AllData = source.GetComponentsInChildren< Transform >(); GameObject target = null ; foreach ( Transform Obj in AllData ) { if ( Obj.name == strName ) { target = Obj.gameObject; break ; } } return target; } } |
위와 같이 작성된 스크립트를 아래의 화면 갈무리와 같이 Hierarchy 뷰의 Grid에게 컴포넌트로 등록시킵니다.
Grid에 추가된 스크립트에서 선언하고 있는 Item 객체에는 미리 만들어 둔 'Item' 프리팹을 연결해 줍니다.
Images 배열은 사이즈를 12로 설정합니다.
사이즈가 설정되고 나면 그 하위에 Element 들을 등록할 수 있는 입력칸이 늘어납니다. 이 곳에 이미지 Texture를 등록해 줍니다.
지금까지의 중간 결과 입니다.
선택한 항목 감지하기
사용자가 터치한 항목을 인식하기 위하여 다음의 스크립트를 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using UnityEngine; using System.Collections; public class ItemClick : MonoBehaviour { // Item 객체가 스스로 인식하게 될 index 값 int index; void Start() { // 일단 0으로 초기화 index = 0; // Item 객체의 부모(=Grid) 하위의 모든 자식요소(=Item들)을 스캔한다. foreach (Transform child in this .transform.parent) { // 특정 자식 요소와 나 자신이 동일하다면 반복을 멈춘다. if (child == transform) { // 여기서 멈추게 되면, 현재의 index값이 나 스스로의 번호가 된다. break ; } // 인덱스 값을 1씩 증가한다. index++; } } // 클릭했을 때 실행될 이벤트 함수 void OnClick() { Debug.Log (index + "번 째 아이템 클릭됨" ); } } |
`Item` 프리팹에 버튼과 같이 클릭했을 경우의 이벤트를 처리하도록 하기 위해서 "NGUI > Interaction > Button" 스크립트를 컴포넌트로 추가합니다.
앞서 작성한 Item.cs 스크립트로 컴포넌트로 추가합니다. 그리고 이 스크립트를 Button 스크립트의 `Notify` 속성에 연결시켜 주면, Scroll View의 항목이 터치되었을 때 Button 스크립트를 통하여 Item.cs의 OnClick() 함수가 실행될 것입니다.
결과 입니다. 스크롤과 터치시에 대한 로그 출력이 잘 되고 있습니다.
이제 즐깁시다~!!
출처 : http://www.itpaper.co.kr/?mid=unity&document_srl=14082&listStyle=viewer
'Game > Unity' 카테고리의 다른 글
[Unity3D]Physics.OverlapSphere 예제 (0) | 2014.11.26 |
---|---|
[Unity3D] NGUI와 BMFont를 이용한 데미지(숫자) 폰트 만들기 (0) | 2014.11.18 |
[Unity3D] 데이터 Path (0) | 2014.10.17 |
[Unity3D]MonoBehaviour 생명주기 (0) | 2014.10.02 |
유니티에서 장면전환시 Fade in 효과 구현 (0) | 2014.09.18 |