충돌

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

충돌은 두 개의 3D 객체가 3D 세계 내에서 접촉할 때 발생합니다. 맞춤형 충돌 처리를 위해 BasePart에는 어떤 물리적 조합이 서로 충돌할지를 제어할 수 있는 충돌 이벤트충돌 필터링 기술 세트가 있습니다.

충돌 이벤트

충돌 이벤트는 두 개의 BaseParts가 3D 세계에서 서로 닿거나 닿지 않을 때 발생합니다. 이러한 충돌은 TouchedTouchEnded 이벤트를 통해 감지할 수 있으며, 이 이벤트는 각 부분의 CanCollide 속성 값과 관계없이 발생합니다. 부분의 충돌 처리를 고려할 때 다음 사항에 유의해야 합니다:

  • 부분의 CanTouch 속성은 충돌 이벤트를 발생시킬지를 결정합니다. 이 속성이 false로 설정되면 TouchedTouchEnded는 발생하지 않습니다.
  • 부분의 CanCollide 속성은 다른 부분과 물리적으로 충돌하는지 여부에 영향을 미치고, 힘이 그들에게 작용하도록 합니다. 부분에 대해 CanCollide가 비활성화되어 있어도 TouchedTouchEnded 이벤트를 통해 접촉 및 비접촉을 감지할 수 있습니다.
  • TouchedTouchEnded 이벤트는 물리적 이동의 결과로만 발생하며, 부분의 Position이나 CFrame 변경으로 인해 다른 부분과 교차하거나 더 이상 교차하지 않게 되어도 발생하지 않습니다.
  • 상위 Terrain 클래스는 BasePart를 상속하므로, 다른 BasePartsTerrain 복셀과 충돌하는지를 결정하기 위해 Terrain충돌 그룹을 할당할 수 있습니다.

Touched

Touched 이벤트는 BasePart가 다른 부분이나 Terrain 복셀과 접촉할 때 발생합니다. 이 이벤트는 물리적 시뮬레이션의 결과로만 발생하며, 부분의 Position이나 CFrame이 명시적으로 설정되어 다른 부분이나 복셀과 교차하는 경우에는 발생하지 않습니다.

다음 코드 패턴은 Touched 이벤트를 사용자 정의 onTouched() 함수에 연결하는 방법을 보여줍니다. 이벤트는 충돌에 관련된 다른 부분을 나타내는 otherPart 인자를 함수에 전송합니다.

Part Collision

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouched(otherPart)
print(part.Name .. "가 " .. otherPart.Name .. "에 충돌했습니다.")
end
part.Touched:Connect(onTouched)

Touched 이벤트는 미세한 물리적 충돌에 따라 빠르게 여러 번 발생할 수 있습니다. 예를 들어, 이동 중인 객체가 "안정된" 위치에 놓이거나 충돌에 다중 파트 모델이 포함되어 있을 때 발생할 수 있습니다. 불필요하게 더 많은 Touched 이벤트가 트리거되지 않도록 하려면, 인스턴스 속성을 통해 "쿨다운" 기간을 시행하는 간단한 디바운스 시스템을 구현할 수 있습니다.

Part Collision With Cooldown

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local COOLDOWN_TIME = 1
local function onTouched(otherPart)
if not part:GetAttribute("Touched") then
print(part.Name .. "가 " .. otherPart.Name .. "에 충돌했습니다.")
part:SetAttribute("Touched", true) -- 속성을 true로 설정
task.wait(COOLDOWN_TIME) -- 쿨다운 시간 대기
part:SetAttribute("Touched", false) -- 속성 초기화
end
end
part.Touched:Connect(onTouched)

TouchEnded

TouchEnded 이벤트는 BasePart의 전체 충돌 경계가 다른 BasePart나 채워진 Terrain 복셀의 경계를 벗어날 때 발생합니다. 이 이벤트도 물리적 시뮬레이션의 결과로만 발생하며, 부분의 Position이나 CFrame이 명시적으로 설정되어 다른 부분이나 복셀과의 교차를 멈출 때는 발생하지 않습니다.

다음 코드 패턴은 TouchEnded 이벤트를 사용자 정의 onTouchEnded() 함수에 연결하는 방법을 보여줍니다. Touched와 마찬가지로, 이벤트는 다른 부분을 나타내는 otherPart 인자를 함수에 전송합니다.

Non-Collision Detection

local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. "가 " .. otherPart.Name .. "와의 접촉이 종료되었습니다.")
end
part.TouchEnded:Connect(onTouchEnded)

충돌 필터링

충돌 필터링은 어떤 물리적 부분이 서로 충돌할지를 정의합니다. 여러 객체에 대한 필터링을 충돌 그룹을 통해 구성하거나, NoCollisionConstraint 인스턴스를 사용하여 파트 간 충돌을 제어할 수 있습니다.

충돌 그룹

