개요
저번 글을 올린 뒤 바로 적고 있는 개발일지 입니다.
시간이 없기 때문에 주말 시간이 비는 때에 최대한 해놓으려고 합니다.
개요 더 적을 시간도 없군요. 글 적으면서 마저 개발합시다.
사전 준비
먼저 사용할 여러가지 패키지들을 임포트 해줍니다.
UI에서 아주 잘 사용할 DOTween이나 New InputSystem, Cinemachine 등을 말이죠.
모델 구하기
일단 저번 글에서 마저 설명 못한 게임 그래픽 컨셉에 대해 알려드리겠습니다.
일단 기본적인 그래픽 스타일은 고스트러너를 따라갈텐데 제가 그정도의 모델을 가져올 방법이 없으니 대충 컨셉정도만 빌려온다고 생각하시면 됩니다.
이런 곳에서 주인공이 사람이면 이건 이거대로 기시감이 들기때문에 주인공은 이 귀여운 로봇입니다.
그리고 사실 모델보단 애니메이션이 중요합니다.
이건 Adobe에서 무료로 제공해주는 킹갓Mixamo를 통해 구해줍니다.
여기 있는 공격 모션을 토대로 넣을 무기들을 대충 추렸습니다.
네, 그게 전 글에 있던 주먹, 카타나, 망치, 양손 도끼 입니다.
New Input System
플레이어의 Animation을 간단한 것들(Idle, Run, Jump) 정도는 프로젝트에 추가해두었습니다.
물론 당장 쓸건 아니죠.
...이 윗 문장까지 쓰고 저는 다시 작업에 들어갔습니다.
그리고선 일단 플레이어 움직이는 코드부터 짜기는 커녕 작업 속도에 비례해 추가될까말까 한 카타나 애니메이션을 엄청나게 만져댔습니다.
이건 나중에 서술하고
아무튼, New Input System을 넣었으니 Player의 Input을 받기 위해 저 아래 숨어있는 Create > Input Actions 을 만들어줍니다.
그 뒤에 스킴?을 만들어 주면 되는데 전 패드를 지원 할 생각이 당장은 없기 때문에 키보드, 마우스만 넣어서 만들어줍니다.
그 후 Input을 용이하게 껐다 켰다 할 수 있는 InputAction을 Player로 구분해 주고 당장 구상해놓은 간단한 Action들을 만듭니다.
Crouch 같은 경우엔 일단 나중이긴 한데 대충 넣어 두었습니다.
근데 키 바인딩을 하다보니 Crouch, 그러니까 앉기 키의 기본 키 바인딩을 어떻게 해야할지 궁금해졌죠.
전 무조건 Shift만 쓰는 편이지만 Ctrl도 많이 쓰는 것 같아 보여서 설문조사를 해봤습니다.
음... Ctrl의 압승입니다.
기본 키 바인딩은 Ctrl로 하죠.
Input Action의 설정은 끝이 났습니다.
New Input System을 사용하는 방법이야 여러가집니다.
Player에게 Player Input이란 컴포넌트를 붙여놓고 사용하는 것도 그 방법중 하나죠.
Player Input의 방식엔 여러가지가 있지만 다 선호하지 않습니다.
그렇기 때문에 만들어놓았던 Input Action에 Generate C# Script를 체크해줍니다.
이렇게 하면 만들어놓았던 Input Action과 똑같은 이름의 C# 스크립트가 나올텐데 내용을 뜯어보면... 잘 모르겠습니다.
이 스크립트에서 저희가 주목해야 할 부분은 이부분 입니다.
인터페이스가 있죠?
이 것을 클래스에 붙여놓고 On~ 함수들을 구현해주면 알아서 마법처럼 알아서 실행되는! 그런건 아니구요.
간단하게 구현해줘야 할게 있습니다.
이 함수들을 Input이 들어올때마다 실행해주도록 이 인터페이스를 상속받는 클래스를 붙여줄 수 있는 함수가 있습니다.
이것을 사용하여 저희는 Input을 관리할겁니다.
그러기 위해선 Control라는 클래스를 인스턴스화 해주는 애랑 IPlayerActions를 상속하는 애도 있어야겠죠?
그 애는 관리하기 편하도록 ScriptableObject로 만듭시다.
IPlayerActons 상속 받고...
OnEnable에 Controls 만들어주고 Callback의 주체가 이 클래스가 된다고 알려줍시다.
그리고 Player의 Input을 활성화 해줍니다.
활성화 하지 않으면 Input이 들어가지 않으니 주의합시다.
그리고선 당장 구현하지 않아서 오류를 뱉어대는 IPlayerActions를 구현해줍니다.
OnCameraRotate는 제가 이 글 쓰면서 개발 하다가 나중에 추가한 것입니다.
멍청하게도 FPS인데 1인칭 카메라만 있고 카메라가 움직이지 않는 진풍경을 선보일뻔했죠.
아무튼 저렇게 인터페이스를 구현하면 알아서 해당하는 Input이 들어왔을때 저 함수를 실행해줍니다.
만약 Input을 받을때 특정 값을 받아오게 설정해두었다면 매개변수로 넘어오는 InputAction.CallbackContext 를 통해 받아올 수 있죠.
들어온 Input에 따라 Vector2 값을 받아오기로 설정해둔 OnMove에서 사용해보겠습니다,
Legacy Input에선 GetAxisRaw와 비슷합니다.
public void OnMove(InputAction.CallbackContext context)
{
Vector2 input = context.ReadValue<Vector2>();
}
음... 너무 간단하죠?
이게 끝입니다.
와 New Input System 개날먹이네요?
Input 관리를 유연하게 하기 위해 Action을 사용해서 필요할때마다 구독했다가 빼주는 작업을 거치게 하겠습니다.
public event Action<Vector2> OnMoveEvent;
public event Action<Vector2> OnCameraRotateEvent;
public event Action OnJumpEvent;
public event Action OnCrouchDownEvent;
public event Action OnCrouchUpEvent;
public event Action OnAttackEvent;
싹다 적어주고
public void OnAttack(InputAction.CallbackContext context)
{
OnAttackEvent?.Invoke();
}
public void OnCrouch(InputAction.CallbackContext context)
{
if (context.performed)
OnCrouchDownEvent?.Invoke();
if (context.canceled)
OnCrouchUpEvent?.Invoke();
}
public void OnJump(InputAction.CallbackContext context)
{
OnJumpEvent?.Invoke();
}
public void OnMove(InputAction.CallbackContext context)
{
Vector2 input = context.ReadValue<Vector2>();
OnMoveEvent?.Invoke(input);
MoveInput = input;
}
public void OnCameraRotate(InputAction.CallbackContext context)
{
CamDelta = context.ReadValue<Vector2>();
}
Invoke만 해주면 끝입니다.
정말 간단하죠? 이제 때에 맞게 함수를 구독했다가 빼기만 하면 Input은 간단하게 처리할 수 있습니다.
마치는 말
이 글을 마무리 하기 전에 개발을 지속하며 여러모로 작고 작은 사건사고가 있었습니다.
그건 다음 글에 플레이어 FSM을 적으며 한번 풀어보죠.
'개발 > UNNAMED' 카테고리의 다른 글
UNNAMED | 네번째 프로젝트 # 5 : 적 FSM (0) | 2024.06.08 |
---|---|
UNNAMED | 네번째 프로젝트 # 4 : 총 (0) | 2024.06.02 |
UNNAMED | 네번째 프로젝트 # 3 : Player FSM (0) | 2024.06.01 |
UNNAMED | 네번째 프로젝트 # 2 : FPS Player Movement (0) | 2024.06.01 |
UNNAMED | 네번째 프로젝트 # 0 : 기획 (0) | 2024.05.24 |