상세 컨텐츠

본문 제목

리지드바디(Rigidbody), 이동, 회전, 폭발

유니티/기능

by MJ_119 2024. 6. 24. 23:02

본문

 

출처 : https://www.youtube.com/watch?v=_U7qUUfRMYs

 

 

 

 

 

FixedUpdate와 Update의 차이

  1. FixedUpdate:
    • 물리 계산: FixedUpdate는 물리 계산이 이루어지는 고정된 시간 간격(기본적으로 0.02초)마다 호출됩니다.
    • 일관성: 물리 엔진과의 일관성을 유지합니다. 물리 엔진의 시간 스텝과 동일한 간격으로 호출되므로, 물리적 상호작용이 정확하고 예측 가능하게 동작합니다.
    • 사용 사례: 물리와 관련된 모든 업데이트(예: Rigidbody의 이동, 힘 적용 등)는 FixedUpdate에서 처리하는 것이 권장됩니다.
  2. Update:
    • 프레임 기반: Update는 매 프레임마다 호출되며, 프레임 속도에 따라 호출 빈도가 달라질 수 있습니다.
    • 비일관성: 프레임 속도가 변동될 수 있기 때문에, 물리 엔진과의 상호작용이 일관되지 않을 수 있습니다.
    • 사용 사례: 사용자 입력 처리, UI 업데이트 등 프레임 기반 로직에 사용됩니다.

 

 

중력 조절

 - Edit -> Project Settings -> Physics -> Gravity에서 조절 가능.

 

RigidBody 속성

  1. Mass (질량):
    • 객체의 무게를 결정합니다. 값이 클수록 객체가 무겁고, 물리적 상호작용 시 더 큰 힘이 필요합니다.
  2. Drag (저항):
    • 객체가 이동할 때 공기 저항을 시뮬레이션하는 값입니다. 값이 클수록 객체의 속도가 더 빨리 감소합니다.
  3. Angular Drag (회전 저항):
    • 객체가 회전할 때 공기 저항을 시뮬레이션하는 값입니다. 값이 클수록 객체의 회전 속도가 더 빨리 감소합니다.
  4. Use Gravity (중력 사용):
    • 체크하면 객체에 중력이 적용됩니다. 체크 해제 시 객체는 중력의 영향을 받지 않습니다.
  5. Is Kinematic (키네마틱):
    • 체크하면 객체는 물리 엔진의 영향을 받지 않고, 스크립트를 통해 직접 위치와 회전을 제어할 수 있습니다. 다른 객체와의 충돌은 감지하지만, 물리적 반응은 하지 않습니다.
  6. Interpolate (보간):
    • 객체의 움직임을 부드럽게 만드는 옵션입니다.
      • None: 보간을 사용하지 않습니다. 움직임이 뚝뚝 끊길 수 있습니다.
      • Interpolate: 이전 프레임의 위치를 사용하여 부드러운 움직임을 만듭니다.
      • Extrapolate: 다음 프레임의 예상 위치를 사용하여 부드러운 움직임을 만듭니다.
  7. Collision Detection (충돌 감지):
    • 충돌 감지 방식을 설정합니다.
      • Discrete: 기본 충돌 감지 방식으로, 프레임 간의 충돌을 감지하지 못할 수 있습니다.
      • Continuous: 고속으로 움직이는 객체의 충돌을 감지합니다. (예를들어 총알.)
      • Continuous Dynamic: 고속으로 움직이는 동적 객체와의 충돌을 감지합니다.
      • Continuous Speculative: 예측 기반 충돌 감지 방식으로, 충돌을 더 잘 감지하도록 합니다.
  8. Constraints (제약):
    • 객체의 위치와 회전을 고정하거나 제한할 수 있습니다.
      • Freeze Position: 특정 축에 대한 위치 이동을 고정합니다 (X, Y, Z).
      • Freeze Rotation: 특정 축에 대한 회전을 고정합니다 (X, Y, Z).

 

 

오브젝트 이동시키기

 - Drag를 높이면 공기저항으로 인해 떨어지는속도나 이동하는 속도가 서서히 느려짐

 - velocity

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

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.velocity = Vector3.forward;
        }
    }
}

 

 

 