충돌 그룹BaseParts를 전용 그룹에 할당하고 각 그룹의 객체와 충돌하는지 여부를 지정할 수 있도록 합니다. 비충돌 그룹의 부분은 서로 완전히 통과하게 되며, 두 부분 모두의 CanCollide 속성이 true로 설정되어 있어도 마찬가지입니다.

위 비디오에서, 회전하는 객체들은 다른 색의 객체와 충돌하지만 자신의 색의 객체와는 충돌하지 않도록 서로 다른 충돌 그룹에 있습니다.

Studio의 충돌 그룹 편집기를 통해 충돌 그룹을 쉽게 설정할 수 있으며, 이는 Studio의 Window ⟩ 3D 메뉴를 통해 접근할 수 있습니다.

편집기는 Studio의 왼쪽 또는 오른쪽에 도킹하기에 유리한 목록 보기 또는 상단 또는 하단에 도킹하기에 유리한 넓은 표 보기로 기능합니다.

충돌 그룹 편집기의 목록 보기 예시

그룹 등록

편집기에는 이름을 바꾸거나 삭제할 수 없는 하나의 기본 충돌 그룹이 포함되어 있습니다. 모든 BaseParts는 다른 그룹에 할당되지 않는 한 자동으로 이 기본 그룹에 속하므로, 이들은 기본 그룹의 다른 모든 객체와 충돌하게 됩니다.

새 충돌 그룹을 생성하려면:

  1. 편집기 패널 상단의 그룹 추가 버튼을 클릭하고 새 그룹 이름을 입력한 후 Enter를 누릅니다. 새 그룹은 목록 보기의 두 열 또는 표 보기의 왼쪽 열과 상단 행 모두에 나타납니다.

    목록 보기에서 충돌 그룹 편집기에 새 그룹이 추가됨
  2. 필요에 따라 고유하고 설명적인 이름을 선택하여 프로세스를 반복합니다. 개발 중에 그룹의 이름은 그 필드를 클릭하거나 선택 후 이름 바꾸기 버튼을 클릭하여 변경할 수 있음을 유의하십시오.

    충돌 그룹 편집기에서 그룹 이름을 바꾸기 위해 버튼과 필드가 표시됨

그룹 충돌 구성

기본 구성에서는 모든 그룹의 객체가 서로 충돌합니다. 한 그룹의 객체가 다른 그룹의 객체와 충돌하지 않도록 하려면, 해당 행과 열의 상자를 체크 해제하십시오.

다음 예시에서, Cubes 그룹의 객체는 Doors 그룹의 객체와 충돌하지 않습니다.

충돌 그룹 편집기의 목록 보기에서 구성된 그룹

객체를 그룹에 할당

Studio 편집기를 통해 이전에 등록한 충돌 그룹에 객체를 할당하려면:

  1. 충돌 그룹의 일부로 간주될 수 있는 하나 이상의 BaseParts를 선택합니다.

  2. 해당 행의 버튼을 클릭하여 그룹에 할당합니다. 객체는 한 번에 하나의 충돌 그룹에만 속할 수 있으므로, 새로운 그룹에 배치하면 현재 그룹에서 제거됩니다.

    충돌 그룹에 선택된 부품을 추가하기 위해 충돌 그룹 편집기에서 플러스 버튼이 표시됨

할당한 후, 새로운 그룹은 객체의 CollisionGroup 속성 아래에 반영됩니다.

선택한 충돌 그룹이 부분의 CollisionGroup 속성으로 나타남

StudioSelectable 충돌 그룹

Studio의 도구들은 충돌 필터링 시스템을 사용하여 3D 뷰포트에서 클릭할 때 어떤 객체가 선택될 수 있는 후보인지 결정합니다. 할당된 충돌 그룹이 StudioSelectable충돌하지 않는 객체는 무시됩니다.

예를 들어, 효과적 영역이 큰 투명 부분에 의해 정의된 레이싱 경험의 체크포인트가 있다고 가정하면, 이들을 Checkpoints 충돌 그룹에 할당한 다음 해당 그룹을 StudioSelectable과 비충돌 리포지션하여 기본 맵 기하학을 편집할 때 방해가 되지 않도록 할 수 있습니다.

Checkpoints 그룹이 StudioSelectable 그룹과 비충돌로 설정됨

플러그인 코드의 경우, 커서 아래의 부분을 찾을 때 충돌 그룹 필터로 "StudioSelectable"을 할당하는 것이 좋습니다. 이는 플러그인이 제작자가 내장된 Studio 도구에서 기대하게 되는 선택 메커니즘과 일치하도록 합니다.

추천 플러그인 선택 레이캐스트

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local raycastParams = RaycastParams.new()
raycastParams.CollisionGroup = "StudioSelectable" -- 관례를 따르기 위해
raycastParams.BruteForceAllSlow = true -- CanQuery가 "false"인 부품도 선택할 수 있도록
local mouseLocation = UserInputService:GetMouseLocation()
local mouseRay = Workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local filteredSelectionHit = Workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 10000, raycastParams)

