Character Controller를 이용하여 점프를 구현해보자.
PlayerMovement 스크립트를 이어서 사용한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 5;
public float rotationSpeed = 720;
// 점프 속도 설정
public float jumpSpeed = 5;
private CharacterController characterController;
// 현재 적용받는 y의 속도값
private float ySpeed;
// CharacterController의 StepOffset 설정값
private float originalStepOffset;
private void Start()
{
characterController = GetComponent<CharacterController>();
// 설정된 StepOffset값 저장
originalStepOffset = characterController.stepOffset;
}
void Update()
{
//..증략
// 중력에 의한 ySpeed 감소
ySpeed += Physics.gravity.y * Time.deltaTime;
// 지상에 있는 경우만 점프
if(characterController.isGrounded)
{
// 기존 설정값으로 다시 설정
characterController.stepOffset = originalStepOffset;
// 안정된 점프를 위한 초기화
ySpeed = -0.8f;
// 점프
if (Input.GetButtonDown("Jump"))
{
ySpeed = jumpSpeed;
}
}
else
{
// 점프 중에는 어딜 올라갈 필요가 없으니 0으로 설정
characterController.stepOffset = 0;
}
// 점프 속도를 포함한 velocity 계산
Vector3 velocity = movementDirection * magnitude;
velocity.y = ySpeed;
// Move() 메서드로 변경
characterController.Move(velocity * Time.deltaTime);
//...중략
}
}
CharacterController.Move
public CollisionFlags Move (Vector3 motion);
Grounded 체크 가능
중력에 영향 받지 않음
Time.deltaTime은 내장 되어있지 않음
ySpeed가 계속 감소하기 때문에 높은 곳에서 떨어질 때 지면에 바로 스냅하는 문제가 발생한다. 이를 해결하기 위해 땅에 접지해있을 때는 ySpeed를 초기화해주도록 한다.
if(characterController.isGrounded)
{
ySpeed = -0.8f;
}
여기서 ySpeed를 0이 아닌 -0.8로 초기화해주는 이유는 isGrounded 체크의 불안정성으로 ySpeed의 값이 더욱 감소했다가 0으로 초기화되는 문제를 해결하기 위함이다.
벽으로 점프하게 되면 Character Controller의 Step Offset 속성으로 인해 계단을 타는 듯한 현상이 발생하게 된다. 이를 해결하기 위해 낙하 중일 때는 Step Offset의 값을 0으로 설정해준다.
if(characterController.isGrounded)
{
characterController.stepOffset = originalStepOffset;
}
else
{
characterController.stepOffset = 0;
}