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

UI 기초 - HUD 미터를 시작점으로 사용하고 UI 기초 - 인터랙티브성를 완성된 참조점으로 이 튜토리얼은 다음을 보여줍니다:
- 화면 상단 가장자리에 설정 버튼을 배치하는 방법.
- 드래그 가능한 슬라이더를 포함하는 설정 메뉴 디자인.
- 상태 선언이 있는 UI 객체의 확장 가능한 제어를 위한 "컨트롤러" 모듈을 형성하기 위한 ModuleScripts 사용법.
- 플레이어 활성화로 버튼을 연결하여 설정 메뉴를 열고 닫는 방법.
- 별도로 효과와 배경 분위기의 소리 수준을 조정하는 드래그 가능한 UI 슬라이더를 연결하는 방법.
장치 에뮬레이터 활성화
HUD 미터 만들기에서 언급했듯이, 휴대 전화와 태블릿은 화면 공간이 가장 적으므로 UI 요소들이 더 작은 화면에 잘 맞고 플레이어에게 명확히 보이는 것이 중요합니다. 아직 하지 않았다면 Studio에서 장치 에뮬레이터를 활성화하세요:
Studio에서 UI 기초 - HUD 미터 템플릿을 여세요.
Studio의 테스트 메뉴에서 장치 에뮬레이터를 활성화합니다.
기본 뷰포트 바로 위의 바에서 iPhone X 또는 Samsung Galaxy A51와 같은 휴대폰 에뮬레이션을 선택합니다. 그런 다음 보기 크기를 창에 맞추기로 설정하여 Studio에서 최대 공간을 활용합니다.

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

설정 버튼을 만들려면:
Explorer 창에서 StarterGui 안에 있는 HUDContainer를 찾습니다.

새 버튼을 선택한 상태에서 속성 창에서 다음을 설정합니다:
- 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)
기본 속성으로 설정된 버튼에 UIAspectRatioConstraint를 삽입합니다 (1:1 너비 대 높이).

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

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

SettingsMenu를 선택한 상태에서 다음 속성을 설정합니다:
- AnchorPoint = 0.5 (중앙 앵커)
- BackgroundColor3 = 30, 30, 60 (네이비 블루)
- BackgroundTransparency = 0.25 (75% 불투명)
- Position = 0.5, 0, 0.5, 0 (화면 중앙)
- Size = 0.75, 0, 0.75, 0 (화면에서의 75% 너비/높이)

SettingsMenu에 UIAspectRatioConstraint를 삽입하고 AspectRatio 속성을 2.5로 설정합니다. (너비 넘 높이 비율 2.5:1).


SettingsMenu에 UICorner 수정을 삽입하고 CornerRadius를 0.1, 0로 설정합니다.


SettingsMenu의 픽셀 너비와 높이를 제한하기 위해 UISizeConstraint를 삽입합니다. MaxSize를 800, inf로 설정하고 MinSize를 350, 0로 설정합니다.



슬라이더 만들기
플레이어가 볼륨 수준을 조정할 수 있도록 설정 메뉴에는 두 개의 드래그 가능한 슬라이더 위젯이 포함되어 UIDragDetector와 함께 작동하며, 이 객체는 2D 사용자 인터페이스 요소와의 상호 작용을 용이하게 합니다.
첫 번째 슬라이더를 위한 부모 컨테이너를 만들려면:
SettingsMenu 컨테이너에 새 Frame을 삽입하고 이름을 EffectsVolumeSlider로 변경합니다.

EffectsVolumeSlider 프레임을 선택한 상태에서 다음 속성을 설정합니다:
- AnchorPoint = 0.5 (중앙 앵커)
- BackgroundTransparency = 1 (완전히 투명)
- Position = 0.5, 0, 0.35, 0 (수평 중앙 및 컨테이너의 상단에서 35%)
- Size = 0.8, 0, 0.1, 0 (컨테이너의 너비의 80% 및 높이의 10%)

