이러한 방식은 간단하게 설정하고 하나의 프로젝트에서 써먹기 좋다. 하지만 여러 프로젝트를 진행해야 하는 상황이라면 지속적으로 lib를 복사해야 하는 귀찮음이 있을 수 있다. (물론 위에서 제시한 방법도 진행해보고 환경변수 설정을 활용한 방법도 진행해봄으로써 실제 상용 프로그램을 만들 때 필요한 프로그램이 무엇인가를 아는 것도 중요하다.)
시스템 환경변수 설정
컴퓨터 시스템은 스스로 할 수 있는 일이 별로 없다. 그래서 우리가 하나하나 알려줘야 한다. "어? 지금까지는 컴퓨터가 알아서 해줬는데요?" 그것은 다른 프로그래머가 하나하나 설정해준 것이므로 이제 우리도 하나하나 할 때가 되었다.
무언가를 시작할 때, 어디에 있는지 알아야 시작하지 않겠는가? 그것이 바로 환경 변수이다. 이름이 환경변수인 이유는 영어를 직역해서 그렇다. (Environment variable)
윈도우10 기준으로 제어판 -> 시스템으로 들어가자.
그곳에서 시스템 정보를 클릭
이렇게 생긴 모습이 나올 것이며, 거기서 고급 시스템 설정을 눌러주자.
딱 대놓고 환경 변수라고 나와있다.
하나의 계정에다가만 만들 것이 아니라 시스템 자체에 추가하려고 하니 '시스템 변수'에다가 추가하도록 하겠다. (위, 아래 칸 두 개가 있다고 당황하지 말자, 위에는 특정 사용자에 해당하는 변수 설정이며, 아래에는 시스템 전체에 해당하는 변수이다. 위에다가 해도 상관없지만, 윈도우 계정 로그아웃 시 환경변수 설정을 다시 해야 한다.) 새로 만들기를 눌러준다.
앞으로의 세 개를 연달아 입력해준다. 다만 필자는 C에다가 압축해제를 해두었으므로 C:\opencv를 놓은 것이니 만약에 D라면 D:\opencv로 진행하도록 하자. 혹은 폴더에 두는 사람도 있는데
D:\opencv\opencv의 형태가 있을 수도 있다. 본인의 상황에 맞는 것으로 하자.
각각의 변수에다가 폴더의 경로를 저장해주는 형태이다.
그 다음으로 시스템 변수 - path를 더블 클릭하자.
그리고서 아까 저장한 OPENCV_DIR 를 아래 처럼 입력해도록 하자.
아까 우리는 OPENCV_DIR = C:\opencv를 저장해두었으니, 아래에 경로명에는
C:\opencv\build\x64\vc15\bin 의 경로가 생성되는 것이다.
우리는 컴퓨터에게 친절하게 알려줄 필요가 있다. 엄마! 내 OO 어딨어!?
확인을 누르고 나면 기본적인 환경설정은 마무리가 되었다.
이제 제대로 설정이 되었는가를 확인하기 위해 CMD (명령 프롬프트)를 켜도록 하자. 윈도우 10이라면 아래에 검색에서 cmd라고 치면 나온다.
제대로 설치가 되었다면 버전이 나온다. 그렇지 않다면 찾을 수 없다는 메시지가 나올 것이다.
Visual Studio 설정하기
프로젝트 -> [프로젝트 이름] 의 속성으로 가보자
*필자는 프로젝트 이름을 opencv_project라 지은 것이다.
1.
창이 열리고 나면, C/C++ → 일반 탭에서
추가 포함 디렉터리에다가 $(OPENCV_INC)
아까 시스템 변수에 저장된 값을 지정해주도록 해야 합니다.
2.
그 다음으로 링커 → 일반에서 추가 라이브러리 디렉터리에
$(OPENCV_LIB)
를 입력하도록 합니다. 이 변수도 위에서 시스템 변수에서 적용한 값이죠.
3. 마지막으로 링커 → 입력에서 추가 종속성을 입력해주도록 합니다.
lib를 연결해주는 역할을 합니다. 여기서 주의하실 점은 opencv의 버전에 따라 이름이 조금씩 다릅니다.
C:\opencv\build\x64\vc15\lib
저의 설치 경로는 이렇게 설치했으며, 직접 가셔서 확인해보는 것이 가장 좋습니다.
두 개가 있으며, d가 붙은 버전과 아닌 버전이 있는데, d가 붙어있으면 debug이며, 안 붙어있는 lib는 release 모드에서 사용됩니다. 둘 다 입력해주도록 합니다.
지난 시간에는 오브젝트를 생성해보고 각 오브젝트의 요소와 더불어 컴포넌트란 것에 대해 살펴보았습니다. 그렇다면 이러한 오브젝트를 조금 더 잘 다룰 수 있도록 하나의 요소가 더 있습니다. 바로 기즈모죠! 물론 앞선 강의에서는 이미 기즈모를 사용하고 있었습니다.
화면에서 요소를 사용하기 편하게 만들어주기 위한 이정표들을 우리는 기즈모라 부릅니다.
여러 요소가 기즈모로 표현함으로써 유니티 사용을 조금 더 용이하게 만들어줍니다.
1. 기즈모
2. 씬 기즈모
Scene 뷰의 오른쪽 위에는 이러한 씬 기즈모가 존재한다. 원뿔의 정육면체에 붙어있는 모양새를 하고 있는데, 씬 기즈모를 활용해서 어떠한 시점을 보고 있는지 확인할 수 있다. 여기서 각각의 요소를 클릭함으로써 원하는 시점으로 이동할 수도 있다.
지난 시간에 실습했던 것을 기준으로 한번 보도록 하겠다. [기존 실습한 파일이 없더라도 상관없다.]
실제로 실습을 해보면 이러한 모양새가 됨을 확인할 수 있다. 원하는 시점에 따라 기즈모를 선택함으로써 시점 관리를 편하게 할 수 있다.
3. Presp(퍼스펙티브), Iso(아이소메트릭) 모드
씬 기즈모에는 두가지 요소가 있다. 퍼스펙티브 모드와 아이소메트릭 요소이다. 씬 기즈모 아래에 모드를 선택할 수 있는 요소가 준비되어 있다.
Persp으로 되어 있다. 실제로 클릭하면 Iso로 바뀌는 것을 확인할 수 있다.
실제로 눌러보면 변화가 일어난다. 아래의 gif를 확인해보자.
누를 때마다 바뀌는 것을 볼 수 있다. 두 개의 차이점은
Iso : 사람의 눈은 보는 시점에 따라 사물이 다르게 보인다. 하지만 게임을 만드는 입장에서 이러한 변하는 시점은 도움이 되지 않는다. 그래서 멀리있는 사물이나 가까이 있는 사물이나 실제 크기로 보여주도록 하는 것이다.
Persp : 관점에 따라 사물은 변하는데, 이러한 현실 세계의 시점을 반영해서 실제처럼 표현해준다. 즉 멀리있으면 작아지고 가까이 있으면 커지는 형태를 표현하는 것이다.
이 기능은 실제로 유용하게 사용된다. 멀리 있는 오브젝트를 작게 지정한줄 알았는데, 가까이서 보니 생각보다 커지는 경우가 있기 때문이다. 예를 들어, 사람에게 다가오는 공을 지정했는데, 가까이서 보니 사람보다 더 큰 공으로 보이는 경우도 있는 것이다. (물론 실제 오브젝트 생성시에 조심하겠지만, 비율에 대한 이야기는 중요하므로 이러한 기능도 유용하게 사용된다.)
씬 기즈모의 관점을 바꾸는 기능은 기즈모를 오른쪽 클릭해서 바꾸기도 한다. 기즈모를 직접 만들어서 사용할 수도 있습니다. (이러한 커스텀 기즈모는 나중에 알아보도록 하겠습니다.)
4. 기즈모 핸들 포지션 토글
기즈모 핸들포지션에는 트랜스폼 도구 기즈모의 위치와 기즈모 자체를 조작하는데 사용하는 중심점을 어떻게 움직이는지에 대해 정의하는데 사용합니다.
피벗(Pivot) / 센터(Center)
로컬(Local) / 글로벌(Global)
으로 이루어져 있습니다
(피벗)Pivot : 피벗은 기즈모의 위치가 오브젝트의 위치를 기준으로 이러한 기즈모를 표사해줍니다.
센터(Center) : 센터는 기즈모의 표시점의 위치가 오브젝트의 중앙점을 기준으로 표시해줍니다. 오브젝트의 생김새의 중앙점을 표시하게 되는 것이죠. [오브젝트의 형태를 기준으로 중앙점이라 생각하면 됩니다]
로컬(Local) : 선택한 오브젝트를 기준으로 한 좌표계
글로벌(Global) : 실제 선택한 오브젝트에 대한 좌표계는 무시한체로 글로벌 좌표계를 기준으로 봅니다. 글로벌 좌표계는 게임 세상의 절대 좌표로 사용합니다.
이러한 요소는 기본 오브젝트에서 나오지 않지만, 디자이너가 오브젝트의 중심점을 어디로 보냐에 따라 값이 다르게 나옵니다. 예를 들어, 사람을 모델링해서 유니티에 임포트 시켰을 경우, 일반적으로 디자이너는 발 쪽에다가 피벗을 두는 경우가 많습니다. 그래야 땅 속으로 들어가지 않으니까요. 이렇게 디자인하는 요소에 따라 기즈모 핸들 포지션은 중요합니다.
일반적으로 기즈모 핸들 포지션은 기본적으로 피벗/글로벌 의 형태로 두고 게임 제작을 많이 합니다. 이는 취향 차이이지만 피벗을 기준으로 만들어진 경우가 많아서 피벗 / 상대좌표계는 좌표의 혼동이 있을 가능성이 있으므로 글로벌 좌표계를 많이 사용합니다.
여기에 추가로 우리의 시점 관리가 힘든 경우가 많습니다. 그래서 시점 관리를 편하게 하는 몇 가지 단축키를 살펴보도록 하겠습니다.
Alt를 누른체로 마우스를 클릭해서 이리저리 돌려보면 특정 축을 기점으로 시야가 회전함을 알 수 있습니다.
Move 도구나 Transform을 움직이는 동안 Ctrl키를 누르고 있으면 특정 단위 만큼씩 움직일 수 있습니다. 뒷자리가 소수가 나오는 것이 아닌 딱딱 떨어지는 값이 나옵니다.
Move를 사용할 때, Shift와 Control키를 누르고 있으면, 두 오브젝트가 충돌하지 않게 이동시켜 줍니다. 만약 겹쳐지려고 하면 오브젝트를 조금 더 먼 곳으로 이동 시켜줍니다. (겹침 방지 해주는 것이죠.)
Rotate 회전 툴을 사용할 때, Shift와 Control 키를 누르고 방향을 이동시키면 특정 방향을 바라보게 만들 수 있습니다. 특히, 특정 오브젝트 방향으로 바라볼 수 있도록 해줍니다.
버텍스 스냅 : Move나 Transform도구를 사용하고 있을때, V를 누르면 버텍스 스냅 모드가 활성화 됩니다. 버텍스 스냅 모드는 오브젝트를 정렬할 때 유용하게 쓰이는데, 다른 오브젝트에 딱 붙이도록 도와줍니다.
지난 시간까지 기본적인 Unity UI 요소들에에 대해 알아보았습니다. 그렇다면 이번에는 유니티의 기본적인 요소 중 하나인 오브젝트를 한번 다뤄보도록 하겠습니다.
일반적으로 화면에 나타나 있는 모든 물체는 Object(오브젝트)라 불리는 물체에 의해 표현됩니다. 이러한 오브젝트는 사람의 눈에 보일수도 있고 눈에 보이진 않지만 어떠한 그룹을 이룰수도 있는 것이죠. 예를 들어, 마법을 사용하는 것이 가능한 게임에서 Sleep(잠재우기) 마법을 썻다고 가정 해봅시다. 이러한 마법은 화면 상에 나오지 않을 수도 있습니다. [이펙트 자체가 표시 안 될 수도 있는 것이죠] 이러한 마법이 날라가는 상황에서 Sleep이라는 오브젝트가 형성됩니다. 다만 사람의 눈에는 안보이게 형성될 뿐이죠.
이러한 오브젝트는 객체지향이라 하는 프로그래밍 기법에서 출발하게 되었습니다. 객체 지향(Object - Oriented)는 컴퓨터 프로그래밍을 도와주기위한 하나의 패러다임 중 하나입니다. 컴퓨터 프로그램 자체르르 명령어의 집합으로만 생각해서 프로그래밍을 하려면 머리가 아프죠. 그래서 생각해낸 것이 실제 생활하는 현실 세계를 기반으로 시뮬레이션을 돌릴 수 있도록 만든 것이 바로 객체 지향 프로그래밍입니다. 프로그래머가 조금 더 쉽게 코딩할 수 있도록 생각을 단수화할 수 있는 특정 시각을 만들어준 것이죠.
물론 객체 지향이라는 표현을 너무 단순화한 경향이 있지만 대략적인 객체 지향의 의미는 이러한 의미를 갖는다고 보면 됩니다.
유니티의 세계에서도 이러한 객체 지향 프로그래밍의 영향을 받아 오브젝트란 단어를 사용합니다. 실제로 게임은 현실 세계를 시뮬레이션하기 위한 도구였으니 충분히 그 맥락이 이해가 될 것입니다. (추가로, C#은 객체지향적 프로그래밍 언어이기 때문에 이러한 C#을 기본 언어로 채택하고 있는 유니티는 당연히 객체 지향적 관점으로 바라볼 수 있습니다.)
2. 프로젝트 생성
오브젝트란 무엇인지 간략하게 알아보았으며, 우리는 새 프로젝트를 만들고 이제 오브젝트를 다루어보도록 하겠습니다. 가장 먼저, 프로젝트를 생성해보도록 하겠습니다.
1. 가장 먼저 Unity Hub를 실행합니다.
2. 유니티 허브에서 프로젝트 -> 새로 생성 을 눌러줍니다.
3. 먼저, 3D를 선택하도록 하겠습니다. 3D를 이용해서 여러 카메라의 관점을 배워보도록 할 것입니다.
2D와 3D에서 당연히 2D가 생각할 요소가 더 적기 때문에 2D가 쉽지만 요새의 게임은 3D로 만들고서 2D로 카메라로 촬영하는 방식을 사용하고 있습니다. 그래서 처음부터 조금 힘들 수도 있지만, 3D 요소로 시작해보도록 하겠습니다.
두번째로, 프로젝트 이름을 생성하도록 하겠습니다. 여기서는 첫 프로젝트라 생각하고 주어진 이름 그대로 사용하도록 하겠습니다. 'New Unity Projcect'
세번째로, 저장위치입니다. 일반적으로 저장 위치는 C:\Users\[사용자이름] 의 형태로 주어지게 됩니다. 이는 변경하셔서 사용해도 되고 아니면 그냥 이대로 사용하셔도 상관없습니다. 일반적으로 프로젝트 이름과 비슷하게 짓거나 폴더 구조를 체계적으로 잡기 위한 이름을 사용합니다.
이대로 생성하도록 하겠습니다.
간혹 프로젝트를 시작했는데,
이러한 메시지를 보내기도 합니다. 업데이트가 있어서 그런거니 업데이트를 해주셔도 되고 안해주셔도 됩니다. 하지만 치명적인 업데이트가 아닌 이상 일단은 업데이트를 하지 않도록 하겠습니다.
Skip new version 을 눌러주도록 하겠습니다.
기본적인 구조는 지난 포스트에서 살펴보았으므로 이번에는 오브젝트 생성에 집중하도록 하겠습니다. 만약에 진행함에 있어서 힘드신 분은 지난 포스트를 보고서 같이 따라해주시면 되겠습니다.
오브젝트를 만드는 방법은 여러가지가 있습니다. 그 중에서 우리는 2가지 정도를 소개하도록 하겠습니다. 가장 많이 쓰이는 사용됩니다.
게임 오브젝트 -> 3D 오브젝트 -> 큐브
를 선택해주도록 하겠습니다. 만약에 영어버전으로 진행하시는 분은 GameObject -> 3D Object -> Cube로 하시면 됩니다.
위의 방법을 사용하셔도 되며, 혹은 계층 구조에서 오른쪽 클릭하신 뒤에 게임
오브젝트 -> 3D 오브젝트 -> 큐브
의 순으로 진행하셔도 됩니다.
오브젝트 생성완료!
실제로 게임 화면 가운데에는 3D 오브젝트인 큐브가 만들어진 것을 확인할 수 있습니다.
이외에도 '게임 오브젝트(GameObject)' 메뉴에 있는 내용은 다양하게 있습니다.
빈 오브젝트 : 여러 오브젝트를 한번에 관리하기 위한 목적으로 사용되는 오브젝트입니다. 예를 들어, 사람을 오브젝트로 구성한다고 한다면 머리, 몸통, 팔, 다리 로 구성되어 있습니다. 캐릭터가 이동한다면 모두 한번에 이동해야 하는데, 따로 구성되어 있다면 이러한 몸 따로 몸통 따로 다리 따로 움직이겠죠? 이러한 사태를 막기 위해 빈 오브젝트를 사용합니다. 눈에는 보이지 않지만, 결속이 되어 있는 무언가를 사용할 때 주로 빈 오브젝트(Empty Object)를 사용합니다.
3D 오브젝트 : 3D 오브젝트는 3D환경에서 쓰이는 여러 형태를 만들 때 사용합니다. 큐브(Cube), 구체(Sphere), 캡슐(Capsule), 원기둥(Cylinder), 평면(Plane), 쿼드(Quad) 등으로 이루어져 있습니다. 이러한 오브젝트를 활용해서 여러 형태를 만들어냅니다. 물론 우리가 생각하는 캐릭터를 만들 경우에는 다른 소프트웨어에서 만든 3D 모델링 된 캐릭터를 삽입해서 사용합니다. 다양한 형태를 만들기에는 유니티로 만들기가 힘들기 때문에 다른 소프트웨어를 사용합니다.
* 각각의 오브젝트는 꼭 생성해보고 이리저리 움직여보고 크기도 키워보면서 실습해보시기 바랍니다. 백 마디의 말보다 한번의 실습이 훨씬 더 체득하기 좋습니다. 그래서 이리 만저보고 저리도 만저보시면서 실제로 어떻게 작동하고 움직이는지 꼭! 살펴보시기 바랍니다.
※ 모델링에 사용되는 소프트웨어는 다양합니다. 3D Max, MaYa, 포토샵 등 여러 도구가 있습니다. 디자이너가 디자인한 여러 모델링된 것을 임포트함으로써 사용합니다.
이러한 형태로 아마존 아이콘을 만들어서 사용하기도 합니다. (AWS에서 사용되는 여러 아이콘 요소들입니다.) * 디자인 요소는 유니티 강의에서 다루지 않을 예정입니다. 하지만 너무 실망하지 않으셔도 됩니다. 우리는 Asset이라 하는 디자이너가 미리 디자인한 요소를 가지고 여러 유니티의 요소를 다루어볼 예정이기 때문에 디자인은 걱정하지 않아도 됩니다.
효과 : 게임에는 다양한 효과(Effect)가 있습니다. 폭발도 있을 수 있으며, 달려갈 때는 바람이 휙휙 날라가는 이펙트가 만드시 필요하죠. 그러한 효과를 만들기 위한 오브젝트입니다.
광원(Light) : 빛에 관련한 오브젝트입니다. 우리가 무언가를 보기 위해서 빛이 필요하듯이 그러한 광원 요소입니다.
광원을 추가함으로써 현실과 더욱 비슷한 게임을 만들 수 있게 됩니다.
오디오 : 소리 요소를 표현하기 위해 사용하는 오브젝트입니다.
비디오 : 비디오를 재생할 때 사용합니다. 간략한 쿠키영상을 보여주는 형태를 비디오로 통해 표현합니다.
UI : User Interface의 약자로 사용자가 실제로 조작하는 부분을 보여주기 위해 화면에 만들어야 하는데, 이러한 화면 요소를 UI오브젝트를 통해 관리합니다.
카메라 : 영화에서 보여주고자 하는 부분을 카메라로 찍어서 보여주듯이 게임도 마찬가지입니다. 그렇다면 이러한 화면을 찍기 위한 카메라가 필요하겠죠? 그래서 카메라 오브젝트로 이러한 요소를 조절합니다. 카메라는 1개 외에도 더 많은 카메라를 만들기도 합니다. 또한 2인용 게임을 위해 화면을 분할해서 사용하는 기법을 사용하거나 심지어 미니맵도 이러한 카메라를 하늘에다가 드론처럼 찍으면서 만드는 것입니다.
4. 오브젝트를 다루기
오브젝트를 다루기 위해서는 오른쪽 옆에 있는 인스펙터(Inspector)를 활용해서 다양한 오브젝트 요소를 다루게 됩니다. 아래 그림에서 보이는 곳이 바로 인스펙터입니다. ↓
이러한 인스펙터는 컴포넌트(Component)라는 요소로 이루어져 있습니다. 컴포넌트마다 특성이 존재하며 이러한 컴포넌트를 활용해서 오브젝트는 자신만의 역할을 부여받게 됩니다.
실제로 오브젝트 - 컴포넌트에다 스크립트를 추가함으로써 오브젝트가 실제로 동작할 수 있도록 진행하는 것입니다.
초록색으로 표시한 곳이 각각의 컴포넌트입니다. 조금더 아래로 스크룰해서 내리게 되면 '컴포넌트 추가(Add Component)' 가 있습니다. 거기서 다양한 추가할 수 있는 컴포넌트를 구경할 수 있습니다.
혹은 상단 메뉴바에 컴포넌트 메뉴를 통해서 확인할 수 있습니다.
컴포넌트 요소에서 가장 많이 사용하는 요소는 Transform요소입니다. [그리고 자동으로 부여되는 요소이기도 하죠]
포지션 : 오브젝트의 위치를 조정한다. x, y, z축으로 움직인다.
회전 : 오브젝트를 회전시키는 요소
스케일 : 오브젝트의 크기를 조정한다.
각각의 요소는 이리저리 만져보면서 익혀보는 것이 가장 좋습니다. 이것저것 만진다고 문제 생기는 것이 아니기 때문에 마음껏 만져두세요!
실제 오브젝트를 클릭함으로써 여러 요소를 사용할 수 있습니다. 팁을 드리자면 단축키론느 q,w,e,r,t를 사용할 수 있습니다. 리그오브레전드 게임을 한다고 생각하세요! 각각의 요소를 화면을 통해 만져볼 수도 있으며,
컴포넌트에서 각각의 요소 위에 올린 뒤에 화살표가 ↔ 모양새로 바뀌면 이를 통해 움직이면서 바꿔볼 수도 있습니다. 혹은 수치를 입력함으로써 각 요소를 움직일 수도 있습니다. 다양하게 움직이는 방법이 있으니 여러 요소를 직접 확인해보시면서 연습해보시면 됩니다.
또 다른 중요한 컴포넌트 요소는 RigidBody(리지드 바디)입니다.
리지드 바디는 우리가 흔히 이야기하는 물리 요소라 생각하면 됩니다. 각 오브젝트를 실제로 실행시켜보면 하늘에 떠있는 형상이 됩니다.
시작 버튼을 눌렀음에도 하늘에 떠있습니다. 이는 물리엔진이 적용되지 않은 상태이므로 실제 상황과 비슷하려면 물리엔진을 넣어보도록 하겠습니다.
# Rigid Body(리지드 바디) 간단 구현
자 우리가 배운대로 하나씩 만들어보도록 하겠습니다. 위에서 배운 내용을 제대로 이해하고 있는가 체크하는 단계이기도 합니다. 하나씩 말로 설명된 부분을 따라하면서 진행하도록 하겠습니다.
1. 게임 오브젝트 -> 3D -> 큐브(Cube)
을 만들어주도록 하겠습니다. 큐브 요소는 캐릭터나, 오브젝트들의 바닥이 되어줄 존재입니다. 무한정으로 떨어지면 안되겠죠?
2. 큐브에서 포지션 X : 0, Y : 0, Z : 0으로 만들고, 회전은 Z : 10, 스케일을 X : 100, Y : 2, Z: 10
으로 만들어줍니다.
이렇게 만들어 줍니다. (살짝 기울여서 만든 이유는 오브젝트가 굴러갈 수 있는 요소를 만들어두기 위함입니다. 실제로 눈으로 보고 확인해야 하니 기울여둠으로써 어떻게 작동하는 여부에 대해 살펴볼 수 있습니다. )
3. 또 다른 Cube를 만들어줍니다.
이 큐브는 위에서 떨어뜨릴 요소입니다. 만들어 준 뒤에
포진션을 변경해줍니다. [X : 0, Y : 5, Z: 0] 참고로 Y는 10도 상관없습니다. 높이를 더 높이셔도 됩니다.
클라우드 - Cloud 즉 구름이라는 의미이다. 이러한 클라우드는 네트워크 속이 어떤 경로인지 모르기에 구름처럼 표시한 것에 유래되어 클라우드란 이름이 붙기 시작한 것이다.
정보 시스템에서는 기본적으로 '정보를 공개' 한다는 의미의 정보 투명성을 기반으로 운영한다. 하지만 클라우드는 오히려 그 반대다. 정보를 공개하는 것이 아닌 오히려 불투명하게 만들어 안보이게 만드는 것이다. 다른 말로 어떤 작동을 하는지 몰라도 나는 그것을 쓸 수 있도록 만들어주는 것이다. 알약 속에 정확하게 어떤 성분이 들어있는지 모르더라도 그 약의 효능은 우리가 아는 것처럼 클라우드 또한 마찬가지이다.
그래서 클라우드 컴퓨팅은 사용자가 원하면 바로 (On-demand Self Service), 어디에 있든 네트워크를 통해서 (broad network access), 필요한 컴퓨팅 자원들을 제공 (Resource Pooling), 필요한 만큼만 쓰고(rapid elasticity), 사용한 만큼만 지불하는 (Measured Service)
클라우드는 총 세 가지 종류가 있다.
IaaS(InfraStructure as a Service)
PaaS(Platform as a Service)
SaaS(Software as a Service)
Iaas의 경우, 하드웨어 계열을 빌려주는 형태
Paas의 경우, 하드웨어와 함께 기본적인 OS, 미들웨어, 런타임을 같이 빌려주는 형태이다.
SaasS의 경우, 하드웨어부터 소프트웨어까지 모든 걸 다 빌려준다. 우리는 서비스만 하면 되게 미리 셋팅해놓은 것을 이야기한다.
각각의 장단점이 있지만, 여기서는 장단점에 대해 살펴보는 것이 아니니 대략적으로 알아보았다. 더 설명이 필요하다면, 이곳을 통해 간략하게 보도록 하자. 혹은 이곳 에서 나름 정리가 잘 되어 있다.
자 이렇게 서비스가 모두 되어 있지만, 적어도 우리의 도전 정신은 여기서 끝나지 않는다. 어차피 클라우드를 통해서 사용하는건 사용하는거지만, 직접 모든 걸 다 구축해보고나서 관리의 용이함을 위해 클라우드에 들어가도 되지 않는가 라는 생각이 든다.
추가로 클라우드는 생각보다 비싸다는 것이 필자의 생각이다. 아 물론 실제 대규모 운영에서는 클라우드는 오히려 싸게 먹힐 수 있다. 관리 인원을 두지 않아도 될 뿐더러, 하드웨어 비용과 관련한 모든걸 부담하지 않아도 되며, 심지어 소규모에서도 간략하게 시작하기 너무 좋다. 그러나 사람이라면! 역시! 하드웨어를 포기할 순 없다! (feat. 좋은 컴은 언제나 옳다) 컴퓨터를 이쁘게 꾸며 보고 싶은 생각이 든다면 당연히 해야 하지 않겠는가?
더불어 클라우드에서 제공하는 엄청나게 좋은 하드웨어를 임대하려면 가격이 좀 많이 비싸다... 사실 그 정도 비용이면 집에서 운영하는게 나을 수도 있다. (전기세는 나중에 생각하도록 하자) 사실 필자는 9kw급 태양열을 달아놔서 괜찮다. 클라우드에서 제공하는 월 비용은 트래픽 비용과 더불어 서버 임대 비용까지 합하면 생각보다 많은 비용이 소모가 된다. 그래서 남는 컴퓨터가 있다면 한번쯤은 서버 구축도 나쁘지 않다고 생각한다. 백업만 잘해두면 언제든 새롭게 구축을 할 수 있으며, 기본적인 서버 구축 소양을 갖추니 일석 이조이지 않겠는가?
Ex) AWS(Amazon Web Service)와 마이크로소프트 Azure(애저)가 대표적이다.
라는 상상을 가지고 출발하였다.
일단 필자의 시작은 미니컴퓨터로부터 시작했다.
대략 이렇게 생긴 친구이며, 굉장히 작다. 대략적인 크기가 115mm * 112mm * 32mm 이 정도의 크기를 가지고 있는 매우 아담한 PC이다.
사양은
CPU : i5 - 5200U , 2.20GHz
RAM : 8GB
SSD : 120GB
정도로 시작했다.
하지만 하드웨어가 없더라도 실망하지 말길 바란다. 우리는 가상머신이 존재하기에 VMware를 사용하면 된다.
이전 시간까지 유니티 한글 적용과 더불어, 실행하는 방법까지 알아보았습니다. 이번 시간에는 기본적인 유니티의 기본 구조에 대해 살펴보도록 하겠습니다.
유니티를 실행하면,
이러한 구조로 되어 있는 것을 볼 수 있습니다. 여기를 영역별로 나누어서 살펴보도록 하겠습니다.
위에서부터
툴바
Hierarchy (계층구조)
Scene 씬-뷰
Inspector (인스팩터)
Project브라우저
상태 표시줄(Status Bar)
1. 툴 바(Toolbar)
맨 위에 있는 표시줄을 툴바라 합니다.
이렇게 생긴 도구 상자를 변환 도구[Transform Tools]라 합니다. 각각의 기능은 하나씩 클릭해보면서 직접 사용해보는게 좋습니다. 왼쪽부터 차례대로 Q, W, E, R, T, Y 단축키로 빠르게 이용할 수 있습니다. (롤 생각하면 쉽겠죠?)
손 모양 도구는 화면을 이동할 때 사용합니다.
2번 째 화살표 모양은 오브젝트의 위치를 조정할 때 사용합니다.
3번 째 동그라미 화살표는 오브젝트를 회전할 때, 사용합니다.
4번 째 도구는 오브젝트의 크기를 조정할 때 사용합니다.
5번 째 Rect Tool (사각형 도구)는 오브젝트를 선택할 때 사용합니다.
6번 째 도구는 이동, 회전, 스케일을 한번에 할 수 있도록 해주는 도구입니다.
* 지금은 간략하게 보도록 하고 차후에 자세히 설명하도록 하겠습니다.
기즈모 핸들 포지션 토글로써 기즈모라 불리는 것을 사용할 때 사용합니다.
좌측 버튼은 Pivot/Center (피봇/중앙)
우측 버튼은 Local/Global (로컬/글로벌)
로 나뉘어서 이야기 합니다.
좌측에서 Pivot과 Center의 차이점은 기즈모의 위치의 차이점입니다. 여기서 기즈모란 특정 오브젝트를 눈으로 보여주기 위해 사용되는 그래픽이라고 생각하면 됩니다. 오브젝트와 오브젝트를 그냥 두면 확인이 불가능할 수 있는데, 이를 가시화시켜주는 도와주는 그래픽이라 볼 수 있습니다.
카메라 오브젝트와 광원 오브젝트에 해당하는 기즈모입니다. 물론 이는 기즈모의 한 종류이며, 아이콘을 부여함으로써 오브젝트를 조금 더 쉽게 식별하는 역할을 합니다. 다양한 기즈모가 존재하며 각각의 경우마다 쓰임새가 있습니다.
Pivot : 기즈모의 위치가 실제 피벗 지점으로 지정해줍니다.
Center : 오브젝트에서 렌더링된 부분과 안된 부분의 경계의 가운데로 지정합니다.
Local : 오브젝트를 기준으로 회전합니다.
Global : 전체를 기준으로 고정
실제 게임을 시작할 수 있게끔 만들어줍니다. 플레이 버튼을 누르면 하나의 장면에서 게임을 플레이할 수 있게 해줍니다. 개발자가 문제가 있는지 없는지 체크할 수 있도록 도와주는 것이죠.
그 외의 요소들은 나중에 익숙한 뒤에 살펴보도록 하겠습니다. 지금은 많이 사용되는 것들만 간략하게 알아보았습니다.
2. 계층 구조 [Hierarchy]
Hierarchy - '하이어라키' 라고 읽으며 한글화에서 된 번역을 볼 수 있듯이 계층 구조라 불리는 곳입니다. 실제 게임에서 사용되는 오브젝트가 관리되는 곳이라 생각하면 됩니다. 전체 오브젝트가 여기서 관리되며, 부모-자식 관계를 설정하거나 해제할 수 있습니다. 대부분의 오브젝트에 대한 관리할 것 입니다.
3. Scene 씬-뷰
이 부분은 씬(뷰) 입니다. 2가지 메뉴가 존재하는데, 씬과 게임이 있습니다. 씬은 우리가 게임을 만들때 사용되는 곳이며, 게임은 실제 게임 상에서 표시되는 화면입니다. (카메라가 찍은 화면을 게임화면이라 하는데, 이를 '게임'이라는 용어로 단축해서 표현하고 있는 것 입니다. 그래서 실제 게임화면은 '게임'을 눌러서 확인해야 합니다. )
Scene(씬)은 게임을 만드는 공간이며, 하나의 게임은 이러한 씬이 모여서 만들어집니다. 예를 들어, 시작 씬 -> 게임 씬 -> 승리 혹은 패배 씬의 형태로 이루어져 있습니다. 그래서 우리는 이러한 씬을 만들기 위해서 배우는 것입니다.
4. Inspector (인스펙터)
오른쪽에 있는 복잡하게 생긴 부분은 인스펙터라고 하는 곳입니다. 계층 구조에서 오브젝트를 다루었다면, 오브젝트에 포함되어 있는 여러 가지 특성, 옵션들(정확하게는 컴포넌트와 스크립트 등)을 다루는 곳입니다. 프로그래밍 코드를 연결해서 이곳에서 수치를 통해 확인할 수 있습니다. 실제로 위의 스크린샷에서도 여러 옵션들을 다룰 수 있음을 확인할 수 있습니다. 이곳에 있는 여러가지를 만져보면서 어떤 느낌으로 바뀌는지 하나하나 실험해보는 것도 좋은 자세입니다.
5. Project 브라우저
아래쪽에 표시된 곳은 프로젝트 브라우저와 콘솔이 표시된 곳입니다. 프로젝트의 경우, 우리가 사용하는 에셋이나 현재 사용되는 장면에 관한 여러 가지 요소를 표시하는 곳입니다. (모델, 텍스처, 사운드, 씬 데이터 등등 다양한 요소를 관리하게 됩니다. )
※ 하나의 씬에서 관리하는 오브젝트는 계층 구조 상에서 다루며, 프로젝트 브라우저는 게임에 사용되는 전반적인 요소 모두를 관리합니다. 프로젝트가 커지게 되면 이러한 프로젝트 브라우저를 폴더별로 잘 지정해두어야 프로젝트를 진행하는 팀원들간의 의사소통에 오류가 생기지 않습니다. 마치 목수가 자기의 연장을 잘 정리해두는 것과 같습니다. 언제 어디서든 바로바로 찾을 수 있도록 말이죠.
콘솔 : 콘솔의 경우, 윈도우에서 쓰이는 명령프롬프트와 비슷한 역할을 해줍니다. 유니티의 여러 경고 혹은 오류에 대한 메시지를 이곳에서 보내줍니다. 초기에는 많이 쓰이지 않을 수 있지만, 점점 실력이 올라가면 올라갈수록 콘솔의 역할은 많아집니다. 제대로 작동하는가에 대한 디버깅을 할 때도 콘솔을 많이 사용합니다.
6. 상태 표시줄 (Status Bar)
맨 아랫줄에는 상태표시줄이다. 스크립트가 제대로 작동하지 않는 경우, 빨간색 에러 표시가 나온다. 혹은 Warning 의미의 노란색으로 표시되기도 한다. [버그 메시지나 오류 메시지가 한 줄로 표시되는 공간이다.]
※ 마지막으로 우리는 항상 기억해야 하는 것이 유니티 전용 레퍼런스는 공식 사이트에 같이 포함되어 있다. 잘 정리되어 있으므로 레퍼런스를 항상 참조하도록 해야 합니다.
이번 포스팅에서는 유니티의 설치와 기본 설정에 대해서 살펴보도록 하겠습니다. 기본 설정에서 많이 어려움을 겪으시는 분들이 많으신데요. 그래서 여러 설정에 대해서 살펴보도록 하겠습니다.
일단, 요새 유니티에서 한국어 번역을 베타테스트 중입니다. 그래서 한국어를 사용할 수 있지만, 완전한 번역은 아닙니다. 게다가 C# 스크립트에서 특정 컴포넌트를 사용하려면 한국어 -> 영어로 번역해서 사용해야 하는 어려움이 있습니다. 그래서 개인적으로는 영어 버전을 사용하기를 추천드리지만, 처음에 사용하시는 분들은 화면에 UI가 익숙치 않아서 정신없어하는 경우가 많습니다. 그래서 일단은 한국어 버전으로 바꿔서 진행하도록 하겠습니다. (나중에는 영어판이 더 익숙해질 수도 있습니다.)
유니티 홈페이지에 들어가도록 합시다.
Google에다가 유니티라고 검색한 뒤에 들어가셔도 되고 아니면 아래의 링크를 따라 들어가셔도 됩니다.
무료에는 버전이 두 가지가 있습니다. 하나는 학생 버전과 하나는 Personal버전이 있습니다. 학생이라면 학생 버전을 쓰시는 것을 추천드립니다. 하지만 범용적으로 사용하는 방법에 대해 이야기할 것이므로 우리는 Personal버전으로 시작하도록 합시다.
Personal의 경우, 10만 달러(1억) 매출까지는 무료이며, 이후에는 라이센스비를 지불하며 사용해야 합니다.꽤 괜찮은 편입니다. Personal의 시작하기를 누르면 다음 화면이 나옵니다.
당연히 우리는 첫 사용자에서 시작하기를 눌러주도록 합시다.
다음 화면에는 유니티 시작하기가 나오는데, 서비스 약관 체크와 Unity Hub를 다운로드 하도록 하면 됩니다.
Unity Hub를 다운로드 받으면 바로 실행시켜주도록 하자.
특별한 선택을 하지 않을 것이라, 동의함 -> 다음 -> 다음 설치를 완료해주면 됩니다.
설치한 후에 실행 해주면, 라이선스가 없다고 나올 것인데, 아직 로그인을 해주지 않았기 때문입니다.
로그인 버튼을 눌러서 로그인을 해주도록 합시다. 활성화가 마무리 되고 나면, 다음과 같은 창이 뜹니다.
새 라이선스 활성화 버튼이 파랗게 돌아옴을 확인가능합니다.
바로 눌러주도록 합시다. 새 라이선스 활성화 버튼을 눌러보면 다음과 같은 창이 나옵니다.
당연히 Unity Personal을 클릭 해줍니다.
클릭 한 뒤에 우리는 비상업적 목적으로 사용할 것이므로 일단은 아랫부분에 클릭 -> 완료하면 라이센스는 끝났습니다. 나중에 상업적 목적으로 사용한다면 그때가서 바꿔도 늦지 않습니다. 어차피 아직은 배우는 단계이므로 상관없습니다. 차후 매출이 생기면 그때가서 바꾸어도 늦지 않습니다. (무료/유료 버전 둘다 광고 넣을 수 있으니 걱정하지 않으셔도 됩니다.)
이제 라이센스는 마무리 되었으니 진짜 유니티를 설치하러 갑시다! 지금까지는 유니티 허브를 설치한 것이었으며, 유니티를 설치한 것은 아니니까요!
자 이제 뒤로 가기를 눌러줍니다.
이 장면은 자주 보게 될 화면이 됩니다. 주로 프로젝트를 생성하고 다룰 부분입니다. 하지만 지금 우리는 유니티 자체가 설치가 안되어 있습니다. 그래서 유니티를 설치하도록 합시다.
설치버튼을 눌러준 뒤에
추가를 눌러주도록 합시다.
버전은 2020.3.0f1 (LTS)버전을 사용하도록 할 예정입니다. LTS와 일반 버전은 차이가 있습니다.
일반 버전은 빠른 업데이트와 더불어 개발에서 사용되는 전반적인 내용이 바뀔 확률이 높습니다. 그래서 장기 프로젝트를 개발시에 엔진 내용이 바뀔 확률이 높습니다. 장점으로는 신기술을 새롭게 사용해볼 수 있다는 장점이 있습니다.
LTS 버전은 Long Term Support로 장기간에 걸쳐서 지원하도록 고안된 소프트웨어 입니다.
사실 초보에게는 큰 차이점은 없지만, 둘 사이의 차이는 단 하나 '안정성'입니다. 프로그램 개발에서 가장 무서운 점 중 하나는 개발 환경의 변화입니다. 환경이 하나 변하면 오류가 어디서 나올지 모르며, 다른 소프트웨어와의 호환이 안 될 가능성이 있기 때문에 그러한 변화를 줄이는 것도 버그를 줄이는 하나의 방법입니다. 그래서 상업 목적의 프로그램 개발에서는 LTS 개발로 합니다. 그래서 일단은 우리에게 있어 신기술은 필요없고 기본적인 유니티 사용에 대해 이야기할 것이므로 LTS버전으로 진행하도록 하겠습니다.
다음으로 넘어가면 추가로 같이 설치할 것들을 고르는 화면이 나옵니다.
C# 작성은 Visual Studio 2019 Community 버전으로 진행할 것이므로 체크!
Language packs에서 한국어 체크!
해주면 됩니다. 나머지는 Buil용, 즉 특정 환경에서 배포하기 위한 빌더 입니다. 안드로이드 환경에서 하고 싶다면 Android Build Support를 추가해야겠죠? [이는 유니티의 장점 중 하나인 멀티플랫폼을 사용할 수 있게 해주는 환경설정입니다. 유니티를 통해 게임을 윈도우 환경에서 만들어도 다양한 플랫폼에서 사용할 수 있습니다. 예를 들어, 윈도우에서 만들어서 iOS, 리눅스 환경에서 게임을 할 수 있는 것이죠.]
iOS는 애플용, tvOS는 스마트 TV에서 지원되는 환경, WebGL Build Support이면 웹 환경에서 실행할 수 있도록 해줍니다. 이는 나중에도 추가할 수 있으므로 일단은 가장 필요한 언어팩과 비주얼 스튜디오 정도 체크하고 다음으로 넘어가면 됩니다. 그러면
혼자서 열심히 설치를 합니다. 만약에 그냥 다음버튼을 눌러버려서 언어팩을 설치 못하더라도 상관없습니다. 나중에 추가할 수 있습니다. 이제 설치는 마무리 되었습니다!
만약에 추가하지 못한 모듈이 있다면,
이제 프로젝트를 클릭하면 유니티를 실행할 수 있습니다!
새로 생성을 누르면
다양한 템플릿이 존재합니다. 우리는 여기서 3D를 선택할 겁니다.
3D를 선택하고, 프로젝트 이름을 정해줍니다. 그리고 생성!
한글 설정하기
실제 실행해보면 모든 것이 영어라 영어 울렁증이 오는 경우가 있습니다. 그렇다면 한글 설정을 해보도록 합시다.
Edit -> Preferences를 클릭!
클릭하고 나면, 설정창이 나옵니다.
거기서 Languages탭을 누르고 한국어로 바꾸어주면 끝!
이제 다시 사작하면 한국어가 적용되어 있는 상태를 볼 수 있습니다. 그런데 지금 한국어 버전은 위의 그림에서도 알 수 있듯이, Experimental, 실험적으로 적용되어 있어서 실제 쓰다보면 적용 안된 부분들이 존재합니다. 참조하도록 하세요~
다른 설정은 따로 건드리지 않은 상태로 나머지 실습을 진행해보도록 하겠습니다. 다음 시간에 뵙도록 하겠습니다. 안녕~★
현대에는 크건 작건 간에 우리는 게임을 한번이라도 접해본 세상에 살고 있습니다. 이러한 세상에서 게임을 하다보면, 게임을 직접 만들어보고 싶은 욕구가 생기기 마련입니다. 그래서 게임 만들기에 대해 한번 이야기하고자 합니다.
1. 게임제작?
게임제작은 거창한 일이 아닙니다. 물론 우리가 잘 알고 있는 NC소프트에서 만든 게임이나, 블리자드에서 만든 거대한 스케일을 가진 게임을 본적이 있습니다. 그러한 게임들은 많은 사람이 모여서 만드는 큰 프로젝트일 수도 있지만, 뭐든 시작은 한 걸음부터입니다. 작은 게임에서부터 시작해서 점차 발전해나가는 것입니다. 초창기 게임들 또한 엄청나게 거대한 프로젝트로부터 시작된 게임은 없습니다. 시작은 작게 시작하다가 점차 커져서 (혹은 회사가 커져서) 큰 프로젝트를 하게 된 것이죠.
다양한 게임이 현재에도 쏟아져 나오고 있습니다. 하지만 우리의 입맛에 맞는 게임이 없을 수도 있습니다. 그리고 친구와 하기 위한 간단한 게임을 제작하고 싶을 수도 있습니다. 다양한 목적에 따라 우리는 게임을 제작하고 만들게 됩니다. 이러한 수요를 위해 게임 제작 툴이 존재하며 복잡한 절차 없이 간단하게 게임을 만들 수 있습니다.
2. 게임 제작 툴
게임을 만들기 위해서는 다양한 게임 제작 툴을 이용할 수 있습니다. 물론 게임 제작 툴이 없더라도 만들 수 있지만, 초보자에게는 쉽지 않은 일이지요. 그래서 게임 제작 툴을 이용하면 여러 고생할 일이 확 줄어들어 스토리 전개에 집중할 수 있게 됩니다. 대표적인 게임 제작 툴은 Unity와 Unreal이죠.
유니티 엔진으로 만든 3d
언리얼 엔진으로 만든 3d
사실 유니티와 언리얼은 게임 제작 툴이기도 하지만 게임에서 사용되는 물리 엔진이기도 합니다. 두 물리엔진의 특성은 여러 차이점이 있습니다.
유니티가 언리얼 엔진보다 모델링 측면에서 유연성을 갖습니다. - 이는 반대로 이야기하면 모델링에서는 할 일이 많다는 소리죠.
언리얼 엔진은 유니티보다 물리엔진에 대해 자유도가 높습니다. - 프로그래머의 역량만 된다면 언리얼 엔진은 무엇이든지 할 수 있는 신이 될 수 있는 것이죠.
프로그래밍의 관점에서 유니티는 물리엔진에 대해 제약이 많은데 반해 언리얼 엔진은 자유도가 높아서 자유자재로 변형할 수 있습니다. 하지만 초보자에게는 이는 좋은 일이 아닙니다. 내가 무엇을 할지도 모르는데, 많은 자유를 주어져 봤자 쓰지도 못합니다. 그래서 만약 초보자가 처음으로 프로그래밍 관련, 그것도 게임 프로그래밍을 시작한다면 유니티 쪽으로 시작하는 것이 좋지 않나 생각이 듭니다. (물론 언리얼도 장점이 아주 많습니다. 하지만 초기 시작에 대해 너무 힘든 부분이 많은 것은 사실입니다. 그래서 처음 배우는 초보자에게는 유니티 쪽이 낫지 않나 생각해보는 것이죠. 어차피 하다보면 둘 다 배워둬야 하는 일이 생기기 마련입니다. ) 둘의 차이점은 조금 더 잘 정리된 여기를 보시면 되겠습니다.
일단 유니티와 언리얼에서 가장 중요한 라이센스의 차이점
유니티의 경우, 일정한 수입이 있으면 유료 라이선스를 구매해야함 (기준 금액은 1억 매출 ( 정확히는 10만 달러))
[유니티는 10만~20만 달러이면 1년에 약 48만원, 20만 달러 이상이면 1년에 216만원이다. 자세한 여기]
언리얼의 경우, 상업 용도로 사용하게 되면 일정한 비율 만큼의 로열티를 지불해야함 (11억이 넘을 경우(정확하게는 $1,000,000, 매출의 5%)
등등이 존재합니다. 하지만 우리의 시작은 유니티로 시작하도록 할 예정입니다. 다양한 플랫폼을 커버하는 것과 동시에 게임 만들기에 대한 기본을 제대로 배울 수 있기에 유니티로 시작하려 합니다.
[ +로 무료라는 강점이 너무 좋다는 점입니다. 다양한 장르의 게임을 만들 수 있기에 아주 좋습니다. 다른 게임 제작 툴 또한 좋은 점이 많지만 그래도 기본을 제대로 배울 수 있는 유니티를 쓰기로 하였습니다. 언리얼은 초보자가 하기에는 생각보다 복잡한 요소가 많기 때문에 이번에는 유니티입니다. 유니티가 모두 끝난 뒤에는 언리얼 엔진 도전하는 것도 좋은 일입니다. ]
3. 기본 언어?
유니티나 언리얼이나 둘 다 기반 언어는 C++를 통해 제작되었습니다. 우리가 사용하고 있는 대부분이 C++로 제작된 것이 많기에 프로그래밍을 한다면 C++와 Java는 반드시 섭렵해야 합니다. 하지만 유니티를 활용해서 게임 제작할 때는 여러 요소를 걱정해야하는 C++를 사용하지 않습니다. 대신에 스크립팅 언어를 사용할 수 있습니다. C++보다 배우기 쉬우며, 사용하기도 쉬운 C#을 사용합니다.
물론 C#만 사용해야 하는 것은 아닙니다. JavaScript로도 사용할 수 있지만, C#을 기반으로 배워보도록 할 예정입니다. 요새는 인터넷에서 많이 쓰이는 자바스크립트가 더 좋을 수도 있지만, 유니티는 C#을 오랫동안 사용되어져 왔으므로 C#을 통해 해보도록 합시다. (가장 큰 장점은 우리가 찾아볼 여러 레퍼런스가 많다는 점이죠. )
지난 시간에는 이미지의 출력을 간단한 예제와 함께 살펴보았다. 이번에는 입력 받아둔 이미지를 간단한 변환인 가우시안블러를 적용해보도록 하자.
1. 가우시안 블러 GaussianBlur()
가우시안 블러는 이미지를 부드럽게 만들어주는 필터 같은 것이다. 가우시안이나 이와 비슷한 커널을 활용해서 이미지에 담긴 정보량을 줄여준다. 이미지 처리에서는 너무 많은 정보로 인해 오히려 정보 사이의 유의미한 연결 고리를 찾기 어려울 수 있으므로 가우시안 블러를 통해 줄여주는 것이다.
결과부터 먼저 살펴보자.
왼쪽이 가우시안블러가 적용된 이미지, 오른쪽이 원본이미지이다. 뿌옇게 변한 것이 가우시안 블러이다.
실습을 바로 해보도록 하자.
#include <opencv2/opencv.hpp> // 헤더 파일을 가볍게 만들기 위해 교체!
using namespace cv;
int main(int argc, char** argv) {
Mat img = imread("cat.png");
Mat blurredImg; //가우시안 처리가 된 이미지를 담을 변수
if (img.empty())
return -1;
namedWindow("img", WINDOW_AUTOSIZE); // 입력 결과를 넣을 윈도우 만들기
namedWindow("blurredImg", WINDOW_AUTOSIZE); // 출력 결과를 넣을 윈도우 만들기
imshow("img", img);
GaussianBlur(img, blurredImg, Size(5, 5), 3, 3);
GaussianBlur(blurredImg, blurredImg, Size(5, 5), 3, 3);
imshow("blurredImg", blurredImg);
waitKey(0);
}
지난 시간에 적용했던 코드를 활용하고 있다.
Mat img = imread("cat.png");
Mat blurredImg;
입력에는 img 변수를 사용하고 있으며, 출력에는 blurredImg를 선언해서 넣어주려고 한다. 여기서는 OpenCV가 자동으로 가우시안블러를 적용함으로써 줄어든 메모리를 자동으로 할당하고 메모리 크기를 조정해준다는 점이다. (간단히 우리를 편리하게 자동으로 조정/재할당 해준다.)
그 다음으로 가우시안 블러를 적용해준다. 여기서는 두 번 연속으로 가우시안블러를 적용하고 있다. 1번만 해도 상관없지만 조금 더 들여다 보기 위해 2번의 가우시안 블러를 적용해보았다. 2번 째 중복된 가우시안 블러 호출은 자기 자신이 입력과 출력으로 사용되는 위에서 이야기했듯이, Mat 구조체에 해당하는 메모리가 자동으로 조정/재할당을 함으로써 메모리 사용을 최적화해준다. (아주 편리하다! 감사합니다 개발자님들)
imshow("blurredImg", blurredImg); 가우시안 블러가 완료된 것을 윈도우에 출력해준다.
#include <opencv2/opencv.hpp> // 헤더 파일을 가볍게 만들기 위해 교체!
using namespace cv;
int main(int argc, char** argv) {
Mat img = imread("cat.png");
Mat blurredImg1, blurredImg2; //가우시안 처리가 된 이미지를 담을 변수
if (img.empty())
return -1;
namedWindow("img", WINDOW_AUTOSIZE); // 입력 결과를 넣을 윈도우 만들기
namedWindow("blurredImg1", WINDOW_AUTOSIZE); //중간 결과를 넣을 윈도우 만들기
namedWindow("blurredImg2", WINDOW_AUTOSIZE); // 마지막 결과를 넣을 윈도우 만들기
imshow("img", img);
GaussianBlur(img, blurredImg1, Size(5, 5), 3, 3);
GaussianBlur(blurredImg1, blurredImg2, Size(5, 5), 3, 3);
imshow("blurredImg1", blurredImg1);
imshow("blurredImg2", blurredImg2);
waitKey(0);
}
중간 과정을 넣을
namedWindow("blurredImg1", WINDOW_AUTOSIZE); 를 추가했으며,
로 이루어져 있다. src는 원본 소스, dst는 출력할 소스를 의미한다. Size는 가우시안 블러를 어떤 범위로 처리할 것인지에 대한 이야기를 하고 있다. 여기서는 5×5 형태로 만들어주고 있으며, 값에 따른 결과는 한번 확인해보도록 하자.(다만 영역의 중심 픽셀에서부터 처리되므로 홀수로 처리해야 한다.)
가우스안블러는 수학에서 사용되는 수식을 활용하는데, 정확한 수학적 근거를 보고 싶은 사람은 이곳을 방문하자. 수학적인 해석은 차후 시간이 되면 다루도록 하겠다.
* 수식을 풀어서 간단히 요약해서 말하자면 사각형의 범위를 두고 그 범위에 해당하는 수치의 적당한 값으로 수치를 변경해버리는 것이다.
정확한 계산은 아니지만 이런 느낌으로 만들어버리는 것이다.
여기서 추가로 다운 샘플링 등과 같은 복잡한 형태의 이미지 변환도 존재한다. 이는 나중에 다루도록 하겠다.
출처
Computer Vision: Algorithms and Applications, 2nd ed, 2021 Richard Szeliski , szeliski.org/Book/
OpenCV에는 다양한 라이브러리와 모듈이 존재한다. 어떤 모듈이 존재하는지는 OpenCV를 설치한 곳에 가면 볼 수 있으며, 공식 웹사이트에서도 레퍼런스를 얻을 수 있다. 어떤 모듈이 존재하는지만 머릿속에 넣어두면 이를 시기적절하게 써주면 되는 것이다. 마치 공구 상자함에 무엇이 들어있는지 알고 있다면 어떤 일을 하던지 수월하게 할 수 있을 것이다. 하지만 어떤 공구가 들어있는지 인지가 되지 않는다면 힘들게 일할 것이다.
D:\opencv\sources\modules
필자는 D:\에다가 opencv를 설치했으므로 이렇게 나오는 것이지만 설치한 파일에 따라서 다 다르다. 이곳에 기본적인 모듈을 확인할 수 있다.
이렇게 폴더의 형태로 존재함을 볼 수 있다. 각각의 기능을 하나하나 실행시키는 것도 좋은 일이지만, 어떻게 사용하는지 알아볼 수 있는 설명서가 있는데, 그것이 레퍼런스이다.
이곳에 가면 여러가지 모듈을 확인하고 설명서를 볼 수 있다. 자주자주 방문하는 습관을 들이자.
2. 헤더
opencv2/opencv.hpp에는 OpenCV의 모든 기능을 사용할 수 있도록 모든 헤더파일이 포함되어 있다. 그래서 하나만 넣어도 충분히 컴파일이 가능하다. 하지만 닭 잡는데 소 잡는 칼을 쓸 수는 없는 법이다. 물론 그래도 되지만 너무 힘들다. 헤더파일도 마찬가지이다. 너무 큰 헤더 파일은 컴파일 시간을 늘린다. 그러므로 가볍게 만들어주는 것도 중요하다.
#include<opencv2/opencv.hpp> // OpenCV의 기능을 사용할 수 있게 해주는 헤더파일
int main(int argc, char** argv) {
cv::Mat img = cv::imread("cat.png");
imshow("img", img);
cv::waitKey(0);
return 0;
}
실제로 두개를 모두 컴파일 해보면 차이남을 알 수 있다. cv::를 사용하고 싶지 않다면 using namespace cv;를 활용하면 cv::를 붙이지 않아도 된다. 이는 C++에서 클래스 이름을 붙여주는 것이므로 컴파일러에게 사전에 알려주는 것이다.
#include<opencv2/opencv.hpp> // OpenCV의 기능을 사용할 수 있게 해주는 헤더파일
using namespace cv; // namespace cv를 알려줌으로써 미리 선언해주는 역할을 한다.
int main(int argc, char** argv) {
Mat img = imread("cat.png");
imshow("img", img);
waitKey(0);
return 0;
}
여기서 헤더 파일이 너무 많은 헤더 파일을 가지고 있으므로 필요한 기능을 담고 있는 헤더파일만 포함시키면 다음과 같다.
#include"opencv2/highgui/highgui.hpp" // 헤더 파일을 가볍게 만들기 위해 교체!
using namespace cv;
int main(int argc, char** argv) {
Mat img = imread("cat.png");
if (img.empty()) return -1;
namedWindow("img", cv::WINDOW_AUTOSIZE);
imshow("img", img);
waitKey(0);
destroyWindow("img");
return 0;
}
OpenCV에는 다양한 유형의 이미지 파일을 읽을 수 있는 유틸들을 제공한다. 기본 패키지 상에 포함되어 있는 HighGUI는 이를 도와준다. 위의 코드는 HighGUI를 활용해서 이미지 파일(여기서는 cat.png)를 열고 화면 상에 출력해주는 역할을 하고 있다.
여기서 int argc, char** argv는 argument라하는 인수들이 저장되는 공간이 된다. argc는 argument가 몇 개인지 알려주는 것이며, argv는 char형으로 저장되는 변수인데 배열로써 저장된다. 가장 처음에 있는 argv[0]는 실행 파일명이 저장되며, 그 뒤부터 argv[1], argv[2] .... 의 순서대로 사용자가 입력한 argument가 저장된다.
3. 코드 해설
다음 코드를 하나씩 해설해보면서 각각의 코드가 어떤 의미를 가지고 있는지 살펴보도록 하자.
#include"opencv2/highgui/highgui.hpp"
using namespace cv;
int main(int argc, char** argv) {
Mat img = imread("cat.png");
if (img.empty()) return -1;
namedWindow("img", cv::WINDOW_AUTOSIZE);
imshow("img", img);
waitKey(0);
destroyWindow("img");
return 0;
}
헤더 파일은 제외하고 main 함수 내부에 있는 것들을 살펴보도록 하자.
Mat img = imread ("cat.png");
if(img.empty()) return -1;
namedWindow("img", cv::WINDOW_AUTOSIZE);
imgshow("img", img);
waitKey(0);
destroyWindow("img");
이런 순서대로 살펴보도록 하자.
1. Mat img = imread ("cat.png")
먼저 나오는 imread 이다.(namespace cv가 없으면 cv::imread) image read 라고 생각하면 되는데, 파일 이름을 기반으로 파일의 포맷을 결정해준다. 예를 들어, cat.png이므로 파일 포맷 PNG에 해당하는 데이터 구조에 필요한 메모리를 자동으로 할당해주는 것이다. 이미지 파일과 관련된 다양한 포맷을 지원한다. (BMP, JPEG, JPG, PNG, DIB, PPM, TIFF 등등 다양한 이미지 포맷을 지원한다.) imread는 최종적으로 구조체 Mat의 형태로 반환한다.
Mat은 구조체로써 OpenCV의 기본을 이루는 구조체라 봐도 무방할 정도로 많이 쓰이는 구조체이다. 이미지 상에 담고 있는 정보를 처리한다. 이 정보는 단일 채널, 다중 채널, 정수 값, 부동 소수 값 등으로 컴퓨터가 이미지를 받아들이는데 사용되는 다양한 데이터를 의미한다. Mat 구조체의 기본 상속은 다음과 같다.
Mat구조체의 이름을 img라 정했으며, 1번에서 imread를 통해 읽어들인 cat.png 파일을 Mat이라는 구조체 변수, 이름은 img에 넣었다. 이를 통해 img.empty()는 받은 파일이 비어있는지 아닌지를 판단해주는 것이다. 반환값은 true, false로 전달해 준다. (비어있으면 true로 반환해줌, 속에 무언가 들어있으먄 false를 반환)
3. namedWindow("img", cv::WINDOW_AUTOSIZE);
namedWindow 함수는 High-level GUI, HighGUI 모듈에 속하는 함수이다. 화면에 이미지를 표시할 수 있는 윈도우를 열어준다. 인수가 두 가지가 있는데, 첫번째 인수는 윈도우 이름을 지정한다. 만약에 이름이 있으면(중복되면) 아무일도 하지 않는다. 두 번째 인수는 윈도우 사이즈를 결정해주는데,
윈도우 사이즈는 자동으로 이미지 크기와 같을 것인지 - WINDOW_AUTOSIZE (이미지 사이즈에 맞춰 자동 조정되며 이후에 사용자가 조정 가능하다. 하지만 윈도우 창 크기를 마우스로 늘러거나 줄이는 것은 불가능하다. 함수에 의해서 조절해야 한다.)
이미지 사이즈 관계없이 동일한 값으로 만들 것인지 - 0 (기본값이다.), 처음에 만들어진 값은 고정 값으로 만들어지지만, 마우스를 통해 늘리거나 줄이는 것이 가능하다.
HighGUI는 4가지의 주요한 함수가 존재하는데, ButtonCallback, MouseCallBack, OpenGIDrawCallback, TrackbarCallback으로 차례대로 버튼, 마우스, 화면 출력, 트랙바에 해당하는 값을 담당한다. [opencv2/highgui.hpp 헤더에 들어있다.] 기본으로 제공된 함수 외 더 많은 기능을 사용하고자 한다면 Qt 를 활용해서 확장해나가면 된다. Qt는 C++을 통해 GUI를 제작하는 크로스플랫폼 프레임워크이다. (C++외에 다른 언어로도 만들 수 있다.) 자동차 계기판 GUI부터 시작해서 스마트 Tv에 들어가는 GUI까지 다양하게 만들어져있다.
Mat구조체 상에 이미지에 대한 정보가 들어있다면 imgshow를 통해 화면에 출력할 수 있다. (조금 더 정확히는 위에서 만든 윈도우에 출력할 수 있다. 만약에 만들어진 윈도우가 없다면 cv::imshow함수는 cv::namedWindow()를 활용해서 새롭게 생성한다. ) 실제로 보여주는 역할을 하게 해주는 함수이다.
5. waitKey(0);
waitKey(0); 의 기본 원형 int cv::waitKey ( int delay = 0 ) 의 원형을 가지고 있으며, 키 입력이 있을 때까지 기다리는 함수이다. 인수는 밀리세컨드 단위로 대기하는 것이다. 0 또는 음수로 설정이 될 경우에, 키 입력을 무한히 기다리는 형태이다. (항상 조심해야 하는 것은 시간의 단위가 밀리세컨드 단위라는 점이다! - millisecond는 1000 분의 1초이다. 0.5초라면 500 millisecond)
6. destroyWindow("img");
OpenCV는 메모리 사용에 대해서 많은 고려가 되었는데, destroyWindw 또한 메모리 해제와 관련된 함수이다. 일반적으로 표준 템플릿 라이브러리(STL)의 스코프 밖으로 벗어나게 되면 자동으로 메모리 할당이 해제 되지만, 규모가 조금이라도 커진다면 프로그래머가 임의로 해제해줘야 하는 상황이 발생할 수도 있다. destroyWindow는 윈도우를 닫고 관련된 모든 메모리 사용에 대해 해제하는 역할을 해준다. (메모리 누수를 방지하기 위해 중요한 역할을 한다.) 위의 코드 상에는 사실 필요가 없지만, 이러한 것이 있다라는 것을 보여주기 위해 넣어두었다.
OpenCV는 Open Source Computer Vision의 약자로 영상 처리에 사용할 수 있는 오픈 소스 라이브러리 입니다. 컴퓨터가 사람의 눈처럼 인식할 수 있게 처리해주는 역할을 하기도 하며, 우리가 많이 사용하는 카메라 어플에서도 OpenCV가 사용하기도 한다. (추가로 자율주행자동차에서 자동차의 눈이 되주는 것이 카메라와 OpenCV가 합작해서 해낸 일이다.) 추가로 사용되는 예로는
공장에서 제품 검사할 때
의료 영상 처리 및 보정 그리고 판단
CCTV영상
로보틱스
등 다양한 범위에서 사용되고 있다. 카메라로 찍어서 할 수 있는 모든 일은 OpenCV로 처리할 수 있다. 여기에 머신 러닝과 A.I를 활용해서 그 활용도를 더욱 넓혀가고 있는 중이다.
OpenCV가 더욱 인기있는 이유는 오픈소스이지만 BSD(Berkely Software Distribution)라이선스를 따르기 때문에, 상업적 목적으로 사용해도 좋다. 그리고 소스코드 공개 의무가 없다는 점에서 강점을 가지고 있다. OpenCV의 기원은 인텔에서부터 시작되는데, 컴퓨터 비전과 인공지능의 발달 시키고자 하는 바램으로 OpenCV를 출시한 것이다. (with Grary Bradski)
OpenCV는 실시간 처리에 중점을 두고 설계되서 빠른 속도와 효율성을 자랑한다. 기반 언어는 C++로 멀티 코어 프로세서를 활용할 수 있다. 심지어 인텔IPP(Integrated Performance Primitives)를 통한 최적화 루틴을 활용함으로써 로우레벨에서 자동화된 최적화를 사용할 수 있다. 이전에는 유료로 구매해야 했지만, OpenCV 3.0 부터는 IPP의 일부를 무료로 제공해주고 있다.
[사실 인텔은 OpenCV를 배포함으로써 OpenCV가 점차 발전함에 따라 빠른 프로세서가 필요시 되고 이는 인텔 프로세서의 수요가 늘어나 수입이 늘어나는 큰 그림을 그리고 있었다.]
그렇다면 여기서 가장 중요한 단어인 컴퓨터 비전이란 무엇인가?
2. 컴퓨터 비전?
컴퓨터 비전은 카메라로 얻은 일련의 영상들을 모두 컴퓨터 비전이라 한다. 사람은 눈을 통해 많은 정보를 받아들인다. 지금 이 글을 읽는 순간에도 눈을 통해서 읽고 있지 않은가? 프로그래밍에서 항상 생각해보아야 할 것 중 하나의 원칙은 '사람에게 쉬운 일은 컴퓨터에게 어려울 수 있다.'라는 말이다. 컴퓨터 비전 또한 마찬가지이다. 사람에게 너무나 쉬운 보는 일은 컴퓨터에게는 너무나도 어려운 일이다. 하나의 사진에서 사람을 가려내고, 그 속에서 지나는 여러 사물을 골라내는 일은 컴퓨터에게 어렵다. 사람은 이렇게 어려운 일을 자연스럽게 해낸다. 카메라의 역할을 하고 있는 눈은 빛을 자연스럽게 조절하며, 초점을 자동으로 조절한다. 정말 대단한 일인 것이다. 카메라는 이를 일일히 작업해서 맞춰줘야 한다. 카메라가 사진을 찍으면 컴퓨터는 이를 단순한 숫자로 인식할 뿐이다. 오로지 0과 1로 이루어져서 다시 나올 뿐이다.
컴퓨터는 이러한 숫자의 행렬로 사진 및 여러 형태를 인식한다. 그렇다면 우리는 이러한 형태를 가지고 컴퓨터에게 유의미한 정보를 입력해줌으로써 사람이 보는 시선과 최대한 비슷하게 만들어야 하는 것이다. 하지만 여기에는 많은 문제가 도사리고 있다. 우리의 시각 정보는 왜곡이 많다. 예를 들어 우리가 보는 관점에 따라 사물이 왜곡될 확률이 있다. 다른 왜곡은 빛의 양에 따라 달라지기도 하며 비가 오는 경우에는 더욱 심각해진다. 심지어 카메라의 성능에 따라 계속 변한다. 전기적 노이즈도 생각해봐야 한다. 이러한 왜곡을 이겨내고서 우리는 정확한 이미지 처리가 필요한 것이다. (심지어 카메라는 3D 정보를 2D로 받아들이고 있다.)
이 부분에 대한 해결책은 머신러닝 기술로 어느정도 보완하고 있다. 혹은 다른 추가적인 데이터를 활용해서, 예를 들어 라이다 센서 혹은 거리 센서를 활용해서 왜곡정보를 올바르게 해석하기 위한 노력을 하고 있다. 그리고 OpenCV는 이러한 다양한 문제들을 해결하기 위한 도구를 제공해주는 것을 목표로 한다. 지금도 많은 연구가 이루어지고 있으며, 다양한 자료들이 쏟아져 나오고 있다.
OpenCV와 사용할 수 있는 언어로는 C/C++, 파이썬, Java등이 있다. 요새 많이 쓰이는 언어로는 파이썬이 많이 사용되고 있다. 빅데이터와 머신 러닝에서 강점을 보이고 있기에 파이썬이 많이 쓰인다. 하지만 이 블로그에서는 C++을 통해서 사용하도록 할 예정이다. 나중에 기회가 된다면 파이썬을 통한 머신러닝과 딥러닝 그리고 A.I를 사용할 때 파이썬을 사용하려 한다. 하나의 언어를 제대로 배워두면 다른 언어에 대한 장벽은 높지 않은 편이므로 일단은 C++로 진행하려 한다.
3. 기본 구조
OpenCV의 기본 아키텍처는 다음과 같다.
각 요소를 살펴보자면,
CV : Computer Vision으로 기본 구성 요소에서는 기본 이지미 처리와 고급 컴퓨터 비전 알고리즘을 포함하고 있다.
ML (Machine Learning) : 머신러닝이 주를 이루므로 이를 활용할 수 있는 기본적인 통계 분류기와 클러스터링 도구를 포함하고 있는 라이브러리들이 있다.
HighGUI : OpenCV에 기본으로 포함되어 있는 GUI이다. 여기에는 비디오와 이미지 저장 그리고 이를 로드하기 위한 I/O 루틴을 포함하고 있다. 이 모듈을 활용해서 사용자의 입력을 받고 그에 따른 출력하는 기능을 하는 유저 인터페이스 기능을 하고 있다. 기본 기능으로 지원하고 있지만 조금 더 범용적으로 Qt를 사용한다. (윈도우 GUI 툴킷 정도라 생각할 수 있다.)
CXCORE : 이곳에는 기본 데이터 구조와 여러 content가 구성되어 있다.
다른 관점에서 보자면 이러한 아키텍처 구조를 갖는다. 다양한 라이브러리의 모듈이다. 업데이트가 되면 달라지겠지만 현재 모듈 구성은 다음과 같다.
Core - 모든 객체 타입과 기본 연산자가 들어 있는 라이브러리 섹션
Imgproc - 이미지 처리 모듈로써 이미지 변환 등을 포함하고 있다.
highgui - 위에서 설명했다. ( 사용자의 입력을 받는 유저 인터페이스 기능 포함)
video - 비디오 라이브러리로써 비디오 스트림을 read/write하는 함수가 포함되어 있다.
calib3d - 캘리브레이션하는데 필요한 알고리즘이 포함된 모듈
features2d - 중요한 feature(특징)을 탐지하고 표현, 매칭하기 위한 알고리즘이 구현된 모듈
objdetect - 말 그대로 오브젝트 디텍트, 특정 오브젝트를 탐지하는 알고리즘이 들어있는 모듈이다. 이를 머신 러닝으로 기계 학습 시켜서 특정 물체들을 탐지할 수 있다.
ml - 머신러닝 라이브러리
flann - Fast Library for Approximate Nearest Neighbors 나중에 이야기하겠지만, 머신러닝에 사용되는 알고리즘이다. 자세한 내용은
gpu - 그래픽 카드를 이용한 연산을 사용한다. 일명 그래픽카드 연산을 위한 라이브러리이다. CUDA연산에 최적화 되어 있다. 당연히 머신러닝을 위한 설계이다. CUDA (Computed Unified Device Architecture)로써 NVIDIA에서 개발한 GPU 개발툴이다. 딥러닝에서 사용하기 위해서 만들어졌으며, 하드웨어에서는 얻을 수 없는 연산을 할 때 많이 사용된다. 비트코인 채굴할 때 사용하는 것이 CUDA이다. (tensorflow도 사용된다.)
photo - 사진을 활용할 수 있는 다양한 도구를 포함하고 있다.
stitching - 스티치 파이프라인을 구현하기 위한 모듈, Image stitching이란 이미지를 포갤 지점을 찾는 과정이라 생각하면 된다. 이를 빠르게 하는 파이프라인을 구현하기 위한 모듈이라 생각하면 된다.
nonfree - OpenCV에서 특허나 사용 제한이 걸려있는 알고리즘의 구현이 이곳에 있다. ( 예를 들어 SIFT알고리즘)
등이 존재한다.
4. 다운로드 및 설치
앞서 이야기했듯이 설치는 C++로 진행할 예정이다. 바인딩 용 언어는 Java, C++, Python 등을 많이 사용하지만 그 원론에 다가가고자 C++를 이용해서 설치하고 실습해볼 예정이다. 처음 배울 때는 역시 라이브러리가 만들어진 언어 혹은 권장하는 언어가 좋다. 필자는 그냥 C++가 빨라보여서 C++를 사용하고자 한다.