본문 바로가기
Learning/Unity

유니티 강좌_#04_리지드 바디

by HappyStar 2020. 9. 5.
반응형

 

 

오늘은 리지드 바디를 사용하는 방법을 알아보도록 하겠습니다. 리지드 바디는 물리효과를 주고 싶은 오브젝트를 선택한 후 Inspector창의 제일 하단에 있는 Add Component에 ri까지만 쳐도 바로 밑에 컴포넌트가 뜹니다. 그걸 클릭하시면 오브젝트에 추가가 됩니다. 여기서 주의해야 할 점은 3d에서는 Rigidbody를 사용해야 하고 2d에서는 Rigidbody 2d를 사용하셔야 합니다. 그렇지 않으면 추가할 수 없는 컴포넌트라고 경고가 뜹니다.

 

 

 

리지드 바디를 추가 하시면 Use Gravity라고 되어 있는 체크 박스가 있는데요. 이것은 중력을 사용한다는 말입니다. 이대로 해 놓은 뒤 실행을 해 볼까요?

 

 

 

실행결과

 

 

위 사진들과 같이 가만히 있던 큐브가 밑으로 떨어지는 것을 볼 수 있습니다. 큐브가 Rigidbody 컴포넌트에 의하여 중력의 영향을 받게 되었기 때문입니다.

 

큐브가 떨어지는 속도는 얼마일가요? 이것을 알아보기 위해서는 왼쪽 상단의 Edit-ProjectSettings를 클릭하면 아래와 같은 창이 나타납니다. 그 창의 왼쪽 리스트에서 Physics라는 키워드를 찾아서 클릭해줍니다. 여기서 Cloth of Gravity의 y값을 보시면 -9.81이라고 되어 있습니다. 중력의 크기는 9.8N이니 실제와 같습니다.

 

Rigidbody 둘러보기

 

 

-Mass : 질량의 양을 정할 수 있습니다. Mass의 값이 크면 클수록 가속력, 관성 등의 힘들의 크기도 커집니다.

-Drag : 저항을 정할 수 있는 기능을 가지고 있습니다. 공기의 저항, 물의 저항과 비슷합니다. Drag가 커지면 아래로 떨어지는 속도도 줄어 듭니다.

-Angular Drag : 회전할 때의 저항을 정할 수 있는 기능을 가지고 있습니다. 이 값이 높으면 높을수록 느리게 회전합니다.

-Use Grvaity : Use Grvaity는 말 그대로 중력을 사용한다는 것입니다.

-Is Kinematic : 물리효과를 사용하지 않는 기능을 가지고 있습니다. 이것을 체크하시면 중력, 관성, 가속도 등 물리효과들이 적용되지 않습니다.

-Interpolate : 캐릭터의 움직임이 부자연스러울 때 사용하는 기능입니다. None은 영향을 주지 않는 것이고, Interpolate는 이전 프레임의 움직임을 통해 다음 프레임을 제작하고, Extrapolate는 다음 프레임의 움직임을 예측하여 움직임을 자연스럽게 만드는 기능을 가지고 있습니다.

-Collision Detection : 충돌을 탐지하는 기능을 가지고 있습니다. Discrete는 충돌을 체크하고, Continuous는 연속적으로 충돌을 체크하는 기능을 가지고 있습니다. Continous Dynamic은 속도가 빠른 물체에게 적용시키면 물리효과를 더욱 정밀한 계산을 해줍니다. 

 

 

-Constraints : 제약사항을 정하는 기능을 가지고 있습니다. Freeze Position에 있는 축을 체크하면 해당 축은 얼려집니다. 즉 값이 고정된다는 소리입니다. Freeze Rotation도 회전할 때 해당 축의 값을 고정시키는 것입니다.

 

Rigidbody 제어하기

스크립트에서 리지드 바디를 사용하기 위해 리지드 바디를 선언해 봅시다. 방법은 두 가지입니다.

public class Test : MonoBehaviour
{
    [SerializeField]
    private Rigidbody Rigid;
    
    void Start()
    {
       
    }
    void Update()
    {
        
    }
}

 

