시작하기
중급 튜토리얼

인터랙티브 UI 만들기

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

게임 내의 HUD (Heads-Up Display)는 일반적으로 HUD 미터 만들기에서 보여준 것처럼 건강 미터와 같은 비대화형 UI 요소를 표시합니다. 게다가 거의 모든 경험에는 플레이어의 활성화에 반응하는 버튼, 활성화될 때 애니메이션을 하는 버튼, 다른 대화형 컨트롤과 메뉴를 함께 트윈하는 것과 같은 대화형 UI가 필요합니다.

설정 버튼과 볼륨 슬라이더가 있는 설정 메뉴를 보여주는 게임 내 보기.

UI 기초 - HUD 미터를 시작점으로 사용하고 UI 기초 - 인터랙티브성를 완성된 참조점으로 이 튜토리얼은 다음을 보여줍니다:

  • 화면 상단 가장자리에 설정 버튼을 배치하는 방법.
  • 드래그 가능한 슬라이더를 포함하는 설정 메뉴 디자인.
  • 상태 선언이 있는 UI 객체의 확장 가능한 제어를 위한 "컨트롤러" 모듈을 형성하기 위한 ModuleScripts 사용법.
  • 플레이어 활성화로 버튼을 연결하여 설정 메뉴를 열고 닫는 방법.
  • 별도로 효과와 배경 분위기의 소리 수준을 조정하는 드래그 가능한 UI 슬라이더를 연결하는 방법.

장치 에뮬레이터 활성화

HUD 미터 만들기에서 언급했듯이, 휴대 전화와 태블릿은 화면 공간이 가장 적으므로 UI 요소들이 더 작은 화면에 잘 맞고 플레이어에게 명확히 보이는 것이 중요합니다. 아직 하지 않았다면 Studio에서 장치 에뮬레이터를 활성화하세요:

  1. Studio에서 UI 기초 - HUD 미터 템플릿을 여세요.

  2. Studio의 테스트 메뉴에서 장치 에뮬레이터를 활성화합니다.

  3. 기본 뷰포트 바로 위의 바에서 iPhone X 또는 Samsung Galaxy A51와 같은 휴대폰 에뮬레이션을 선택합니다. 그런 다음 보기 크기를 창에 맞추기로 설정하여 Studio에서 최대 공간을 활용합니다.

    뷰포트 창 상단에 표시된 장치 에뮬레이터 설정 옵션.

설정 버튼 만들기

GuiButtons는 클릭되거나 탭될 때 발생하는 다중 플랫폼 Activated 이벤트와 같은 내장 기능을 가지고 있는 대화형 사용자 인터페이스 요소입니다. GuiButton 클래스는 TextButtonImageButton의 두 가지 변형으로 확장되며, 이 튜토리얼은 설정 메뉴를 열고 닫기 위해 "기어" 모양의 ImageButton을 사용합니다.

설정 버튼을 위한 Roblox 구성 요소.

설정 버튼을 만들려면:

  1. Explorer 창에서 StarterGui 안에 있는 HUDContainer를 찾습니다.

    선택된 HUDContainer를 보여주는 Explorer 창.
  2. HUDContainerImageButton을 삽입하고 이름을 SettingsButton으로 변경합니다.

    SettingsButton으로 삽입되고 이름이 변경된 새 ImageButton을 보여주는 Explorer 창. 뷰포트에 있는 새 ImageButton.
  3. 새 버튼을 선택한 상태에서 속성 창에서 다음을 설정합니다:

    • AnchorPoint = 0.5, 0.25 (수평 중앙 및 수직 상단 1/4)
    • BackgroundTransparency = 1 (완전히 투명)
    • Position = 0.5, 0, 0, 0 (상단 중앙 위치)
    • Size = 0.1, 0, 0.1, 0 (비율이 제한되었을 때 화면 높이의 10%)
    • Image = rbxassetid://104919049969988 (기어 기호의 자산 ID)
  4. 기본 속성으로 설정된 버튼에 UIAspectRatioConstraint를 삽입합니다 (1:1 너비 대 높이).

    SettingsButton 버튼에 삽입된 새 UIAspectRatioConstraint를 보여주는 Explorer 창.
  5. 버튼의 최대 픽셀 높이를 제한하려면 UISizeConstraint를 삽입하고 MaxSizeinf, 44로 설정합니다.

    SettingsButton 버튼에 삽입된 새 UISizeConstraint를 보여주는 Explorer 창.
    새 UISizeConstraint의 예상 값을 보여주는 속성 창.
    화면 상단 중앙에 위치한 최종 설정 버튼.

