충돌

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

충돌은 두 개의 3D 객체가 3D 세계에서 접촉할 때 발생합니다. 사용자 정의 충돌 처리를 위해 BasePart충돌 이벤트충돌 필터링 기술 세트를 제공하므로, 어떤 물리적 조합이 다른 조합과 충돌하는지를 제어할 수 있습니다.

충돌 이벤트

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

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

Touched

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

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

부품 충돌
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 이벤트가 발생하지 않도록 간단한 디바운스 시스템을 구현하여 인스턴스 속성을 통해 "쿨다운" 기간을 강제할 수 있습니다.

쿨다운이 있는 부품 충돌
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 인수를 함수에 전달합니다.

비충돌 감지
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의  ⟩ 3D 메뉴를 통해 접근할 수 있습니다.

편집기는 목록 보기 모드에서 Studio의 왼쪽 또는 오른쪽에 도킹하는 것을 선호하거나, 더 넓은 표 보기 모드에서 상단 또는 하단에 도킹하는 것을 선호합니다.

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

그룹 등록

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

새 충돌 그룹을 만들려면:

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

    목록 보기에서 충돌 그룹 편집기에 새 그룹이 추가됨
  2. 필요에 따라 이 과정을 반복하고 각 그룹에 대해 고유하고 설명적인 이름을 선택합니다. 개발 중에 그룹의 이름을 변경하려면 해당 필드를 클릭하거나 선택한 후 이름 변경 버튼을 클릭하면 됩니다.

    충돌 그룹 편집기에서 그룹 이름을 변경하기 위한 버튼과 필드 표시

그룹 충돌 구성

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

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

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

객체를 그룹에 할당

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

  1. 충돌 그룹의 일부로 적합한 하나 이상의 BaseParts를 선택합니다.

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

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

할당되면 새 그룹은 객체의 CollisionGroup 속성에 반영됩니다.

부품의 CollisionGroup 속성으로 선택된 충돌 그룹 표시

StudioSelectable 충돌 그룹

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

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

StudioSelectable 그룹과 비충돌로 구성된 Checkpoints 그룹

플러그인 코드의 경우, 커서 아래의 부품을 찾을 때 RaycastParams의 충돌 그룹 필터로 "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'은 미국 및 기타 국가 내 당사의 등록 및 미등록 상표입니다.