[Unity3D] Character Controller 점프

oy Hong·2024년 5월 1일

점프


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가 계속 감소하기 때문에 높은 곳에서 떨어질 때 지면에 바로 스냅하는 문제가 발생한다. 이를 해결하기 위해 땅에 접지해있을 때는 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;
}

0개의 댓글