스크립트 라이프 사이클, InputManager와 InputSystem, TileMap

유승아·2024년 5월 9일

내일배움캠프

목록 보기
39/69

1. 스크립트 작성 방법

MonoBehaviour를 상속받은 클래스를 작성한다.
Start(), Update(), FixedUpdate() 등을 활용하기 위해서 MonoBehaviour를 상속받는 것은 필요하다.
(Unity에서 제공한 이벤트 함수를 활용하기 위해서)

게임 오브젝트에 연결된 컴포넌트로써 동작을 하게 된다.
변수, 함수, 이벤트 등을 정의하고 구현한다.

Start() 게임 오브젝트가 처음 시작할 때 호출
Update() 매 프레임마다 호출
FixedUpdate() 매 물리 업데이트마다 호출

1) 스크립트 라이프 사이클

MonoBehaviour를 상속받는 클래스들은 Unity 이벤트 함수를 활용할 수 있다.

Awake 가장 먼저 실행
OnEnable OnEnable이 활성화되어 있을 때 발생
Start 까지 첫 프레임 시작하기 전에 발동

FixedUpdate 매 물리 업데이트마다 발생
물리 업데이트랑 관련된 OnTrigger, OnCollision 발생
Update 매 프레임마다 발생
LateUpdate 렌더링과 직접적으로 관련되어 있는 것(카메라 이동 등) 관리

OnDisable 꺼졌을 때
OnDestroy 파괴됐을 때
OnApplicationQuit 프로그램 껐을 때


2. 핵심 기능

1) Pixels Per Unit(PPU)

Unit = Unity Size 1
1Unit이 몇 Pixel이냐?
→ 스프라이트의 픽셀수와 해당 스프라이트가 게임 세계에서 차지하는 공간의 관계

스프라이트의 크기

PPU 값이 클수록 스프라이트는 작아진다.
더 많은 픽셀이 동일한 게임 세계의 공간에 매핑되기 때문

물리 시뮬레이션

PPU 값은 물리 시뮬레이션에 영향을 미친다.
높은 PPU 값은 더 작은 스프라이트를 생성하므로, 더 높은 해상도의 물리 시뮬레이션을 가능하게 한다.
더 작은 스프라이트가 되면 물리 시뮬레이션이 달라질 수 있다.

일관성

모든 스프라이트에 대해 일관된 PPU 값을 사용하는 것이 좋다.
스프라이트 간의 크기 비율을 일정하게 유지하고, 물리적 행동의 일관성을 보장하는 데 도움이 된다.

2) 계층구조(Transform 구조)

각 게임 오브젝트는 Transform 컴포넌트를 가지고, Transform 컴포넌트는 게임 오브젝트의 위치, 회전 및 크기를 정의한다.

부모 게임 오브젝트의 Transform이 변경되면, 그 자식 오브젝트들의 Transform도 동일하게 적용된다.

게임 오브젝트들 사이에 계층적인 관계가 형성되고, 이를 '트리 구조'라고 부른다.

🤔 이름이 왜 Transform인지?

Transform의 데이터들이 부모에 대한 변환(Transformation)을 나타내고 있기 때문

3) 로컬 좌표계와 월드 좌표계

로컬 좌표계(Local Coordinate System)

유니티에서 인스펙터창에서 볼 수 있는 position, scale, retation 등이 로컬 좌표계에 따른 값에 해당한다.
월드 좌표계가 아닌 부모에 대한 좌표를 말하며, 부모에 대해 x축으로 2만큼 떨어져 있으면 이 오브젝트의 로컬 포지션은 (2, 0, 0)이 되는 것이다.
스크립트에서는 localPosition, localRotation, localScaale 등이 있다.

월드 좌표계(World Coordinate System)

게임 세계의 전체적인 참조 프레임을 제공한다.
모든 게임 오브젝트가 공유하며, 월드 좌표계에서의 위치는 게임 환경 내에서 오브젝트의 절대적인 위치를 나타낸다. 월드 좌표계는 변하지 않고 일정하게 유지된다.
스크립트에서는 position, rotation, lossyScale 를 통해 참조한다.

4) Input.GetAxis

유니티의 입력 시스템에서 사용되는 메서드, 입력 축의 값을 반환한다.
Input Manager의 대표적인 기능

5) Time.deltaTime

이전 프레임부터 현재 프레임까지의 경과 시간
게임의 프레임 속도에 상관없이 일정한 시간 간격으로 동작하는 게임을 만들 때 유용하게 사용
주로 움직임, 애니메이션, 물리 시뮬레이션 등에서 시간에 따른 변화를 조정하는 데 사용

Time.deltaTime은 초 단위의 값을 반환하며, 1초에 1 값을 가진다.
게임의 로직이 매 프레임마다 일정한 속도로 실행되어야 할 때, deltaTime을 이용하여 이동, 회전, 애니메이션 등의 연산에 일정한 시간 간격을 적용할 수 있다.
이를 통해 게임이 일정한 속도로 동작하고, 다양한 기기나 환경에서도 일관된 경험을 제공할 수 있다.

