[Unity] 오브젝트의 발사

PublicMinsu·2023년 12월 18일
0

개요

아이디어가 바뀌었으니 움직임도 바뀌는 것이 옳은 이치이다.
기존 움직임은 목표 지점까지로 가는 것이었다면 변경할 움직임은 목표 방향만 존재하는 것이다.

발사라는 표현이 적절한 것 같기도 하다.

유니티에서의 발사

Rigidbody.AddForce

출처 : https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html

발사를 구현할 때 여러 방법이 있겠지만 AddForce가 지금 방법에 어울릴 것 같다.

AddForce는 특정 방향으로 힘을 주는 함수이다.

AddForce는 2개의 파라미터를 가지는데 첫 번째는 방향을 나타내는 Vector3, 두 번째는 AddForce의 동작 방식을 선택하는 ForceMode를 받는다. 두 번째 파라미터인 mode는 기본값으로 ForceMode.Force를 가진다.

ForceMode.Force는 무엇일까?

ForceMode


출처 : https://docs.unity3d.com/ScriptReference/ForceMode.html

ForceMode는 4개의 유형을 가지고 있다.
각 4가지는 즉각적인지, 질량에 영향을 받는지에 따라 다르게 작동한다고 볼 수 있다.

4개의 유형의 차이

각각의 모드를 질량(Mass)을 5로 설정하고 AddForce를 5의 힘(Vector3.right * 5f)으로 사용해 본 모습이다.
이후 velocity를 확인해 보면 속도를 확인할 수 있다.

VelocityChange의 경우 설명과 동일하게 즉각적으로 속도를 변경시키는 효과를 주었다.
Impulse의 경우에는 힘을 가했지만 질량에 영향을 받았기에 5에서 5를 나눈 1이 되었다.

여기까지는 직관적인 이해가 된다.
하지만 나머지 두 값(Force, Acceleration)에서 의문을 가질 수 있다. 왜 저런 값을 가지게 된 걸까?

질량에 영향받는 지로 묶는다면 VelocityChange와 Acceleration, Impulse와 Force의 velocity는 0.02배라는 것을 알 수 있다.

눈치챈 사람도 있겠지만 이는 Time.fixedDeltaTime의 값과 동일하다.

즉 Force는 VelocityChange의 값(5)에서 질량의 값(5)을 나누고 Time.fixedDeltaTime의 값(0.02)을 곱한 것이다.

결론

힘이 F, 질량이 M이라면 이렇게 설명할 수 있는 것이다.

VelocityChange는 F (즉각적인 힘, 질량에 영향을 받지 않음)
Impulse는 F / M (즉각적인 힘, 질량에 영향받음)
Acceleration는 F * Time.fixedDeltaTime (지속적인 힘, 질량에 영향을 받지 않음)
Force는 F / M * Time.fixedDeltaTime (지속적인 힘, 질량에 영향받음)

지속적인 힘에 경우에는 일정 기간에 걸쳐서 힘을 주기 위하여 deltaTime이 이미 고려된 것이다.
그렇기에 따로 fixedDeltaTime을 곱할 필요가 없는 것이다.

출처 : https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html

사실 이러한 내용은 공식 문서를 찾아보면 존재합니다.
그럼에도 많이 알려지지 않은 이유는 모르겠다.

Rigidbody.velocity

AddForce에 경우에는 처음에도 말했듯이 특정 방향으로 힘을 가하는 느낌이다.
그렇다면 만약 해당 오브젝트를 재활용한다면 어떻게 할까?
만약 다른 방향으로 가야 한다면 이미 힘이 가해져있기에 기존에 속도를 제거해 줘야 할 것이다.

그럴 땐 Rigidbody.velocity를 사용하면 된다.
velocity는 이름과 동일하게 속도를 나타낸다.
위에서 4개의 유형을 확인할 때 속도를 확인할 수 있었던 것도 velocity덕분이다.

velocity의 값을 변경시키면 속도가 변경된다.
velocity에 Vector3.zero를 대입시켜주면 속도가 0으로 초기화되는 것이다.

코드로 적용

방향의 경우 구 위의 랜덤 좌표를 구하는 Random.onUnitSphere을 활용했다.
이후 LookRotation으로 해당 방향을 바라보게 하고 Vector3.zero를 velocity에 대입하여 이전의 속도를 제거해 주었다.
이후 AddForce로 목표 방향으로 힘을 가하게 하였다.

코드를 작성하고 이런 생각이 들었다.
굳이 매 사용마다 속도를 제거할 거면 AddForce를 사용할 필요가 있을까?

이미 작성된 코드에서 AddForce를 제거하고 velocity에 대입하는 방식으로 해결했다.

테스트

간단한 테스트 코드를 작성하고 테스트를 해보았다.
의도한 대로 꽤 재밌는 결과가 나왔다.

공부하며 느끼게 된 지난날의 과오

이전에 프로젝트를 하면서 기능 구현을 우선시하였다.
이번 글을 작성하면서 AddForce를 잘못 사용했던 적이 있었던 것 같다는 생각이 들었다.

다른 사람들의 블로그를 확인해도 모두 연속적인 힘, 질량을 무시 정도만 적어놨기에 나한테는 제대로 된 설명이 안 되었다.

그래도 이번 기회에 알게 되었으니 다음에 사용할 때에는 자신 있게 사용할 수 있을 것이다.

profile
연락 : publicminsu@naver.com

0개의 댓글