EffectsVolumeSlider에 새 UIListLayout을 삽입합니다. 이 레이아웃 수식어는 형제 GuiObjects를 부모 컨테이너 내의 수평 행 또는 수직 열로 자동으로 정렬하는 강력한 방법이며, 플렉스 개념을 적용할 수 있는 기능을 포함합니다.

새 UIListLayout에 대해 다음 속성을 설정합니다:
- Padding = 0.06, 0 (리스트 요소 간의 6% 패딩)
- FillDirection = Horizontal (왼쪽에서 오른쪽으로 요소 정렬)
- HorizontalFlex = Fill (부모 컨테이너의 전체 공간을 채우기 위해 요소를 수평으로 크기 조정)
- VerticalAlignment = Center (수직 중앙에 따라 요소 정렬)
슬라이더 아이콘
오디오 노트와 "버스트" 기호와 같은 간단한 아이콘은 플레이어가 설정 메뉴를 열었을 때 슬라이더의 목적을 식별하는 데 도움을 줍니다.

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

Icon을 선택한 상태에서 다음 속성을 설정합니다:
- BackgroundTransparency = 1 (완전히 투명)
- Size = 2.5, 0, 2.5, 0 (현재 상위 프레임 높이의 250%)
- Image = rbxassetid://90019827067389 (오디오 노트 및 "버스트" 기호의 자산 ID)
범위 프레임
아이콘의 오른쪽에 위치한 슬라이더의 인터랙티브 부분은 또 다른 Frame에 포함되어야 합니다.

EffectsVolumeSlider 프레임에 새 Frame을 삽입하고 이름을 SliderFrame으로 변경합니다. UIListLayout 레이아웃 수정자의 직접적인 형제여야 함을 주의하세요.

SliderFrame을 선택한 상태에서 다음 속성을 설정합니다:
- BackgroundColor3 = 0 (검은색)
- BackgroundTransparency = 0.75 (25% 불투명)
- LayoutOrder = 1
- Size = 1, 0, 1, 0 (상위 프레임의 100% 너비/높이)
SliderFrame에 다음 수식어를 삽입합니다:

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

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

Handle을 선택한 상태에서 다음 속성을 설정합니다:
- AnchorPoint = 0.5 (중앙 앵커)
- Position = 0.5, 0, 0.5, 0 (부모 프레임의 수평 및 수직 중앙)
- Size = 1.2, 0, 1.2, 0 (현재 상위 프레임 높이의 120%)
- ZIndex = 3 (다른 슬라이더 요소보다 시각적으로 앞에 배치)
Handle에 다음 수식어를 삽입합니다:
- UIAspectRatioConstraint 를 기본 속성(1:1 너비 대 높이)으로 설정합니다.
Handle에 UIDragDetector 객체를 삽입합니다. 이 편리한 객체는 2D 사용자 인터페이스 요소와의 상호작용을 촉진하고 장려합니다.

새 UIDragDetector에 대해 다음 속성을 설정합니다:
- ResponseStyle = Scale (탐지기의 부모 위치 스케일 값으로 이동)
핸들의 선형 드래그 범위가 컨테이너로 제한되도록 BoundingUI 속성을 SliderFrame 컨테이너에 연결합니다:
- UIDragDetector를 선택합니다.
- 속성 창에서 BoundingUI 속성을 클릭합니다.
- Explorer 창에서 핸들의 부모 SliderFrame을 클릭합니다.

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

