본문 바로가기

Unity

[Unity] 캐릭터 점프

이번에는 캐릭터의 점프를 구현해보겠습니다. 먼저 초기 코드입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float Speed = 10.0f;

    public float rotateSpeed = 10.0f;

    public float jumpForce = 1.0f;          // 점프하는 힘

    Rigidbody body;                         // 컴포넌트에서 RigidBody를 받아올 변수

    float h, v;

    // 유니티 실행과 동시에 한번 실행되는 함수
    void Start()
    {
        body = GetComponent<Rigidbody>();   // GetComponent를 활용하여 body에 해당 오브젝트의 Rigidbody를 넣어준다.
    }

    // Update is called once per frame
    void Update()
    {

    }

    // 이동 관련 함수를 짤 때는 Update보다 FixedUpdate가 더 효율이 좋다고 한다. 그래서 사용했다.
    void FixedUpdate()
    {
        Move();
        Jump();
    }

    // 이전 FixedUpdate에 있던 것을 보기 좋게 묶기 위해 Move로 옮김
    void Move()
    {
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");

        Vector3 dir = new Vector3(h, 0, v); 

        if (!(h == 0 && v == 0))
        {
            transform.position += dir * Speed * Time.deltaTime;
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * rotateSpeed);
        }
    }

    void Jump()
    {
        // 스페이스바를 누르면(또는 누르고 있으면)
        if (Input.GetKey(KeyCode.Space))
        {
            // body에 힘을 가한다(AddForce)
            // AddForce(방향, 힘을 어떻게 가할 것인가)
            body.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
        }
    }
}

 

jumpForce와 body를 추가했고, Start함수에서 body를 정의하였습니다. 이후 Jump 함수에서 기능을 구현하였습니다. 

저기서 방향은 Vector3.up(위 방향)에 jumpForce를 곱하여 위로 어느 정도의 힘만큼 뛰어오를지를 설정하였고, ForceMode.Impurse를 사용하여 순간적으로 힘을 주는 방식으로 구현하였습니다. 

 

ForceMode에는 4가지 속성이 있으며, 이를 자세히 알고 싶으시다면 m.blog.naver.com/gold_metal/221486016593 를 참고하시면 좋을 것 같습니다.

 

[유니티 강좌] ForceMode 종류

이번 강좌에서는 AddForce 와 AddTorque를 다루어보았는데요,여기서 공통적으로 사용하는 ForceMode...

blog.naver.com

 

 

이제 이대로 실행하면 점프는 잘 되는데, 공중에서도 점프가 계속 될 수 있다는 것을 알 수 있습니다. 이러한 현상을 개선해보도록 합시다.

 

먼저 Ground에 태그를 추가해주도록 합니다. 저는 태그명 또한 Ground로 설정하겠습니다.

 

태그를 설정했다면 코드를 수정해봅시다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float Speed = 10.0f;

    public float rotateSpeed = 10.0f;

    public float jumpForce = 10.0f;          // 점프하는 힘

    private bool isGround = true;           // 캐릭터가 땅에 있는지 확인할 변수

    Rigidbody body;                         // 컴포넌트에서 RigidBody를 받아올 변수

    float h, v;

    // 유니티 실행과 동시에 한번 실행되는 함수
    void Start()
    {
        body = GetComponent<Rigidbody>();   // GetComponent를 활용하여 body에 해당 오브젝트의 Rigidbody를 넣어준다.
    }

    // Update is called once per frame
    void Update()
    {

    }

    // 이동 관련 함수를 짤 때는 Update보다 FixedUpdate가 더 효율이 좋다고 한다. 그래서 사용했다.
    void FixedUpdate()
    {
        Move();
        Jump();
    }

    // 이전 FixedUpdate에 있던 것을 보기 좋게 묶기 위해 Move로 옮김
    void Move()
    {
        h = Input.GetAxis("Horizontal");
        v = Input.GetAxis("Vertical");

        Vector3 dir = new Vector3(h, 0, v);

        if (!(h == 0 && v == 0))
        {
            transform.position += dir * Speed * Time.deltaTime;
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * rotateSpeed);
        }
    }

    void Jump()
    {
        // 스페이스바를 누르면(또는 누르고 있으면), 그리고 캐릭터가 땅에 있다면
        if (Input.GetKey(KeyCode.Space) && isGround)
        {
            // body에 힘을 가한다(AddForce)
            // AddForce(방향, 힘을 어떻게 가할 것인가)
            body.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);

            // 땅에서 떨어졌으므로 isGround를 false로 바꿈
            isGround = false;
        }
    }

    // 충돌 함수
    void OnCollisionEnter(Collision collision)
    {
        // 부딪힌 물체의 태그가 "Ground"라면
        if (collision.gameObject.CompareTag("Ground"))
        {
            // isGround를 true로 변경
            isGround = true;
        }
    }
}

 

1. 먼저, 점프하는 힘을 10으로 늘려주었습니다. 이는 임의로 변경하셔도 무방합니다.

2. 그리고 isGround라는 bool 변수를 추가하여 캐릭터가 땅에 있는지를 확인할 수 있도록 하였습니다.

3. Jump함수의 if문의 조건을 스페이스바를 누르기 and 캐릭터가 땅에 붙어있는가를 확인할 수 있도록 하였습니다.

4. 점프를 했다면 땅에서 떨어진 것이므로 isGround를 false로 변경합니다.

5. OnCollisionEnter는 어딘가에 충돌했다면 벌어지는 이벤트 함수입니다. 어딘가에 충돌했을 때

6. 충돌한 물체의 태그가 "Ground"라면 땅에 내려온 것이므로 isGround를 true로 변경해줍니다.

 

이렇게 하면 공중에서 연속으로 점프가 되는 현상을 방지할 수 있습니다. 

 

 

 

 점프를 하다 보면 낙하하는 속도가 너무 낮다고 느끼시는 분도 계실 것 같습니다. 그럴 때는 [Edit] -> [Project Settings]의 Physics 에서 Gravity의 Y부분을 더욱 낮게 조정해주시면 됩니다. 해당 부분은 중력가속도를 설정하는 부분입니다.