← Back to Portal Hub

로블록스 커스텀 카메라 시스템 개발: 2차 스프링 물리, 숄더 오프셋 및 스피어캐스트 충돌 방지

By DopaBrain Studio Engineering Team • 2026-09-30 • Technical Guide

로블록스의 기본 `PopperCam`과 플레이어 카메라는 소셜 게임에는 충분하지만, 3인칭 슈팅(TPS), 액션 RPG, 고난도 점프맵이 요구하는 정밀한 조작감과 시각적 무게감을 충족하지 못합니다.

`CameraType.Scriptable`을 선언하고 `RenderStepped` 렌더 파이프라인에서 카메라를 직접 제어하면 완벽한 시네마틱 조작감을 구현할 수 있습니다. 2차 미분 스프링 물리로 자연스러운 관성을 부여하고, 3D 스피어캐스트(Spherecast)로 벽 뚫림 현상을 차단하며, 숄더뷰 조준을 결합하여 AAA급 카메라 시스템을 완성할 수 있습니다.

1. 기본 카메라의 한계: 왜 커스텀 카메라를 제작해야 하는가

빠른 속도감의 현대 게임에서 로블록스 기본 카메라가 겪는 문제점:

2. 2차 미분 스프링 물리와 임계 감쇠(Critical Damping)

화면 떨림이나 고무줄 튕김 없이 부드러운 관성 추적을 구현하는 수학적 원리:

Luau 2차 스프링 카메라 컨트롤러 및 스피어캐스트 충돌 방지 시스템
--!strict
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local CameraController = {}

local camera = Workspace.CurrentCamera
local player = Players.LocalPlayer

local yaw = 0
local pitch = 0
local targetDistance = 12
local currentDistance = 12

-- 스프링 물리 상태 (위치, 속도, 강도, 감쇠)
local springPos = Vector3.zero
local springVel = Vector3.zero
local SPRING_STIFFNESS = 140
local SPRING_DAMPING = 22

local SPHERE_RADIUS = 0.6
local RAY_PARAMS = RaycastParams.new()
RAY_PARAMS.FilterType = RaycastFilterType.Exclude

function CameraController.Init()
    camera.CameraType = Enum.CameraType.Scriptable
    UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
    
    UserInputService.InputChanged:Connect(function(input, processed)
        if processed then return end
        if input.UserInputType == Enum.UserInputType.MouseMovement then
            local sensitivity = 0.003
            yaw -= input.Delta.X * sensitivity
            pitch = math.clamp(pitch - (input.Delta.Y * sensitivity), -1.2, 1.2)
        end
    end)
    
    RunService.RenderStepped:Connect(CameraController.Update)
end

function CameraController.Update(dt: number)
    local char = player.Character
    if not char then return end
    local head = char:FindFirstChild("Head") :: BasePart?
    if not head then return end
    
    RAY_PARAMS.FilterDescendantsInstances = { char }
    
    -- 1. 기준 초점 CFrame 및 우측 숄더 오프셋 설정
    local focusCFrame = CFrame.new(head.Position) * CFrame.Angles(0, yaw, 0) * CFrame.Angles(pitch, 0, 0)
    local desiredOffset = Vector3.new(2.2, 1.0, 0) -- 우측 어깨 오프셋
    
    -- 2. 2차 스프링 적분 계산
    local force = (desiredOffset - springPos) * SPRING_STIFFNESS - (springVel * SPRING_DAMPING)
    springVel += force * dt
    springPos += springVel * dt
    
    -- 3. 스피어캐스트를 통한 3D 벽 충돌 사전 예측
    local rayOrigin = head.Position
    local targetCamPos = (focusCFrame * CFrame.new(springPos)).Position - (focusCFrame.LookVector * targetDistance)
    local castDirection = targetCamPos - rayOrigin
    
    local hit = Workspace:Spherecast(rayOrigin, SPHERE_RADIUS, castDirection, RAY_PARAMS)
    local adjustedDistance = targetDistance
    if hit and hit.Instance and hit.Instance.CanCollide then
        adjustedDistance = math.max(1.5, (hit.Position - rayOrigin).Magnitude - SPHERE_RADIUS)
    end
    
    -- 거리 보간으로 부드러운 카메라 줌인/줌아웃
    currentDistance += (adjustedDistance - currentDistance) * math.min(1, dt * 25)
    
    -- 4. 최종 카메라 CFrame 적용
    local finalCFrame = focusCFrame * CFrame.new(springPos) * CFrame.new(0, 0, currentDistance)
    camera.CFrame = finalCFrame
end

return CameraController

3. 스피어캐스트(Spherecast) 기반 3차원 벽 관통 방지

벽 너머 공허 공간이 노출되거나 카메라가 오브젝트를 뚫는 현상을 방지하는 기술:

4. 동적 숄더 시프트(어깨 전환) 및 ADS 조준 줌

슈팅 및 전투 상황에서 시야각을 극대화하는 숄더뷰 기법:

5. 모바일 터치 제스처와 멀티플랫폼 조작 최적화

터치스크린, 게임패드, 키보드 마우스 전반을 아우르는 컨트롤러 설계:

Frequently Asked Questions

카메라 충돌 감지에 Raycast 대신 Spherecast를 쓰는 이유는 무엇인가요?

Raycast는 두께가 없는 선이라 벽 모서리를 비껴갈 수 있습니다. 두께를 가진 Spherecast를 사용해야 카메라 렌즈가 벽 내부를 파고드는 그래픽 버그를 완벽히 차단할 수 있습니다.

벽 근처를 지날 때 카메라가 덜덜 떨리는 현상을 어떻게 잡나요?

충돌 지점의 거리로 즉시 끊어 이동하지 않고, `currentDist += (targetDist - currentDist) * math.min(1, dt * 25)`와 같은 점근적 보간을 적용하면 떨림이 사라집니다.

RenderStepped에서 매 프레임 스피어캐스트를 돌리면 모바일에서 렉이 걸리지 않나요?

1회의 스피어캐스트와 기본 벡터 연산은 프레임당 0.05ms 미만의 CPU 시간만 소비하므로 모바일 기기에서도 프레임 드랍 없이 부드럽게 동작합니다.

Explore More Interactive Tests & Guides

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

Go to Portal Hub