이제 경험을 플레이테스트하면 핸들을 부모 컨테이너 내에서 왼쪽과 오른쪽으로 드래그할 수 있습니다:
내부 채우기
슬라이더가 0%에서 100% 사이의 범위를 제어한다는 것을 더 명확히 나타내기 위해, 핸들의 가변 위치와 동기화되는 내부 채우기를 컨테이너의 왼쪽 측면에 추가할 수 있습니다.

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

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 (부모 프레임의 채우기/윤곽선보다 시각적으로 앞에 배치)
슬라이더 복제하기
첫 번째 슬라이더가 구성되면 이를 쉽게 복제하고 시각적 요소를 수정하여 또 다른 목적을 나타낼 수 있으며, 경우에 따라 음악 노트 아이콘으로 상징되는 배경 오디오의 볼륨 수준을 나타낼 수 있습니다.

완료된 EffectsVolumeSlider 객체를 선택합니다.

복제합니다 (CtrlD 또는 ⌘D) 그런 다음 복제한 것을 BackgroundVolumeSlider로 이름을 변경합니다.

복제한 Position을 0.5, 0, 0.7, 0로 변경하여 처음 슬라이더 아래로 이동합니다.

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



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

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% 불투명)
제어 모듈 만들기
확장 가능한 제어 모듈 설정은 각 객체 내에 개별 스크립트를 배치하는 것보다 인터랙티브 UI 관리를 더 간소화합니다. ModuleScripts는 클라이언트-서버 경계의 서로 다른 측면에서 스크립트 간에 코드를 재사용할 수 있게 하여 이 확장 가능한 기능을 용이하게 합니다.
상태 기반 객체 컨트롤러
상태 기반 객체 컨트롤러 모듈은 UI 객체에 행동을 붙이고 SettingsButton 및 SettingsMenu와 같은 객체의 상태 간 전환/트윈을 쉽게 할 수 있도록 합니다. 모듈을 만들려면:
ReplicatedStorage 컨테이너에 ModuleScript를 삽입하고 이름을 StatefulObjectController로 변경합니다.

모듈 내에 다음 코드를 붙여넣습니다:
StatefulObjectControllerlocal TweenService = game:GetService("TweenService")local StatefulObjectController = {}StatefulObjectController.__index = StatefulObjectControllerexport type StateName = stringexport 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.initialStateNamelocal self = setmetatable({states = states,currentStateName = initialStateName,tweens = {},}, StatefulObjectController)-- 새 상태가 변경될 때마다 새로운 트윈을 생성하는 것을 피하기 위해 재사용할 트윈 만들기for stateName, state in states doself.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)endself:setState(self.currentStateName)return selfendfunction StatefulObjectController:setState(stateName: StateName)local stateTween: Tween = self.tweens[stateName]if not stateTween thenwarn(string.format("Unknown state '%s' for %s", stateName, self.object:GetFullName()))returnendself.currentStateName = stateName-- 다른 트윈이 충돌하지 않도록 하기for _, tween in self.tweens dotween:Cancel()endstateTween:Play()endreturn StatefulObjectController코드 설명행 목적 6‑10 이 모듈을 사용할 때 자동 완성과 린팅을 개선하기 위해 Luau 유형을 정의하고 내보냅니다. 12‑33 상태 기반 UI 객체에 행동을 초기화하고 부착하는 데 사용되는 함수입니다. GuiObject를 object로, 상태와 관련된 TweenInfo 데이터를 테이블로 전달합니다. 이 함수 내에서 26항부터 28항까지 각 상태의 Tweens를 생성하며, 30항은 모듈의 setState() 함수를 호출하여 객체를 초기 상태로 설정합니다. 35‑50 상태 기반 객체의 상태를 설정/변경하는 데 사용되는 함수입니다. 42항에서 객체의 currentStateName을 설정하며, 45‑47항에서 실행 중인 트윈을 취소하여 충돌을 방지하고, 49항은 상태의 트윈을 실행합니다.
슬라이더 컨트롤러
추가 모듈이 두 개의 볼륨 슬라이더를 초기화하고 제어합니다. 이 모듈은 각 슬라이더의 플레이어 상호작용을 탐지하고 원하는 변경 사항을 적용하는 콜백 함수를 연결할 수 있게 해줍니다.
ReplicatedStorage 컨테이너에 ModuleScript를 삽입하고 이름을 SliderController로 변경합니다.

