게임개발/게임플랫폼 응용 프로그래밍
좀비 서바이버 (1) 플레이어 이동하기
pudding81
2024. 3. 6. 13:06
플레이어를 따라다니는 카메라
렌즈 줌인 Vertical FOV 숫자가 작을수록 가까워짐
바디 카메라와 플레이어와의 간격 , 이동의 제동값을 신속하게
조준 추적대상에서 얼마나 더 떨어진 곳을 조준할지, 회전속도에 대한 제동값을 지연시간없이
키보드 입력으로 앞 뒤로 이동하기
앞 1 / 뒤 -1
회전 방향으로 방향 바꾸기
오른쪽 1 / 왼쪽 -1
총 발사 입력 여부 확인 : 마우스 왼쪽을 클릭하면 true
재장전 입력 여부 확인 : R키를 눌러도 아직 false
재생속도가 1 또는 -1에 가까울 수록 걷다가 -> 뛰는 애니메이션으로 변화함.
using UnityEngine;
// 플레이어 캐릭터를 조작하기 위한 사용자 입력을 감지
// 감지된 입력값을 다른 컴포넌트들이 사용할 수 있도록 제공
public class PlayerInput : MonoBehaviour {
public string moveAxisName = "Vertical"; // 앞뒤 움직임을 위한 입력축 이름 --
public string rotateAxisName = "Horizontal"; // 좌우 회전을 위한 입력축 이름 --
public string fireButtonName = "Fire1"; // 발사를 위한 입력 버튼 이름 --마우스 왼쪽 버튼
public string reloadButtonName = "Reload"; // 재장전을 위한 입력 버튼 이름 --r
// 값 할당은 내부에서만 가능
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() {
// 게임오버 상태에서는 사용자 입력을 감지하지 않는다
if (GameManager.instance != null && GameManager.instance.isGameover)
{
move = 0;
rotate = 0;
fire = false;
reload = false;
return;
}
// move에 관한 입력 감지
move = Input.GetAxis(moveAxisName);
Debug.LogFormat("앞 뒤 이동 {0}", move); // 뒤 -1
// rotate에 관한 입력 감지
rotate = Input.GetAxis(rotateAxisName);
Debug.LogFormat(" 오른쪽 왼쪽 방향 {0}", rotate); //왼쪽 -1
// fire에 관한 입력 감지
fire = Input.GetButton(fireButtonName);
Debug.LogFormat("총 발사 {0}", fire); // 마우스 클릭
// reload에 관한 입력 감지
reload = Input.GetButtonDown(reloadButtonName);
Debug.LogFormat("총알 재장전 {0}", reload); //r키
}
}
using UnityEngine;
// 플레이어 캐릭터를 사용자 입력에 따라 움직이는 스크립트
public class PlayerMovement : MonoBehaviour {
public float moveSpeed = 5f; // 앞뒤 움직임의 속도
public float rotateSpeed = 180f; // 좌우 회전 속도
private PlayerInput playerInput; // 플레이어 입력을 알려주는 컴포넌트
private Rigidbody playerRigidbody; // 플레이어 캐릭터의 리지드바디
private Animator playerAnimator; // 플레이어 캐릭터의 애니메이터
private void Start() {
// 사용할 컴포넌트들의 참조를 가져오기
playerAnimator = GetComponent<Animator>();
playerRigidbody = GetComponent<Rigidbody>();
playerInput = GetComponent<PlayerInput>();
}
// FixedUpdate는 물리 갱신 주기에 맞춰 실행됨
private void FixedUpdate() {
// 물리 갱신 주기마다 움직임, 회전, 애니메이션 처리 실행
Rotate();
Move();
//무브 파라미터값 변경
playerAnimator.SetFloat("Move", playerInput.move); // -1~ 1의 값
}
// 입력값에 따라 캐릭터를 앞뒤로 움직임
private void Move() {
//이동할 거리 계산
// playerInput.move -1이면 뒤쪽
Vector3 moveDistance = playerInput.move * transform.forward *moveSpeed *Time.deltaTime;
Debug.LogFormat("이동거리 {0}",moveDistance);
//위치변경 / 물리처리 실행 +
playerRigidbody.MovePosition(playerRigidbody.position + moveDistance);
}
// 입력값에 따라 캐릭터를 좌우로 회전
private void Rotate() {
//회전할 수치 계산
float turn =playerInput.rotate *rotateSpeed * Time.deltaTime;
Debug.LogFormat("회전방향 {0}", turn);
//회전 방향 변경 y축 회전 *
playerRigidbody.rotation =playerRigidbody.rotation* Quaternion.Euler(0,turn,0);
}
}
move 앞을 바라본채로 앞 뒤로 이동하기
rotate 회전 방향만 변경하기
회전방향을 변경한 후 앞 뒤로만 움직일 수 있음
-------------------------------
변경 후
이동과 회전을 동시에 할수 있음
카메라의 위치와 방향키의 위치가 동일함
using UnityEngine;
// 플레이어 캐릭터를 사용자 입력에 따라 움직이는 스크립트
public class PlayerMovement : MonoBehaviour {
public float moveSpeed = 5f; // 앞뒤 움직임의 속도
public float rotateSpeed = 180f; // 좌우 회전 속도
private PlayerInput playerInput; // 플레이어 입력을 알려주는 컴포넌트
private Rigidbody playerRigidbody; // 플레이어 캐릭터의 리지드바디
private Animator playerAnimator; // 플레이어 캐릭터의 애니메이터
private Camera mainCamera; // 메인 카메라
private Vector3 dir; // 입력받은 벡터
private Vector3 move;// 최종 이동 벡터
private void Start() {
// 사용할 컴포넌트들의 참조를 가져오기
playerAnimator = GetComponent<Animator>();
playerRigidbody = GetComponent<Rigidbody>();
playerInput = GetComponent<PlayerInput>();
mainCamera =Camera.main;
}
private void FixedUpdate() {
// 물리 갱신 주기마다 움직임, 회전, 애니메이션 처리 실행
Rotate();
Move();
//무브 파라미터값 변경
playerAnimator.SetFloat("Move", dir.magnitude); // -1~ 1의 값
}
private void Move() {
// 입력받은 벡터
dir = new Vector3(playerInput.rotate, 0, playerInput.move);
// 카메라의 방향에 기반한 이동 방향 계산
Vector3 cameraForward = mainCamera.transform.forward;
Vector3 cameraRight = mainCamera.transform.right;
// 카메라가 바라보는 방향에서의 Y축 영향 제거
cameraForward.y = 0;
cameraRight.y = 0;
cameraForward.Normalize();
cameraRight.Normalize();
// 최종 이동 벡터 계산
move = (cameraForward * playerInput.move + cameraRight * playerInput.rotate) * moveSpeed;
// Rigidbody를 이용하여 캐릭터 이동
playerRigidbody.velocity = move;
}
private void Rotate() {
if (move != Vector3.zero)
{
// 캐릭터가 이동 방향을 바라보도록 회전
Vector3 targetDirection = playerRigidbody.position + move;
transform.LookAt(targetDirection);
}
}
}