설정 메뉴 만들기

새로운 설정 버튼은 설정 메뉴를 열고 닫기 위해 스크립트화될 것이며, 플레이어가 즉시 설정이나 다른 정보를 접근할 수 있게 합니다. 이 튜토리얼에서는 메뉴에 배경 오디오와 사운드 효과의 볼륨 수준을 독립적으로 조정할 수 있는 대화형 슬라이더가 포함됩니다.

설정 메뉴에 사용되는 기본 구성 요소.

부모 프레임 만들기

HUD 미터 만들기에서 언급했듯이, Frame는 다른 UI 객체의 컨테이너 역할을 합니다. 전체 설정 메뉴는 단일 부모 프레임으로 구성되어, 현재 상태에 따라 입력 반응이 달라지는 상태 기반 객체로 쉽게 관리할 수 있습니다.

  1. HUDContainerFrame을 삽입하고 이름을 SettingsMenu로 변경합니다.

    SettingsMenu으로 삽입되고 이름이 변경된 새 프레임을 보여주는 Explorer 창.
  2. SettingsMenu를 선택한 상태에서 다음 속성을 설정합니다:

    투명한 네이비 블루 배경으로 재배치, 크기 조정 및 스타일이 적용된 프레임.
  3. SettingsMenuUIAspectRatioConstraint를 삽입하고 AspectRatio 속성을 2.5로 설정합니다. (너비 넘 높이 비율 2.5:1).

    SettingsMenu 프레임에 삽입된 새 UISizeConstraint를 보여주는 Explorer 창.
    새 UISizeConstraint의 예상 값을 보여주는 속성 창.
  4. SettingsMenuUICorner 수정을 삽입하고 CornerRadius0.1, 0로 설정합니다.

    SettingsMenu 프레임에 삽입된 새 UICorner를 보여주는 Explorer 창.
    새 UICorner 수정자의 예상 값을 보여주는 속성 창.
  5. SettingsMenu의 픽셀 너비와 높이를 제한하기 위해 UISizeConstraint를 삽입합니다. MaxSize800, inf로 설정하고 MinSize350, 0로 설정합니다.

    SettingsMenu 프레임에 삽입된 새 UISizeConstraint를 보여주는 Explorer 창.
    새 UISizeConstraint의 예상 값을 보여주는 속성 창.
    모서리가 둥근 스타일의 프레임.

슬라이더 만들기

플레이어가 볼륨 수준을 조정할 수 있도록 설정 메뉴에는 두 개의 드래그 가능한 슬라이더 위젯이 포함되어 UIDragDetector와 함께 작동하며, 이 객체는 2D 사용자 인터페이스 요소와의 상호 작용을 용이하게 합니다.