모듈 내에 다음 코드를 붙여넣습니다:
SliderControllerlocal SliderController = {}SliderController.__index = SliderControllerexport type Value = numberexport type OnChanged = (Value) -> ()function SliderController.hydrate(props: {object: Instance,onChanged: OnChanged,initialValue: Value?})local object, onChanged, initialValue = props.object, props.onChanged, props.initialValuelocal handle = object:FindFirstChild("Handle", true)if not handle thenwarn(string.format("슬라이더 %s를 초기화하려고 했으나 핸들을 찾을 수 없습니다.", object:GetFullName()))endlocal innerFill = object:FindFirstChild("InnerFill", true)if not innerFill thenwarn(string.format("슬라이더 %s를 초기화하려고 했으나 InnerFill을 찾을 수 없습니다.", object:GetFullName()))endlocal dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")if not dragDetector thenwarn(string.format("슬라이더 %s를 초기화하려고 했으나 UIDragDetector를 찾을 수 없습니다.", object:GetFullName()))endlocal 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 selfendfunction 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 thenwarn("슬라이더 콜백 오류:", changeResult)endendreturn SliderController코드 설명행 목적 7‑46 슬라이더 요소를 초기화하고 행동을 부착하는 데 사용되는 함수입니다. 슬라이더의 부모 Frame를 object로 받아들이고 슬라이더 변경을 처리하기 위한 onChanged 콜백 함수 및 슬라이더 핸들 위치에 대한 초기 값을 입력합니다. 이 함수 내에서 14‑27항은 슬라이더의 핸들, 내부 채우기 및 UIDragDetector 요소가 존재하는지 확인합니다. 38항은 모듈의 setValue() 함수를 호출하며, 41‑43항은 드래그 감지기의 DragContinue 이벤트를 모듈의 setValue() 함수에 연결합니다(다음 행에서 추가 설명). 48‑61 슬라이더의 값을 설정하는 데 사용되는 함수입니다. 이 함수 내에서 53‑54항은 핸들 위치와 내부 채우기 크기를 동기화하며, 57항은 변경 값을 콜백 함수로 전달하여 필요에 따라 해당 값을 활용할 수 있도록 합니다.
설정 스크립트 만들기
설정 버튼과 설정 메뉴가 완료된 후, 이를 하나의 스크립트로 연결하여 제어 모듈을 활용합니다.
HUDContainer에 새 LocalScript를 삽입하고 이름을 SettingsScript로 변경하여 목적을 설명합니다. 이 스크립트는 SettingsMenu 및 SettingsButton과 동일한 수준(형제)이어야 하며, 이들 위젯을 관리할 것입니다.

