유니티 강좌2014. 4. 9. 06:00

(5) NGUI 기초 실습


먼저 'Chapter 2' 프로젝트에서 'Practice NGUI' Scene을 하나 생성합니다.

그리고 Hierarchy창에서 Main Camera를 지웁니다. (NGUI에서 2D UI Root을 생성했을 때 자동으로 생성되는 2D화면 용 카메라를 사용할 예정.)

그리고 NGUI > Create a New UI 메뉴를 클릭해서 UI Tool 창을 엽니다.


[그림 4-5]


UI Tool 창이 열렸으면 거기에서 기본으로 설정되어 있는 값( Layer = Default, Camera = Simple 2D) 그대로 Create Your UI 버튼을 눌러서 기본적인 UI Root를 Hierarchy에 생성합니다.

   

[그림 4-6]


그러면 Hierarchy창에 다음과 같이 4개의 오브젝트가 생성되어 있는 것을 볼 수 있습니다.


[그림 4-7]


다음으로 메뉴 NGUI > Create a Widget 메뉴를 클릭해서 Widget Tool창을 엽니다.


[그림 4-8]


[그림 4-9]


Widget 을 만들기 위해서는 먼저 Image Map. 즉, Atlas와 Font가 필요합니다.

이번 순서에서는 NGUI에서 기본으로 제공하는 Atlas와 Font를 사용해보도록 하겠습니다.


[그림 4-10]


[그림 4-10]에서와 같이 Project창에서 NGUI > Examples > Atlases > SciFi 폴더를 열어서 그 안에 있는 SciFi Atlas Prefab을 클릭 & 드래깅하여 Widget Tool창의 Atlas에 집어 넣습니다.

그리고 마찬가지로 Font 또한 SciFi Font –Normal을 클릭 & 드래깅하여 Widget Tool창의 Font에 집어 넣습니다.

   

Atlas와 Font가 지정되면, Widget이 생성 가능하다는 의미로 Add 버튼에 녹색 불이 들어옵니다.

우선 Template을 Button으로 지정한 뒤에 Add To 버튼을 눌러서 Panel의 하위 객체로 버튼을 하나 만들겠습니다.


[그림 4-11]


버튼 생성에 성공했다면, 아래의 그림과 같이 Scene창과 Game창에 버튼이 생성된 것을 확인할 수 있습니다.


[그림 4-12]


※ Widget을 생성할 때, Add To 버튼 옆에 있는 객체를 주목하시길 바랍니다.

위의 과정에서는 결과적으로 Add To [Panel]. 즉, Panel 오브젝트의 하위 객체로 생성이 되었지만, 그 이후로 Widget을 생성할 때, Add To 버튼 옆에 있는 객체를 확인하지 않으면, 버튼 안에 버튼을 또 넣는 등의 실수를 하게 됩니다.

   

다음으로는 본격적으로 UI를 더 만들어 보기에 앞서, UI Root (2D), Camera, Anchor, Panel, 이 4가지 오브젝트들의 중요한 기능을 짚어보도록 하겠습니다.

   

1) UI Root (2D)


오브젝트를 클릭해보면 UIRoot (Script)라는 컴포넌트가 들어가 있는 것을 확인할 수 있습니다.


[그림 4-13]


컴포넌트의 내용을 살펴보면 UIRoot이라는 Script 파일이 연결되어 있고 그 아래로 Automatic 선택 여부 항목과 Manual Height라는 수치가 보입니다.

   

Manual Height는 실제로 Out Put이 이루어질 Game 화면의 높이 해상도가 현재 얼마의 값인지 표시해주는 곳입니다.

   

Automatic은 실제로 Out Put이 이루어질 Game 화면의 높이 해상도에 따라서 변화될 수 있는 내부에 있는 UI 사이즈를 개발자가 셋팅한 사이즈가 시각적으로 항상 같은 사이즈 일 수 있도록 만들어준다는 의미입니다.

반대의 뜻으로 해석하자면, Automatic이 선택되어 있지 않으면, 화면의 높이 해상도가 바뀌면 안에 들어있는 UI들의 사이즈들도 변경된다는 의미입니다.

   

간단히 테스트를 한 번 해보겠습니다.

Manual Height 수치를 보면서 Game창의 높이 해상도를 낮게 맞춘 뒤에AutoMatic 체크를 풀고 화면 해상도를 높게 맞춰보면, 버튼의 크기가 커지는 것을 볼 수 있습니다.

반면에 AutoMatic을 체크 한 상태에서 화면의 높이를 변경시켜도 버튼의 크기는 변하지 않고 일정한 것을 볼 수 있습니다.


[그림 4-14]


(Height값에 따른 버튼 크기 변화)

   

이러한 화면의 높이 해상도에 따른 UI 사이즈 조절이 UIRoot (Script)오브젝트에서 대표적으로 하는 기능입니다.

   

다음 장에서는 Camera에 대해서 알아보겠습니다.



스마트 앱 전문 교육기관 스마트아카데미가 추천하는 안드로이드앱(1)

스마트 폰 삶 속으로 들어오다

정부 벤처창업지원 통해 경제 활성화 나선다

3D프린팅과 스마트네트워크는 우리생활에 어떤 영향을 미칠까?

스마트안경 웨어러블 대세되나 - 스마트아카데미

한국의 구글 핸드스튜디오 안준희 대표 - 스마트아카데미

한국의 구글 핸드스튜디오 - 스마트아카데미 (2)


   

Posted by 알 수 없는 사용자
유니티 강좌2014. 4. 8. 06:00

(4) NGUI 구성


1) Anchor

화면에 구성되는 GUI 포지션의 제로 좌표(x=0, y=0, z=0) 값의 위치를 카메라를 기준으로 어디로 할 것인지 지정해줄 수 있는 역할을 합니다.

   

예를 들어, 일반적으로 2D UI구성을 할 때는 카메라를 기준으로 좌측 상단 모서리에 제로 좌표가 있어야 작업을 하기 편할 것이기 때문에, Anchor에서 카메라상 보이는 좌측 상단 모서리를 제로 좌표로 사용하도록 지정할 수 있습니다.

   

