오늘 한 일
- 챌린지반 과제 풀이
- 프로젝트 진행하기 (~ 선택 구현 사항 3)
Rigidbody는 게임 오브젝트가 물리 제어로 동작하게 합니다. Rigidbody는 Force와 Torque를 받아 오브젝트가 사실적으로 움직이도록 해주고, Rigidbody가 포함된 모든 게임 오브젝트는 중력의 영향을 받을 수 있게되며, 스크립팅을 통해 가해진 힘으로 움직이거나 NVDIA PhysX 물리 엔진을 통해 다른 오브젝트와 상호작용하게 됩니다.
- 오브젝트의 질량 (디폴트 값을 킬로그램)
- 코드
_rigidbody.mass = 10;
테스트 영상
각종 이동 처리
- 각 물체의 mass는 흰색은 1 회색은 100으로 설정해주었다.
_rigidbody.velocity = direction * speed * Time.deltaTime;
흰색과 회색에서 각각 250으로 설정해주었다.
- 둘이 속도가 균일하게 나온다.
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.Force);
흰색과 회색에게 각각 50으로 설정해주었다.
- 가속이 생기는데 mass에 따라서 차이가 발생한다.
Force 모드에서 흰색은 50 회색은 5000으로 설정
- 서로 mass 차이가 나는 상태에서 Force로 동일한 속도를 내고자 한다면 a(mass) : b(mass) = a(Force) : b(Force)를 통해서 계산해줘야할 것 같다.
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.Acceleration);
흰색과 회색에게 각각 50으로 설정해주었다.
- mass 상관 없이 둘이 동일한 속도로 가속이 발생한다.
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.Impulse);
흰색과 회색에게 각각 10으로 설정해주었다.
- 가속이 폭발적으로 증가하고 mass에 따라서 차이가 발생한다.
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.VelocityChange);
흰색과 회색에게 각각 10으로 설정해주었다.
- mass 상관없는 impulse mode인 것 같다.
- 위치 이동의 저항 (중력과 움직임에 저항이 생긴다)
- 코드
_rigidbody.drag = 10;
테스트 영상
중력 저항
초기 설정
- Drag 설정
- 파란색은 기본값(0)
- 빨간색은 20
- 각자에게 중력을 추가해주었다.
- Drag가 없는 파란색 직육면체는 바로 떨어지고 Drag가 20인 빨간색은 천천히 떨어진다.
이동 저항
초기 설정
- Drag 설정
- 파란색은 기본값(0)
- 빨간색은 20
사용된 이동 코드
IEnumerator MovePlatform() { Vector3 direction = (directions[curDirectionIdx] - transform.position).normalized; // 방향 단위 벡터 while (true) // 목표 지점에 도착할 때까지 반복합니다. { if (Vector3.Distance(transform.position, directions[curDirectionIdx]) < 0.2f) { break; } _rigidbody.velocity = direction * speed * Time.deltaTime; // 초를 따라 추가 yield return null; } _rigidbody.velocity = Vector3.zero; // velocity 0으로 만들기 (이게 없으면 날라가니 주의) yield return new WaitForSeconds(waitTime); // 멈추는 시간 설정 curDirectionIdx++; // 다음 목적지로 if (curDirectionIdx >= directions.Count) // Count를 넘는다면 { curDirectionIdx = 0; // 다시 0으로 } StartMove(); // 움직임 재시작 }
- speed는 500으로 설정해주었다.
- 해당 영상에서 보이듯이 Drag가 없는 파란색은 빠르게 움직이고 Drag가 있는 빨간색은 천천히 움직인다.
+ 정지 코드 제외
speed를 250으로 바꿔주었다.
- 빨간색은 Velocity를 주는 것을 멈추면 잘 멈추는 반면 파란색은 그대로 나아가버린다.
각종 이동 처리
_rigidbody.velocity = direction * speed * Time.deltaTime;
파란색과 빨간색에게 각각 250으로 설정해주었다.
- 빨간색이 저항을 받아서 그런지 속도가 감속되는 현상이 생긴다. (프레임 단위로 velocity = 처리이다.)
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.Force);
파란색과 빨간색에게 각각 50으로 설정해주었다.
- 파란색은 가속이 잘 전달되는 반면 빨간색은 이상하게 속도 제한이 걸리는 것 같다.
_rigidbody.AddForce(direction * speed * Time.deltaTime, ForceMode.Impulse);
파란색과 빨간색에게 각각 10으로 설정해주었다.
- 위와 마찬가지로 빨간색에게 속도 제한이 걸린다.
Impulse 모드 빨간색만 200으로 설정
- 아무리 힘을 줘도 저항 때문에 속도가 중첩이 되질 않는다..
- 회전의 저항
- 코드
_rigidbody.angularDrag = 10;
테스트 영상
_rigidbody.angularVelocity = Vector3.up * rotateSpeed;
- AngularDrag 설정
- 파란색은 기본값(0.05)
- 빨간색은 20
- rotateSpeed를 20으로 설정했다.
- 멈추는 버튼을 추가해서 멈추는 실험
해당 영상을 보면 파란색 직육면체가 좀 더 빨리 회전하는 것을 볼 수 있고 움직임을 멈췄을 경우 파란색은 천천히 멈추고 빨간색은 바로 멈추는 것을 알 수 있다.
_rigidbody.AddTorque(Vector3.up * rotateSpeed);
- AddTorque는 각도 버전의 Addforce라 생각해주면 된다. (기본 Forcemode는 Force이다.)
- 속도는 각각 20으로 설정해뒀다.
- 해당 영상을 보면 알 듯이 빨간색은 저항을 받아서 속도의 제한을 받고 파란색은 잘 회전되는 모습을 볼 수 있다.
- 그리고 멈췄을 경우 저항이 있는 빨간색(20)은 바로 멈추고 파란색(0.05)은 천천히 멈추고 있는 것을 볼 수 있다.
- 중력 유무
앞선 Drag 영상에서 봤듯이 물체에 중력을 부여해줄 수 있다. 중력을 사용하지 않겠다면 체크란을 비워주면 된다.
- 코드
Rigidbody(의 인스턴스).useGravity = true;
- 오브젝트가 물리 엔진으로 제어되지 않고 오로지 Trasnform으로만 조작된다. 플랫폼을 옮기는 경우나 HingeJoint가 추가된 리지드바디를 애니메이션화하는 경우에 유용하다
- 코드
Rigidbody(의 인스턴스).isKinematic = true;
- 당연하겠지만 velocity에 변화를 주려하면 이러한 에러가 발생한다.
- 리지드바디의 움직임이 어색해 보일 경우에 사용한다.
- None - 보간 없음
- Interpolate - 이전 프레임의 트랜스폼에 맞게 움직임을 부드럽게 처리합니다.
- Extrapolate - 다음 프레임의 트랜스폼을 추정해 움직임을 부드럽게 처리합니다.
- 코드
Rigidbody(의 인스턴스).interpolation = RigidbodyInterpolation.Interpolate;
- 빠르게 움직이는 오브젝트가 충돌의 감지 없이 다른 오브젝트를 지나쳐가는 것을 방지합니다.
Discrete
- 물리 시스템이 불연속 충돌 검사를 사용하여 이 리지드바디의 콜라이더에 대한 충돌을 계산합니다. 이 리지드바디가 빠르게 움직이는 충돌에 관여하지 않는 경우 Discrete를 선택합니다.Discrete 충돌 검사는 컴퓨터 리소스를 많이 사용하지 않습니다.
Continous
- 물리 시스템은 스위핑 기반 CCD를 사용하여 이 리지드바디의 콜라이더와 정적 콜라이더(연관된 리지드바디가 없는 콜라이더) 간의 충돌을 계산합니다. 이 리지드바디가 정적 콜라이더와의 빠르게 움직이는 충돌에 관여하는 경우 Continuous를 선택합니다. 스위핑 기반 CCD는 Discrete 또는 Continuous Speculative보다 컴퓨터 리소스를 많이 사용합니다.
Continuous Dynamic
- 물리 시스템은 스위핑 기반 CCD를 사용하여 이 리지드바디의 콜라이더와 Discrete 충돌 검사로 설정된 콜라이더를 제외한 다른 모든 콜라이더 간의 충돌을 계산합니다. 이 리지드바디가 임의의 콜라이더와의 빠르게 움직이는 충돌에 관여하는 경우 Continuous Dynamic을 선택합니다. 스위핑 기반 CCD는 Discrete 또는 Continuous Speculative보다 컴퓨터 리소스를 많이 사용합니다.
Continuous Speculative
- 리지드바디와 콜라이더에 추측성 연속 충돌 검사를 사용합니다. 키네마틱 바디를 설정할 수 있는 유일한 CCD 모드입니다. 이 메서드는 스위핑 기반 연속 충돌 검사보다 리소스를 덜 소모합니다.
- 리지드 바디의 움직임에 대한 제약사항
- Freeze Position - 월드 좌표계의 X, Y, Z 축에서 이동하는 리지드 바디의 움직임 제한 유무
- Freeze Rotation - 로컬 좌표계의 X, Y, Z 축에서 회전하는 리지드 바디의 움직임 제한 유무
- 코드
혹여나 Rigidbody에 힘을 가했는데 의도된 대로 움직여지지 않으면 이 체크란을 확인해주자.
Transform.position을 이용한 이동의 제한은 막힌 게 아니니 그것을 사용해도 된다.
유니티 공식 문서
유니티 공식 문서 스크립트 레퍼런스
유니티 입문 강좌 part 3 - 리지드 바디 - 케이디
유니티라는 엔진을 알면 알수록 생각보다 자기가 모르는 것에 대한 실험을 하기가 좋은 환경이라고 생각이 든다.