첫 번째 슬라이더를 위한 부모 컨테이너를 만들려면:

  1. SettingsMenu 컨테이너에 새 Frame을 삽입하고 이름을 EffectsVolumeSlider로 변경합니다.

    SettingsMenu 프레임에 삽입되고 이름이 변경된 새 프레임을 보여주는 Explorer 창.
  2. EffectsVolumeSlider 프레임을 선택한 상태에서 다음 속성을 설정합니다:

    • AnchorPoint = 0.5 (중앙 앵커)
    • BackgroundTransparency = 1 (완전히 투명)
    • Position = 0.5, 0, 0.35, 0 (수평 중앙 및 컨테이너의 상단에서 35%)
    • Size = 0.8, 0, 0.1, 0 (컨테이너의 너비의 80% 및 높이의 10%)
    슬라이더 요소를 포함하기 위해 삽입된 빈 프레임.
  3. EffectsVolumeSlider에 새 UIListLayout을 삽입합니다. 이 레이아웃 수식어는 형제 GuiObjects를 부모 컨테이너 내의 수평 행 또는 수직 열로 자동으로 정렬하는 강력한 방법이며, 플렉스 개념을 적용할 수 있는 기능을 포함합니다.

    EffectsVolumeSlider 프레임에 삽입된 새 UIListLayout을 보여주는 Explorer 창.
  4. UIListLayout에 대해 다음 속성을 설정합니다:

슬라이더 아이콘

오디오 노트와 "버스트" 기호와 같은 간단한 아이콘은 플레이어가 설정 메뉴를 열었을 때 슬라이더의 목적을 식별하는 데 도움을 줍니다.

설정 메뉴에서 슬라이더의 목적을 나타내는 아이콘.
  1. EffectsVolumeSlider 프레임에 ImageLabel을 삽입하고 이름을 Icon으로 변경합니다. 이 아이콘은 플레이어가 슬라이더가 경험 내에서 제어하는 요소가 무엇인지 이해하는 데 도움을 줍니다.

    EffectsVolumeSlider 프레임에 삽입된 ImageLabel을 보여주는 Explorer 창.
  2. Icon을 선택한 상태에서 다음 속성을 설정합니다:

    • BackgroundTransparency = 1 (완전히 투명)
    • Size = 2.5, 0, 2.5, 0 (현재 상위 프레임 높이의 250%)
    • Image = rbxassetid://90019827067389 (오디오 노트 및 "버스트" 기호의 자산 ID)
  3. IconUIAspectRatioConstraint을 삽입하고 기본값(너비 대 높이)으로 두십시오 (1:1).

    ImageLabel에 삽입된 UIAspectRatioConstraint을 보여주는 Explorer 창. 설정 메뉴의 최종 아이콘.

범위 프레임

아이콘의 오른쪽에 위치한 슬라이더의 인터랙티브 부분은 또 다른 Frame에 포함되어야 합니다.

슬라이더의 인터랙티브 부분의 목표 크기와 위치.
  1. EffectsVolumeSlider 프레임에 새 Frame을 삽입하고 이름을 SliderFrame으로 변경합니다. UIListLayout 레이아웃 수정자의 직접적인 형제여야 함을 주의하세요.

    EffectsVolumeSlider 프레임에 삽입된 하위 프레임을 보여주는 Explorer 창.
  2. SliderFrame을 선택한 상태에서 다음 속성을 설정합니다:

  3. SliderFrame에 다음 수식어를 삽입합니다:

    아이콘의 오른쪽에 위치한 슬라이더 프레임.

상호작용 핸들

슬라이더 컨테이너가 구성되면, 플레이어가 게임 중에 상호작용할 수 있는 드래그 가능한 핸들을 생성할 수 있습니다.

