본문 바로가기

테크/로블록스

로블록스 스튜디오 튜토리얼 - 툴 만들기

앞서 로블록스 스튜디오 설치 및 기초 과정 (프로그램 구성, 3D 모델 생성, 단축키 등)에 대해 알아보았습니다. 이번 포스팅에서는 다양한 게임 개발에 사용될 수 있는 "툴(Tool)" 만들기 과정에 대해 알아보겠습니다.[이전 글] 로블록스 스튜디오만 있으면 나도 게임 개발자! - 설치 및 기초

 

로블록스 스튜디오만 있으면 나도 게임 개발자! - 설치 및 기초

로블록스에 관한 두 번째 포스팅은 "로블록스 스튜디오" 첫 체험기입니다. 본격적인 개발에 앞서 설치 과정과 기초 사용법을 익히는 시간을 가져보겠습니다. 로블록스가 처음이신 분은 지난 포

dumbofphilosophy.tistory.com


 

목차

튜토리얼 개요
프로젝트 만들기
Workspace에 툴(Tool) 추가하기
3D 파트(Part)를 이용해 망치 모델 만들기 - SimpleHammer.Handle
툴 스크립트 (Tool Script) 작성하기 - Skeleton
툴을 어떻게 잡을 것인지에 관한 설정 - Grip
툴을 사용할 때 캐릭터의 움직임 정의 - 애니메이션
툴을 사용할 때 호출되는 function 정의
최종 툴 장착 및 사용 모습

 

 

튜토리얼 개요

3D 모델을 이용하여 망치(hammer) 모양의 툴(Tool)을 생성 하는 것이 목표입니다. 바닥에 떨어져있는 망치가 플레이어의 캐릭터 몸에 닿으면 플레이어의 백팩(backpack)으로 툴이 추가되어야 합니다. 망치 툴을 캐릭터에 장착한 후, 왼쪽 마우스 클릭을 하면 캐릭터가 망치를 휘둘러야 합니다.

 

프로젝트 만들기

먼저 로블록스 스튜디오 프로그램의 왼쪽 탭에서 "New" 버튼을 클릭하여 새로운 프로젝트를 만듭니다. 기본으로 제공되는 템플릿들 중 "Baseplate"를 선택합니다.

 

Workspace에 툴(Tool) 추가하기

Explorer 창의 Workspace 우측 "+" 버튼을 클릭한 뒤, "Tool"을 선택하여 추가합니다. Tool의 이름을 아래 그림과 같이 "SimpleHammer"로 바꿔주었습니다. 최종적으로 망치 모델(Handle)과 휘두르는 액션 애니메이션(Animation)을 추가하는 것이 목표입니다.

 

3D 파트(Part)를 이용해 망치 모델 만들기 - SimpleHammer.Handle

[Model]-[Part]에 있는 block, sphere, wedge, cylinder와 적절한 move, scale, rotate를 이용해 3D 망치 모델을 만들 수 있습니다. 직접 만드는 대신 [View]-[Toolbox]에서 망치 모양 메쉬(mesh)를 가져와서 서용해도 됩니다. 크기가 다른 cylinder 두 개를 적절히 조합하여 만들어진 SimpleHammer 모델은 아래 그림과 같습니다. 두 개의 cylinder 모델을 동시에 선택한 뒤 [Model]-[Solid Modeling] 탭의 Union을 클릭하면 하나의 모델로 합쳐집니다.

 

아래 그림에서 오른쪽 두 그림은 각각 망치 모델을 로컬 모델 프레임(L) 축들과 글로벌 월드 프레임(W) 축들과 함께 나타낸 것입니다. Cmd+L의 단축키 (혹은 모델 선택 후 오른쪽 마우스 클릭, 드롭다운 메뉴에서 Use Local/World Space 선택)를 누르면 두 프레임 간에 전환이 가능합니다.

 

그리고 모델 선택 후 오른쪽 마우스 클릭, 드롭다운 메뉴에서 Show Orientation Indicator를 클릭하면 파란색 F와 작은 화살표 모양이 나타나는데, 이는 로컬 모델 프레임(L)의 Front와 Up 방향을 나타냅니다. 참고로, 로블록스에서 모델의 Right, Up, Forward 방향은 각각 L 프레임의 +X, +Y, -Z 축 방향에 해당합니다. 아래 두번째 그림에서 파란색 F 부분이 물체의 정면이기 때문에, L 프레임의 +Z 축은 뒤쪽 방향이고, 작은 초록색 화살표가 Up 방향, 즉 +Y 축이 됩니다. 그에 따라 자연히 +X 축은 지면 방향이 됩니다. W 프레임의 축들은 로블록스 스튜디오 화면 우측 상단에 표시된 XYZ 축 방향에 따라 아래 세번째 그림과 같습니다.

 