6) 접근 제한자와 직렬화 속성

Public

변수나 메서드가 외부에서 접근 가능하도록 공개
다른 클래스나 스크립트에서 해당 멤버에 접근하여 값을 설정하거나 호출

Private

변수나 메서드가 같은 클래스 내에서만 접근 가능하도록 제한
다른 클래스나 스크립트에서는 접근할 수 없고, 해당 클래스 내부에서만 사용
보통 내부 상태를 관리하거나 내부 구현에 사용

SerializeField

private으로 선언된 변수를 인스펙터에서 직접 접근
기본적으로 private 변수는 인스펙터에 표시되지 않지만, SerializeField를 사용하면 해당 변수가 인스펙터에서 수정 가능한 필드로 표시


3. 이동 기본 코드 작성

InputManager로 작성해보기

↓ 캐싱 작업


4. InputManager 문제점

조이스틱 등 다양한 입력 장비 대응

현재 InputManager에서는 다양한 플래새폼에 대응하거나, 키를 변경하는 리바인딩하는 등의 부분이 부족하다.

입력 처리와 실제 로직 실행 주체 분리

구현한 내용들이 모두 한 클래스에 모여있어, 클래스에 대한 확장성과 유지 보수성이 많이 떨어지는 문제가 있다. 기능별로 클래스를 나누는 것은 설계에 많은 도움을 준다.

객체지향 프로그래밍에서 이런 설계 원칙을 단일 책임 원칙(Single Responsibility Principle) 이라고 한다.

한 대상이 하나의 역할만 하도록!


5. New Input System

Input Action

점프, 공격 등의 입력 행동을 정의
행동을 트리거하는 키 또는 버튼을 지정할 수 있음

Input Action Asset

여러 개의 입력 행동을 그룹화

Player Input Component

자동으로 입력 행동을 처리하고 해당 게임 오브젝트에 메시지를 보냄

1) 장점

Cross-Platform Compatibility

다양한 플랫폼과 입력 장치에 대해 일관된 방식으로 작동

Rebinding

플레이어가 게임 내에서 자신의 입력 설정을 변경할 수 있도록 지원

Multiplayer Support

여러 플레이어가 동일한 장치에서 게임을 플레이하거나, 각각의 장치에서 게임을 플레이할 때 입력을 쉽게 처리할 수 있음

2) Package 추가하기

Unity는 한 프로젝트가 차지하는 용량이 작아질 수 있도록 기본 패키지를 포함하지 않고 출시를 한다.
Package Manager를 들어가서 추가를 해주자.

Window - Package Manager - Unity Register - Input System - Install

3) New Input System 준비하기

Input 폴더 생성 후 Create - Input Action

Control Scheme 만들기
XBox용, PC용 등 분류 나누기

키보드와 마우스를 추가할 때 좌클릭은 클릭이 안 되지만 우클릭은 됨🤣

Player Action Map 추가
Player가 할 수 있는 Action들 추가할 것.

Action 단위로 등록할 것임

세팅 다 하면 Player 오브젝트 생성 후 적용시키기


6. 플레이어 만들기

TopDownController 스크립트
캐릭터랑 몬스터의 공통적인 기능들을 넣어 놓는 곳

PlayerInputController 스크립트
지시하고 실제로 행동은 하지 않는 관리자

TopDownMovement 스크립트
실제 움직임이 발생하는 곳

아까 만들었던 InputManager 와 다른 점?
확장하기 편한 구조로 만들었다.


7. TileMap

Unity에서 충돌과 관련하여 중요한 개념은 Collider와 Rigidbody 컴포넌트이다.
이 컴포넌트들은 Unity에서 물리 시뮬레이션과 충돌 감지를 처리하는데 필수적이다.

Collider

충돌하는 범위를 나타내는 컴포넌트
게임 오브젝트에 물리적 형태를 부여함
이는 충돌 감지를 가능하게 한다.
모양에 따라서 Box, Sphere, Mesh 등의 Collider를 제공한다.

Rigidbody

게임 오브젝트에 물리 법칙을 적용
중력에 영향을 받게 하고, 힘과 토크를 통해 움직일 수 있다.(물리적인 대상이 된다)

충돌이 되는 대상 중 한 쪽(움직이는 쪽)에는 Rigidbody 컴포넌트가 있어야짐만 Collider가 충돌을 할 수 있다.
움직이는 쪽이 물리 시뮬레이션을 하면서 충돌 체크를 하기 때문이다.
Trigger 충돌도 Rigidbody 필요하다.

Trigger는 물리적인 충돌이 아닌, 들어왔는지 확인하는 것
Collision은 물리적 충돌이 같이 수반되는 것

Tilemap Renderer

실제로 모양을 그리는 것

Tilemap Collider 2D

Tilemap에 충돌을 걸고 싶을 때 사용
게임 캐릭터가 타일맵 환경과 상호작용할 수 있게 됨

Tile Assets

Tile 관리하는 파일들

강의를 따라서 맵을 만들어보았다.

0개의 댓글