파트 간 필터링

두 개의 특정 파트 간의 충돌을 방지하려면, 예를 들어 차량의 바퀴와 차체 간의 충돌을 조정해야 할 때 No Collision 제약 조건을 고려하십시오. 이점은 다음과 같습니다:

  • 충돌 그룹 및/또는 구성 스크립트가 필요하지 않으므로, 맞춤형 충돌 필터링으로 모델을 쉽게 만들고 공유할 수 있습니다.
  • 연결된 부분은 서로 충돌하지 않지만, 다른 객체와는 여전히 충돌할 수 있습니다.

캐릭터 충돌 비활성화

Roblox 플레이어 캐릭터는 기본적으로 서로 충돌합니다. 이는 캐릭터가 특정 영역에 도달하기 위해 서로 위로 점핑하는 등 흥미롭지만 의도치 않은 게임 플레이로 이어질 수 있습니다. 이러한 동작을 원하지 않는 경우, 다음 ScriptServerScriptService에 추가하여 이를 방지할 수 있습니다.

스크립트 - 캐릭터 충돌 비활성화

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)
local function onDescendantAdded(descendant)
-- 모든 부분 후손을 위한 충돌 그룹 설정
if descendant:IsA("BasePart") then
descendant.CollisionGroup = "Characters"
end
end
local function onCharacterAdded(character)
-- 기존 및 새로운 후손에 대해 물리 설정 프로세스
for _, descendant in character:GetDescendants() do
onDescendantAdded(descendant)
end
character.DescendantAdded:Connect(onDescendantAdded)
end
Players.PlayerAdded:Connect(function(player)
-- 플레이어의 캐릭터가 추가될 때 감지
player.CharacterAdded:Connect(onCharacterAdded)
end)

모델 충돌

Model 객체는 파트 용기이기 때문에 BasePart를 상속하지 않으며, 따라서 BasePart.Touched 또는 BasePart.TouchEnded 이벤트에 직접 연결할 수 없습니다. 모델이 충돌 이벤트를 트리거하는지 여부를 판단하기 위해서는 자식들을 순회하며 각 자식 BasePart에 사용자 정의 onTouched()onTouchEnded() 함수를 연결해야 합니다.

다음 코드 샘플은 다중 파트 모델의 모든 BaseParts를 충돌 이벤트에 연결하고 다른 부분과의 총 충돌 수를 추적합니다.

모델 충돌

local model = script.Parent
local numTouchingParts = 0
local function onTouched(otherPart)
-- 모델이 자신과 교차하는 인스턴스 무시
if otherPart:IsDescendantOf(model) then return end
-- 모델 부분이 닿아 있는 카운트 증가
numTouchingParts += 1
print(model.Name, "가", otherPart.Name, "와 교차했습니다.| 모델 부분 개수:", numTouchingParts)
end
local function onTouchEnded(otherPart)
-- 모델이 자신과 차단된 인스턴스 무시
if otherPart:IsDescendantOf(model) then return end
-- 모델 부분이 닿아 있는 카운트 감소
numTouchingParts -= 1
print(model.Name, "가", otherPart.Name, "와의 교차를 종료했습니다.| 모델 부분 개수:", numTouchingParts)
end
for _, child in model:GetChildren() do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
child.TouchEnded:Connect(onTouchEnded)
end
end

메시 및 솔리드 모델 충돌

MeshPartPartOperation (여기서 파트는 솔리드 모델링으로 결합됨)은 BasePart의 하위 클래스이므로 메시 및 솔리드 모델링된 파트는 일반 파트와 동일한 충돌 이벤트충돌 필터링 옵션을 상속합니다. 그러나 메시와 솔리드 모델링된 부분은 일반적으로 더 복잡한 기하학을 가지고 있기 때문에 물리적 경계가 시각적 표현과 얼마나 정밀하게 일치하는지를 결정하는 독특한 CollisionFidelity 속성을 가집니다.

CollisionFidelity 속성은 다음 옵션이 있으며, 성능 영향과 정밀도 순으로 나열됩니다:

  • 박스 — 작은 또는 비대화형 객체에 적합한 경계 충돌 박스를 생성합니다.
  • — 덜 두드러진 움푹 파인 부분이나 구멍이 있는 객체에 적합한 볼록 헐을 생성합니다.
  • 기본 — 비대칭을 지원하는 근사 충돌 형태를 생성하며, 복잡한 객체에 적합합니다.
  • 정확한 볼록 분해 — 가장 정밀한 정밀도를 제공하지만 여전히 시각적과 1:1로 관련되지 않습니다. 이 옵션은 가장 성능 비용이 비쌉니다.
성의 원래 메쉬

충돌 정밀도 옵션의 성능 영향과 이를 완화하는 방법에 대한 자세한 정보는 성능 최적화을 참조하십시오.

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