아래 코드는 Rigid변수에 이 스크립트가 포함되어 있는 오브젝트에서 Rigidbody를 가져오는 방법을 사용하였습니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        
    }
}

 

여기서 velocity는 속도를 나타냅니다. 이 코드를 실행하면 위쪽 화살표 키를 한번만 누르면 앞으로 계속 갑니다. 저항이 없기 때문입니다. 무중력(우주)과 같은 상태입니다. 만약 Rigidbody에서 Drag에 값을 준다면 어떻게 될까요? 저항이 생겼기 때문에 앞으로 가다가 멈추게 됩니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.velocity = new Vector3(0, 0, 1);
        }
    }
}

 

angularVelocity는 회전 값을 나타냅니다. 여기서도 저항을 줘 볼까요? Rigidbody에서 AngularDrag를 높여 주시면 저항 때문에 더 느리게 회전할 것입니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.angularVelocity = new Vector3(0, 0, 1);
        }
    }
}

 

저항을 유니티 프로그램에서 정하는 게 귀찮다면 직접 코드로 저항을 정할 수 도 있습니다. isKinematic이나 useGravity도 true나 false를 이용해 사용 유/무를 정할 수 있습니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.drag = 10f;
            Rigid.angularDrag = 1f;
            Rigid.isKinematic = true;
            Rigid.useGravity = true;
        }
    }
}

 

maxAngularVelocity는 리지드 바디가 빠르게 회전할 때 생기는 불안정감을 피하기 위해서 사용합니다. 기본 값은 7

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.maxAngularVelocity = 50;
            Rigid.angularVelocity = Vector3.forward*1000;
        }
    }
}

 

메서드

이제부터는 Rigidbody와 관련되어 있는 메서드를 사용해보도록 하겠습니다. 아래의 메서드는 MoveRotation입니다. MoveRotation은 특정한 방향으로 회전하는 기능을 가지고 있습니다. 

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    private Vector3 rotation;
    
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
        rotation = this.transform.eulerAngles;
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            rotation += new Vector3(90, 0, 0) * Time.deltaTime;
            Rigid.MoveRotation(Quaternion.Euler(rotation));
        }
    }
}

 

MovePosition은 특정한 방향으로 이동하는 기능을 가지고 있습니다. MovePosition과 MoveRotation은 물리법칙을 적용받지 않고 강제로 움직이게 하는 메서드들입니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.MovePosition(transform.forward);
        }
    }
}

 

물리법칙을 적용받으며 움직이려면 AddForce메서드를 사용하면 됩니다. 그리고 drag를 1.5f로 설정하면 아주 조금 가다가 멈춥니다. 저항이 있기 때문입니다. 그리고 Mass의 값도 줄이면 아까보다 더 빠르게 가고 이동한 거리가 많아집니다. AddForce는 질량의 영향도 받기 때문입니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.AddForce(Vector3.forward);
            Rigid.drag = 1.5f;
        }
    }
}

 

AddTorque는 MoveRotation과 같이 키를 누르지 않으면 바로 회전이 멈추는 게 아니라 물리법칙에 의하여 힘이 계속 남아있습니다. 만약 AngularDrag가 높으면 천천히 움직입니다. 그리고 키를 누르지 않을 때 회전하는 시간도 느려집니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.AddTorque(Vector3.forward);
        }
    }
}

 

AddExplosionForce는 폭발력을 전달해주는 메서드입니다. 파라미터는 3개인데 첫 번째는 폭발력의 세기, 두 번째는 폭발 후 영향을 받을 위치, 마지막은 폭발 반경입니다. 그리고 질량을 줄이고 저항도 줄이면 더 멀리 날아갑니다.

public class Test : MonoBehaviour
{
    private Rigidbody Rigid;
    void Start()
    {
        Rigid = GetComponent<Rigidbody>();
    }
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            Rigid.AddExplosionForce(20, this.transform.right, 20);
        }
    }
}

 

오늘은 여기까지 하겠습니다! 다음 강의도 기대해 주세요!

반응형

댓글