유니티를 설치하고, 오브젝트 만들기부터 코드를 적용시켜 실행하기까지 게임 개발의 기초적인 부분을 학습했다.
프로젝트 명은 <빗물받는 르탄이>로, 하늘에서 떨어지는 빗물을 받아 점수를 모으는 게임을 만드는 것이다.
게임을 만들기 위해서는 게임이 실행될 환경이 구축되어야 한다. 2D 탬플릿의 새로운 프로젝트를 생성하고, 작업하기 쉬운 레이아웃으로 변경한 뒤 본격적인 제작에 들어갔다.
▼ 레이아웃 변경을 통한 작업 환경 구축
[ 오브젝트 ]
추가
구성 요소인 오브젝트를 추가하는 방법은 Hierarchy 창에서 우클릭 후, 2D Object > Sprites > 모양 선택을 하면 된다. 배경 화면을 만들기 위해서 네모 오브젝트를 추가했다.
추가된 오브젝트는 Inspector 창에서 다양한 속성을 부여할 수 있다.
Transform에서는 위치, 회전, 크기 변화를 줄 수 있고, Sprite Renderer에서는 sprite 종류, 색상 등을 바꿀 수 있다. 이러한 것들을 컴포넌트라고 하는데, 이외에도 스크립트, 애니메이션 등 다양한 컴포넌트를 추가할 수 있다.
이동
Inspector의 Transform 말고도 씬에서 오브젝트 위에 나오는 화살표를 이용해서 움직일 수도 있다.
초록색 화살표를 잡고 드래그하면 상하로 움직일 수 있고, 빨간색 화살표를 잡고 드래그하면 좌우로 움직일 수 있다. 파란색 사각형을 잡고 드래그하면 자유롭게 움직일 수 있다.
[ 애니메이션 ]
애니메이션을 만들고, 적용하고 싶은 씬을 클릭 후 맨 아래 빈 공간에 드래그를 하면 오브젝트에 추가가 된다.
애니메이션을 클릭하고 Loop Time의 체크박스를 활성화해서 애니메이션이 반복되게 한다.
설정하고 싶은 애니메이션을 더블 클릭하면 창이 열린다. 그리고 사용하고 싶은 사진을 원하는 시간에 드래그한다. 그러면 두 개의 사진이 번갈아가며 실행되어 캐릭터가 연속해서 움직이는 것처럼 보인다.
[ 스크립트 ]
프로젝트의 빈 공간을 우클릭해서 C# Script를 추가해 준다. 스크립트를 오브젝트에 적용하고 창을 불러오는 것은 애니메이션과 동일하다.
using 부분은 C#의 네임스페이스를 가져오는 역할을 한다. 네임스페이스는 함수 또는 함수의 연합인 클래스의 집합으로, 이름 충돌을 방지한다. 따라서 이름이 중복돼서 사용되어도 네임스페이스가 다르면 사용할 수 있다.
class는 객체의 설계도 같은 개념으로, 하나의 클래스를 정의함으로써 코드를 중복해서 사용하는 수고를 덜 수 있다. public은 해당 클래스가 어디에서든 접근 가능함을 의미하고, 'Rtan'은 클래스의 이름이며 'MonoBehaviour' 클래스를 사용한다는 것을 의미한다. MonoBehaviour는 유니티에서 스크립트를 게임 오브젝트에 연결하여 이벤트 기반 로직을 처리하는 데 사용되는 기본 클래스다.
클래스에서 수행하는 작업을 메소드라고 하는데, Start와 Update 모두 메서드이다.둘의 차이점은 호출 횟수이다.
void Start()는 게임 오브젝트가 활성화되었을 때 한 번만 호출되며, 초기화할 로직을 구현한다.
void Update()는 매 프레임마다 호출되며, 반복하고 싶은 로직을 구현한다.
[ 캐릭터 움직이기 ]
캐릭터 이동
void Update()
{
transform.position += new Vector3(0.05f, 0, 0);
}
캐릭터를 오른쪽으로 움직이게 하려면 다음과 같은 코드를 사용한다. 코드를 해석해보면 Transform 컴포넌트의 Position 속성을 가져오는 것이다. Vector3은 3차원 벡터를 의미하며, 소괄호 내에서 차례대로 X, Y, Z 값을 가진다. 따라서 해당 코드는 매 프레임마다 오브젝트가 X축 방향으로 0.05만큼 움직이는 것을 의미한다.
void Update()
{
transform.position += new Vetor3.right * 0.05f;
}
또는 (1, 0, 0)의 의미를 함축하고 있는 right를 사용할 수도 있다. left는 (-1, 0, 0)을 의미한다. 각 X축 방향으로 1, -1씩 움직이는 것을 의미한다. 위 코드와 같게 해 주려면 * 0.05f를 해준다.
참고로 스크립트에서 컴포넌트를 불러오려면, 스크립트가 있는 Inspector 안에 해당 컴포넌트가 함께 있어야 한다.
void Start()
{
Application.targetFrameRate = 60;
}
Update 메소드는 매 프레임마다 호출된다. 프레임은 1초에 화면에 표시되는 횟수로, 컴퓨터의 성능이 좋을수록 1초에 연산할 수 있는 횟수가 많아지고 프레임 또한 많아진다. 하지만 컴퓨터의 성능에 따라 캐릭터가 움직이는 속도가 다르면 안 되기 때문에, 이를 고정시키기 위해서 Start 메서드에 프레임을 60으로 설정하는 코드를 추가한다.
캐릭터 움직임 방향 변환
이후 프로젝트를 실행시키면, 캐릭터가 오른쪽 방향으로 무한정 움직이게 된다. 캐릭터가 화면 내에서 계속 보일 수 있도록 벽에 부딪히면 방향을 바꾸는 코드를 추가하기 위해, 먼저 캐릭터가 벽에 닿았을 때의 X 값이 2.6인 것을 확인한다.
public class Rtan : MonoBehaviour
{
float direction = 0.05f;
void Start()
{
Application.targetFrameRate = 60;
}
void Update()
{
if(transform.position.x > 2.6f)
{
direction = -0.05f;
}
if(transform.position.x < -2.6f)
{
direction = 0.05f;
}
transform.position += Vector3.right * direction;
}
}
0.05f라고 적어놨던 것을 direction 변수를 따로 설정해서 초기화 값으로 저장한다.
그리고 Update 메소드에 if문을 이용해서 X값이 2.6보다 크면 direction은 -0.05f가 되게 한다. 그러면 위치가 (-0.05f, 0, 0) 돼서 왼쪽으로 움직이게 된다. 반대로 X값이 -2.6보다 작으면 direction은 다시 0.05f가 되고, (0.05f, 0, 0)으로 변화하여 오른쪽으로 움직이게 된다.
캐릭터 이미지 방향 변환
이미지의 방향을 바꾸는 데 영향을 미치는 것은 Sprite Renderer의 Flip이다.
그중에서도 X축 방향인 수평 뒤집기를 하려면 X 체크박스를 활성화하면 된다. 반대로 Y축 방향인 수직 뒤집기를 하려면 Y 체크박스를 활성화하면 된다.
public class Rtan : MonoBehaviour
{
float direction = 0.05f;
SpriteRenderer renderer;
void Start()
{
Application.targetFrameRate = 60;
renderer = GetComponent<SpriteRenderer>();
}
void Update()
{
if(Input.GetMouseButtonDown(0))
{
direction *= -1;
renderer.flipX = !renderer.flipX;
}
if(transform.position.x > 2.6f)
{
renderer.flipX = true;
direction = -0.05f;
}
if(transform.position.x < -2.6f)
{
renderer.flipX = false;
direction = 0.05f;
}
transform.position += Vector3.right * direction;
}
}
먼저 SpriteRenderer 타입의 변수인 renderer를 선언한다. 하지만 현재 아무런 값도 없는 null 상태이므로, GetComponent<SpriteRenderer>()를 통해서 SpriteRenderer 컴포넌트를 renderer 변수에 할당한다. 이렇게 초기화를 시키면 renderer 함수가 SpriteRenderer 컴포넌트에 접근할 수 있는 권한을 갖게 된다.
Update 메서드에서는 마우스 왼쪽 버튼을 클릭했을 때, 이미지가 반대로 변화한다는 조건문을 작성한다. 마우스는 클릭, 스크롤과 같은 입력 정보를 발생하는데, 이처럼 키보드, 마우스와 같은 외부 입력 장치의 정보가 Input에 담겨있다.
GetMouseButtonDown()은 클릭했을 때를 기준으로 불리언 값을 반환한다. 클릭하면 true, 클릭하지 않으면 false이다. 비슷한 것으로 마우스를 클릭 후 뗀 것을 감지하는 GetMouseButtonUp(), 마우스 버튼을 계속해서 누르고 있는 것을 감지하는 GetMouseButton()이 있다.
괄호 안의 숫자는 마우스의 버튼을 의미한다. 0은 왼쪽, 1은 오른쪽, 2는 가운데(휠)이다.
따라서 Input.GetMouseButtonDown(0)은 마우스 왼쪽 버튼을 클릭했는지를 판단하는 코드이다.
해당 조건문을 해석해보면 마우스 왼쪽 버튼을 클릭했다면: true → 조건문 실행
direction에 1을 곱하고: 캐릭터 방향 전환
flipX 버튼의 불리언 값을 반대로 변화시킨다: true(버튼 활성화) → false(버튼 비활성화), false → true
※! 연산자는 불리언의 반대 값을 반환한다.
클릭 이벤트 외에도 벽에 부딪혔을 때 이미지 방향 변화를 주기 위해서, 아래의 조건문에도 renderer.flipX의 불리언 값을 지정해준다.
[ 회고 ]
오늘의 목표는 1주 차 강의를 모두 수강하는 것이었는데, 절반 밖에 듣지 못했다.
그 이유로는 외부 요인과 내부 요인으로, 크게 두 가지가 있다.
<외부 요인>
1. 본 캠프 OT와 팀 회의 진행
본격적인 캠프에 앞서 진행된 OT가 약 2시간 정도가 소요됐다. 이후 팀끼리 S.A. 내용을 채우기 위한 회의를 진행했고, ZEP 서버 문제로 회의가 신속하게 이루어지지 못했다. 또한 일주일 간 원활한 팀 프로젝트를 위해 노션을 수정하는데 시간이 추가로 소요되어, 오롯이 공부할 수 있는 시간이 다른 날보다 적었다.
→ 2일 차부터는 이러한 특수 일정이 없기 때문에, 공부할 시간이 확보되었다.
<내부 요인>
1. 모든 코드를 분석하려는 태도
스크립트를 생성했을 때 기본적으로 주어지는 코드부터, 코드를 설명할 때 등장하는 개념들까지 모두 파악을 하려고 하니 다소 예상보다 시간이 오래 걸린다.
→ 하지만 계속해서 공부를 하기 위해서는 필요한 단계라고 생각되기 때문에, 다른 코드들도 공부하되 상대적으로 중요하지 않은 코드에 대해서는 완벽하게 이해할 때까지 깊게 파고들지 않도록 한다.
2. 컨디션에 따른 집중력 저하
전날 알바, 타 프로젝트 회의 등 15시간 동안 쉬지 않고 활동을 한 뒤, 충분한 휴식을 취하지 못해 컨디션이 좋지 않았다. 피곤한 상태로 공부를 하려니 집중이 잘 되지 않고, 졸음이 쏟아져서 시간을 허비한 부분이 있었다.
→ 스케줄 조정을 통해 최상의 컨디션을 유지하고, 피곤하면 커피나 에너지 드링크를 마시며 졸음을 깨려는 노력을 한다.
<내일 목표>
1. 나머지 1주 차 강의 수강
2. 2주 차 강의 전체 수강
'Coding > Unity' 카테고리의 다른 글
[내일배움캠프 17일차 TIL] 게임 엔진, PPU, 계층 구조, Input.GetAxis, 직렬화 (0) | 2024.05.08 |
---|---|
[내일배움캠프 5일차 TIL] 복습, 체력바, isKinematic, isTrigger, 레벨 (1) | 2024.04.19 |
[내일배움캠프 4일차 TIL] 복습, 마우스 포인터 추적, 점수 저장 (1) | 2024.04.18 |
[내일배움캠프 3일차 TIL] UI, 싱글톤, 점수 적용, 게임 오버, 다시 시작 (0) | 2024.04.17 |
[내일배움캠프 2일차 TIL] 오브젝트 중력, 충돌, 파괴, 랜덤, 반복, 클래스 (0) | 2024.04.16 |