게임이나 어플을 개발하다 보면, 메인 메뉴 버튼이나 게이지바 같은 것들이 화면의 크기와 관계없이 화면비율상 특정 위치(ex. 메인 메뉴 버튼은 화면 크기 상관없이 항상 우측아래)에 있어야 하는 경우가 많이 있는데, Anchor를 잘 사용하면 이러한 문제를 쉽게 해결할 수 있습니다.

   

2) Panel

화면을 구성하는 하나의 판입니다.

Panel에는 Sprite(이미지), Label(텍스트), Button 등 다양한 Widget들을 배치할 수 있고, 그렇게 배치됨으로써 Widget들은 Panel의 좌표를 제로 좌표로 하여 하나의 그룹으로 형성될 수 있습니다.

   

3) Widget

화면에 실질적으로 보이는 Contents들입니다.

그림, 문장, 버튼 등 다양하게 화면에 출력되는 내용들 모두를 일컫는 말입니다.

   

4) Atlas

사용할 그림들의 집합.

개발된 게임이나 앱의 이미지 리소스들을 보면, 리소스 최적화를 하기 위해서 버튼의 이미지, 스크롤 바, 팝업창의 줄무늬 등 다양한 이미지들을 모아서 하나의 그림 파일에 오밀조밀하게 배치하여 둔 것을 볼 수 있습니다.

이것이 바로 Atlas 입니다.

   

원래 Atlas를 일반적으로 제작하기 위해서는 전문 UI디자이너가 필요합니다.

포토샵과 같은 그래픽 툴을 이용하여, Atlas의 크기를 정하고 그 안에 다양한 UI이미지들을 배치한 뒤에 이미지들의 하나, 하나의 Rect값(좌표 값과 크기 값)을 모두 list화 시켜서 프로그래머와 공유하는 작업을 해야 하기 때문입니다.

그리고 원하는 UI 이미지를 화면에 배치하기 위해서는 프로그래머가 Rect List를 전달 받아서 해당 이미지를 Atlas에서 불러와, 화면에서 조립하여 보여주는 작업을 해야 합니다.

   

NGUI에서는 Atlas를 구성하고 싶은 이미지들을 선택하여 클릭 몇 번을 통해 간단히 Atlas를 구성할 수 있으며, 화면에 배치하는 것 또한 자동으로 구성되는 Rect List를 클릭만 하여 쉽게 불러다 사용할 수 있습니다.

   

5) Font

사용할 글씨체입니다.

유니티 자체에서 GUI Font 기능을 제공하고 있긴 하지만, NGUI에서는 그래픽적, 기능적으로 그보다 더 많은 퍼포먼스를 지원하고 있으며, Font Maker를 통해서 자신이 원하는 폰트를 다채롭게 사용할 수 있습니다.

   

다음 장에서는 NGUI 기초 실습에 대해서 알아보겠습니다.



스마트 아카데미 창의인재 교육 6개월 과정 등록안 -스마트 앱 전문 교육기관

스마트 앱 전문 교육기관 스마트아카데미가 추천하는 안드로이드앱(1)

스마트 폰 삶 속으로 들어오다

정부 벤처창업지원 통해 경제 활성화 나선다

한국의 구글 핸드스튜디오 안준희 대표 - 스마트아카데미

한국의 구글 핸드스튜디오 - 스마트아카데미 (2)

ICT란 무엇인가 - 스마트 아카데미

차량에서 아이폰을 쓴다면 - 스마트 아카데미

국내기업 개인정보유출 정리 - 스마트 아카데미

   

Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 31. 06:00

(1) GUI의 정의

GUI란 Graphic User Interface의 약자로 사용자 편의를 위해 시각적인 그래픽 요소로 화면을 꾸미고 배치하여 상호작용할 수 있게 만든 것을 의미합니다. GUI이전에는 컴퓨터와의 상호작용을 Text로 했었으나 점차 기술이 발달되어 그래픽으로 표현된 인터페이스를 사용함으로써 지금과 같이 상호작용 요소를 인지(cognition)하기 쉽게 되었습니다.

   

보다 쉽게 얘기하자면, 게임이나 앱에서 화면을 구성하는 버튼, 스크롤 바 등과 같이 사용자가 행동을 통해서 컨트롤을 하여 컴퓨터가 자신이 원하는 행동을 하게끔 만들 수 있는 객체나, 시계, 배터리 게이지 등과 같이 필요한 정보를 시각적으로 쉽게 확인할 수 있는 객체라고 생각하시면 됩니다.

   

   

(2) NGUI란?

NGUI는 유니티3D 개발자가 편리하게 GUI를 원하는 대로 만들 수 있게 해주는 플러그인 툴 입니다. 유니티3D 자체에도 GUI를 만들 수 있게 도와주는 기능이 있지만 복잡한 UI 구성이 어렵거나 프로그램 성능이 저하되는 경우가 있어 별도의 툴을 소개합니다.

   

Playmaker가 프로그래밍을 담당하여 초보자가 쉽게 프로그램 할 수 있는 플러그인 툴이었다면, NGUI는 GUI를 담당하는 플러그인 툴 입니다.

   

NGUI를 UI 툴로 다룰 수 있게 되면, 프로그래밍을 Playmaker로 사용하여서 손쉽게 앱을 제작할 수 있게 됩니다.

  

[그림 4-1]



(3) NGUI 설치하기

Playmaker를 설치했을 때와 같이 유니티3D를 실행한 상태에서 Ctrl + 9로 Asset Store를 연 뒤, 검색 창에서 NGUI로 검색을 하면 쉽게 NGUI를 찾으실 수 있습니다.


[그림 4-2]


여기서 NGUI를 바로 구입하실 수 있고, 구입을 하시면 바로 정품 버전으로 아무런 제한 없이 사용하실 수 있습니다.

   

