Unity Chapter 11-5. 좀비 TPS 게임 만들기 : Player Input, Player 컴포넌트들

Date:     Updated:

카테고리:

태그:

인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!


Chapter 11. 좀비 TPS 게임 만들기

🔔 Player의 컴포넌트들

Character Controller 컴포넌트

Rigidbody의 물리 시스템을 필요로 하지 않는 캐릭터에게 움직이는 기능을 부여할 때 사용하는 컴포넌트

  • Rigidbody를 사용하지 않는다.
    • 즉, 사실적인 물리시스템을 사용하지 않는다.
    • Rigidbody는 현실적인 물리 기반(중력, 마찰력 등등 적용)으로 이루어지기 때문에 수정 없이 사용하면 실제 게임과 어울지 않을 수 있다.
      • 즉 너무 사실적으로 현실과 비슷하게 물리를 적용하면 안됨.
        • FPS, TPS 게임에서는 플레이어가 멈추면 바로 딱 멈추어야 하는데 Rigidbody가 붙어있다면 관성에 의해 바로 안멈추고 조금 움직일 것이다.
      • 예상치 못한 플레이어의 움직임이 발생할 수 있다.
  • Character Controller 컴포넌트는 Collider를 확장해서 만들어진 컴포넌트이기 때문에 기본으로 캡슐 모양의 Collider가 장착 되어 있다.
    • image
  • ⭐움직임 대부분을 개발자의 코드에 의해서 통제하게 한다.
    • 사실적인 물리시스템을 사용하지 않고 움직임을 내가 통제한다.

파라미터 조정

image

캡슐 모양의 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 할 때 👉 자동 호출
    • setprivate 👉 클래스 내부에서만 값 할당 가능. 외부에서 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;
          
        • image
        • 대각선 방향 이동 처리 (즉 두 키를 한꺼번에 누를 때)
          • 조이스틱으로 입력시 수평, 수직 입력 값이 길이가 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 방향이라고 착각하지 말기!


📜PlayerMovement.cs

플레이어의 입력에 따라 플레이어를 움직인다. 입력을 감지하는건 📜PlayerInput.cs가 하기 때문에 입력을 감지하는 부분은 빠져있다.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기


댓글남기기