Unreal

문제들과 Float 값에 대한 고찰 - Unreal, C++

workbench34 2025. 1. 24. 20:31

 최근 코드를 짜면서 여러 문제에 봉착했다. 문제라 하면 어떤 상황에 어떤 변수가 있는지 잘 몰라 헤메이는 경우도 있고 의도한대로 만들었다 생각했는데 여실없이 오류가 뜰 때도 있고... 특히 Unreal C++은 한 문장이라도 오류가 뜨면 갑자기 47개정도의 오류가 발생했다고 알림이 와서 당황할때가 많다. (이건 아마 Macro 함수쪽을 잘못 불러와서 생기는 오류인 듯 하다. Visual Studio를 껐다 키면 정상화 되는 경우도 종종 있다.)

 

 제일 문제인 점은 BluePrint에서는 쉽게 만들 수 있었던 Trigger 등이 구현하기 생각보다 어렵다는 점이다. BluePrint에서는 쉽게 구현하는 BoxTrigger 이나 Overlap Event들이 C++로 넘어오니 어떤 함수나 변수를 써야할지 잘 모르겠다. Unreal 공식 문서의 레퍼런스를 계속 참고하고 있지만 내가 원하는 함수를 바로바로 찾기에는 시간이 좀 걸릴 것 같다.

 

 여러 문제점이 있었으나 오늘 제일 큰 문제는 float 였다. 일단 float 에 대해 정의를 내리고 가보자.

 

 float 형이란?

 

float 형은 컴퓨터에서 실수를 표현하기 위해 사용하는 자료형 중 하나이다. 즉, 소수점 이하의 숫자를 나타내기 위해 사용한다고 볼 수 있다. 특징으로는 부동소수점 표현, 빠른 연산 속도 등이 있겠다. 여기서 부동소수점이란 컴퓨터가 실수를 나타낼 대 컴퓨터사엥서 근사하게 표현할 때의 소수점의 위치를 고정하지 않고 그 위치를 낱내는 수를 따로 적는 것으로 유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수로 나누어 표현하는 방식이다. 아주 어렵게 나와있지만 즉 실수 값을 표현할 때 아주 근사한 값을 나타내 준다는 의미이다. 즉, 약간의 오차가 발생할 수 있다.

 

 여기서 float형의 한계가 나타난다. 분명 코드상으로는 오차가 없어야 할 문제이나 float 형의 한계로 인하여 정밀도가 떨어진다. 그래서 이 문제를 해결하기 위해 오늘 시간을 좀 사용했다.

 

1번 double 형 사용하기

 

 결과부터 말하면 별 의미가 없었다... 큰 폭으로 오차범위가 줄어들었으나 결국 오차범위가 생기는 것 자체는 막을 수 없었다. double 형이 float 형에 비해 더 정확하고 범위가 크지만 이 또한 부동소수점을 사용하기에 오차가 생기는 것은 당연하다고 볼 수 있겠다.

 

2번 정수형 변환 및 스케일링

 

 이동 거리를(내가 만든 것은 움직이는 플랫폼으로 전에 썼던 글에서 그 코드를 볼 수 있다. 보면 float 형으로 MoveSpeed 들이 구현된 것을 볼 수 있다.) 정수형으로 변환하고 끝에 도달하면 다시 float 형으로 바꾸어 적용하는 과정을 거친다. 효과는 있었으나 너무 번거로웠다. 만약 코드가 더 길어지고 신경 써야할 변수들이 늘어나면 사용이 거의 불가능 해진다 볼 수 있다.

 

3번 오차 보정

 

 그럼 그냥 일정 위치에 도달하면 강제로 멈추게 하면 되는 것이 아닌가? 에서 나온 발상으로 현 시점에서는 이게 제일 잘 먹히는 것 같다. 만약 320.0f까지 도달하게 만들고 싶다면 320.0f가 넘는 순간 강제로 320.0f로 SetLocation을 활용해 순간이동 시키는 방식이다. 실제로도 아주 근소한 값으로는 순간이동 시켜도 눈에 보이지 않기 때문에 이는 효과적이었다. 그러나 프로그래머로써 이렇게 해결하면 좀 이상하지 않나 자문하게 된다.

 

4번 FFixedPointNumber 사용

 

 놀랍게도 언리얼 엔진에서는 고정소수점 숫자가 있다! 하지만 사용 방법을 아직 숙지하지 못해 실제로 실험해 보지는 못했다. 그러나 이 클래스가 있다면 오차범위 없이 원하는 거리 만큼 도달할 수 있을거라 생각한다. 프로그램 상으로도 3번보다는 이 클래스를 사용하는게 보기에도 깔끔하고 더 전문적으로 보일 듯 하다.

 

 이번 액터를 만들때에는 3번으로 문제를 해결하려 한다. 4번은 더욱 공부해 사용법을 익히고 사용해보도록 하겠다. 기회가 되면 FFixedPointNumber 에 대한 글도 포스팅 해보겠다.

 

 오늘은 원래 C++을 이용해 캐릭터가 올라가면 높이 띄워주는 발판을 만드려고 했었다. 하지만 아직 캐릭터를 C++로 구현하는 방법을 배우지 않아 이를 실험하기는 불가능 했다. 또한 Static Mesh 와 SceneComponent 를 C++로 불러오는 방법은 알겠는데 TriggerBox는 어떻게 불러오는지 아직 숙지하지 못했다. 이 또한 배워서 포스팅 해보겠다.