범위 프레임 내에 위치한 인터랙티브 슬라이더 핸들.
  1. SliderFrame 컨테이너에 새 Frame을 삽입하고 이름을 Handle로 변경합니다.

    SliderFrame 프레임에 삽입되고 이름이 변경된 하위 프레임을 보여주는 Explorer 창.
  2. Handle을 선택한 상태에서 다음 속성을 설정합니다:

    • AnchorPoint = 0.5 (중앙 앵커)
    • Position = 0.5, 0, 0.5, 0 (부모 프레임의 수평 및 수직 중앙)
    • Size = 1.2, 0, 1.2, 0 (현재 상위 프레임 높이의 120%)
    • ZIndex = 3 (다른 슬라이더 요소보다 시각적으로 앞에 배치)
  3. Handle에 다음 수식어를 삽입합니다:

  4. HandleUIDragDetector 객체를 삽입합니다. 이 편리한 객체는 2D 사용자 인터페이스 요소와의 상호작용을 촉진하고 장려합니다.

    Handle 프레임에 삽입된 UIDragDetector를 보여주는 Explorer 창.
  5. UIDragDetector에 대해 다음 속성을 설정합니다:

  6. 핸들의 선형 드래그 범위가 컨테이너로 제한되도록 BoundingUI 속성을 SliderFrame 컨테이너에 연결합니다:

    1. UIDragDetector를 선택합니다.
    2. 속성 창에서 BoundingUI 속성을 클릭합니다.
    3. Explorer 창에서 핸들의 부모 SliderFrame을 클릭합니다.
    탐지기의 BoundingUI 속성을 SliderFrame 컨테이너에 연결하는 과정을 보여주는 다이어그램.

    BoundingUI 속성 링크는 이제 SliderFrame 컨테이너를 반영합니다:

    탐지기의 BoundingUI 속성이 SliderFrame 컨테이너에 연결된 속성 창.

이제 경험을 플레이테스트하면 핸들을 부모 컨테이너 내에서 왼쪽과 오른쪽으로 드래그할 수 있습니다:

내부 채우기

슬라이더가 0%에서 100% 사이의 범위를 제어한다는 것을 더 명확히 나타내기 위해, 핸들의 가변 위치와 동기화되는 내부 채우기를 컨테이너의 왼쪽 측면에 추가할 수 있습니다.

SliderFrame에 삽입된 슬라이더의 내부 채우기 부분.
  1. SliderFrame 컨테이너에 새 Frame을 삽입하고 이름을 InnerFill로 변경합니다.

    SliderFrame 프레임에 삽입되고 이름이 변경된 하위 프레임을 보여주는 Explorer 창.
  2. InnerFill 프레임에 대해 다음 속성을 설정합니다:

    • AnchorPoint = 0, 0.5 (왼쪽 모서리와 수직 중앙)
    • BackgroundColor3 = [0, 150, 255] (슬라이더 핸들과 같은 푸른색)
    • BackgroundTransparency = 0.35 (65% 불투명)
    • Position = 0, 0, 0.5, 0
    • Size = 0.5, 0, 1, 0 (부모 프레임의 50% 너비 및 100% 높이)
    • ZIndex = 2 (부모 프레임의 채우기/윤곽선보다 시각적으로 앞에 배치)
  3. 원형 SliderFrame 컨테이너와 일치시키기 위해 UICorner 수정자를 삽입하고 CornerRadius 속성을 0.5, 0로 설정합니다.

    InnerFill 프레임에 삽입된 UICorner 수정자를 보여주는 Explorer 창.
    새 UICorner의 예상 값을 보여주는 속성 창.
    내부 채우기 프레임이 푸른색 배경과 둥근 모서리로 스타일이 적용된 모습.

슬라이더 복제하기

첫 번째 슬라이더가 구성되면 이를 쉽게 복제하고 시각적 요소를 수정하여 또 다른 목적을 나타낼 수 있으며, 경우에 따라 음악 노트 아이콘으로 상징되는 배경 오디오의 볼륨 수준을 나타낼 수 있습니다.