왼쪽부터 - Decal 근처에 생성된 망치, 망치 모델과 local object 프레임 XYZ 축, 망치 모델과 world 프레임 XYZ 축

 

Explorer 창에서 합쳐진 모델의 이름을 Handle로 바꿉니다. 그리고 Handle 모델을 앞서 만든 SimpleHammer 툴 아래에 속하도록 드래그해서 추가합니다. Handle 하위 항목으로 "TouchInterest"가 생긴 것을 볼 수 있는데, 플레이어의 캐릭터가 Handle 모델에 터치하게 되면 툴을 장착할 수 있게 됩니다.

 

Explorer 창에 추가된 Tool named SimpleHammer

 

툴 스크립트 (Tool Script) 작성하기 - Skeleton

SimpleHammer 우측의 "+" 버튼을 눌러 Script를 추가해 줍니다. 이 스크립트에 Lua 언어로 된 코드를 작성함으로써, SimpleHammer의 behavior를 정의할 수 있습니다. 본 튜토리얼에서는 필수적인 요소만 소개하겠습니다. 

 

Explorer 창에서 Handle 하위 항목으로 Script를 추가.

전체적인 틀은 아래와 같습니다.

local tool = script.Parent

function onEquip()
	-- Occurs when the player selects the tool from their backpack.
end

function onUnequip()
	-- Occurs when the player drops the tool or switches tools.
end

function onActivate()
	-- Occurs when the player starts activating the tool
	-- (clicks, taps, or presses A on a gamepad).
end

function onDeactivate()
	-- Occurs when the player stops the activation input
	-- (releases the button or touch).
end

tool.Equipped:Connect(onEquip)
tool.Unequipped:Connect(onUnequip)
tool.Activated:Connect(onActivate)
tool.Deactivated:Connect(onDeactivate)

 

먼저, 첫번째 라인입니다. 현재 코드를 작성하고 있는 스크립트 object를 "script"라는 변수로 접근할 수 있고, Explorer의 hierarchy를 토대로 Parent를 통해 상위 항목에 접근할 수 있습니다. Lua에서 새로운 tool이라는 이름의 로컬 변수를 선언할 때 local tool 이렇게 선언해주면 됩니다.

 

다음으로 4개의 function을 정의하였는데, 아직 내용은 없는 상태입니다. 이들은 일종의 특정 이벤트가 발생했을 때 호출되는 callback function의 개념으로 생각하면 됩니다. 어떤 이벤트에 호출이 되는지는 각 function마다 comment로 작성되어 있습니다. 가장 하단의 네 줄은 정의된 각 function을 이벤트에 연결시켜주는 것으로 생각하면 됩니다.

 

  • Equipped/Unequipped는 플레이어 캐릭터가 백팩에 있는 툴들을 선택적으로 장착, 혹은 해제할 경우 (다시 백팩에 툴을 넣거나 backspace 키를 눌러 툴을 아예 버릴 때)에 발생하는 이벤트들입니다.
  • Activated/Deactivated는 장착된 툴을 마우스 클릭 등을 통해 사용할 때, 그리고 사용이 끝난 이후에 발생하는 이벤트들입니다.

 

망치 툴을 캐릭터에 장착한 후 왼쪽 마우스 클릭을 하면 캐릭터가 망치를 휘두르게 하는 것이 본 튜토리얼의 목표입니다. 이를 위해서는 아직 몇가지 요소가 필요합니다.

 

  • 플레이어 캐릭터가 툴을 잡는 Grip에 관한 설정
  • 장착된 툴을 사용할 때 캐릭터의 움직임 정의 (애니메이션)
  • 장착된 툴을 사용할 때 호출되는 function onActivate()에 관한 정의

각 항목을 순서별로 알아보겠습니다.

 

툴을 어떻게 잡을 것인지에 관한 설정 - Grip

Explorer 창에서 가장 상위의 Tool 이름(SimpleHammer)을 클릭하면 바로 아래 Properties 창에서 Appearance에 관한 설정이 나타납니다. 자세한 항목으로는 GripForward, GripPos, GripRight, GripUp, ToolTip이 있습니다. 

 

우선 GripForward, GripRight, GripUp이 뜻하는 바는, 캐릭터가 툴을 손에 쥐었을 때 캐릭터가 앞을 바라보는 방향, 오른쪽 방향, 지면에서 하늘로 향하는 방향이 툴의 3D 모델 프레임에서 어떤 축들에 해당이 되는지 설정해주어야 합니다. 참고로 Forward, Right, Up 방향의 개념은 앞서 설명한 것처럼 -Z, +X, +Y 방향을 뜻합니다.

 

캐릭터는 오른손에 툴을 쥐게 되는데, 망치를 어떤 위치, 어떤 방향으로 쥐게 할 것인지는 원하는 대로 하면 됩니다. 저는 가장 간단한 방법으로, 망치를 지면에서 하늘 방향으로 직각으로 들되, 망치를 내리치기 위해서는 망치 머리 부분 cylinder의 회전축이 Forward 방향과 평행이 되도록 쥐게 설정하였습니다. (아래 그림 참조)

 

