Unity Chapter 11-5. 좀비 TPS 게임 만들기 : Player Input, Player 컴포넌트들
카테고리: Unity Lesson 1
태그: Unity Game Engine
인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!
Chapter 11. 좀비 TPS 게임 만들기
🔔 Player의 컴포넌트들
Character Controller 컴포넌트
Rigidbody의 물리 시스템을 필요로 하지 않는 캐릭터에게 움직이는 기능을 부여할 때 사용하는 컴포넌트
Rigidbody
를 사용하지 않는다.- 즉, 사실적인 물리시스템을 사용하지 않는다.
Rigidbody
는 현실적인 물리 기반(중력, 마찰력 등등 적용)으로 이루어지기 때문에 수정 없이 사용하면 실제 게임과 어울지 않을 수 있다.- 즉 너무 사실적으로 현실과 비슷하게 물리를 적용하면 안됨.
- FPS, TPS 게임에서는 플레이어가 멈추면 바로 딱 멈추어야 하는데
Rigidbody
가 붙어있다면 관성에 의해 바로 안멈추고 조금 움직일 것이다.
- FPS, TPS 게임에서는 플레이어가 멈추면 바로 딱 멈추어야 하는데
- 예상치 못한 플레이어의 움직임이 발생할 수 있다.
- 즉 너무 사실적으로 현실과 비슷하게 물리를 적용하면 안됨.
- Character Controller 컴포넌트는 Collider를 확장해서 만들어진 컴포넌트이기 때문에 기본으로 캡슐 모양의 Collider가 장착 되어 있다.
- ⭐움직임 대부분을 개발자의 코드에 의해서 통제하게 한다.
- 사실적인 물리시스템을 사용하지 않고 움직임을 내가 통제한다.
파라미터 조정
캡슐 모양의 Collider 모양 조정. 대략 플레이어의 모습과 일치하도록.
- Center
- Y : 0.9
- Radius
- 0.3
- Height
- 1.8
Audio Source
플레이어가 공격 받았을 때 소리를 낼 수 있도록 붙여준다.
- Play On Awake 는 체크 해제.
📜PlayerInput.cs
플레이어의 입력을 감지하고 이를 다른 컴포넌트들에게 알리는 역할만 딱 수행한다.
입력을 감지하는 부분과 입력에 따라 플레이어를 동작하게 하는 다른 기능(컴포넌트)들과는 분리가 되어 있다. 유지 보수를 위하여! 👉 각 컴포넌트들이 자기만의 입력 감지 코드를 가지게 되면 수정시 일일이 다 찾아가야 하기 때문에 매우 힘들 것이다.
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
public string moveHorizontalAxisName = "Horizontal"; // 좌우 회전을 위한 입력축 이름 (👉유니티 입력 설정에 기본으로 추가 되있는 이름)
public string moveVerticalAxisName = "Vertical"; // 앞뒤 움직임을 위한 입력축 이름 (👉유니티 입력 설정에 기본으로 추가 되있는 이름)
public string fireButtonName = "Fire1"; // 발사를 위한 입력 버튼 이름 (👉유니티 입력 설정에 기본으로 추가 되있는 이름)
public string jumpButtonName = "Jump"; // 점프를 위한 입력 버튼 이름 (👉유니티 입력 설정에 기본으로 추가 되있는 이름)
public string reloadButtonName = "Reload"; // 재장전을 위한 입력 버튼 이름
// 값 할당은 내부에서만 가능
public Vector2 moveInput { get; private set; } // Horizontal, Vertical
public bool fire { get; private set; } // 감지된 발사 입력값
public bool reload { get; private set; } // 감지된 재장전 입력값
public bool jump { get; private set; } // 감지된 점프 입력값
// 매 프레임 사용자 입력을 감지
private void Update()
{
// 게임오버 상태에서는 사용자 입력을 감지하지 않는다
if (GameManager.Instance != null
&& GameManager.Instance.isGameover)
{
moveInput = Vector2.zero;
fire = false;
reload = false;
jump = false;
return;
}
moveInput = new Vector2(Input.GetAxis(moveHorizontalAxisName), Input.GetAxis(moveVerticalAxisName));
if (moveInput.sqrMagnitude > 1) moveInput = moveInput.normalized;
jump = Input.GetButtonDown(jumpButtonName);
fire = Input.GetButton(fireButtonName);
reload = Input.GetButtonDown(reloadButtonName);
}
}
- “Reload” 는 유니티 기본 입력 설정에 없으니까 추가해주기
- 유니티 - Edit - Project Settings - Input - Axes
- size를 1 늘리면 새롭게 추가 되는데 이걸 “Reload”로 수정하고 positive button에
r
를 추가해주자.- 이제
r
버튼 누르면 “Reload” 로 연결 되게끔!
- 이제
- 프로퍼티들
moveInput
,fire
,reload
,jump
get
할 때 👉 자동 호출set
은 private 👉 클래스 내부에서만 값 할당 가능. 외부에서 write 할 수 없다.
- private void Update()
- 매 프레임마다 유저의 입력을 감지한다.
- 게임 오버 상태면 유저의 입력을 전부 기본값으로 설정한 후 update 함수를 종료시켜버린다.
- 게임 오버 상태
- 게임 오브젝트(싱글톤)가 존재하고 and isGameOver 플래그가 true이면
- return
- update 함수 종료
- 게임 오버 상태
- 유저 입력 감지하기
moveInput = new Vector2(Input.GetAxis(moveHorizontalAxisName), Input.GetAxis(moveVerticalAxisName));
moveInput
은 애니메이션을 섞을 정도를 결정하는, 수평 방향 입력 값, 수직 방향 입력 값을 담는 벡터2 다.if (moveInput.sqrMagnitude > 1) moveInput = moveInput.normalized;
- 대각선 방향 이동 처리 (즉 두 키를 한꺼번에 누를 때)
- 조이스틱으로 입력시 수평, 수직 입력 값이 길이가 1인 원 테두리에 위치한듯이 적절히 입력이 되기 때문에 수평, 수직 입력 Vector2의 길이가 언제나 1이지만
- 키보드로 입력시 수평, 수직 입력 값이 그냥 따로 따로 들어가기 때문에 두 값이 1이라면 길이가 \(\sqrt{2}\) 인 Vectro2가 되버린다.
- 이렇게 되면 조이스틱보다 키보드로 입력할 때 더 빠르게 이동하는 것이 되버리므로 벡터의 길이 제곱(sqrtMagnitude)이 1을 넘을 때 똑같은 방향의 길이가 1인 벡터(normalized)로 바꾸어 준다.
- 그냥 벡터의 길이(magnitude)가 1을 넘는다고도 할 수 있지만 벡터의 길이를 구하는건 제곱근 연산을 해야 하기때문에 제곱근 연산은 좀 무겁다. 어차피 길이의 제곱이 1을 넘으면 길이도 1을 넘기 때문에 그냥 길이의 제곱이 1을 넘느냐를 따짐.
-
착각하지 말것 👉 여기서 수평, 수직은 양옆, 앞뒤 을 뜻한다. 즉 게임 월드 상에서의 Y 방향 (수직)을 말하는게 아니라는 것 !
moveInput
은 Vector2이며moveInput.x
는 게임 월드 상에서의 x 방향 이동을 뜻하는 Input.GetAxis(moveHorizontalAxisName) 양옆 이동 입력 값을 뜻함.moveInput.y
는 게임 월드 상에서의 y 방향이 아닌 !!!!! 그저 Vector2에서 두번째 인수로 넘겨서 y로 접근했던 것 뿐인, 어쩌면 유니티 게임월드 상에서는 z 방향에 가까운 Input.GetAxis(moveVerticalAxisName) 잎 뒤 이동을 뜻한다. 유니티 게임 웓드 상에서 y 방향이라고 착각하지 말기!
- 게임 오버 상태면 유저의 입력을 전부 기본값으로 설정한 후 update 함수를 종료시켜버린다.
- 매 프레임마다 유저의 입력을 감지한다.
📜PlayerMovement.cs
플레이어의 입력에 따라 플레이어를 움직인다. 입력을 감지하는건 📜PlayerInput.cs가 하기 때문에 입력을 감지하는 부분은 빠져있다.
- 다음 포스트 PlayerMovement 참고!
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기