배경 오디오 슬라이더의 목표 위치.
  1. 완료된 EffectsVolumeSlider 객체를 선택합니다.

    완료된 EffectsVolumeSlider가 선택된 Explorer 창.
  2. 복제합니다 (CtrlD 또는 D) 그런 다음 복제한 것을 BackgroundVolumeSlider로 이름을 변경합니다.

    BackgroundVolumeSlider로 복제된 슬라이더를 보여주는 Explorer 창.
  3. 복제한 Position0.5, 0, 0.7, 0로 변경하여 처음 슬라이더 아래로 이동합니다.

    EffectsVolumeSlider 아래에 위치한 BackgroundVolumeSlider.
  4. BackgroundVolumeSlider의 최상위 브랜치를 확장하고 Icon 이미지 레이블을 선택하여 Image 속성을 rbxassetid://101125859760167 (음악 노트 아이콘의 자산 ID)으로 변경합니다.

    BackgroundVolumeSlider 내의 Icon 레이블을 보여주는 Explorer 창.
    Icon 레이블의 예상 값을 보여주는 속성 창.
    아이콘 이미지가 수정된 BackgroundVolumeSlider.
  5. SliderFrameHandle 브랜치를 확장하고 그 안에 있는 UIStroke 수정자를 선택한 후 Color 속성을 [255, 0, 125] (마젠타)로 설정합니다.

    BackgroundVolumeSlider의 핸들 내의 UIStroke 수정자를 보여주는 Explorer 창.
    UIStroke 수정자의 예상 값을 보여주는 속성 창.
    수정된 핸들이 있는 BackgroundVolumeSlider.
  6. SliderFrame 내의 InnerFill 프레임을 선택하고 BackgroundColor3 속성을 동일한 마젠타 색상 ([255, 0, 125])으로 변경합니다.

    BackgroundVolumeSlider의 SliderFrame 내의 InnerFill 프레임을 보여주는 Explorer 창.
    InnerFill 프레임의 예상 값을 보여주는 속성 창.
    수정된 InnerFill 색상이 있는 BackgroundVolumeSlider.

닫기 버튼 만들기

설정 메뉴의 마지막 요소는 플레이어에게 메뉴를 닫을 수 있는 추가 입력을 제공하는 닫기 버튼입니다 (상단 중앙의 SettingsButton도 동일한 목적을 수행합니다).

오른쪽 상단 모서리에 닫기 버튼이 있는 설정 메뉴.
  1. SettingsMenu 컨테이너에 새 ImageButton을 삽입하고 이름을 CloseButton으로 변경합니다.

    SettingsMenu에 삽입되고 이름이 변경된 새 ImageButton을 보여주는 Explorer 창. 설정 메뉴의 왼쪽 상단 모서리에 위치한 빈 ImageButton.
  2. CloseButton을 선택한 상태에서 다음 속성을 설정합니다:

    • AnchorPoint = 1, 0 (상단 오른쪽 모서리)
    • BackgroundTransparency = 1 (완전히 투명)
    • Position = 1, -10, 0, 10 (상단 오른쪽 모서리에서 10픽셀 내측)
    • Size = 0.15, 0, 0.15, 0 (비율이 제한된 후 프레임 높이의 15%)
    • Image = rbxassetid://5577404210 (닫기 버튼 기호의 자산 ID)
    • ImageTransparency = 0.25 (75% 불투명)
  3. 버튼에 기본 속성(너비 대 높이)으로 UIAspectRatioConstraint을 삽입합니다.

    CloseButton 버튼에 삽입된 UIAspectRatioConstraint을 보여주는 Explorer 창. 설정 메뉴의 오른쪽 상단 모서리에 최종화된 닫기 버튼.

제어 모듈 만들기

확장 가능한 제어 모듈 설정은 각 객체 내에 개별 스크립트를 배치하는 것보다 인터랙티브 UI 관리를 더 간소화합니다. ModuleScripts는 클라이언트-서버 경계의 서로 다른 측면에서 스크립트 간에 코드를 재사용할 수 있게 하여 이 확장 가능한 기능을 용이하게 합니다.

상태 기반 객체 컨트롤러

