2년 전 임시 블로그에 있던 글을 옮겨왔다.
부력 물리 계산
(영상의 2 번째 scene)
삼각함수 법칙에 의하여, x축은 cos로, y축은 sin으로 구하자. 파도에 사용된 sin함수 => 진폭(float형 변수) * Mathf.Sin(길이 / offset);
부력 효과를 만들 때, 면의 모양에 따라 (물에 닿는 꼭짓점의 개수만큼) 중력을 나누어 주고, 각 꼭짓점 마다 부력 효과 스크립트를 모두 붙인다. 힘을 주는 효과는 AddForceAtPosition으로 만든다. 테스트로 직육면체는 4개, 구는 한개를 주었다. 나누는 값을 (floatCount)라 한다면,
=> rb.AddForceAtPosition(Physics.gravity / floaterCount, transform.position, ForceMode.Acceleration);
ForceMode.Acceleration
- 질량을 무시하고, rigidbody에 연속적인 가속력을 가한다.
ForceMode.VelocityChange
- 질량을 무시하고, rigidbody에 같은 순간적인 속도변화를 적용한다.
AddTorque rigidbody에 토크를 추가하여, rigidbody가 토크 축을 중심으로 회전하기 시작한다.
포물선 계산
(영상 소리주의!)
포물선에 대한 계산은 Vector로 이루어진다.
먼저 생성지점(origin)과 목표지점(target), 그리고 생성지점부터 목표지점까지 도달하는데 걸리는 시간(time)을 계산한다.
이후, Vector3로 목표지점에서 생성지점을 뺀 변수를 만든다.
- Vector3 distance = target - origin
그리고 이 값을 다른 벡터값에 저장해둔다. - Vector3 distanceXz = distance
distanceXz의 y값은 0으로 만들어준다. - distanceXz.y = 0f;
distance의 y값, distanceXz의 길이를 담는 float형 변수 2개를 만든다.
- float sY = distance.y;
- float sXz = distanceXz.magnitude;
그리고 sXz에 시간을 곱해준 값과, sY를 시간으로 나눈 값과 중력의 y절대값과 시간의 곱을 더한 float형 변수 2개를 만든다
- float Vxz = sXz * time;
- float Vy = (sY / time) + (0.5f * Mathf.Abs(Physics.gravity.y) * time)
결과값은 Vector3 result = distanceXz.normalized로 만들어주고,
- result *= Vxz, result.y = Vy로 해준다.
그리고 이 벡터함수가 result를 반환하도록 만들어준다.
이 벡터함수를 담은 변수를 업데이트문에서 실행해주고, 그 변수를 물체의 Rigidbody의 velocity에 넘겨주자.
+) 유니티에서는 Slerp라는 구면 선형 보간에 기반한 이동 함수가 존재한다. 이를 사용하면 위와같은 공식을 사용하지 않고도 쉽게 포물선 이동을 구현할 수 있다.
smoothdamp, lerp, slerp등은 알아두면 굉장히 유용하게 사용할 수 있다.