이번게임에서는 키보드의 입력과 플레이어의 이동 로직을 분리한다. 이렇게 하는것이 업그레이드 관리에 용이하기 때문이다. 우선 입력부분부터 만들어본다.
Player를 선택하고 Add Component>Script add하고 이름을 PlayerInput으로 바꾼다.
Input.GetAxis()에 사용될 스트링의 선언이다.
public string moveAxisName = "Vertical"; // 앞뒤 움직임을 위한 입력축 이름
public string rotateAxisName = "Horizontal"; // 좌우 회전을 위한 입력축 이름
public string fireButtonName = "Fire1"; // 발사를 위한 입력 버튼 이름
public string reloadButtonName = "Reload"; // 재장전을 위한 입력 버튼 이름
키보드 입력을 받아올 변수의 정의 인데 잘보면 프로퍼티라고 클래스이다. 변수와 다른점을 클래스 안에서 필요에 따라 좀더 유연한 정의가 가능하다는 점이다.
public float move { get; private set; } // 감지된 움직임 입력값
public float rotate { get; private set; } // 감지된 회전 입력값
public bool fire { get; private set; } // 감지된 발사 입력값
public bool reload { get; private set; } // 감지된 재장전 입력값
Update()함수는 Input.GetAxis()함수를 이용해 입력값을 읽어와 프로퍼티에 저장한다.
PlayerInput 전체코드
using UnityEngine;
// 플레이어 캐릭터를 조작하기 위한 사용자 입력을 감지
// 감지된 입력값을 다른 컴포넌트들이 사용할 수 있도록 제공
public class PlayerInput : MonoBehaviour {
public string moveAxisName = "Vertical"; // 앞뒤 움직임을 위한 입력축 이름
public string rotateAxisName = "Horizontal"; // 좌우 회전을 위한 입력축 이름
public string fireButtonName = "Fire1"; // 발사를 위한 입력 버튼 이름
public string reloadButtonName = "Reload"; // 재장전을 위한 입력 버튼 이름
// 값 할당은 내부에서만 가능
public float move { get; private set; } // 감지된 움직임 입력값
public float rotate { get; private set; } // 감지된 회전 입력값
public bool fire { get; private set; } // 감지된 발사 입력값
public bool reload { get; private set; } // 감지된 재장전 입력값
// 매프레임 사용자 입력을 감지
private void Update() {
// move에 관한 입력 감지
move = Input.GetAxis(moveAxisName);
// rotate에 관한 입력 감지
rotate = Input.GetAxis(rotateAxisName);
// fire에 관한 입력 감지
fire = Input.GetButton(fireButtonName);
// reload에 관한 입력 감지
reload = Input.GetButtonDown(reloadButtonName);
}
}
이제 움직임을 담당할 PlayerMovement를 만들어본다.
앞뒤 움직임 속도, 회전속도를 지정할 변수를 설정한다.
public float moveSpeed = 5f; // 앞뒤 움직임의 속도
public float rotateSpeed = 180f; // 좌우 회전 속도
Start()함수에서 PlayerInput(), Rigidbody()컴포넌트 참조를 가져온다. PlayerInput()도 Player오브젝트의 컴포넌트로 추가되어 있어야한다.
private void Start() {
// 사용할 컴포넌트들의 참조를 가져오기
playerInput = GetComponent<PlayerInput>();
playerRigidbody = GetComponent<Rigidbody>();
}
FixedUpdate()함수는 Unity에서 Rigidbody컴포넌트 처리(물리갱신주기)가 이루어지는 곳이다. 여기서 움직임을 처리한다. Update()는 화면갱신주기이다.
private void FixedUpdate() {
// 회전 실행
Rotate();
// 움직임 실행
Move();
// 입력값에 따라 애니메이터의 Move 파라미터 값을 변경
//playerAnimator.SetFloat("Move", playerInput.move);
}
Move()와 Rotate()는 Rigidbody.MovePosition()메써드나 position을 변경해도 된다. 주의할점은 게임오브젝트의 transform.position을 사용해도 되지만 Rigidbody컴포넌트가 추가되어 있을때는 계산의 엉킴을 방지하기위해 리지드바디에서 처리하는게 좋은듯 하다.
private void Move() {
// 상대적으로 이동할 거리 계산
Vector3 moveDistance =
playerInput.move * transform.forward * moveSpeed * Time.deltaTime;
// 리지드바디를 통해 게임 오브젝트 위치 변경
playerRigidbody.MovePosition(playerRigidbody.position + moveDistance);
//playerRigidbody.position += moveDistance;
}
Quaternion.rotation의 회전의 + 가 아니라 * 이다. 행렬계산을 해야하기 때문이다. 따라서 회전시키고 싶은 오일러각(Vector3)를 Quaternion.Euler()로 변경시켜 곱해줘서 회전을 하게 만들어 준다.
private void Rotate() {
// 상대적으로 회전할 수치 계산
float turn =
playerInput.rotate * rotateSpeed * Time.deltaTime;
// 리지드바디를 통해 게임 오브젝트 회전 변경
playerRigidbody.rotation = playerRigidbody.rotation * Quaternion.Euler(0, turn, 0f);
}
PlayerMovement 전체코드, 이번 강좌에서는 Animator를 사용하지 않기 때문에 주석처리되어있다
using UnityEngine;
// 플레이어 캐릭터를 사용자 입력에 따라 움직이는 스크립트
public class PlayerMovement : MonoBehaviour {
public float moveSpeed = 5f; // 앞뒤 움직임의 속도
public float rotateSpeed = 180f; // 좌우 회전 속도
//private Animator playerAnimator; // 플레이어 캐릭터의 애니메이터
private PlayerInput playerInput; // 플레이어 입력을 알려주는 컴포넌트
private Rigidbody playerRigidbody; // 플레이어 캐릭터의 리지드바디
private void Start() {
// 사용할 컴포넌트들의 참조를 가져오기
playerInput = GetComponent<PlayerInput>();
playerRigidbody = GetComponent<Rigidbody>();
//playerAnimator = GetComponent<Animator>();
}
// FixedUpdate는 물리 갱신 주기에 맞춰 실행됨
private void FixedUpdate() {
// 회전 실행
Rotate();
// 움직임 실행
Move();
// 입력값에 따라 애니메이터의 Move 파라미터 값을 변경
//playerAnimator.SetFloat("Move", playerInput.move);
}
// 입력값에 따라 캐릭터를 앞뒤로 움직임
private void Move() {
// 상대적으로 이동할 거리 계산
Vector3 moveDistance =
playerInput.move * transform.forward * moveSpeed * Time.deltaTime;
// 리지드바디를 통해 게임 오브젝트 위치 변경
playerRigidbody.MovePosition(playerRigidbody.position + moveDistance);
}
// 입력값에 따라 캐릭터를 좌우로 회전
private void Rotate() {
// 상대적으로 회전할 수치 계산
float turn =
playerInput.rotate * rotateSpeed * Time.deltaTime;
// 리지드바디를 통해 게임 오브젝트 회전 변경
playerRigidbody.rotation = playerRigidbody.rotation * Quaternion.Euler(0, turn, 0f);
}
}
'유니티좀비게임 > 레벨아트와 플레이어' 카테고리의 다른 글
시네머신 (0) | 2023.04.27 |
---|---|
레벨아트및 플레이어 만들기 (0) | 2023.04.27 |