상태 기반 객체 컨트롤러 모듈은 UI 객체에 행동을 붙이고 SettingsButtonSettingsMenu와 같은 객체의 상태 간 전환/트윈을 쉽게 할 수 있도록 합니다. 모듈을 만들려면:

  1. ReplicatedStorage 컨테이너에 ModuleScript를 삽입하고 이름을 StatefulObjectController로 변경합니다.

    상대 스토리지 컨테이너에 있는 StatefulObjectController 모듈을 보여주는 Explorer 창.
  2. 모듈 내에 다음 코드를 붙여넣습니다:

    StatefulObjectController

    local TweenService = game:GetService("TweenService")
    local StatefulObjectController = {}
    StatefulObjectController.__index = StatefulObjectController
    export type StateName = string
    export type State = {
    transition: TweenInfo,
    properties: { [string]: any },
    }
    function StatefulObjectController.hydrate(props: {
    object: Instance,
    states: { [StateName]: State },
    initialStateName: StateName
    })
    local object, states, initialStateName = props.object, props.states, props.initialStateName
    local self = setmetatable({
    states = states,
    currentStateName = initialStateName,
    tweens = {},
    }, StatefulObjectController)
    -- 새 상태가 변경될 때마다 새로운 트윈을 생성하는 것을 피하기 위해 재사용할 트윈 만들기
    for stateName, state in states do
    self.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)
    end
    self:setState(self.currentStateName)
    return self
    end
    function StatefulObjectController:setState(stateName: StateName)
    local stateTween: Tween = self.tweens[stateName]
    if not stateTween then
    warn(string.format("Unknown state '%s' for %s", stateName, self.object:GetFullName()))
    return
    end
    self.currentStateName = stateName
    -- 다른 트윈이 충돌하지 않도록 하기
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    목적
    610이 모듈을 사용할 때 자동 완성과 린팅을 개선하기 위해 Luau 유형을 정의하고 내보냅니다.
    1233상태 기반 UI 객체에 행동을 초기화하고 부착하는 데 사용되는 함수입니다. GuiObjectobject로, 상태와 관련된 TweenInfo 데이터를 테이블로 전달합니다. 이 함수 내에서 26항부터 28항까지 각 상태의 Tweens를 생성하며, 30항은 모듈의 setState() 함수를 호출하여 객체를 초기 상태로 설정합니다.
    3550상태 기반 객체의 상태를 설정/변경하는 데 사용되는 함수입니다. 42항에서 객체의 currentStateName을 설정하며, 4547항에서 실행 중인 트윈을 취소하여 충돌을 방지하고, 49항은 상태의 트윈을 실행합니다.

슬라이더 컨트롤러

