마그누스 효과 & 공기저항 적용하기
[스토리]
Unity 자체적으로 제공되는 Physics을 사용하던, 개인적으로 Physics를 설계하던 복잡한 물리학을 적용해야 할 때가 온다.
오늘은 탁구공에 적용되는 물리학으로 골머리를 썩히고 있는데, 그 범인은 마그누스 효과와 공기저항이라 할 수 있다.
기본적으로 Unity에서 공간을 만들면 공기가 없는 진공 상태로 시작하기 때문에, [Rigidbody] - Drag에서 값을 조정해주지 않는 이상
공중에서 감속하지 않는 Object를 만날 수 있을 것이다.
처음에는 공기저항을 주기 위해서 Drag 값을 조정했지만, 투박하게 적용되는 느낌이 강해 공기저항 Script를 구현했다.
마그누스 효과는 구기 종목에 관한 게임을 만들 때 필수 불가결한 효과라고 볼 수 있다.
아시다시피, 유체속에서 회전하는 Obejct에서 둘 사이의 상대속도가 존재할 때, 물체 속도의 수직 방향으로 힘이 발생하는 현상이다.
(너무 어려울 수 있으니 필자는 스핀이 들어갔을 때 공의 진행 방향이 휘는 현상이라고 이해했다.)
탁구도 마찬가지로 다양한 스핀이 들어가고 그에 따른 탁구공 진행 방향의 변화, Bounce의 변화가 발생한다.
지금 구현된 탁구 게임은 스핀이 들어가든, 들어가지 않든 상관하지 않고 Force된 진행 방향에 따라 탁구공이 움직이기 때문에
다소 괴리감이 있어 마그누스 효과 Script를 구현했다.
* 출처: https://www.aiaa.org/microlesson22/
* 소스코드를 작성하기 까지 수 많은 YouTube자료와 Unity Forum, Stack Overflow를 참조했음을 밝힙니다.
1. 소스코드
공기저항 값을 Return하는 함수)
1 2 3 4 5 6 7 8 | private Vector3 AirForce() { float velocityMag = rigidbody.velocity.magnitude; Vector3 velocityDir = rigidbody.velocity.normalized; float airDragMag = dragConst * Mathf.Pow(velocityMag, 2f); return airDragMag * -velocityDir; } | cs |
Magnes Force 값을 Return하는 함수)
1 2 3 4 5 6 | private Vector3 MagnesForce() { Vector3 magnesForce = magnesConst * Vector3.Cross(rigidbody.velocity, rigidbody.angularVelocity); return magnesForce; } | cs |
사용법)
1 2 3 4 5 | void FixedUpdate() { rigidbody.AddRelativeForce(MagnesForce()); rigidbody.AddRelativeForce(AirForce()); } | cs |
magnesConst와 dragConst는 0.005f 정도의 상수 값이다. (테스트를 통해 조절이 가능하다.)
rigidbody는 Object의 Component이기 때문에 GetComponent<Rigidbody>();로 얻을 수 있다.
3. Debug
- 처음에 적용했을 경우, 공이 생각보다 많이 휘는 경우를 맞이했다.
Object의 Angular Drag가 너무 작은 값을 가졌을 때, 많은 회전량으로 인해 발생했다.
'C# Unity3D' 카테고리의 다른 글
[Physics] 빠르게 움직이는 Object의 충돌 감지 (0) | 2019.03.22 |
---|---|
[Physics] Cast에 관해서 Gizmo 그리기 (0) | 2019.03.19 |
[Physics] Kinematic Object에서 Velocity 값 얻기 (0) | 2019.03.19 |
[Physics] Raycast를 활용한 충돌감지 (0) | 2019.03.13 |
[Animation] Blend Tree를 활용한 단계별 움직임 적용 (0) | 2019.03.12 |