리지드 바디
리지드 바디는 물리효과를 주고 싶은 오브젝트를 선택한 후 Inspector창의 제일 하단에 있는 Add Component에 ri까지만 쳐도 바로 밑에 컴포넌트가 뜬다. 그걸 클릭하면 오브젝트에 추가가된다. 여기서 주의할 점은 3d에서는 Rigidbody를 사용해야 하고 2d에서는 Rigidbody 2d를 사용해야란다. 그렇지 않으면 추가할 수 없는 컴포넌트라고 경고가 뜬다.

리지드 바디를 추가하면 Use Gravity라고 되어 있는 체크 박스가 있는데, 이것은 중력을 사용한다는 말이다. 실행해보자.



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

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

-Mass
질량의 양을 정할 수 있다.
Mass의 값이 크면 클수록 가속력, 관성 등의 힘들의 크기도 커진다.
-Drag
저항을 정할 수 있는 기능을 가지고 있다.
공기의 저항, 물의 저항과 비슷하다.
Drag가 커지면 아래로 떨어지는 속도도 줄어든다.
-Angular Drag
회전할 때 저항을 정할 수 있는 기능을 가지도 있다.
이 값이 높을수록 느리게 회전한다.
-Use Gravity
Use Gravity는 말 그대로 중력을 사용한다는 것이다.
-Is Kimematic
물리효과를 사용하지 않는 기능을 가지고 있다.
이것을 체크하면 중력, 관성, 가속도 등 물리효과들이 적용되지 않는다.
-Interpolate
캐릭터의 움직임이 부자연스러울 때 사용하는 기능이다.
None은 영향을 주지 않는 것이고, Interpolate는 이전 프레임의 움직임을 통해 다음 프레임을 제작하고, Extrapolate는 다음 움직임을 예측하여 움직임을 자연스럽게 만드는 기능을 가지고 있다.
-Collision Detection
충돌을 탐지하는 기능을 가지고 있다.
Discrete는 충돌을 체크하고, Continous는 연속적으로 충돌을 체크하는 기능을 가지고 있다.
Continous Dynamic은 속도가 빠른 물체에게 적용시키면 물리효과를 더욱 정밀한 계산을 해준다.

-Constraints
제약사항을 정하는 기능을 가지고 있다.
Freeze Postion에 있는 축을 체크하면 해당 축은 얼려진다.
즉 값이 고정된다는 소리이다.
Freeze Rotation도 회전할 때 해당 축의 값을 고정시키는 것이다.
Rigidbody 제어하기
스크립트에서 리지드 바디를 사용하기 위해 리지드 바디를 선언해야한다.
방법은 2가지이다.
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도 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;
}
}
}
메서드
아래의 메서드는 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은 특정한 방향으로 이동하는 기능을 가지고 있다. MovePositiom과 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);
}
}
}