← Back to Portal Hub

로블록스 반응형 HUD 아키텍처: UIAspectRatioConstraint, CanvasGroup 최적화 및 모바일 터치 인체공학

By DopaBrain UI/UX 시스템 팀 • 2026-09-30 • Technical Guide

로블록스에서의 사용자 인터페이스(UI) 엔지니어링은 플랫폼 내 하드웨어의 극단적인 다양성으로 인해 까다롭기로 유명합니다. 단 하나의 게임이 고해상도 4K PC 모니터, 울트라와이드 디스플레이, 중형 태블릿, 카메라 노치가 있는 보급형 스마트폰, TV 콘솔 디스플레이에서 모두 왜곡 없이 실행되어야 합니다. 고정 픽셀 Offset에 의존하거나 무분별하게 CanvasGroup을 사용하면 텍스트 잘림 현상, 터치 불가능한 버튼, 심각한 프레임 드랍이 발생합니다.

본 인터페이스 엔지니어링 가이드에서는 상용급 반응형 HUD의 아키텍처를 심층 분석합니다. Scale 대 Offset 배치 수학, UIAspectRatioConstraint 비율 고정, CanvasGroup 래스터화 성능 경계, 노치 세이프존 보정, 엄격한 모바일 터치 인체공학 불변 규칙을 상세히 제공합니다.

1. 반응형 GUI 배치 수학: Scale, Offset 및 AnchorPoint의 조화

로블록스의 UDim2 좌표계는 상대적 비율인 Scale(부모 크기의 0.0~1.0)과 절대 픽셀인 Offset을 결합합니다. 해상도 독립성을 달성하기 위한 기본 원칙은 다음과 같습니다:

2. 상용급 동적 반응형 HUD 매니저 구현 코드

아래는 카메라 노치 세이프존 보정, 종횡비 유지, 모바일 터치 영역 자동 확장을 구현한 클라이언트 측 Luau 모듈입니다:

ResponsiveHUDManager.luau (클라이언트 UI 컨트롤러)
--!strict
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")

local HUDManager = {}
HUDManager.__index = HUDManager

local player = Players.LocalPlayer
local isTouch = UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled

export type HUDConfig = {
    ScreenGui: ScreenGui,
    RootFrame: Frame,
    CanvasGroup: CanvasGroup?,
    MinTouchSize: number
}

function HUDManager.Init(screenGui: ScreenGui, rootFrame: Frame): HUDConfig
    screenGui.ResetOnSpawn = false
    screenGui.IgnoreGuiInset = true -- 노치 안전영역 커스텀 처리
    screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling

    local config: HUDConfig = {
        ScreenGui = screenGui,
        RootFrame = rootFrame,
        CanvasGroup = rootFrame:FindFirstChildOfClass("CanvasGroup"),
        MinTouchSize = 44
    }

    HUDManager.ApplySafeInsets(config)
    GuiService:GetPropertyChangedSignal("TopBarInset"):Connect(function()
        HUDManager.ApplySafeInsets(config)
    end)

    return config
end

function HUDManager.ApplySafeInsets(config: HUDConfig)
    local topLeftInset, bottomRightInset = GuiService:GetGuiInset()
    local root = config.RootFrame

    -- 안전 표시 영역 내에 루트 프레임 배치
    root.Position = UDim2.new(0, topLeftInset.X, 0, topLeftInset.Y)
    root.Size = UDim2.new(1, -(topLeftInset.X + bottomRightInset.X), 1, -(topLeftInset.Y + bottomRightInset.Y))
end

function HUDManager.EnforceTouchErgonomics(button: GuiButton)
    if not isTouch then return end

    local currentSize = button.AbsoluteSize
    local minSize = 44
    local scaleX = math.max(currentSize.X, minSize)
    local scaleY = math.max(currentSize.Y, minSize)

    local sizeConstraint = button:FindFirstChildOfClass("UISizeConstraint")
    if not sizeConstraint then
        sizeConstraint = Instance.new("UISizeConstraint")
        sizeConstraint.MinSize = Vector2.new(scaleX, scaleY)
        sizeConstraint.Parent = button
    else
        sizeConstraint.MinSize = Vector2.new(scaleX, scaleY)
    end
end

function HUDManager.FadeHUD(canvasGroup: CanvasGroup, visible: boolean, duration: number)
    local targetAlpha = visible and 1 or 0
    canvasGroup.Visible = true
    
    local tween = TweenService:Create(
        canvasGroup,
        TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
        { GroupTransparency = 1 - targetAlpha }
    )
    tween:Play()
    tween.Completed:Connect(function()
        if not visible then
            canvasGroup.Visible = false
        end
    end)
end

return HUDManager

3. CanvasGroup 성능 분석: 렌더 캐싱과 메모리 트랩

CanvasGroup은 하위 UI 요소들을 오프스크린 텍스처로 래스터화하여 렌더링합니다. 일괄 페이드와 모서리 클리핑에는 이상적이지만 잘못 사용하면 모바일 성능에 심각한 타격을 줍니다:

4. 모바일 터치 인체공학: 엄지 영역 및 불변 원칙

모바일 플레이어는 양손으로 기기를 쥐고 엄지손가락으로 조작합니다. 엄지 가동 범위를 벗어난 UI 배치는 피로감을 유발하고 조작 실수를 낳습니다:

5. 상용 배포 검증 및 접근성 체크리스트

모든 기기에서 안정적인 UI를 제공하기 위한 단계별 검증 절차입니다:

Frequently Asked Questions

스마트폰 모델에 따라 UI 버튼이 납작해지거나 길쭉하게 늘어나는 이유는 무엇인가요?

Scale 좌표를 지정했더라도 화면 종횡비(16:9, 21:9 등)가 다르면 화면 비율대로 늘어나기 때문입니다. UIAspectRatioConstraint를 추가하여 가로세로 비율을 고정하면 왜곡을 방지할 수 있습니다.

일반 Frame 대신 CanvasGroup을 사용해야 하는 시점은 언제인가요?

하위 요소가 복잡하게 얽힌 모달 창 전체를 한꺼번에 서서히 나타나거나 사라지게 할 때(GroupTransparency), 또는 둥근 모서리로 하위 그래픽을 깔끔하게 자를 때 사용합니다.

로블록스 모바일 UI에서 권장되는 최소 버튼 크기는 얼마인가요?

모바일 터치 표준 가이드라인에 따라 최소 44x44 물리 픽셀 크기를 확보해야 사용자가 오터치 없이 편안하게 조작할 수 있습니다.

아이폰 노치나 안드로이드 펀치홀 카메라에 UI가 가려지지 않게 하려면 어떻게 하나요?

ScreenGui.IgnoreGuiInset을 true로 둔 상태에서 GuiService:GetGuiInset()을 호출하여 반환된 상단/하단 여백만큼 루트 프레임의 위치와 크기를 빼주면 됩니다.

Explore More Interactive Tests & Guides

Discover personalized cognitive assessments, stress evaluations, and game psychology tools on DopaBrain.

Go to Portal Hub