유니티 기초/개념

[Unity 개념] 3. 중력 적용에 대하여

갓것걋 2024. 3. 2. 21:35
※참고사항※
해당 포스트는 본업 개발자가 정성껏 포스팅한 포스트가 아닙니다!
평범한 고등학생이 유니티를 배우면서 적어나가는 포스트라는 점을 이해해 주십사 하고 청하는 바입니다.
(잘못된 정보는 댓글로 감사히 받겠습니다!)

목차

1. 중력 적용
  1-1. 중력 적용이 필요한 이유
  1-2. Rigidbody란?
  1-3. Rigidbody의 사용법

1. 중력 적용

1-1. 중력 적용이 필요한 이유

먼저 중력을 적용해야 하는 이유에 대해서 알려드리겠습니다.

그냥 오브젝트만 딸랑 만들어 놓으면 그 오브젝트는 일절 움직이지 않습니다.

어떻게 보면 당연하죠?

(저는 솔직히 오브젝트를 만들면 중력이 적용될 거라고 생각했습니다.)

 

"그렇다면 그냥 중력 없이 만들면 되는거 아닌감?"

하시는 분이 있을 수 있을 것 같은데요.

 

만약 중력을 설정하지 않고 FPS 게임을 해보겠습니다.

게임 도중 오브젝트 위로 올라가기 위해 점프를 했다고 칩시다.

이 때 중력이 없다면 점프를 하고나서 땅으로 떨어지지 않게 됩니다!

 

중력이 없으니 그럴만도 하죠?

이 외에도 많은 문제들이 있지만 대충 넘기도록 하고 중력을 적용하는 법에 대해 알아보겠습니다!

 

1-2. Rigidbody란?

중력을 적용하는 방법에는 Rigidbody 컴포넌트를 이용하는 방법이 있습니다!

중력을 적용하기 전에 이 Rigidbody라는 녀석을 알아야겠죠.

 

Rigidbody는 유니티에서 제공하는 물리 효과 중 하나입니다!

 

오브젝트 생성 후 아래 사진처럼 Rigidbody를 검색해서  추가하시면 됩니다.

아래에 오브젝트 생성 방법이 서술됩니다.

 

 

위의 사진은 Rigidbody 컴포넌트입니다. (저는 2D를 집중적으로 공부 중이라 2D 컴포넌트를 중심으로 알려드리겠습니다!)

뭔 소린지 모르겠는 영어들이 널브러져 있는데요...

지금부터 어떤 속성들인지 알아보도록 하겠습니다!

 

위에서 부터 차례대로 정리하도록 하겠습니다!

더보기
  • Body Type : 물리현상을 어떻게 받을지 설정합니다. (Dynamic, Kinematic, Static이 있습니다!)
    • Dynamic
      • 모든 물리현상을 받도록 합니다.
      • 대충 현실에 있는 물체라고 생각해도 좋을 것 같습니다.
    • Kinematic
      • 물리현상은 받지 않지만 프로그래머가 정의하는 스크립트 (명령어)를 통해 움직입니다.
      • 물리현상과는 관계없이 프로그래머가 어떤 목적을 가지고 움직이려고 할 떄 사용됩니다.
    • Static
      • 단어 그대로 정적인 물체로 설정합니다.
      • 그 어떤 물리현상도 받지 않고 그 자리에서 움직이지 않도록 합니다.
  • Material
    • 우선 순위로 사용할 Material을 설정합니다.
    • (Material은 아직 잘 모르겠습니다 ㅠㅠ)
  • Simulated
    • 다른 물체와의 상호작용 여부를 설정합니다.
    • 해제하면 다른 물체와 상호작용을 하지 않게 됩니다.
  • Use Auto Mass
    • 질량을 자동으로 감지하도록 합니다.
  • Mass
    • 해당 오브젝트의 질량을 설정합니다.
  • Linear Drag
    • 포지션에 대한 저항 계수입니다.
    • 0으로 설정하면 무한하게 날라갑니다.
  • Angular Drag
    • 각 (각도)에 대한 저항 계수입니다.
    • 0으로 설정하면 빙그르르 돌게 됩니다.
  • Gravity Scale
    • 중력의 크기를 설정합니다.
    • 0으로 설정하면 중력을 없앨 수 있습니다.
  • Collision Detection : 충돌을 탐지하는 방식을 설정합니다. (Discrete, Continuous이 있습니다!)
    • Discrete
      • 빠른속도로 충돌시 통과 혹은 겹칠 수 있습니다.
      • 기본 설정입니다.
    • Continuous
      • 절대 겹지치 않습니다. (총알과 같이 굉장히 빠른 속도로 움직이는 오브젝트에 설정하면 좋습니다!)
      • 하지만 CPU부하가 커집니다
  • Sleeping Mode : 오브젝트가 휴면 상태일 때 프로세서를 절약합니다. (Never Sleep, Start Awake, Start Asleep이 있습니다.)
    • Never Sleep
      • 절전모드를 비활성화 합니다.
      • 유니티에서도 추천하지 않는 속성입니다.
    • Start Awake
      • 게임을 시작할 때 오브젝트가 깨어있도록 합니다.
      • 기본 설정입니다.
    • Start Asleep
      • 게임을 시작할 때는 절전모드지만 충돌 시 깨어나도록 합니다.
  • Interpolate : 물리 업데이트 사이의 보간의 방식을 정의 합니다. (None, Interpolate, Extrapolate이 있습니다.)
    • None
      • 보간이 적용되지 않습니다
    • Interpolate
      • 이전 프레임에서 오브젝트의 위치에 따라 보간합니다
    • Extrapolate
      • 다음프레임에서의 추정치를 기반으로 보간합니다
  • Constraints : Position (위치)값, Rotation (회전)값을 고정시킵니다. (체크 시 값이 변하지 않도록 합니다.)

 

