3D 게임에서 자주 사용하는 GUI로, 어떤 사물에 가까이 다가갔을때 보여주는 GUI가 있다. 예를 들어 화면에 상자가 있다고 하면 처음엔 그냥 상자만 보이지만, 플레이어가 충분히 가까이 다가가면 "Open"이라는 버튼이 나오거나 설명이 나오는 식의 GUI를 많이 접해 봤을 것이다. 이런 방식을 Proximity Prompt라고 한다.
프로젝트 편집
이번 포스팅은 Dungeon Delve라는 로블록스에서 제공하는 데모게임을 편집하면서 진행하겠다.
프롬프트 만들기
위의 동영상에서 보듯 게임상에서 뭔가를 알려주는 GUI창을 프롬프트라고 한다. 로블록스 게임 내에서 제공하는 기본 프롬프트를 만드는 떄는 ProximityPrompt 객체를 통해 구현할 수 있다. 이 근접프롬프트는 Attachment, BasePart 또는 Model의 자식으로 게임 내에 추가할 수 있다.
Attachment 는 BasePart의 자식으로 위치와 방향성을 표현하는데 사용된다. ProximityPrompt 객체의 부모로써 원하는 포인트에 근접했을 때를 알기 위해 자주 사용된다.
탐색기에서 Workspace → PromptObjects → PrisonDoor 을 선택하자.
PrisonDoor 모델의 화살표를 눌러서 펼치고 그 안에 Door 파트를 선택하자.
Door 에 Attachment를 추가하자. 그냥 PrisonDoor 모델이나 Door 파트에 근접프롬프트를 적용시키지 않고 굳이 Attachment를 추가하는 이유는 모델이나 파트의 경우 범위가 넓어지니 원하는 위치에 딱 적용시키기 위함이다. 여기서는 도어의 자물쇠 부근 위치를 중심으로 근접했을 때 근접 프롬프트가 나오는 것을 구현하였다. Attachment의 이름을 PromptAttachment 으로 변경하자.
추가한 Attachment의 위치는 자물쇠 위치로 맞추기 위해 -2.25, -0.5, -0.5 로 변경하자.
추가한 PromptAttachment의 자식으로 ProximityPrompt 객체를 추가한다.
프롬프트의 외형
ProximityPrompt 객체의 프롬프트의 외형은 아래와 같이 3가지 요소가 있다.
- ObjectText — 플레이어와 상호작용을 할 게임 오브젝트의 이름. 예) 도어
- ActionText — 플레이어가 어떤 행동을 할 것인가에 대한 이름. 예) 오픈
- KeyboardKeyCode — 트리거가 되는 키. 예) E키
- GamepadKeyCode — 트리거가 되는 게임패드의 키. 게임패드를 사용할 시. 모바일 화면일 경우 터치 이벤트를 보여주기다 한다.
프롬프트의 정보를 변경하자. ObjectText는 Door.
ActionText 는 Pick Lock.
발동 거리(Activation Distance)
ProximityPrompt 객체의 MaxActivationDistance 속성의 값은 Attachment와 플레이어 캐릭터와의 거리에 대한 값이다. Attachment와 캐릭터와의 거리가 그보다 가까워지면 프롬프트가 표시된다.
MaxActivationDistance 을 4로 변경.
Hold Duration
HoldDuration 속성은 프롬프트의 액션이 발동되기까지의 시간임. 이 시간만큼의 키를 눌러줘야 액션이 실행된다. 적당한 시간을 설정해 준다.
플레이어의 키 입력에 반응하기
프롬프트 이벤트를 감지하는 가장 좋은 방법은 ProximityPromptService 서비스를 이용하는 것이다. ProximityPromptService 서비스를 사용하면 각각의 ProximityPrompt에 모두 스크립트를 추가할 필요없이 한곳에서 처리할 수 있게 도와준다.
프롬프트의 이벤트에 대해 ProximityPromptService 서비스로 어떻게 작동하는지 살펴보자.
local ProximityPromptService = game:GetService("ProximityPromptService")
-- 프롬프트의 액션이 실제로 발동될 때 실행될 함수
local function onPromptTriggered(promptObject, player)
end
-- 프롬프트 액션 실행을 위해서 키를 누르기 시작할 때 실행될 함수
local function onPromptHoldBegan(promptObject, player)
end
-- 프롬프트 액션 실행을 위해서 키를 누르고 마치고 키를 놨을 때 실행될 함수
local function onPromptHoldEnded(promptObject, player)
end
-- 각 이벤트에 함수들을 연결
ProximityPromptService.PromptTriggered:Connect(onPromptTriggered)
ProximityPromptService.PromptButtonHoldBegan:Connect(onPromptHoldBegan)
ProximityPromptService.PromptButtonHoldEnded:Connect(onPromptHoldEnded)
Dungeon Delve 프로젝트에서는 이 이벤트들은 모두 PromptEvent라는 스크립트에서 처리된다. 탐색기창에서 ServerScriptService 서비스에 추가되어 있다.
이 스크립트를 더블 클릭하면 게임 편집창에서 스크립트 편집창으로 바뀌고 내용을 편집할 수 있다. 내용을 살펴보면 ServerScriptService 서비스에 ObjectActions라는 이름으로 추가된 모듈 스크립트내의 함수들을 호출하는 방식으로 되어 있다.
local ProximityPromptService = game:GetService("ProximityPromptService")
local ServerScriptService = game:GetService("ServerScriptService")
local ObjectActions = require(ServerScriptService.ObjectActions)
-- Detect when prompt is triggered
local function onPromptTriggered(promptObject, player)
ObjectActions.promptTriggeredActions(promptObject, player)
end
-- Detect when prompt hold begins
local function onPromptHoldBegan(promptObject, player)
ObjectActions.promptHoldBeganActions(promptObject, player)
end
-- Detect when prompt hold ends
local function onPromptHoldEnded(promptObject, player)
ObjectActions.promptHoldEndedActions(promptObject, player)
end
-- Connect prompt events to handling functions
ProximityPromptService.PromptTriggered:Connect(onPromptTriggered)
ProximityPromptService.PromptButtonHoldBegan:Connect(onPromptHoldBegan)
ProximityPromptService.PromptButtonHoldEnded:Connect(onPromptHoldEnded)
루아에서 모듈스크립트는 한번 정의하면 여러곳에서 재사용할 수 있는 소스코드의 컨테이너를 말한다. 단 한번만 실행되기 때문에 여러 스크립트에서 필요한 경우 유용하다. 다른 언어의 inclue나 using과 비슷한 개념이라고 생각하면 될 듯하다. 모듈스크립트를 사용하지 않고 그냥 위의 PromptEvents 스크립트안에서 다 처리해도 상관없다. 모듈 스크립트는 어디까지나 구조화를 위한 스크립트이다. 구조화시켜놓으면 재사용을 하기 편리하고 소스를 파악하기도 편리하다.
다음글
'로블록스 개발 중급' 카테고리의 다른 글
자연스럽게 열리는 문 만들기(1) (2) | 2021.05.03 |
---|---|
파트에 붙어 있는 GUI 구현 (0) | 2021.04.30 |
버튼 만들기 (0) | 2021.04.28 |
스코어 바 만들기(2) (0) | 2021.04.27 |
스코어 바 만들기(1) (0) | 2021.04.27 |