하지만, 정품을 구입하기 전에 먼저 한 번 테스트 버전을 사용해보고 싶다면, NGUI제조사의 홈페이지(http://www.tasharen.com)로 가서 무료 테스트 버전을 다운 받아서 사용하시면 됩니다.


[그림 4-3]


홈페이지에서 Products > NGUI: Next-Gen UI Kit 클릭

* NGUI: Next-Gen UI Kit 페이지에서 Evaluation Version 카테고리에 있는 'Free Edition of NGUI here' 링크를 클릭하시면 무료 테스트 버전을 다운받으실 수 있습니다.

   

다운을 받으셨으면, Playmaker unitypackage를 프로젝트에 Import 시켰던 것 같이 NGUI unitypackage 파일을 Import 시켜주시면 됩니다.

   

Import가 끝난 뒤에 Playmaker와 마찬가지로 NGUI도 유니티 상단에 있는 메인 메뉴바의 빈 곳을 한 번 클릭해주면 메뉴가 나타납니다.


[그림 4-4]


   

NGUI 설치가 끝났으면, 본격적으로 NGUI 예제를 해보기 전에 먼저 NGUI의 구성요소와 그 기능을 살펴 보도록 하겠습니다.

   

다음 강의에서는 NGUI의 구성에 대해 알아보겠습니다.



스마트아카데미-시설 소개

페이스북 왓츠앱 인수

스마트 아카데미 창의인재 교육 6개월 과정 등록안 -스마트 앱 전문 교육기관

정부 벤처창업지원 통해 경제 활성화 나선다

한국의 구글 핸드스튜디오 안준희 대표 - 스마트아카데미

한국의 구글 핸드스튜디오 - 스마트아카데미 (2)

ICT란 무엇인가 - 스마트 아카데미


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 26. 06:00

3) Prefab 만들기


이제 이렇게 만들어진 큐브를 Prefab 구성을 통해서 하나 더 만들어보겠습니다.

그럼 우선 Prefab을 만들어보겠습니다.

   

먼저 Project 창에서 Create > folder 메뉴로 새 폴더를 하나 생성해준 뒤에 폴더의 이름을 Prefab이라고 지어줍니다.

그리고 Hierarchy창에서 'Cube' 오브젝트를 앞서 생성한 Prefab폴더로 드래그합니다.

그러면, 파란 상자모양의 아이콘이 달려있는 'Cube' Asset이 생성되어 있는 것을 보실 수 있는데, 이 Asset이 바로 Prefab입니다.


[그림 3-34]

   

이렇게 생성한 Prefab은 현재까지 설정한 오브젝트가 가진 모든 컴포넌트 설정을 동일하게 저장하고 있습니다. 따라서 비슷한 오브젝트를 대량으로 복제를 해야 하거나, 앱이나 게임을 제작할 때 특정 오브젝트를 어떠한 이벤트를 통해 생성할 때, 유용하게 사용됩니다.

   

'Cube' Prefab을 클릭 & 드래그 해서 Hierarchy창 안으로 넣어봅시다.

그러면 [그림 3-35]와 같이 짙은 파란색 글씨로 Prefab을 통해서 생성된 'Cube' 오브젝트를 확인할 수 있습니다.


[그림 3-35]


이 오브젝트를 기존의 'Cube' 오브젝트와 차별성을 두기 위해서 이름을 'Cube2'로 변경해줍니다.



[그림 3-36]


   

[그림 3-37]


Scene 창에서 위의 그림과 같이 'Cube2'오브젝트가 잘 배치가 되었는지 확인해보자.

   

지금까지 프로그래밍에 대한 전반적인 이해와 Playmaker를 통한 비주얼 프로그래밍 방법에 대해서 알아보았고, FSM코드를 포함한 다양한 정보를 가지고 있는 오브젝트를 Prefab으로 구성하는 방법에 대해서도 알아보았습니다.

   

다음 장에서는 GUI에 대해서 알아보겠습니다.


스마트아카데미 책 소개 - 개발자, 나를 말하다

창의융합형 교육이 대세다.

스마트아카데미-시설 소개

페이스북 왓츠앱 인수

스마트 아카데미 창의인재 교육 6개월 과정 등록안 -스마트 앱 전문 교육기관

스마트 앱 전문 교육기관 스마트아카데미가 추천하는 안드로이드앱(1)

스마트 폰 삶 속으로 들어오다

정부 벤처창업지원 통해 경제 활성화 나선다


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 25. 06:00

2) State 구성하기


Playmaker의 Editor창에 있는 State탭에서 'State 1'이라고 되어 있는 이름을 'Wait' 이라고 변경해줍니다.


[그림 3-20]


이 State가 하게 될 역할은 큐브가 바닥에 떨어지는 시간 동안 기다릴 역할을 하게 될 것입니다.


그러면 이제 기다리라는 내용의 Action을 State에 넣어서, State 구성을 완성해보겠습니다.


Playmaker Editor 창에서 State를 선택한 상태에서 State 탭을 보면 우측 하단에 Action Browser라는 버튼을 볼 수 있습니다.


[그림 3-21]


이 버튼을 클릭하면, State에 넣을 수 있는 액션들이 나열된 창을 보실 수 있습니다.

Action Browser에서 Time > Wait 메뉴를 더블 클릭해서, 'Wait' State에 추가해줍니다.

  

[그림 3-22]


'Cube'가 'Plane' 위에 떨어지는 속도는 1초 정도 걸리므로, Time의 수치는 기본으로 설정되는 1 값을 그대로 사용합니다.

그 다음, Playmaker Editor창에서 'Wait' State를 우 클릭 했을 때 나타나는 메뉴에서 Add Transition > FINISHED 메뉴를 클릭해서 FINISHED Event를 생성해줍니다.


[그림 3-23]


그리고 다시 State에 설정된 Wait 액션으로 돌아와서 Finish Event를 앞서 설정한 FINISHED Event 이벤트로 연결해줍니다.

 

[그림 3-24]


이로써, Wait 액션의 기능이 [1초 동안 기다린 다음, FINISHED 이벤트를 발동시켜라.] 라는 행동을 할 수 있게 되었습니다.

   

※Playmaker Editor에서 작업을 진행하다 보면, State에 빨간색 느낌표가 나타나는 경우가 있습니다.


   [그림 3-25]


아마 'Wait' State에 FINISHED 이벤트를 생성해준 순간 빨간색 느낌표가 나타났을 것입니다.

이 느낌표 표시는 현재의 State에 에러가 있다는 것을 의미하며, 자세한 내용은 PlaymakerEditor창의 하단에 있는 error 버튼을 누르면 확인할 수 있습니다.


[그림 3-26]


[그림 3-26]에서 에러 내용을 살펴보면 ['Cube'오브젝트에 있는 'FSM CUBE POSITION RESET' FSM의 'Wait' State에 설정된 이벤트 중, 타겟이 될 State에 연결되지 않은 것이 있다.] 입니다.