1-3. Rigidbody의 사용법

 

이 파트는 아래에 있는 코드에 있는 주석으로 설명하도록 하겠습니다.

(간단하게 알아볼거라서 코드는 별거 없습니다!)

 

일단 임의의 스크립트를 만들기 위해서 프로젝트를 만들어야 합니다. (2D로 만들어주세요!)

(저번 포스팅에서 설명했기 때문에 생략하겠습니다!)

 

그 다음 아래에 있는 에셋 창에 우클릭을 누르고 

 

 

Create - C# Script를 눌러 스크립트를 생성합니다.

 

그 후 아래에 있는 코드를 적어줍니다! (// 부분은 주석으로 코드에는 영향이 없으니 생략하실 분들은 생략해도 좋습니다!)

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

public class RigidbodyTest : MonoBehaviour
{
    // Rigidbody2D 타입의 변수 선언
    private Rigidbody2D rigid;

    // 게임이 시작하자마자 실행되는 메소드
    private void Awake()
    {
        // 변수 초기화 (변수를 선언만 했지, 값을 넣은 것이 아니기 때문에 초기화를 해야함)
        rigid = GetComponent<Rigidbody2D>();
    }

    // 프레임 마다 실행되는 메소드 (그냥 계속해서 실행된다고 생각하시면 편합니다!)
    private void Update()
    {
        // 오브젝트를 움직이게 하는 방법 (제가 사용해 보았던 방법들입니다!, 다른 방법들은 잘 몰라요 ㅠㅠ)
        // 1. rigid.AddForce() : Rigidbody에게 힘을 전달해줌
        //              사용법 : AddForce(방향 * 힘의 값, 힘의 종류)

        // 2. rigid.position : Rigidbody의 위치를 Get/Set합니다.
        //                   : 또한 다음 물리 시뮬레이션 후에 위치가 업데이트 되어서 transfrom.position 보다 10배 정도 빠르게 계산합니다.

        // 3. transform.position : transform의 위치를 Get/Set합니다.
        //                       : 또한 모든 콜라이더가 해당 RIgidbody의 위치를 재계산해주기 때문에 계산 속도가 느립니다.

        // 키 입력을 체크하는 방법
        // 1. Input.GetKey() -> KeyCode를 통해서 자신이 원하는 키를 누르도록 설정할 수 있음
        if (Input.GetKey(KeyCode.W)) // W키를 눌렀을 때
        {
            rigid.AddForce(Vector2.right, ForceMode2D.Impulse); // 오른쪽으로 이동함
        }
        
        if (Input.GetKey(KeyCode.S)) // S키를 눌렀을 때
		{
    		rigid.AddForce(Vector2.left, ForceMode2D.Impulse); // 왼쪽으로 이동함
		}

        // 2. Input.GetAxisRaw() -> 키가 정해져 있도록 함 (Horizontal : 좌우 화살표 OR A/D키, Vertical : 위아래 화살표 또는 W/S키)
        float h = Input.GetAxisRaw("Horizontal"); // 좌우 화살표를 눌렀을 때 -1, 0, 1의 값을 가지게 됨 (오른쪽 : 1, 가만히 있을 때 : 0, 왼쪽 : -1)

        // 오른쪽이라는 방향값에 위에서 정의한 h 값을 곱해서
        // - 값이면 (왼쪽 화살표를 눌렀으면) 오른쪽의 반대편인 왼쪽으로 이동하게 하고
        // + 값이면 (오른쪽 화살표를 눌렀으면) 오른쪽으로 그대로 이동하게 함
        rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
    }
}

 

그 다음 Ctrl + S를 눌러 코드를 저장하고 유니티로 넘어갑니다!

 

그러면 아래 사진과 같이 스크립트가 생기는데요.

이 스크립트를 적용할 오브젝트를 만들어 봅시다.

 

오브젝트 생성을 위해 아래와 같은 Hierarchy(하이아라키) 창에 우클릭 또는 좌측 상단의 + 버튼을 눌러서 

 

2D Object - Sprites - 임의의 모양 (저는 사각형으로 생성했습니다!)을 눌러 오브젝트를 생성합니다!

 

생성하면 바로 이름을 바꿔줄 수 있는데요.

바꾸든 말든 상관 없지만 바꾸실 분들은 바꿔도 좋습니다.

 

생성하셨다면 아래의 영상과 같이 스크립트를 오브젝트에 드래그 앤 드롭해서 적용 시켜줍니다.

(위에서 나온 것처럼 임의의 스크립트도 스크립트명을 검색해서 추가할 수 있습니다!)

 

스크립트를 적용시킨 후 움직이는 것을 보여드리며 포스팅 마치겠습니다.

 

 

 

위의 영상을 보면 아실 수 있듯이 속도에 대한 제어는 필수입니다!

 

이상으로 포스팅을 마치겠습니다.

다음 포스팅에서는 Collider를 사용한 충돌에 대해서 공부해보겠습니다!