스크립트 내에 다음 코드를 붙여넣습니다:
SettingsScriptlocal 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 theneffectsAudio.Volume = valueendend,})-- 배경 볼륨 슬라이더 초기화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 thenbackgroundAudio.Volume = valueendend,})-- 버튼을 플레이어 상호작용에 연결하기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)다음 섹션을 참조하여 스크립트가 제어 모듈들을 어떻게 활용하는지 살펴보세요.
설정 버튼10-27 행은 설정 버튼을 초기화하여 행동을 부착합니다:
행 목적 10‑11 로컬 참조 settingsButton이 선언되고 StatefulObjectController.hydrate() 함수를 통해 초기화되며, HUDContainer 내의 SettingsButton 버튼이 물체로 참조됩니다. 12‑25 menuOpen 및 menuClosed의 두 개의 고유한 상태가 있는 states 테이블이 전달됩니다. 각 상태는 상태가 도달할 목표 속성을 선언하는 전환을 포함합니다. 이 경우, menuOpen은 버튼의 회전을 45°로 설정하며, menuClosed는 버튼을 원래 회전값인 0으로 되돌립니다. 26 버튼의 초기 상태를 menuClosed로 설정합니다(이는 states 테이블 내의 임의의 상태 이름으로 설정할 수 있습니다). 스크립트 아래쪽에서 (행 76-86), 버튼은 플레이어와의 상호작용에 연결되어 UI 상태 변경을 트리거합니다:
행 목적 76‑82 SettingsButton는 Activated 이벤트에 연결되어 익명 함수를 호출하게 됩니다. 익명 함수 내부에서 targetState 변수가 menuOpen 및 menuClosed 사이를 전환합니다. 80행은 버튼의 상태를 targetState로 설정하기 위해 setState()를 호출하고, 81행은 SettingsMenu를 동일하게 설정하여 SettingsButton의 활성화와 함께 열리거나 닫히게 합니다. 83‑86 CloseButton은 Activated 이벤트에 연결되어 익명 함수를 호출하며, 이 함수는 SettingsButton과 SettingsMenu의 상태를 모두 menuClosed로 설정합니다. 설정 메뉴30-49 행은 설정 메뉴를 초기화하여 행동을 부착합니다 다음과 같이:
행 목적 30‑31 로컬 참조 settingsMenu가 선언되고 StatefulObjectController.hydrate() 함수로 초기화되며 HUDContainer 내의 SettingsMenu 프레임이 물체로 참조됩니다. 32‑46 설정 버튼과 비슷하게, menuOpen 및 menuClosed의 두 개의 고유한 상태가 있는 states 테이블이 전달됩니다. 여기서 menuOpen은 프레임의 Position을 UDim2.fromScale(0.5, 0.5)로 변경하며 Bounce로 ½초의 트윈을 선언하고, Visible 상태를 true로 설정합니다. 반대로 menuClosed는 Visible을 false로 설정합니다; 41행에서의 TweenInfo가 0의 지속 시간으로 상태 변경이 즉시 발생하도록 합니다. 48 프레임의 초기 상태를 menuClosed로 설정합니다. 스크립트 아랫부분 (행 76-86), 설정 메뉴는 플레이어 상호작용에 연결됩니다:
행 목적 81 설정 버튼 활성화에 따른 SettingsMenu의 targetState를 설정합니다. 85 CloseButton이 활성화되었을 때 SettingsMenu의 상태를 menuClosed로 설정합니다. 볼륨 슬라이더51-73 행은 EffectsVolumeSlider와 BackgroundVolumeSlider에 행동을 초기화하고 부착합니다 다음과 같이:
행 목적 52 특정한 로컬 참조를 Effects SoundGroup에 설정합니다. SoundGroup은 여러 Sounds 상호 연관하여 그룹의 Volume 속성을 통해 모든 소리의 볼륨을 제어할 수 있게 합니다. 53‑54 로컬 참조 effectsVolumeSlider가 선언되고 SliderController.hydrate() 함수로 초기화되며, HUDContainer 내의 EffectsVolumeSlider 프레임이 물체로 참조됩니다 ⟩ SettingsMenu. true라는 두 번째 매개 변수는 FindFirstChild()가 HUDContainer 분기를 따라 EffectsVolumeSlider를 찾도록 지정합니다. 55 슬라이더의 초기값은 Effects 사운드 그룹의 현재 Volume으로 설정되며 기본값으로 0.5를 사용합니다. 56‑60 슬라이더 값 변경을 처리하기 위해 콜백 함수를 설정합니다. 64‑73 52-61과 본질적으로 동일하지만, HUDContainer 내의 BackgroundVolumeSlider 프레임을 초기화하고 슬라이더 값 변경을 Background 사운드 그룹의 볼륨에 적용합니다.
SettingsScript가 설정되면, 경험은 이제 관련된 UI 객체 세트를 플레이어 상호작용과 연결하여 완벽하게 작동하는 인터랙티브 UI 예제를 제공합니다.



