추가 모듈이 두 개의 볼륨 슬라이더를 초기화하고 제어합니다. 이 모듈은 각 슬라이더의 플레이어 상호작용을 탐지하고 원하는 변경 사항을 적용하는 콜백 함수를 연결할 수 있게 해줍니다.

  1. ReplicatedStorage 컨테이너에 ModuleScript를 삽입하고 이름을 SliderController로 변경합니다.

    상대 스토리지 컨테이너에 있는 SliderController 모듈을 보여주는 Explorer 창.
  2. 모듈 내에 다음 코드를 붙여넣습니다:

    SliderController

    local SliderController = {}
    SliderController.__index = SliderController
    export type Value = number
    export type OnChanged = (Value) -> ()
    function SliderController.hydrate(props: {
    object: Instance,
    onChanged: OnChanged,
    initialValue: Value?
    })
    local object, onChanged, initialValue = props.object, props.onChanged, props.initialValue
    local handle = object:FindFirstChild("Handle", true)
    if not handle then
    warn(string.format("슬라이더 %s를 초기화하려고 했으나 핸들을 찾을 수 없습니다.", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("슬라이더 %s를 초기화하려고 했으나 InnerFill을 찾을 수 없습니다.", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("슬라이더 %s를 초기화하려고 했으나 UIDragDetector를 찾을 수 없습니다.", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- 초기 값 설정
    self:setValue(self.value)
    -- 플레이어 조작에 감지기 연결
    self.dragConnection = dragDetector.DragContinue:Connect(function()
    self:setValue(handle.Position.X.Scale)
    end)
    return self
    end
    function SliderController:setValue(value: Value)
    local clampedValue = math.clamp(value, 0, 1)
    self.value = clampedValue
    -- 핸들 위치와 내부 프레임 크기를 동기화
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- 최신 값으로 사용자의 콜백 실행
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("슬라이더 콜백 오류:", changeResult)
    end
    end
    return SliderController
    목적
    746슬라이더 요소를 초기화하고 행동을 부착하는 데 사용되는 함수입니다. 슬라이더의 부모 Frameobject로 받아들이고 슬라이더 변경을 처리하기 위한 onChanged 콜백 함수 및 슬라이더 핸들 위치에 대한 초기 값을 입력합니다. 이 함수 내에서 1427항은 슬라이더의 핸들, 내부 채우기UIDragDetector 요소가 존재하는지 확인합니다. 38항은 모듈의 setValue() 함수를 호출하며, 4143항은 드래그 감지기의 DragContinue 이벤트를 모듈의 setValue() 함수에 연결합니다(다음 행에서 추가 설명).
    4861슬라이더의 값을 설정하는 데 사용되는 함수입니다. 이 함수 내에서 5354항은 핸들 위치와 내부 채우기 크기를 동기화하며, 57항은 변경 값을 콜백 함수로 전달하여 필요에 따라 해당 값을 활용할 수 있도록 합니다.

설정 스크립트 만들기

설정 버튼설정 메뉴가 완료된 후, 이를 하나의 스크립트로 연결하여 제어 모듈을 활용합니다.

  1. HUDContainer에 새 LocalScript를 삽입하고 이름을 SettingsScript로 변경하여 목적을 설명합니다. 이 스크립트는 SettingsMenuSettingsButton과 동일한 수준(형제)이어야 하며, 이들 위젯을 관리할 것입니다.

    HUDContainer 안의 SettingsScript를 보여주는 Explorer 창.
  2. 스크립트 내에 다음 코드를 붙여넣습니다:

    SettingsScript

    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local SoundService = game:GetService("SoundService")
    local SliderController = require(ReplicatedStorage.SliderController)
    local StatefulObjectController = require(ReplicatedStorage.StatefulObjectController)
    local HUDContainer = script.Parent
    -- 설정 버튼 초기화
    local settingsButton = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsButton"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 45,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 0,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- 설정 메뉴 프레임 초기화
    local settingsMenu = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsMenu"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out),
    properties = {
    Position = UDim2.fromScale(0.5, 0.5),
    Visible = true,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0),
    properties = {
    Position = UDim2.fromScale(0.5, 0.4),
    Visible = false,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- 효과 볼륨 슬라이더 초기화
    local effectsAudio = SoundService:FindFirstChild("Effects")
    local effectsVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("EffectsVolumeSlider", true),
    initialValue = effectsAudio and effectsAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if effectsAudio then
    effectsAudio.Volume = value
    end
    end,
    })
    -- 배경 볼륨 슬라이더 초기화
    local backgroundAudio = SoundService:FindFirstChild("Background")
    local backgroundVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("BackgroundVolumeSlider", true),
    initialValue = backgroundAudio and backgroundAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if backgroundAudio then
    backgroundAudio.Volume = value
    end
    end,
    })
    -- 버튼을 플레이어 상호작용에 연결하기
    HUDContainer:FindFirstChild("SettingsButton").Activated:Connect(function()
    local targetState = if settingsButton.currentStateName == "menuClosed"
    then "menuOpen"
    else "menuClosed"
    settingsButton:setState(targetState)
    settingsMenu:setState(targetState)
    end)
    HUDContainer:FindFirstChild("CloseButton", true).Activated:Connect(function()
    settingsButton:setState("menuClosed")
    settingsMenu:setState("menuClosed")
    end)
  3. 다음 섹션을 참조하여 스크립트가 제어 모듈들을 어떻게 활용하는지 살펴보세요.

    10-27 행은 설정 버튼을 초기화하여 행동을 부착합니다:

    목적
    1011로컬 참조 settingsButton이 선언되고 StatefulObjectController.hydrate() 함수를 통해 초기화되며, HUDContainer 내의 SettingsButton 버튼이 물체로 참조됩니다.
    1225menuOpenmenuClosed의 두 개의 고유한 상태가 있는 states 테이블이 전달됩니다. 각 상태는 상태가 도달할 목표 속성을 선언하는 전환을 포함합니다. 이 경우, menuOpen은 버튼의 회전을 45°로 설정하며, menuClosed는 버튼을 원래 회전값인 0으로 되돌립니다.
    26버튼의 초기 상태를 menuClosed로 설정합니다(이는 states 테이블 내의 임의의 상태 이름으로 설정할 수 있습니다).

    스크립트 아래쪽에서 (행 76-86), 버튼은 플레이어와의 상호작용에 연결되어 UI 상태 변경을 트리거합니다:

    목적
    7682SettingsButtonActivated 이벤트에 연결되어 익명 함수를 호출하게 됩니다. 익명 함수 내부에서 targetState 변수가 menuOpenmenuClosed 사이를 전환합니다. 80행은 버튼의 상태를 targetState로 설정하기 위해 setState()를 호출하고, 81행은 SettingsMenu를 동일하게 설정하여 SettingsButton의 활성화와 함께 열리거나 닫히게 합니다.
    8386CloseButtonActivated 이벤트에 연결되어 익명 함수를 호출하며, 이 함수는 SettingsButtonSettingsMenu의 상태를 모두 menuClosed로 설정합니다.

    30-49 행은 설정 메뉴를 초기화하여 행동을 부착합니다 다음과 같이:

    목적
    3031로컬 참조 settingsMenu가 선언되고 StatefulObjectController.hydrate() 함수로 초기화되며 HUDContainer 내의 SettingsMenu 프레임이 물체로 참조됩니다.
    3246설정 버튼과 비슷하게, menuOpenmenuClosed의 두 개의 고유한 상태가 있는 states 테이블이 전달됩니다. 여기서 menuOpen은 프레임의 PositionUDim2.fromScale(0.5, 0.5)로 변경하며 Bounce로 ½초의 트윈을 선언하고, Visible 상태를 true로 설정합니다. 반대로 menuClosedVisiblefalse로 설정합니다; 41행에서의 TweenInfo가 0의 지속 시간으로 상태 변경이 즉시 발생하도록 합니다.
    48프레임의 초기 상태를 menuClosed로 설정합니다.

    스크립트 아랫부분 (행 76-86), 설정 메뉴는 플레이어 상호작용에 연결됩니다:

    목적
    81설정 버튼 활성화에 따른 SettingsMenutargetState를 설정합니다.
    85CloseButton이 활성화되었을 때 SettingsMenu의 상태를 menuClosed로 설정합니다.

    51-73 행은 EffectsVolumeSliderBackgroundVolumeSlider에 행동을 초기화하고 부착합니다 다음과 같이:

    목적
    52특정한 로컬 참조를 Effects SoundGroup에 설정합니다. SoundGroup은 여러 Sounds 상호 연관하여 그룹의 Volume 속성을 통해 모든 소리의 볼륨을 제어할 수 있게 합니다.
    5354로컬 참조 effectsVolumeSlider가 선언되고 SliderController.hydrate() 함수로 초기화되며, HUDContainer 내의 EffectsVolumeSlider 프레임이 물체로 참조됩니다 ⟩ SettingsMenu. true라는 두 번째 매개 변수는 FindFirstChild()HUDContainer 분기를 따라 EffectsVolumeSlider를 찾도록 지정합니다.
    55슬라이더의 초기값은 Effects 사운드 그룹의 현재 Volume으로 설정되며 기본값으로 0.5를 사용합니다.
    5660슬라이더 값 변경을 처리하기 위해 콜백 함수를 설정합니다.
    647352-61과 본질적으로 동일하지만, HUDContainer 내의 BackgroundVolumeSlider 프레임을 초기화하고 슬라이더 값 변경을 Background 사운드 그룹의 볼륨에 적용합니다.

SettingsScript가 설정되면, 경험은 이제 관련된 UI 객체 세트를 플레이어 상호작용과 연결하여 완벽하게 작동하는 인터랙티브 UI 예제를 제공합니다.

©2026 Roblox Corporation. Roblox 및 Roblox 로고, 'Powering Imagination'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.