오늘부터 유니티를 시작했다.
오늘 과제에 대한 개발 내용은 없고 공부한 내용이 어려운 부분이 많아서 정리를 해야한다.
원래 알고있고 슥 넘어갈만한 부분은 제외하고 어려운 부분만 싹 가져와서 정리해본다.
유니티에서 1 단위당 픽셀의 비율이다. PPU 50이면 1칸당 픽셀 50이 공간을 차지한다.
가로 16 픽셀의 스프라이트를 1칸에 채우고 싶으면 스프라이트의 PPU를 16으로 설정하면 된다.
PPU가 높아질 수록 엔진에서 부담하는 것이 높아진다.
솔직히 이거 외우는건 말이 안되니까 여기다가 적어놓고 나중에 필요할 때 또 봐야겠다.
Input System
을 설치한다.Input Actions
를 선택하여 생성한다. (이름은 상관없음)Action Maps
를 하나 생성해준다.Action Maps
는 입력 방법의 모음 같은 것이고, 나중에 플레이어 객체에 컴포넌트에 붙였을 때 선택해줄 수 있다.Actions
를 "Move"라는 이름으로 하나 생성해준다. 이 이름은 나중에 이벤트 처리에서 중요하다.Actions
는 어떤 키의 입력을 받을 것인지에 대해 설정할 수 있다.Action Type
을 Value
로Control Type
을 Vector2
로 해준다.Player Input
이라는 컴포넌트를 붙여준다.Actions
에는 2번부터 7번까지 만든 것을 넣어준다.Default Map
에는 4번에서 만든 Action Maps
를 선택할 수 있다.public class CharacterController : MonoBehaviour
{
public event Action<Vector2> OnMoveEvent;
public event Action<Vector2> OnLookEvent;
public void CallMoveEvent(Vector2 direction)
{
OnMoveEvent?.Invoke(direction);
}
public void CallLookEvent(Vector2 direction)
{
OnLookEvent?.Invoke(direction);
}
}
나중에 입력에 따라서 호출할 메서드들을 받아놓을 이벤트 멤버는 클래스 CharacterController
에 모아놓는다.
외부에서 클래스에 있는 이벤트 멤버에 접근할 수 없으니 이벤트를 호출하는 Call~
메서드도 만들어준다.
CallMoveEvent
의 내용은 아래와 같다.
if(OnMoveEvent != null)
OnMoveEvent(direction);
Invoke는 특별한 기능은 없고 델리게이트의 메서드를 호출한다는 것을 명시하는 용도라고 생각하면 편하다.
이 코드가 제일 중요하다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerInputController : CharacterController
{
private Camera _camera;
private void Awake()
{
_camera = Camera.main; // 활성화된 카메라 중 "MainCamera" 태그 가진 Camera get
}
//InputValue : 인풋 시스템에 있는 클래스
public void OnMove(InputValue value)
{
Vector2 moveInput = value.Get<Vector2>().normalized;
CallMoveEvent(moveInput);
}
public void OnLook(InputValue value)
{
Vector2 newAim = value.Get<Vector2>();
//전체 스크린 좌표계에 종속된 마우스의 위치를 게임 화면의 좌표계로 변경
Vector2 worldPos = _camera.ScreenToWorldPoint(newAim);
newAim = (worldPos - (Vector2)transform.position).normalized;
if(newAim.magnitude >= .9f)
CallLookEvent(newAim);
}
public void OnFire(InputValue value)
{
Debug.Log("OnFire" + value.ToString());
}
}
using UnityEngine.InputSystem;
을 사용함으로써Send Messages
기능을 사용할 수 있다.Input Actions
에서 만들었던 Move
, Look
, Fire
는 각각 설정했던 키의 입력이나 알맞은 값이 들어오면 OnMove
, OnLook
, OnFire
를 호출한다. 그리고 이 함수들은 재정의가 가능한 것 같다.각 On~
함수에서는 CharacterController
에서 상속 받은 이벤트 호출 함수를 호출한다.
간략히 말하면 이 클래스는 플레이어의 입력에 따라서 이벤트를 호출하는 메서드가 모인 클래스이다.
public class TopDownMovement : MonoBehaviour
{
private CharacterController _controller;
private Vector2 _movementDirection = Vector2.zero;
private Rigidbody2D _rigidbody;
private void Awake()
{
_controller = GetComponent<CharacterController>();
_rigidbody = GetComponent<Rigidbody2D>();
}
void Start()
{
_controller.OnMoveEvent += Move;
}
private void FixedUpdate()
{
ApplyMovement(_movementDirection);
}
private void Move(Vector2 direction)
{
_movementDirection = direction;
}
private void ApplyMovement(Vector2 direction)
{
direction = direction * 5;
_rigidbody.velocity = direction;
}
}
Start()
에서는 일단 CharacterController
의 이벤트에 시그니처가 맞는 Move 메서드를 등록한다.
Move()
에서는 전달 받은 벡터 값으로 방향만 정해준다.
FixedUpdate()
에서 ApplyMovement()
를 방향을 인자로 계속 호출.
ApplyMovement()
에서는 받은 방향에 일정 값 곱해서 강체의 속도로 할당해줌.
충돌은 간단하다.
입문 강의를 받아서 공부를 시작했는데,, 이거 입문이 아니라 중급으로 올라가는 난이도를..
(많은 분들이 당황하셨을 것 같다.)
솔직히 유튜버 골드메탈의 친절한 강의 수준을 생각했는데 그런거 없이 바로 불맛 난이도..
내가 필요로 하던 수준의 강의이긴 한데 너무 갑작스런 만남이라 좀 당황스럽다.
델리게이트, 이벤트의 활용은 꼭 알고싶었던 부분인데 갑자기 다가와서 이해하느라 오늘 진을 다 뻈다.
(갑작스런 패턴과의 만남 ㅋㅋㅋ)
어..일단 나의 특기인 [글 정리로 어떻게든 이해하기]를 계속 시전해야겠다는 생각뿐이다.
new input system과 이벤트 처리의 연계는 나중에 잘 정리해서 유니티 시리즈에 넣어놔야겠다.
아무리봐도 코드와 입력 처리 방식이 고급지고 참 좋아보인다.
파이팅이다.