// Movement3D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement3D : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 5.0f; // 이동 속도
private Vector3 moveDirection; // 이동 방향
private CharacterController characterController;
private void Awake()
{
characterController = GetComponent<characterController>();
}
private void Update()
{
characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
}
public void MoveTo(Vector3 direction)
{
moveDirection = direction;
}
}
// PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement3D movement3D;
private void Awake()
{
movement3D = GetComponent<Movement3D>();
}
private void Update()
{
// x, z 방향 이동
float x = Input.GetAxisRaw("Horizontal"); // 방향키 좌/우 움직임
float z = Input.GetAxisRaw("Vertical"); // 방향키 위/아래 움직임
movement3D.MoveTo(new Vector3(x, 0, z));
}
}
CharacterController 컴포넌트는 충돌처리는 가능하지만 중력은 적용되지 않는다
중력은 스크립트를 통하여 입력을 해야한다
// Movement3D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement3D : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 5.0f; // 이동 속도
private Vector3 moveDirection; // 이동 방향
private float gravity = -9.81f; // 중력 계수
private CharacterController characterController;
private void Awake()
{
characterController = GetComponent<CharacterController>();
}
private void Update()
{
if(characterController.isGrounded == false)
{
moveDirection.y += gravity * Time.deltaTime;
}
characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
}
public void MoveTo(Vector3 direction)
{
// moveDirection = direction;
moveDirection = new Vector3(direction.x, moveDirection.y, direction.z);
}
}
CharacterController.isGround
발 위치의 충돌을 체크해 충돌이 되면 true, 충돌이 되지 않으면 false값을 나타내는 변수
if (characterController.isGrounded == false) { moveDirection.y += gravity * Time.deltaTime; }
// Movement3D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement3D : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 5.0f; // 이동 속도
[SerializeField]
private float jumpForce = 3.0f; // 뛰는 힘
private float gravity = -9.81f; // 중력 계수
private Vector3 moveDirection; // 이동 방향
private CharacterController characterController;
private void Awake()
{
characterController = GetComponent<CharacterController>();
}
private void Update()
{
if (characterController.isGrounded == false)
{
moveDirection.y += gravity * Time.deltaTime;
}
characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
}
public void MoveTo(Vector3 direction)
{
// moveDirection = direction;
moveDirection = new Vector3(direction.x, moveDirection.y, direction.z);
}
public void JumpTo()
{
if (characterController.isGrounded == true)
{
moveDirection.y = jumpForce;
}
}
}
// PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Movement3D movement3D;
private KeyCode jumpKeyCode = KeyCode.Space;
private void Awake()
{
movement3D = GetComponent<Movement3D>();
}
private void Update()
{
// x, z 방향 이동
float x = Input.GetAxisRaw("Horizontal"); // 방향키 좌/우 움직임
float z = Input.GetAxisRaw("Vertical"); // 방향키 위/아래 움직임
movement3D.MoveTo(new Vector3(x, 0, z));
// 점프키(스페이스)를 눌러 y축 방향으로 뛰어오르기
if (Input.GetKeyDown(jumpKeyCode))
{
movement3D.JumpTo();
}
}
}
- Slope Limit
경사 한계 각도, 위와 같이 45도로 되어있으면 45도까지의 경사만 올라갈 수 있다
- Step Offset
서로 인접한 두 계단 사이의 높이가 Step offset 이하일 때 계단을 올라 갈 수 있다
카메라 오브젝트가 플레이어를 쫓아 다니도록 플레이어 오브젝트의 자식으로 설정을 한다
// Movement3D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement3D : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 5.0f; // 이동 속도
[SerializeField]
private float jumpForce = 3.0f; // 뛰는 힘
private float gravity = -9.81f; // 중력 계수
private Vector3 moveDirection; // 이동 방향
private CharacterController characterController;
[SerializeField]
private Transform cameraTransform; // 카메라 Transform 컴포넌트
private void Awake()
{
characterController = GetComponent<CharacterController>();
}
private void Update()
{
if (characterController.isGrounded == false)
{
moveDirection.y += gravity * Time.deltaTime;
}
characterController.Move(moveDirection * moveSpeed * Time.deltaTime);
}
public void MoveTo(Vector3 direction)
{
// 카메라가 보고있는 전방방향 기준으로 이동할 수 있도록
Vector3 moveDdis = cameraTransform.rotation * direction;
// 회전 값을 방향 정보에 곱해 준다
moveDirection = new Vector3(moveDdis.x, moveDirection.y, moveDdis.z);
}
public void JumpTo()
{
if (characterController.isGrounded == true)
{
moveDirection.y = jumpForce;
}
}
}
CameraController
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraController : MonoBehaviour { private float rotateSpeedX = 3; private float rotateSpeedY = 5; private float limitMinX = -80; private float limitMaxX = 50; private float eulerAngleX; private float eulerAngleY; public void RotateTo(float mouseX, float mouseY) { // 마우스를 좌/우로 움직이는 mouseX 값을 y축에 대입하는 이유는 // 마우스를 좌/우로 움직일 때 카메라도 좌/우를 보려면 카메라 오브젝트의 // y축의 회전되어야 하기 때문 eulerAngleY += mouseX * rotateSpeedX; // 감은 개념으로 카메라가 위/아래를 보려면 카메라 오브젝트의 x축이 회전한다 eulerAngleX -= mouseY * rotateSpeedY; // x축 회전 값의 경우 아래, 위를 볼 수 있는 제한 각도가 설정되어 있다 eulerAngleX = ClampAngle(eulerAngleX, limitMinX, limitMaxX); // 실제 오브젝트의 쿼터니온 회전에 적용 transform.rotation = Quaternion.Euler(eulerAngleX, eulerAngleY, 0); } // 최대 최소 각도를 설정하여 기정한 값을 넘기지 않도록 만든다 private float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; // Mathf.Clamp()를 이용해 angle이 min <= angle <= max를 유지하도록 한다 return Mathf.Clamp(angle, min, max); } }
PlayerController
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { private Movement3D movement3D; [SerializeField] private KeyCode jumpKeyCode = KeyCode.Space; [SerializeField] private CameraController cameraController; private void Awake() { movement3D = GetComponent<Movement3D>(); } private void Update() { // x, z 방향 이동 float x = Input.GetAxisRaw("Horizontal"); // 방향키 좌/우 움직임 float z = Input.GetAxisRaw("Vertical"); // 방향키 위/아래 움직임 movement3D.MoveTo(new Vector3(x, 0, z)); // 점프키(스페이스)를 눌러 y축 방향으로 뛰어오르기 if (Input.GetKeyDown(jumpKeyCode)) { movement3D.JumpTo(); } float mouseX = Input.GetAxis("Mouse X"); // 마우스 좌/우 움직임 float mouseY = Input.GetAxis("Mouse Y"); // 마우스 위/아래 움직임 cameraController.RotateTo(mouseX, mouseY); } }