State에 설정되는 이벤트들은 어떠한 상황이 일어난 것을 액션에서 감지하고, 그 액션에서 [현재의 상태를 특정 이벤트가 타겟으로 잡고 있는 상태로 변화하라.]는 명령을 실행할 때, 타겟을 잡아주는 과정에 포함되기 위해서 존재합니다.


앞서 설정한 'Wait' State의 경우에는 FINISHED 이벤트가 설정된 이유가 [1초 동안 기다린 후, FINISHED 이벤트가 타겟으로 잡고 있는 상태로 변화하라.] 라는 명령을 구성하기 위해서 입니다.

그런데, 정작 FINISHED 이벤트에 연결된 다음 상태가 없기 때문에 에러가 나타난 것입니다.

   

이제 다음 State를 하나 더 만들어 준 후에 State 이름을 'Reset Cube Position'이라고 이름을 지어줍니다.

그리고 'Wait' State의 FINISHED 이벤트를 클릭 & 드래그를 해서 화살표를 꺼낸 뒤, 'Reset Cube Position' State에 연결시켜줍니다.


[그림 3-27]


[그림 3-28]


그 다음 'Reset Cube Position' State를 선택하고 Action Browser 창을 Open 한 뒤, Transform 카테고리에서 Set position 액션을 찾아서 더블 클릭하여 'Reset Cube Position' State에 삽입합니다.

  

[그림 3-29]


※ Action의 카테고리 종류와 그 안의 내용 배치에 대해서 다 이해할 수 있을 때까지는 검색기능을 사용하기보다, 직접 카테고리를 클릭해서 열어보며 액션들과 카테고리의 연결점에 대해서 생각해보는 것이 좋습니다.

   

그리고 삽입한 Set Position 액션에서 Y축 입력 칸의 우측에 있는 변수 사용(Use Variable) 버튼을 눌러서 해제 상태로 만들어준 뒤, 절대값 2를 입력합니다. (2를 입력하는 이유는 Cube를 선택하고 Inspector창에서 Transform을 확인해보면 큐브가 떨어지기 전에 셋팅되어 있는 Y축 좌표 값이 2이기 때문입니다.)


[그림 3-30]


이렇게 설정된 Set Position 액션의 내용을 설명하자면 다음과 같습니다.

① 움직여야 할 Game Object는 Use owner (FSM이 존재하는 오브젝트. 즉, 'Cube' 자기 자신)

② 움직여야 할 위치는 Y축으로 변수 값이 아닌 절대값 2만큼

③ 움직일 때 참고할 방향 좌표는 World를 기준으로


[그림 3-31]


이제 플레이 버튼을 눌러서 어떤 결과가 나타나는지 확인해봅시다.

Game창에 보이는 화면에서 'Cube'가 'Plane' 위에 떨어졌다가, 다시 원래의 위치로 되돌아가서 떨어지는 것을 보실 수 있습니다.

Playmaker Editor창을 보면 초기에 Start > 'Wait' State에 녹색빛이 머물렀다가, 1초 뒤에 'Reset Cube Position' State로 이동하는 것을 볼 수 있습니다.

   

※ 오브젝트에 FSM 컴포넌트가 들어간 이후에는 Scene 창에서 오브젝트를 보면 PlayMaker 로고가 반투명하게 표시되어 보이는 것을 보실 수 있습니다. 이 로고가 오브젝트를 가려서 거슬리는 분들은 아래의 그림과 같이 Scene창에서 Gizmos버튼을 클릭했을 때 나오는 메뉴에서 PlaymakerFSM의 체크를 풀어주면 됩니다.

 

[그림 3-32]


다음으로 큐브가 한 번만 포지션이 리셋되는 것이 아니라, 떨어질 때마다 매번 포지션이 리셋이 되도록 한 번 만들어 보겠습니다.

   

먼저 Playmaker Editor 창에서 'Reset Cube Position' State를 우 클릭 했을 때 나타나는 메뉴에서 Add Transition > FINISHED 메뉴를 클릭해서 FINISHED Event를 생성해줍니다.

그리고, FINISHED Event를 클릭 & 드래그하여 'Wait' State를 타겟으로 하도록 연결시켜 줍니다.


   [그림 3-33]


   그리고 다시 플레이 버튼을 눌러서 매 1초마다 큐브의 위치가 잘 Reset 되는 지를 확인해봅시다.

   

※'Reset Cube Position' State는 내부에 있는 액션이 Finished Event를 설정할 수 없는 액션이 없는데도 불구하고, FINISHED 이벤트가 타겟으로 설정하고 있는 'Wait' State로 상태 변환이 잘 일어나는 것을 볼 수 있습니다.

그 이유는 시스템에서 기본으로 제공하는 FINISHED 이벤트는 State 내에 Every Frame 과 같이 지속적으로 체크를 해줘야 하는 액션설정이 존재하지 않는 이상 자동으로 다음 State로 처리과정을 넘겨주는 기능을 가지고 있기 때문입니다.

만약, State내에 지속적으로 체크를 하는 속성의 액션이 있다면, Wait이나 Send Event 액션으로 Finished Event를 설정해줘야 처리과정을 다음 State로 넘길 수 있습니다.

   

다음 강좌에서는 Prefab 만들기에 대해 알아보겠습니다.


스마트 아카데미 '스마트 앱 개발' 교육과정 안내

스마트 앱 개발 학원 국비지원 안내

K팝 홀로그램 상설공연장 개소

구글의 네스트 인수 의미

스카이 아카데미 취업 정보 - 선데이토즈 이야기

창의인재과정 안내

미래창조과학부 창조경제 실현

크리에이티브 UX교육 훈련과정 안내


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 24. 06:00

(6) PlayMaker 사용해보기


1) FSM 만들기.


1강에서 연습했던 프로젝트 파일을 열고, 그 안에 설치된 Playmaker를 활용해서 간단하게 어떤 구조로 비주얼 프로그래밍이 이루어지는지 살펴보도록 하겠습니다.

   

PlayMaker > PlayMaker Editor 메뉴를 사용해서 Playmaker Editor 창을 엽니다.


[그림 3-13]



[그림 3-14]


위의 그림과 같이 창이 열리면 해당 창을 유니티 인터페이스 안에 적절하게 공간을 할당하여 배치합니다.

