앞에서는 게임오브젝트의 이동을 Transform을 이용했는데 이제 물리엔진의 힘을 이용해 발사해보자. 그러기 위해서는 Ridigbody 컴포넌트가 필요하다.
하이라키의 Bullet오브젝트를 선택한후 인스펙터뷰에서 Ridigbody컴포넌트를 추가한다.
실행해보면 총알이 바닥으로 떨어지는데 Rigidbody 컴포넌트의 Use Gravity속성이 체크되어 중력의 영향을 받았기 때문이다. 이속성을 언체크해서 안 떨어지게 한다.
Rigidbody는 물리학 용어의 강체를 의미한다. 충돌감지및 물리 시뮬레이션을 위한 중요한 컴포넌트다. 아래 내용은 지금은 넘어가도 되지만 꼭 한번 읽어보시기 바랍니다. Rigidbody는 Transform에 영향을 주므로 둘을 같이 제어하면 안됩니다.
리지드바디 (유니티매뉴얼 2021.3)
Rigidbody 는 GameObject 가 물리 제어로 동작하게 합니다. 리지드바디는 힘과 토크를 받아 오브젝트가 사실적으로 움직이도록 해줍니다. 리지드바디가 포함된 모든 게임 오브젝트는 중력의 영향을 받아야 하며 스크립팅을 통해 가해진 힘으로 움직이거나 NVIDIA PhysX 물리 엔진을 통해 다른 오브젝트와 상호 작용해야 합니다.
프로퍼티
프로퍼티:기능:
Mass | 오브젝트의 질량입니다(디폴트값은 킬로그램). |
Drag | 오브젝트가 힘에 의해 움직일 때 공기 저항이 영향을 미치는 정도를 나타냅니다. 0이면 공기 저항이 없으며 무한대라면 오브젝트가 즉시 정지합니다. |
Angular Drag | 오브젝트가 토크로 회전할 때 공기 저항이 영향을 미치는 정도를 나타냅니다. 0이면 공기 저항이 없습니다. 앵글 드래그를 무한대로 설정한다고 해서 오브젝트의 회전이 멈추지는 않으니 주의해야 합니다. |
Use Gravity | 활성화되면 오브젝트는 중력의 영향을 받습니다. |
Is Kinematic | 활성화되면 오브젝트는 물리 엔진으로 제어되지 않고 오로지 Transform 으로만 조작됩니다. 플랫폼을 옮기는 경우나 HingeJoint 가 추가된 리지드바디를 애니메이션화하는 경우에 유용합니다. |
Interpolate | 리지드바디의 움직임이 어색해 보일 경우 다음 옵션 중에서 하나를 시도해보아야 합니다. |
- None | 보간이 적용되지 않습니다. |
- Interpolate | 이전 프레임의 트랜스폼에 맞게 움직임을 부드럽게 처리합니다. |
- Extrapolate | 다음 프레임의 트랜스폼을 추정해 움직임을 부드럽게 처리합니다. |
Collision Detection | 빠르게 움직이는 오브젝트가 충돌의 감지 없이 다른 오브젝트를 지나쳐가는 것을 방지합니다. |
- Discrete | 씬에서 다른 모든 콜라이더에 대해 불연속 충돌 검사를 사용합니다. 다른 콜라이더는 충돌 테스트에 불연속 충돌 검사를 사용합니다. 일반적인 충돌에 활용됩니다(기본값). |
- Continuous | (리지드바디가 있는) 동적 콜라이더에 불연속 충돌 검사를, (리지드바디가 없는) 정적 콜라이더에 스위핑 기반 연속 충돌 검사를 사용합니다. Continuous Dynamic__으로 설정된 리지드바디는 이 리지드바디와의 충돌을 테스트할 때 연속 충돌 검사를 사용합니다. 다른 리지드바디는 불연속 충돌 검사를 합니다. Continuous Dynamic__ 검사로 충돌해야 하는 오브젝트에 사용됩니다(물리 퍼포먼스에 큰 영향을 미치므로 빠른 오브젝트의 충돌 문제가 없다면 Discrete__으로 설정합니다). Continuous 및 Continuous Dynamic 충돌로 설정된 게임 오브젝트에 스위핑 기반 연속 충돌 검사를 사용합니다. 또한 (리지드바디가 없는) 정적 콜라이더에도 연속 충돌 검사를 사용합니다. 그 외 다른 콜라이더에는 불연속 충돌 검사를 사용합니다. 빠르게 움직이는 오브젝트에 쓰입니다. |
- Continuous Speculative | 리지드바디와 콜라이더에 추측성 연속 충돌 검사를 사용합니다. 키네마틱 바디를 설정할 수 있는 유일한 CCD 모드입니다. 이 메서드는 스위핑 기반 연속 충돌 검사보다 리소스를 덜 소모합니다. |
Constraints | 리지드바디의 움직임에 대한 제약사항입니다.- |
- Freeze Position | 월드 좌표계의 X, Y, Z 축에서 이동하는 리지드바디를 선택적으로 중지시킵니다. |
- Freeze Rotation | 로컬 좌표계의 X, Y, Z 축에서 회전하는 리지드바디를 선택적으로 중지시킵니다. |
세부 정보
리지드바디를 사용하면 게임 오브젝트의 동작이 물리 엔진으로 제어됩니다. 따라서 사실적인 충돌과 다양한 조인트 타입 같은 동작이 가능해집니다. 리지드바디에 힘을 더해서 게임 오브젝트를 조작하면 Transform 컴포넌트 를 직접 조정할 때와 느낌과 모양이 상당히 다릅니다. 일반적으로 동일한 게임 오브젝트의 리지드바디와 트랜스폼을 모두 조작하지 않고 둘 중 하나만 조작해야 합니다.
트랜스폼 조작과 리지드바디 조작의 가장 큰 차이점은 힘의 사용입니다. 리지드바디는 힘과 토크를 받을 수 있지만 트랜스폼은 그렇지 않습니다. 트랜스폼도 트랜스폼되고 회전할 수는 있지만 물리를 사용할 때와는 다릅니다. 리지드바디에 힘/토크를 더하면 오브젝트 Transform 컴포넌트의 포지션과 회전을 바꿉니다. 그러므로 둘 중에서 하나만을 사용해야 하는 것입니다. 트랜스폼을 바꾸면서 물리를 사용하면 충돌 및 기타 연산에 문제가 발생할 수 있습니다.
리지드바디는 물리 엔진의 영향을 받기 전에 게임 오브젝트에 명시적으로 추가되어야 합니다. 메뉴의 Components->Physics->Rigidbody 에서 선택한 오브젝트에 리지드바디를 추가할 수 있습니다. 이제 오브젝트에 물리 연산이 일어날 수 있게 된 것입니다. 중력의 영향을 받고 스크립팅을 통해 힘을 받을 수 있지만 원하는 대로 정확하게 동작시키려면 Collider 나 조인트를 추가해야 합니다.
부모 설정
오브젝트가 물리 제어를 받으면 트랜스폼 부모가 움직이는 방식에 의존하게 됩니다. 부모를 움직이면 리지드바디의 자식이 같이 따라갑니다. 하지만 리지드바디는 여전히 중력때문에 떨어지고 충돌 이벤트에 반응합니다.
스크립트
리지드바디를 제어하기 위해 기본적으로 스크립트를 사용하여 힘이나 토크를 추가합니다. 이 작업은 AddForce() 와 AddTorque() 를 리지드바디의 오브젝트에 호출해야 합니다. 물리를 사용할 때는 오브젝트의 트랜스폼을 직접 변경하면 안 된다는 사실을 기억해야 합니다.
애니메이션(Animation)
래그돌 효과를 만드는 등 일부 상황에서는 애니메이션과 물리 간 오브젝트의 제어를 전환해야 합니다. 이를 위해 리지드바디는 isKinematic 으로 지정될 수 있습니다. 리지드바디가 isKinematic 으로 정해진 경우 충돌, 힘이나 어떤 물리 연산에도 영향을 받지 않습니다. 이 경우 트랜스폼 컴포넌트를 직접 조작해서 오브젝트를 제어할 수밖에 없습니다. 키네마틱 리지드바디는 다른 오브젝트에 영향을 주지만 그들 자체는 물리의 영향을 받지 않습니다. 예를 들어, 키네마틱 오브젝트에 추가된 조인트는 이에 추가된 다른 리지드바디를 제한하지만 키네마틱 리지드바디는 충돌을 통해 다른 리지드바디에 영향을 미칩니다.
콜라이더(Colliders)
콜라이더는 충돌이 일어나게 만들기 위해 리지드바디에 함께 추가해야 하는 또 다른 유형의 컴포넌트입니다. 두 개의 리지드바디가 서로 충돌하더라도 두 오브젝트 모두 콜라이더가 추가되어 있지 않으면 물리 엔진은 충돌을 연산하지 않습니다. 콜라이더가 없는 리지드바디는 물리 시뮬레이션 동안 서로를 지나쳐가기만 합니다.
콜라이더는 리지드바디의 물리적 경계를 정의합니다.
Component->Physics 메뉴에서 콜라이더를 추가합니다. 보다 자세한 내용은 각 콜라이더의 컴포넌트 레퍼런스 페이지를 참조하십시오.
- 박스 콜라이더 - 박스의 프리미티브 셰이프
- 스피어 콜라이더 - 구체의 프리미티브 셰이프
- 캡슐 콜라이더 - 캡슐의 프리미티브 셰이프
- 메시 콜라이더 - 오브젝트의 메시에서 콜라이더를 생성하며 다른 메시 콜라이더와는 충돌할 수 없습니다.
- 휠 콜라이더 - 특별히 차량이나 기타 이동수단을 생성하는 데 쓰입니다.
- 터레인 콜라이더 - Unity 터레인 시스템과의 충돌을 처리합니다.
복합 콜라이더
복합 콜라이더는 기본 콜라이더의 조합으로, 단일 리지드바디처럼 함께 움직입니다. 정확하게 시뮬레이션하기에는 성능 측면에서 너무 복잡하거나 비용이 큰 모델을 가지고 있어 간단한 근사값을 사용해 최적의 방법으로 셰이프 충돌을 시뮬레이션할 때 유용합니다. 컴파운드 콜라이더를 생성하기 위해서는 충돌 오브젝트의 자식 오브젝트를 만든 후 Collider 컴포넌트를 각각의 자식 오브젝트에 추가합니다. 이렇게 하면 각 콜라이더의 포지션, 회전, 스케일을 손쉽고 개별적으로 수행할 수 있습니다. 자체적인 컴파운드 콜라이더를 여러 기본 콜라이더 및/또는 볼록한 메시 콜라이더로 빌드할 수 있습니다.
실제 월드 복합 콜라이더 설정
위의 그림에서 총 모델 게임 오브젝트에는 리지드바디가 추가되어 있고 여러 기본 콜라이더가 자식 게임 오브젝트로 있습니다. 힘에 의해 부모 리지드바디가 이동하면 자식 콜라이더도 따라서 이동합니다. 프리미티브 콜라이더는 환경에서 메시 콜라이더와 충돌하며, 부모 리지드바디는 자식 콜라이더가 다른 콜라이더와 씬에서 상호작용하는 방식을 기반으로 이동 방식을 변경합니다.
일반적으로 메시 콜라이더는 서로 충돌하지 않습니다. 메시 콜라이더가 Convex 로 지정되면 다른 메시 콜라이더와 충돌할 수 있습니다. 일반적인 해결책은 움직이는 모든 오브젝트에는 기본 콜라이더를 사용하고 정적 배경 오브젝트에는 메시 콜라이더를 쓰는 것입니다.
참고: 충돌 콜백을 사용하는 경우 복합 콜라이더는 각 콜라이더 충돌 페어에 대한 개별 콜백을 반환합니다.
연속 충돌 검사(Collision Detection)
연속 충돌 검사는 빠르게 움직이는 콜라이더가 서로 통과하는 것을 방지하는 기능입니다. 일반적인(Discrete) 충돌 검사를 사용할 때 이런 일이 발생할 수 있는데 한 프레임에서 오브젝트 하나가 콜라이더의 이쪽 편에 있고 다음 프레임에서 이미 콜라이더를 지나쳐버리는 것입니다. 빨리 움직이는 오브젝트의 리지드바디에서 연속 충돌 검사를 활성화하면 문제를 해결할 수 있습니다. 충돌 검사 모드를 Continuous 로 설정해 리지드바디가 다른 정적 (즉, 리지드바디가 아닌)메시 콜라이더를 통과하지 않게 합니다. Continuous Dynamic 으로 설정해도 리지드바디가 Continuous 또는 Continuous Dynamic 으로 충돌 검사 모드가 설정된 리지드바디를 통과하지 않습니다. 연속 충돌 검사는 박스-, 구체- 및 캡슐 콜라이더 용으로 지원됩니다. 연속 충돌 검사는 오브젝트가 서로 통과하는 경우에 충돌을 잡기 위한 안전망 역할을 하나 물리적으로 정확한 충돌 결과를 내지는 않습니다. 그러므로 빠르게 움직이는 오브젝트와 관련해 문제가 생기면 TimeManager 인스펙터의 고정 타임 스텝 값을 줄여 보다 정확한 시뮬레이션을 구현하는 방안을 고려할 수 있습니다.
올바른 크기의 사용
게임 오브젝트의 메시 크기는 리지드바디의 질량보다 훨씬 중요합니다. 리지드바디가 천천히 움직이거나, 떠 있거나, 제대로 충돌하지 않는 등 예상한 대로 동작하지 않으면 메시 에셋의 스케일을 조정해 보아야 합니다. Unity의 기본 단위 스케일은 1 unit = 1 미터이므로 임포트한 메시의 스케일은 유지되며 물리 연산에 적용됩니다. 예를 들어 무너지고 있는 고층 빌딩은 장난감 블록으로 쌓아 올린 탑과는 붕괴되는 양상이 상당히 다를 것입니다. 그러므로 다른 크기의 오브젝트를 정확한 스케일로 모델링해야 합니다.
사람을 모델링한다면 Unity에서 모델의 신장이 약 2미터인지 확인해야 합니다. 오브젝트가 올바른 크기인지 여부를 확인하려면 기본 큐브와 비교해봅니다. 큐브는 GameObject > 3D Object > Cube 로 생성할 수 있습니다. 큐브의 높이는 정확히 1미터이기 때문에 사람은 큐브보다 두 배 정도 커야 합니다.
메시 자체를 조정할 수 없다면 Project View 를 선택하고 메뉴에서 Assets->Import Settings… 에서 특정 메시 에셋의 균등한 스케일을 바꿀 수 있습니다. 여기에서는 스케일을 변경하고 메시를 다시 임포트할 수 있습니다.
게임 오브젝트를 다른 스케일로 인스턴스화할 필요가 있는 경우 트랜스폼의 스케일 축 값을 조정해도 됩니다. 이 때 단점은 오브젝트가 인스턴스화될 때 물리 시뮬레이션이 더 많은 작업을 해서 게임 퍼포먼스를 저하시킬 수 있다는 점입니다. 상당한 손실까지는 아니지만 다른 두 가지 옵션으로 스케일을 마무리하는 것만큼 효율적이지는 않습니다. 또한 불균등한 스케일은 부모가 사용될 때 원하지 않는 동작을 수행하게 할 수 있습니다. 그렇기 때문에 언제나 오브젝트를 모델링 애플리케이션에 맞게 정확한 스케일로 생성하는 것이 좋습니다.
힌트
- 두 리지드바디의 상대 Mass 는 둘이 서로 충돌했을 때 어떻게 반응할지를 결정합니다.
- 한 리지드바디의 Mass 를 다른 리지드바디보다 크게 만들어도 자유 낙하 시 더 빨리 낙하하지 않습니다. 이 경우 Drag 를 사용해야 합니다.
- Drag 값이 작으면 오브젝트가 무거워 보이고 값이 크면 가벼워 보입니다. Drag 의 일반적인 값은 .001(단단한 금속 덩어리)과 10(깃털) 사이입니다.
- 오브젝트의 Transform 컴포넌트를 직접 조작하면서도 물리 연산이 필요하다면 리지드바디를 추가하고 키네마틱으로 만듭니다.
- Transform 컴포넌트를 통해 게임 오브젝트를 이동시키면서도 충돌/트리거 메시지를 받고자 한다면 이동하는 오브젝트에 리지드바디를 추가해야 합니다.
- 앵글 드래그를 무한대로 설정하는 것 만으로는 오브젝트의 회전을 멈추게할 수는 없습니다.
'유니티게임강좌 > 총 발사 로직' 카테고리의 다른 글
[총발사로직] Collider 컴포넌트 (0) | 2023.02.27 |
---|---|
[총발사로직] 물리 엔진 속성 설정 - Physics Manager (0) | 2023.02.27 |
[총발사로직] Bullet Script - AddForce, AddRelativeForce (0) | 2023.02.27 |
[총발사로직] 총알 모델 준비 (0) | 2023.02.26 |
[총발사로직] 총발사 로직 (0) | 2023.02.26 |