캐릭터가 툴을 장착한 모습 (좌) 망치 모델과 local object 프레임 XYZ 축 (우)

 

이를 위해서는, 3D 모델 프레임 (L)을 기준으로, Up 방향은 -X 축, Right 방향은 +Y 축, 그리고 Forward 방향은 -Z 축으로 설정하면 됩니다. 그리고 캐릭터의 손이 툴을 잡는 위치는 원점에서 약간 아래쪽으로 설정하겠습니다. 최종 Grip 설정 값들은 다음과 같습니다. 참고로 GripForward, GripRight, GripUp은 방향 벡터들이기 때문에, unit vector가 아닌 값들을 입력하면 자동으로 unit vector로 전환되는 것을 볼 수 있습니다.

 

Properties 창의 Appearance 탭에 위치한 Grip에 관한 설정.

 

툴을 사용할 때 캐릭터의 움직임 정의 - 애니메이션

다음으로, 캐릭터가 툴을 장착한 상태에서 화면에 마우스 클릭을 하면 망치를 내리치는 액션을 추가하고자 합니다. 이러한 캐릭터의 액션은 애니메이션 편집 기능을 이용할 수 있습니다.

 

  • 로블록스 스튜디오 상단의 메뉴 탭에서 [Plugins]-[Animation Editor]를 클릭하여 애니메이션 편집 창을 오픈합니다.
  • [Plugins]-[Build Rig]를 클릭한 뒤 원하는 Rig를 선택합니다. R6과 R15가 있는데 각각 몸의 중심부(root)를 제외한 캐릭터의 몸 부위가 나눠진 개수가 6개와 15개입니다. 즉, 더 정교한 움직임을 표현하기 위해서는 R15 중 하나를 선택하면 됩니다.
  • Rig를 만들면 Explorer 창에 Dummy 그룹이 생기고, 그 안에는 여러 몸 부위 모델들이 있는 것을 확인합니다.
  • 애니메이션 편집 창을 클릭한 뒤 안내에 따라 Dummy Rig를 클릭하여 선택하면, 아래와 같이 애니메이션 이름을 입력하여 새로운 애니메이션을 생성할 수 있습니다.

 

애니메이션 생성 named AttackWithHammer

 

  • 애니메이션 편집 창에 타임라인이 뜨는데, 해당 시간을 클릭한 뒤, Dummy 휴머노이드의 특정 몸 부위를 클릭하여 선택하고, 원하는 만큼 회전시켜 원하는 움직임을 기록할 수 있습니다.
  • 완료 후, 애니메이션 편집 창 좌측 상단에 애니메이션 이름 바로 옆, "..."를 클릭하면 "Set Animation Priority"가 있습니다. 클릭하여 "Action"을 선택합니다.
  • 다시 "..."를 클릭한 뒤 "Export"를 누른 뒤 "Submit" 버튼을 누르면 로블록스 라이브러리에 애니메이션이 등록이 되고, 고유 ID가 생성됩니다. 이를 클립보드에 복사합니다.
  • (더이상 애니메이션 편집이 필요없다면 Explorer의 Dummy 그룹을 삭제해도 됩니다.)
  • 가장 상위 툴 이름(SimpleHammer)의 우측 "+"를 클릭하여 "Animation"을 추가합니다.
  • Animation을 클릭한 뒤 바로 아래 Properties창의 Data 부분 AnimationId 옆 빈칸에 클립보드에서 복사해 두었던 애니메이션 ID를 붙여넣습니다.

 

 

툴을 사용할 때 호출되는 function 정의

끝으로, onActivate(), 즉 장착된 툴을 사용할 때 호출되는 function을 정의해주면 됩니다. 제가 작성한 코드는 다음과 같습니다. 내용은 아주 직관적이기 때문에 자세한 설명은 생략합니다.

 

function onActivate()
	if not tool.Enabled then
		return
	end
	
	tool.Enabled = false

	local humanoid = tool.Parent.Humanoid
	if humanoid == nil then
		print("Humanoid not found")
		return
	end
	
	local animation = tool.Parent.Humanoid:LoadAnimation(script.Parent.Animation)
	animation:Play()
	
	tool.Enabled = true
 end

 

최종 툴 장착 및 사용 모습

툴을 장착하면 백팩에 추가되고, 화면 아래 작은 번호와 함께 표시됩니다. 해당 번호 키를 누르면 Equip/Unequip을 할 수 있습니다. 장착된 툴을 사용해보기 위해 마우스로 화면을 클릭하면 됩니다. 툴을 백팩에서 아예 버리고 싶다면 backspace 키를 눌러서 버릴 수 있습니다. 

 

반응형