에디터 창의 안을 보면 'Select a GameObject'라는 글씨를 볼 수 있는데, 현재 Hierarchy창에서 아무 오브젝트도 선택한 상태가 아니라면 이와 같은 메시지가 나타나게 됩니다. Hierarchy창에서 'Cube' 오브젝트를 선택하면 다음과 같이 내용이 변경됩니다.


[그림 3-15]


'Right-Click to Add FSM' 이 말은 즉, 현재의 창에서 마우스 우측 버튼을 클릭해서 FSM을 생성하라는 뜻입니다.


이 말이 설명하는 대로 창에서 마우스 우측 버튼을 클릭해서 FSM을 생성해보겠습니다.


[그림 3-16]


마우스 우측 버튼을 클릭했을 때, 나오는 메뉴에서 Add FSM을 클릭하면 FSM이 생성됩니다.


[그림 3-17]


FSM을 생성했다면 위의 그림과 같이 Start 라는 이름의 State와 State 1 이라는 이름의 State가 생성된 것을 볼 수 있습니다.


그리고 큰 회색 글씨로 쓰여있던 'Right-Click to Add FSM'이라는 메시지도 'Cube: FSM'이라는 내용으로 바뀐 것을 볼 수 있습니다. (즉, 'Cube' 오브젝트에 'FSM'이라는 이름의 FSM이 생성된 것입니다.)

이제 본격적으로 FSM 프로그래밍을 할 준비가 되었습니다..

   

이제 'Cube: FSM' Edit창에 있는 FSM 탭을 클릭한 뒤, 'FSM'만 적혀있는 이름 칸의 내용을 'FSM CUBE POSITION RESET'으로 바꿔봅시다.


[그림 3-18]


이렇게 이름을 바꿔주면, 큰 회색 글씨로 쓰여있던 'Cube: FSM'이라는 메시지도 바뀐 것이 보일 것입니다.

이렇게 생성된 'FSM CUBE POSITION RESET' FSM이 컴포넌트로 큐브에 잘 들어가 있는지 확인해봅시다.


[그림 3-19]


Hierarchy창이나, Scene창에서도 Playmaker 로고를 통해 FSM이 존재하는 오브젝트라는 것을 확인할 수 있습니다.


다음 강좌에서는 첫 번째 State의 구성에 대해 알아보겠습니다.


우아한 형제들 김봉진 대표 - 앱 개발 전문 학원 스마트 아카데미

창의융합형 교육이 대세다.

창조경제시대 왜 코딩교육인가 - 스마트 아카데미

페이스북 왓츠앱 인수

스마트 앱 전문 교육기관 스마트아카데미가 추천하는 안드로이드앱(1)

스마트 폰 삶 속으로 들어오다

3D프린팅과 스마트네트워크는 우리생활에 어떤 영향을 미칠까?


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 18. 06:00

플레이메이커(PlayMaker) 설치하기

   

유니티3D는 통합 툴로써 비교적 저렴하고 좋은 툴이지만 여전히 프로그래밍을 C나 Java를 배우거나 할 줄 알아야만 사용할 수 있습니다. 즉 C#이나 Java script 를 잘 하지 못하면 유니티3D의 다양한 기능을 사용하여 앱이나 게임을 만들 수 없습니다. 이러한 프로그래밍은 한 두 달 또는 몇 주 만에 아주 잘하게 되어 자신이 생각하는 앱이나 게임을 구현하는 수준이 되기 어렵습니다. 


또한 그러한 프로그램을 배우는 것이 쉽지 않기에 거의 불가능하다고 하겠습니다. 따라서 프로그램을 전혀 할 줄 모르는 아주 초보자가 자신이 생각하는 앱이나 게임을 만들기 위해서는 유니티3D 메뉴사용법만 알아서는 안됩니다.


이 책에서는 어려운 C#이나 Java Script와 같은 텍스트(Text) 프로그래밍이 아니라 누구나 따라하고 쉽게 이해하여 자신의 논리를 컴퓨터에 구현할 수 있는 비주얼(Visual) 프로그래밍을 하려고 합니다.


이 비주얼 프로그래밍은 여러 가지 툴들이 나와 있습니다. 유니티3D와 같이 사용할 수 있는 플러그 인에서도 Playmaker, UScript, Antares Visio등 몇 개의 툴이 있습니다. 이들 중 초보자가 사용하기에 편리하다고 생각되고 또 재사용성 측면에서 훌륭하다고 생각하는 툴은 플레이메이커입니다.

   

이제 플레이메이커를 다운받아 설치하겠습니다.

   

유니티3D를 실행한 상태에서 Ctrl+9 단축키를 사용해서 Asset Store를 오픈 합니다.

그리고 우측 상단에 있는 Search 칸에서 "Playmaker" 로 검색을 합니다.

[그림 3-3]


검색 결과 [그림 3-4]와 같이 PlayMaker가 나오면, 클릭해서 구입을 하시면 됩니다.

[그림 3-4]


PlayMaker를 다운받으면 아래의 그림과 같이 패키지 파일을 볼 수 있습니다.


이 패키지 파일은 플러그인 형식을 띄고 있으며, 유니티에 Import해서 사용할 수 있습니다.

그럼, 이런 패키지 파일을 유니티에 Import 하는 방법을 알아보겠습니다.


[그림 3-5]


위의 [그림 3-5]와 같이 유니티 창 상단 메뉴에서 Asset > Import Package > Custom Package 메뉴를 클릭해서 패키지 로드 창을 오픈 합니다.


[그림 3-6]


그리고 컴퓨터에 저장되어 있던 PlayMaker 패키지 파일을 선택하여 열기 버튼을 누릅니다.


Unity에서는 한글을 기본적으로 지원하지 않습니다.

따라서, 파일을 읽는 경로나, 저장경로에 한글이 있어서는 안되며, 파일의 이름도 한글로 만드시면 로딩 시 에러가 발생할 수 있으니 주의하시기 바랍니다.


그리고 한 번의 로딩이 끝난 후, 다음 그림과 같이 Importing package 창이 나타나면, Import 버튼을 눌러서 PlayMaker 플러그인 설치를 마칩니다.

  

[그림 3-7]


Import가 끝나면 Project 창에 우측 그림과 같이 플레이 메이커 Asset들이 생성된 것을 확인할 수 있습니다.


[그림 3-8]


[그림 3-9]