오브젝트 회전시키기

 - angular Drag를 높이면 회전저항으로 인해 물체의 회전속도가 서서히 줄어듦.

 - angularVelocity

  • 물리적 힘을 사용하여 자연스러운 회전 운동을 만들 수 있습니다.
  • 객체에 각속도를 적용하여 회전시킵니다.
  • 다른 물리 객체와의 상호작용이 자연스럽습니다.
  • 직접적인 각도 설정이 어렵고, 각속도를 조절해야 합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.angularVelocity = Vector3.right;
        }
    }
}

 

 - MoveRotation();

 - 질량과 관성에 영향받지 않음. 

 - 물리효과 X

  • 특정 각도로 바로 회전시키고 싶을 때 유용합니다.
  • 물리적 힘을 사용하지 않기 때문에 예측 가능한 회전 결과를 얻을 수 있습니다.
  • 물리 엔진의 영향을 받지 않기 때문에 자연스러운 회전 운동을 만들기 어렵습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;
    private Vector3 rotation;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
        rotation = this.transform.eulerAngles;
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            rotation += new Vector3(90, 0, 0) * Time.deltaTime;
            myRigid.MoveRotation(Quaternion.Euler(rotation));
        }
    }
}

 

- AddTorque()

  • 객체에 토크(회전력)를 가하여 회전시킵니다.
  • 물리적 힘을 사용하여 자연스러운 회전 운동을 만들 수 있습니다.
  • 직접적인 각도 설정이 어렵습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.AddTorque(Vector3.up);
        }
    }
}

 

 

오브젝트 회전속도 늘리기

 - maxAngularVelocity

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

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.maxAngularVelocity = 100; // 회전속도 최대치 증가
            myRigid.angularVelocity = Vector3.right * 100;
        }
    }
}

 

@ MovePosition();

오브젝트를 특정 위치로 한번에 이동시키기

 - 물리효과 X

 - 강제로 순간이동

 - 관성과 질량에 영향을 받지 않음

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

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.MovePosition(new Vector3(2,2,2));
        }
    }
}

 

using UnityEngine;

public class CharacterMovementRigidbody : MonoBehaviour
{
    public float moveSpeed = 5f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 moveDirection = new Vector3(moveHorizontal, 0.0f, moveVertical).normalized;
        rb.MovePosition(transform.position + moveDirection * moveSpeed * Time.fixedDeltaTime);
    }
}

설명

  • 연속적인 이동: 이 코드는 캐릭터를 플레이어 입력에 따라 연속적으로 이동시키는 예제입니다.
  • 물리 기반: Rigidbody를 사용하여 물리 법칙에 따라 이동이 이루어집니다.
  • FixedUpdate: 물리 계산과 관련된 업데이트는 FixedUpdate에서 이루어지며, 이는 물리 시뮬레이션의 일관성을 유지하기 위해 고정된 시간 간격으로 호출됩니다.
  • 충돌 처리: 이동 중에 다른 오브젝트와의 충돌이 자연스럽게 처리됩니다.

위 두개의 코드 차이점 요약

항목연속적인 이동 (CharacterMovementRigidbody)특정 위치로 순간 이동 (Test)

이동 방식 플레이어 입력에 따라 연속적인 이동 특정 키 입력 시 즉시 특정 위치로 이동
물리 기반 물리 법칙에 따라 이동 물리 법칙을 무시하고 강제로 이동
메서드 호출 위치 FixedUpdate에서 호출 Update에서 호출
관성 및 질량의 영향 관성과 질량에 영향을 받음 관성과 질량에 영향을 받지 않음
주 사용 사례 캐릭터와 같은 움직이는 오브젝트 순간 이동이나 텔레포트와 같은 경우

 

  • Rigidbody.MovePosition을 FixedUpdate에서 사용하는 경우, 물리 기반의 자연스러운 이동을 구현할 수 있습니다. 이는 캐릭터의 연속적인 이동이나 물리적 상호작용이 중요한 경우에 적합합니다.
  • Rigidbody.MovePosition을 Update에서 사용하는 경우, 특정 위치로 오브젝트를 강제로 이동시키는 데 사용할 수 있습니다. 이는 물리 법칙을 무시하고 즉시 특정 위치로 이동시켜야 하는 경우(예: 텔레포트)에 적합합니다.

 

 

 

- AddForceRigidbody에 물리적 힘을 가하여 이동시키는 방법입니다.

- 물리 엔진의 영향을 받아 더 자연스러운 이동을 만들어 줍니다.

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

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if(Input.GetKey(KeyCode.R))
        {
            myRigid.AddForce(Vector3.forward);
        }
    }
}

물리적 상호작용이 중요한 경우 AddForce를, 특정 위치로 정확하게 이동시켜야 하는 경우 MovePosition을 사용하는 것이 좋습니다.

 

 

- AddExplosionForce(폭발세기, 폭발위치, 폭발반경)

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

public class Test : MonoBehaviour
{
    private Rigidbody myRigid;

    private void Start()
    {
        myRigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.R))
        {
            myRigid.AddExplosionForce(20, this.transform.position, 20);

            myRigid.AddExplosionForce(20, this.transform.right, 20);
        }
    }
}

관련글 더보기