가상 세계

피사(Pisa)의 사탑에서 자유낙하 운동 실험해보기 (with 언리얼 엔진과 블렌더)

myhahu 2025. 4. 29. 22:36

 하이!

블로그에 무슨 글을 써볼까? 하며 핸드폰을 만지작 거리다 갑자기 문뜩 구글 지도가 생각났다. 언리얼에서 만들 가상공간 및 물리적인 무언가 결합하면 좋지 않을까 고민하였다. 그래서 예전 물리 시간 때 배운 자유낙하 관련된 무언가를 표현해 보면 좋겠다고 생각이 들었다. 그러고 나서 든 생각이 "아하~ 피사의 사탑! 갈릴레오 아저씨가 자유낙하 실험했었지?"라고 들었다.  그래서 바로 작업 시작~

피사의 사탑은 아래 캡처한 사진을 바탕으로 제작한다.

 

 

 우선 블렌더(Version 4.3)를 실행시킨 뒤 원기둥 오브젝트 한 개를 생성한다. 그 뒤 에디트 모드로 들어가 Loop cut을 이용해 해당 오브젝트를 8 등분한다. 등분한 사이의 공간으로 Loop cut을 한 개씩 내주어 작은 두께의 원판모양의 층을 형성한다. 이 층은 E키를 누르고 S키를 눌러 사이즈를 키워준다. 그러면 원기둥 오브젝트에서 옆구리가 튀어나가는 듯한 모습을 보이게 된다. 그런 층은 총 9개로 구성된다.

 

 

 

 원기둥 전체 사이즈를 살짝 슬림하게 하고 원기둥 맨 윗부분의 사이즈는 축소시킨다. 이를 위해 뷰포트 오른쪽 상단 위의 Toggle X - Ray를 눌러주면 오브젝트가 투명하게 보인다. 이 상태에서 마우스를 드래그해 내가 원하는 영역을 드래그해 주면 내가 보는 면만 드래그되는 것이 아니라 관통되는 듯 전체 영역이 드래그가 가능하게 된다. 이 기능을 활용하면 오브젝트의 사이즈 조절에 용이하다.

원기둥 옆에 면(Plane)한 개를 생성한다. 그 뒤 에디트 모드로 들어가고 나서 면을 y축 기준으로 90도 꺾은 뒤 면의 맨 위쪽 선을 클릭하고 마우스 오른쪽 버튼 - Subdivide를 통해 선을 수십 등분해 준다. 그러면 선 자체에 수십 개의 점이 형성된다. 이 점들 중 가장 중앙에 있는 점을 골라 위쪽으로 드래그해 준다. 이때 뷰포트 중앙 상단의 Proportional Editing - Sphere를 눌러주면 점들을 끌고 가는 모습이 스피어(3차원의 구)처럼 보이게 된다. 물론 여기선 평면을 끌고 올라가는 거라 3차원은 아니고 2차원이다.

그러고 나서 면 전체를 클릭한 상태로 E키를 눌러 면을 돌출시켜 3차원 오브젝트를 만들어 준다.

 

 

 위에서 생성한 오브젝트를 원기둥에 가까이 놓은 상태로 에디트 모드로 들어간다. 해당 오브젝트를 전체 클릭한 상태로(보통 A키를 누르면 가능함) 뷰포트 왼쪽 하단의 Spin을 눌러준다. Spin은 내가 선택한 영역을 원하는 만큼 복사시켜 주고 원하는 각도에 원하는 개수만큼 늘려준다. 여기서는 10개로 늘리고 360도 범위 안에 들어가게 했다.

Spin으로 만든 오브젝트는 원기둥 표면에 벽화처럼 박혀 무늬가 될 것이다.

 

 

 원기둥 오브젝트를 선택한 상태에서 오른쪽 패널 - Modifiers - Add Modifier - Generate - Boolean을 눌러준다. 그 뒤 Difference를 누르고 타깃은 Spin으로 생성한 오브젝트를 선택한다. 그러고 Difference 버튼 바로 위의 화살표 버튼 - Apply버튼을 눌러주면 원기둥 표면이 Spin으로 생성한 오브젝트의 형상처럼 파이게 된다. 원기둥의 1층을 이런 식으로 만들었고 나머지 층들도 이와 거의 동일하게 만들었다.

 

 

 Difference 기능으로 만들어진 홈에 추가적으로 틈을 만들기 위해 원기둥을 두 개 형성한 뒤 한 곳에 포갠다. 그러고 이것 역시 Difference 기능을 활용해 원기둥 한 개를 타깃으로 다른 원기둥 가운데 거대한 구멍을 만든다. 그러면 마치 도넛 모양이 된다. 이 도넛 오브젝트를 원기둥 오브젝트 중앙에 놓고 다시 한번 Difference 기능을 사용한다. 그러면 우측 사진처럼 spin으로 형성된 오브젝트로 인한 홈 안쪽으로 도넛 오브젝트가 파고들어 비어 있는 공간을 만들게 된다.

 

 

 현실의 피사의 사탑을 보니까 사탑 아래쪽에 마름모 모양이랑 사탑 위쪽에 난간이 보이길래 그것도 제작하였다.