그리고 상단 메뉴 바의 비어 있는 부분을 한 번 클릭하면, 위의 그림과 같이 PlayMaker 메뉴가 생성되는 것을 볼 수 있습니다.

   

※ Import Package 메뉴 아래에는 Export Package라는 메뉴가 있습니다

 


[그림 3-10]


 

   

이 메뉴는 현재 내가 Project 창에서 선택하고 있는 Asset을 패키지 파일로 만들어 주는 메뉴 입니다.

다른 프로젝트를 개발할 때, 이전 프로젝트 개발에 사용했던 Asset 중 필요한 것이 있다면, 이런 식으로 Export 시킨 후, Import로 불러다가 사용할 수도 있습니다.


다음강좌에서는 Finite State Machine(FSM)에 대해 알아보겠습니다.


구글의 네스트 인수 의미

스카이 아카데미 취업 정보 - 선데이토즈 이야기

미래창조과학부 창조경제 실현

우아한 형제들 김봉진 대표 - 앱 개발 전문 학원 스마트 아카데미

창의융합형 교육이 대세다.

스마트아카데미-시설 소개

페이스북 왓츠앱 인수

정부 벤처창업지원 통해 경제 활성화 나선다


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 17. 06:00

프로그래밍의 구조


(3) Data Type


비주얼 프로그래밍이 어떤 것인지 배우기 이전에, 프로그래밍이라는 것이 어떤 구조로 이루어져 있는지 그림과 함께 컴퓨터의 부품으로써 역할 분류로 간략히 알아보았습니다.


컴퓨터는 정보(Information)의 저장과 가공을 편리하게 하기 위하여 약속된 저장방법, 즉 데이터(Data)를 사용합니다. 컴퓨터는 이진법 즉 0,1의 기호(bit)를 사용하여 정보를 최종적으로 저장 및 처리하지만 지금은 이러한 비트나 바이트가 아닌 정보의 측면에서 데이터를 표현하고자 합니다.


정보의 처리를 위하여 프로그래밍을 하다 보면, 필수적으로 사용하게 되는 변수(Variables)라는 것이 있습니다. 변수는 말 그대로 변할 수 있는 수를 뜻하며, 프로그램에서 변수는 단순한 숫자가 아니라 문자, 진실과 거짓, 위치 등 다양한 형태가 변하므로 이것들을 변수로 사용할 수 있습니다.


이러한 변수들은 어떻게 사용되며, 어떻게 프로그램에서 데이터로 활용되는지 간단하게 알아 보겠습니다.

   

자판기를 예를 들어보겠습니다.



 

자판기에서 음료수를 꺼내는 우리들의 행동을 먼저 생각해봅시다. 자판기에서 음료수를 꺼내기 위해서는 돈을 넣어야 하고, 내가 넣은 돈의 액수에 맞는 음료수를 선택해서 버튼을 누르면 음료수가 나오게 됩니다.

   

그럼 이제 자판기의 입장에서 어떻게 행동을 하는지 생각해보겠습니다.


먼저 돈이 들어오는 것에 대한 이벤트를 체크해야 합니다. 그렇게 해서 돈이 들어왔을 때, 현재 내가 받은 돈이 얼마인지 확인해서 내가 가진 제품들 중 어떤 것들이 판매가 가능한지 확인을 해야 합니다.


그리고 판매가 가능한 제품들을 소비자가 선택할 수 있게 버튼에 불을 켜주고, 소비자가 버튼을 클릭했을 때, 해당 제품을 소비자에게 제공한 뒤, 다시 한 번 남은 돈을 체크해서 어떤 제품들이 판매가 가능한지 체크해서 버튼의 불을 켜줍니다.


마지막으로 소비자가 거스름 돈을 받기 위한 레버를 돌렸다면, 남아있던 돈들을 체크해서 500원, 100원, 50원, 10원 단위로 빼기 계산을 하여 가장 큰 동전 단위부터 거스름 돈을 거슬러주는 것으로 자판기의 역할이 종료됩니다


이런 자판기의 행동에서 변수는, 돈이 들어 왔는지, 들어오지 않았는지에 대한 사실을 실시간으로 체크하여 판별하여 True or False로 값을 저장하고 있는 것도 변수이고, 들어온 돈의 액수를 체크하여, 어느 가격대의 제품까지 불을 켤 것인지 결정할 수 있게 해주는 돈의 액수를 저장하는 부분도 변수입니다.


이처럼 데이터의 역할은 프로그램이 다음 행동을 하기 위해 상황을 판별하기 위한 조건 값의 역할을 하며, 대표적으로 아래와 같은 타입들이 존재합니다.

   

1) Int

Integer(정수) 값으로 이루어진 수로 구성되는 변수 타입입니다.

소수점 변수는 CPU와 램에 주는 연산의 부담이 크기 때문에, 단순한 카운트의 역할 등 정수만으로도 충분히 사용이 가능한 변수 부분은 Int 타입의 변수를 사용합니다.

Ex) 1, 2, 3, 199, -1, -12 ……

   

2) float

floating point (부동 소수점, 소수). 즉, 정수가 아닌 소수점이 있는 실수들이 바로 float 입니다.

물체가 위치한 좌표, 회전값, 등 세세하게 표현이 이루어져야 하는 부분들의 수치를 비교나 계산할 때 float 변수 타입을 사용합니다.

Ex) 0.02, 300, 1.1, 5.223, -1000.1124……

   

3) bool

ture or false. 즉, 어떠한 상황에 대해서 참과 거짓을 판별하여 그 결과에 따라 어떤 행동을 해야 할지 결정할 때 사용되는 변수 타입이 bool 타입입니다.

   

4) String

단어나 문장과 같은 문자열을 조건으로 비교하거나, 화면에 출력하기 위해서 그 텍스트 값을 담을 수 있도록 해주는 것이 String 변수 타입 입니다.

Ex) This is a string, Hello world……

   

5) Vector3

Vector3는 3차원 좌표계를 표현하는 단위이며, X, Y, Z의 축에 대한 좌표를 3개의 float number 값으로 표현한 형태를 말합니다. 오브젝트의 좌표, 목표가 되는 특정 지점 설정 등을 표현하거나 계산할 때 Vector3 변수 타입을 사용합니다.

Ex) (1.0 , 2.5 , 3.5)

   

6) Object

Object는 씬에서 역할을 수행하는 하나의 객체를 뜻합니다. Unity에서는 Hierarchy에 나타나는 모든 Game Object가 Object입니다.


다음 강좌에서는 플레이메이커(Play Maker)의 설치에 대해 알아보겠습니다.


 APP 개발 온라인 강좌 - 제1강 모바일 개발 환경과 Tool 소개 [1-1]

스마트 앱 개발 학원 국비지원 안내

스마트 아카데미 '스마트 앱 개발' 교육과정 안내

K팝 홀로그램 상설공연장 개소

창의인재과정 안내

미래창조과학부 창조경제 실현

크리에이티브 UX교육 훈련과정 안내

우아한 형제들 김봉진 대표 - 앱 개발 전문 학원 스마트 아카데미

창의융합형 교육이 대세다.


Posted by 알 수 없는 사용자
유니티 강좌2014. 3. 10. 06:00

6)물리 컴포넌트 구성하기


이제 큐브에 물리 컴포넌트를 넣어보도록 하겠습니다.

큐브에 물리 컴포넌트를 넣기에 앞서 먼저 큐브가 물리작용을 일으킬 수 있는 조건을 충족시키기 위해서 플랜을 생성하여 바닥의 역할을 하게 바닥에 깔아보도록 하겠습니다.

   

- GameObject > Create Other > Plane를 사용해서 플랜을 하나 생성해주세요.

그리고 Inspector창에서 아래의 그림과 같이 Transform 정보를 깔끔하게 다듬어줍니다.



플랜을 정렬하고 나면, 아래의 그림과 같이 큐브와 플랜이 맞물려 있는 상태가 되는데, 이는 큐브와 플랜 모두가 Y축 포지션 좌표가 0이라서 나타나는 현상입니다.



이러한 문제를 고치기 위해서, 큐브들의 Y축 좌표를 2로 만들어 줍니다.



그리고 플레이 버튼 을 눌러보세요.

   

위의 그림처럼 아무런 미동도 없이 3개의 오브젝트가 화면에 잘 보이고 있다면, 정상입니다. 혹시, 이것저것 연습을 하면서 지우지 못한 컴포넌트가 있어서 오브젝트들이 움직임을 보인다거나, 위치나 회전 값이 이상해지는 현상이 나타난다면 앞으로 가셔서 다시 차근히 위의 그림처럼 화면이 구성되게 세팅해주세요.

   

이제 본격적으로 큐브에 물리 컴포넌트를 넣어보겠습니다.

-'Cube'오브젝트를 선택한 다음, Inspector 창에서 Add Component > Physics > Rigidbody를 클릭해서 'Cube'에 Rigidbody 컴포넌트를 추가합니다.



Rigidbody는 생성과 동시에 자동으로 Use Gravity가 체크가 되어 있어, 큐브에 중력이 적용되도록 만드는 것을 볼 수 있습니다.

- 플레이 버튼을 눌러서 Rigidbody 컴포넌트로 인해 큐브가 어떻게 움직이는지 확인해봅시다.



위의 그림과 같이 'Cube' 오브젝트가 플랜 위로 떨어졌다면, 정상적으로 Rigidbody가 적용된 것 입니다.

※ Rigidbody에서 Mass(무게), Drag(저항), Angular Drag(공기저항)의 값을 바꿔보고 Is Kinematic(물리작용 제외) 체크를 해보고, 풀어보면서 플레이 버튼을 눌러봅시다.

   

그리고 그런 행동에 따라 큐브가 어떤 물리적 속성을 가지게 되는지 확인해봅시다.

   

-이제 그 옆에 있는 'Cube1'에도 Rigidbody를 넣어봅시다.

그리고 플레이를 눌러봅시다.



플레이 화면에서 위의 그림과 같이 'Cube1'이 Plane을 뚫고 내려가는 것을 볼 수 있습니다.

왜 그럴까요?

잘 모르겠다면, 두 개의 큐브의 컴포넌트 상태를 비교해보면 정답을 알 수 있습니다.

   

'Cube'는 충돌 체 역할을 하는 Collider가 있지만, 'Cube1'은 없는 것을 확인할 수 있습니다. 따라서, 'Cube1'에도 Box Collider를 생성해서 충돌체가 존재하도록 해줍니다.

   

그리고 다시 플레이 버튼을 눌러서 확인을 합니다.



상위 그림과 같이 두 개의 큐브가 떨어져서 플랜 위에 멈춰있다면, 정상으로 수정이 된 것입니다.

   

7)컴포넌트에 대한 개념 정리


앞서서 우리는 다양한 컴포넌트를 만들어 봤습니다.

카메라 컴포넌트, 모델 형태 컴포넌트, 모델 렌더링 컴포넌트, 충돌 컴포넌트, 물리 컴포넌트……

이처럼 컴포넌트는 게임 오브젝트라는 그릇 안에서 다양한 형태로 존재하며, 씬에서 오브젝트의 활동, 또는 씬에서 일어나는 특수한 이벤트 등을 관리하는 역할을 합니다.




APP 개발 온라인 강좌 - 제1강 모바일 개발 환경과 Tool 소개 [1-1]

APP 개발 온라인 강좌 - 제1강 모바일 개발 환경과 Tool 소개 [1-2]

APP 개발 온라인 강좌 제1강 - 모바일 개발 환경과 Tool 소개 [1-3]

APP 개발 온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-1]

APP 개발 온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-2-1]

APP 개발 온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-3,4] -씬 만들기와 오프젝트 만들기

APP 개발 온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-5] -큐브(상자)씬 만들기


Posted by 알 수 없는 사용자
창의교육2014. 2. 19. 11:07

창조경제가 뜨면서 초등학교 코딩 교육이 이슈가 됐습니다. 실효성 논란이 있지만 '창조경제의 선봉' 미래창조과학부는 초등학생들을 대상으로한 프로그래밍 교육에 적극 나설 방침입니다.

 

윤종록 미래창조과학부 제2차관은 초등학생 코딩 교육과 관련해 영국의 사례를 주목해왔다며국에 적용할만한 '거리'가 많다고 했습니다. 영국은 내년 9월부터 전국 초등학교 정규 교과목에 코딩 수업을 포함시킬 예정입니다.


   