모름모 모양에는 재질을 따로 입혔고 나머지 부분에는 연한 상아색으로 재질을 입혔다. 그러고 나서 파일은 저장한 뒤 Fbx 확장자로 바탕화면에 저장한다.

 

 

 이제 언리얼 엔진 작업 차례이다. 자유 낙하 운동을 구현하기에 앞서 언리얼 엔진의 중력값은 우리가 알고 있는 9.81 m/s² 이 만든 지 확인하기 위해 단위랑 중력값을 확인해 본다. 우선 언리얼 엔진(Version: 5.0)에서 프로젝트 Level 맵 한 개를 형성한다. 그리고 Project Setting으로 들어간 뒤 검색창에 'Unit'이라고 치고 단위를 확인하였는데 센티미터라고 되어있다. 그리고 검색창에 'Gravity'라고 쳤는데 -980이라고 적혀있었다. 단위나 중력값은 내가 마음대로 바꿀 수 있으나  그대로 쓰기로 하였다. 

 

 

 아까 fbx확장자로 저장한 데이터를 레벨 맵파일 안에 import 시켜준다. 그 뒤 블루프린트 엑터를 한 개 생성하고 그 안에 피사의 사탑 오브젝트를 배치한다. 사탑에서 자유낙하를 위해 네모난 판자랑 판자에 매달 줄이랑 줄에 매달린 뒤 아래로 떨어지기 위한 동그란 돌 한 개를 만든다. 줄은 블루프린트 왼쪽 패널에서 Components - Add - Cable 순으로 찾아서 불러왔고 돌은 돌 재질을 가져와 구체형 오브젝트에 덧입힌 것이다.

돌 오브젝트의 움직임을 위해 블루프린트에서 아래의 사진처럼 Mobility는 movable, simulate Physics은 키고 Linear랑 Angular Damping은 0으로 해둔다. 이 두 개는 각각 공기저항 역할을 해주는데 Linear는 물체의 속도를 늦춰주고 Angular는 물체가 회전하는 것을 막아준다. 둘 다 값이 커지면 커질수록 막는 힘도 커진다.

 

 

 블루프린트의 노드의 구성은 다음과 같다. Event Tick을 중심으로 1초의 딜레이를 주어 지속적으로 반복하게 하였다. 딜레이가 끝나면 Text Render의 Text에 공 오브젝트의 Z 축 높이값이 모이게 하였다. 이 말은 물체가 지지대에서 떨어지고 1초가 지나면 그 시간대의 물체의 높이를 알려준다.

 

 

 아래 영상처럼 총 10번을 실험했다. 처음 값인 z = 26.885부터 마지막 10번째인 z = 25.607번까지의 평균을 내었는데 25.456이 나왔다. 이게 참 웃기는 일인데 블루프린트 코딩을 수정한 것도 아니고 그냥 플레이 버튼만 키고 껐을 뿐인데 할 때마다 값이 다르다. 이상적으로는 몇 번을 켜고 꺼도 동일한 값이 나와야 하는데 컴퓨터 문제인지 프로그램 자체 문제인지 그렇지 못했다. 이러한 이유로 10번을 진행하여 평균을 내었고 이 값을 이용해 실제로 언리얼 엔진의 중력가속도 값이 9.81이 나오는지 알아볼 것이다.

일단 생각해보아야 하는 게 자유낙하 운동은 등가속도 운동이며 공기저항이 없는 상태에서 진행된다.

이러면 쓸 수 있는 공식이 V(t) = at + V0, X(t) = at²/2  +V0t +X0, 2a(X-X0) = V²- V0 ² 이렇게 3가지 있다. 우선 자유낙하 운동이니까 처음속도랑 처음 위치를 0으로 둘 수 있다. 공식에서는 X0 = 300, V0  = 0이다.  여기서 300은 돌 오브젝트의 Z 축 처음높이를 나타낸다. 그러면 V(t) = at, X(t) = at²/2+300, 2aX = V²로 변한다. 아까 평균 높이를 25.456이 나왔는데 이건 지상 0으로부터 25.456만큼 떨어졌다는 말이다. 그러나 자유낙하 운동공식에 거리를 넣으려면 시작위치부터 얼마만큼 떨어졌는지 알아야 한다. 이 값은 바로 나온다. 300-25.456 = 274.544다. 단위를 표시하자면 언리얼은 cm이고 중력가속도에서는 m를 쓰니까 274.544cm는 2.745m로 바꾸어 준다. 이것을 통해 2.745 = a/2(t = 1초), a = 5.49m/s²가 나온다. 이 수치는 원래 우리가 알던 9.81의 절반정도의 값이다. 언리얼 엔진의 물리 시스템을 완벽히 몰라서 그런지 아님 원래 이렇게 나오는 게 정상인지 잘 모르겠다.

 

 

 이번에는 Linear Damping = 2로 설정한 상태에서 실험해 보았다. 10번 실험의 평균값은 z = 91.716이 나왔다. 그러면 300 - 91.716 = 208.284이고 m로 환산하면 2.083m가 된다. 그러면 a = 4.166 m/s²가 나온다. 

 

 

 마지막으로  Linear Damping = 4로 설정한 상태에서 실험해 보았다. 10번 실험의 평균값은 z = 161.595이 나왔다. 그러면 300 - 161.595 = 138.408이고 m로 환산하면 1.384m가 된다. 그러면 a = 2.768 m/s²가 나온다. 

Damping이 없을 때의 가속도  a = 5.49m/s², Damping = 2 일 때의 가속도 a = 4.166 m/s²,  Damping = 4  일 때의 가속도 a = 2.768 m/s² 를 보면 확실히 공기저항이 있을 때 가속도가 줄어드는 것을 알 수 있다. 또한 댐핑수치가 4 배수일 때 원래 가속도의 절반이 된다는 것도 어느 정도 유추해 볼 수 있다. 그럼 댐 핌이 8이면 원래 가속도의 4분의 1이 될까? 이건 한번 나중에 해보려고 한다.

프로젝트 설정에서 -980으로 되어있길래 당연히 1초당 9.81m씩 쭉쭉 아래로 떨어지겠거니 했는데 아니었다. 설정을 더 꼼꼼히 체크했어야 하는지도 모르겠다. 원래 9.81m로 떨어지는 게 맞는데 내가 못한 것일 수도 있다. 이 점은 참고하고 보길 바란다.