지난 7월 영국 교육부장관 마이클 고브는 5세에서 14세 학생들에게 적용되는 새로운 교과과정을 발표했습니다. 이에 따라 5살부터 간단한 프로그램을 작성하고 테스트하고 또 데이터를 저장하고 검색하고 구성하는 법을 배우게 됩니다. 11세 이상 학생들은 실제 프로그래밍 언어를 교육받게 됩니다.

 

고브장관은 "컴퓨터 프로그래밍 교육을 통해 우리 아이들이 글로벌 레이스에서 경쟁력을 갖출 수 있게 될 것"이라고 도입 취지를 밝혔습니다.



   


이런 가운데 영국의 가디언은 내년부터 시행될 초.중교 컴퓨터 프로그래밍 의무 교육과정 도입을 앞두고 민간기관을 주축으로 운영되고 있는 방과후 코딩교육 프로그램을 소개해 눈길을 끌었습니다.

 

영국의 경우 이미 초등학생 때부터 코딩을 가르치는 시도가 민간에서도 활발한 상태입니다. 현재 1천300여 초등학교에 방과후 교육과정을 무료로 운영 중인 '코드클럽'이 대표적입니다.

 

코드클럽은 웹 디자이너 클레어 서트클리프(Clare Sutcliffe)와 웹 프로그래머 린다 샌드빅(Linda Sandvik)이 지난 2012년 4월 만든 비영리단체입니다. 방과후 코딩 교육을 원하는 학교에 무료로 클럽을 개설해 주고 자원봉사자들이 교사로 뜁니다.

   

서트클리프는 "학교에서 코딩을 가르치지 않는 것을 걱정했고 9~11살 아이들에게 코딩을 배울 수 있는 기회를 주자는 단순한 아이디어에서 시작했다"고 말했습니다. 코딩 클럽은 처음에는 22개 초등학교에만 대상으로 했지만 현재는 영국 전역에 1천300여 학교에서 운영 중이다. 또 전 세계에 적어도 100개 이상의 클럽이 운영 중입니다.





영국의 학생들은 수업이 끝난 오후 3시30분 학교 컴퓨터 실습실로 아이들이 모였고, 초급반 아이들을 위한 코딩 수업 교실이 시작하였습니다. 각자 컴퓨터 앞에 앉아 소프트웨어를 열고 아이들은 '스크래치'라고 불리는 간단한 코딩 프로그램을 다뤘습니다.

   

스크래치는 MIT미디어랩이 학생들을 위해 개발한 언어로 레고 블록처럼 생긴 명령어를 테트리스 조각을 맞추듯 끼워 넣는 식으로 코드를 만들 수 있습니다. 온라인에서 누구라도 무료로 이용할 수 있습니다.

   

설립자 서트클리프는 "아이들이 개발자가 되지 않는다해도, 문제해결과 논리적 사고를 키워주는데 도움이 되기 때문에 컴퓨터 언어적으로 생각하는 것은 중요하다"고 말했습니다. 기자는 이런 활동이 코드클럽의 취지를 정확하게 보여준다고 전했습니다.

   

실제 교사들은 코드클럽에 참여한 아이들이 새로운 것을 배우는데 두려움이 없고 모든 교과목에서 자신감을 키우고 있다는 일화적 증거가 있으며 특히 과학과목에서 코딩을 배운 아이들의 강점이 두드러진다고 말하고 있습니다.

   

학교에 따르면 지역에서 코드 클럽은 상당히 유명해졌습니다. 다른 학교의 부모들이 아이를 코드 클럽에 등록하고 싶다는 문의가 많지만 이미 대기자 명단이 꽉 차있는 상태입니다. 또 집에 컴퓨터가 없는 아이들이 지역 도서관에 프로그램을 다운받아 코딩을 하는 바람에 도서관 사서가 학교 교장실로 이런 현상이 적절한 것인지 문의하는 해프닝도 생겼습니다.

   

영국에는 코드클럽 외에도 7세부터 18세 이하 학생들이 개발자로 발아할 수 있도록 돕는 '영리워드스테이트'라는 프로젝트도 있습니다. 전세계적으로 코딩이 정규 교육과정에 포함된 사례가 거의 없었으나 최근 들어 세계 각국이 이를 추진하는 모습입니다. 지난 10월 에스토니아가 첫 번째로 7세 이상의 모든 공공 교육을 받는 학생들이 프로그래밍을 배우도록 하겠다고 발표한 것이 처음입니다.   

 

서트클리프 코딩 교육이 개발자 군단을 양성하기 위한 목적으로 이뤄지는 것보다 아이들에게 문제 해결을 방법을 가르치는 도구가 돼야 한다고 강조합니다. 그는 홈렌팅업체인 에어비앤비(Airbnb)의 공동창업자 겸 CTO인 네이선 블레차르지크의 예를 들어 설명했습니다.

 

에어비앤비는 현재 1억달러의 가치를 인정받고 있는 회사로 네이선 블레차르지크는 12살 때 혼자 코딩을 배웠고 14살 땐 고객을 위한 소프트웨어를 만들었습니다.

   

 

블레차르지크는 "너무 많은 기술과 지식을 주입식으로 배우기 보다는 실제 세계에 발생한 문제를 해결하기 위해 기술을 적절히 적용하는 방법을 연습하는 것이 더 중요하다"고 말합니다. 그는 또 "필요한 기술은 아주 기본이 되는 요건만 충족하면 되고, 문제를 해결하기 위해 기술을 어떻게 적용할지에 대한 비전과 창의성이 다음 단계이며 더 고차원의 기술"이라고 덧붙였습니다.

   

 

서트클리프가 네이선 블레차르지크의 말을 보탠 이유는 코딩을 배우는 것이 곧 성공한 IT CEO를 만드는 전부가 아니라는 점을 강조하기 위해서다. 그는 더 중요한 것은 기술을 이용해 문제를 해결할 수 있는 창의력을 키워야 한다는 점을 부각했습니다.





스마트아카데미-시설 소개

온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-3,4] -씬 만들기와 오프젝트 만들기

스마트아카데미 책 소개 - 개발자, 나를 말하다

창의융합형 교육이 대세다.

APP 개발 온라인 강좌 제2강 - 유니티의 기본 구성 및 조작법 [2-1]

우아한 형제들 김봉진 대표 - 앱 개발 전문 학원 스마트 아카데미



Posted by 알 수 없는 사용자