Sample CodeiOS, iPadOSReviewed 2026-07-21View on Apple Developer

Controlling Entity Collisions in RealityKit

At a glance

Item Summary
Purpose Create collision filters to control which objects collide.
App architecture The UIKit app keeps collision setup in ViewController; custom entity types define shapes and filters, and subscriptions respond only to collision pairs allowed by those masks.
Main patterns UIKit lifecycle composition, UI–RealityKit bridge, Delegate callback adapter, Collision filter matrix
Project style Code-rich sample with 4 scanned Swift file(s) and 426 implementation line(s).

Project structure

Source bundle/
└── RealityKitCollisionGroups/
    ├── ViewController.swift  # ViewController
    ├── Custom Entities/
    │   ├── Entities.swift  # MovableEntity, BoxEntity, BeveledBoxEntity
    │   └── PlaneEntity.swift  # PlaneEntity
    └── AppDelegate.swift  # AppDelegate

Structure observations

  • The runtime boundary is UIApplicationDelegate + UIViewController; the tree is pruned to lifecycle, state, framework, rendering, and ECS files.
  • The source is Swift; role-named types and feature folders separate the major responsibilities.

Overall architecture

Reference code

RealityKitCollisionGroups/AppDelegate.swift:11 — executable or app-lifecycle anchor.

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

}

The diagram is a responsibility flow, not a claim that every adjacent node directly calls the next. It separates lifecycle, presentation, stable state, framework/session work, and the RealityKit entity graph.

Ownership and state

Ownership evidence

RealityKitCollisionGroups/ViewController.swift:44 — representative stored state or nearest verified lifecycle anchor.

    let cube1 = BoxEntity(size: 0.05, color: .green, roughness: 0.0)
    let cube2 = BoxEntity(size: 0.05, color: .green, roughness: 0.0)
    let cube3 = BoxEntity(size: 0.05, color: .green, roughness: 0.0)
    
    let sphere1 = SphereEntity(size: 0.05, color: .orange, roughness: 1.0)
    let sphere2 = SphereEntity(size: 0.05, color: .orange, roughness: 1.0)
    let sphere3 = SphereEntity(size: 0.05, color: .orange, roughness: 1.0)
Owner Object or state Relationship Mutation authority
ViewController BoxEntity as cube1 creates and retains The owning type coordinates writes
ViewController BoxEntity as cube2 creates and retains The owning type coordinates writes
ViewController BoxEntity as cube3 creates and retains The owning type coordinates writes
ViewController SphereEntity as sphere1 creates and retains The owning type coordinates writes

Ownership is intentionally narrow: environment, bindings, observed objects, weak links, and delegate callbacks do not prove lifetime ownership. Initialized stored services and wrapper-managed state do; entities added inside a RealityKit content closure belong to that entity graph.

Class and protocol design

Type Responsibility Depends on or conforms to
AppDelegate (RealityKitCollisionGroups/AppDelegate.swift:11) Declares app lifecycle and top-level dependency lifetime. UIResponder, UIApplicationDelegate
ViewController (RealityKitCollisionGroups/ViewController.swift:13) Coordinates long-lived framework or cross-view work. UIViewController, UIGestureRecognizerDelegate

The reviewed source defines no local substitution protocol. Its App, View, delegate, renderer, ARKit, and RealityKit conformances are framework-facing contracts, so this document does not label the whole app protocol-oriented.

Access control

Symbol Access Verified effect Likely rationale
fileprivate func configureEntityAccessibility() { (RealityKitCollisionGroups/ViewController.swift:169) fileprivate Use is limited to declarations in this source file. Inference: Share with same-file helpers without making the symbol module-wide.

No reviewed Swift access example uses private(set), public, open; declarations without a modifier are internal.

Reference code

RealityKitCollisionGroups/ViewController.swift:169 — representative visibility boundary.

    fileprivate func configureEntityAccessibility() {
        // ...
    }

Logic ownership and placement

Logic Owning type or file Placement rationale
Application/command lifecycle AppDelegate The executable boundary determines app, controller, scene, or command lifetime.
Presentation and user intent ViewController The view/controller forwards input and owns only presentation-local work.

Design patterns

Pattern Source evidence Purpose or tradeoff
UIKit lifecycle composition RealityKitCollisionGroups/AppDelegate.swift:11 Uses the application delegate and view controller as the explicit lifecycle and scene-ownership boundary.
UI–RealityKit bridge RealityKitCollisionGroups/ViewController.swift:13 Builds or hosts the RealityKit entity graph from SwiftUI or a platform view/controller lifecycle.
Delegate callback adapter RealityKitCollisionGroups/AppDelegate.swift:11 Inverts imperative framework callbacks into the sample’s owning controller, coordinator, or model.
Collision filter matrix RealityKitCollisionGroups/ViewController.swift:80 Expresses interaction policy as group and mask values rather than conditional checks in every collision callback.

Naming conventions

  • Role suffixes are evidence, not decoration: Controller: ViewController.
  • Protocols: no app-defined protocol in the reviewed source.
  • Commands use verb-led methods: tappedResetButton, toggleDebugDrawing, viewDidLoad, setInitialTransforms, setPhysicsModeAll, setCollisionFilters, configureEntityAccessibility, setScene.
  • Files and folders use primary-type or responsibility names such as Views, Models, Rendering, Components, Systems, Packages, or feature names where those boundaries exist.

Architecture takeaways

  • Treat AppDelegate as the owner of executable or scene lifecycle, not automatically as the owner of every entity created later.
  • Keep view/controller input near presentation, but move sessions, reconstruction, capture, rendering, shared game state, or documents into stable owners when their lifetime exceeds one callback or render pass.

Source map

Source file Relevant symbols
RealityKitCollisionGroups/ViewController.swift:13 ViewController
RealityKitCollisionGroups/Custom Entities/Entities.swift:13 MovableEntity, BoxEntity, BeveledBoxEntity, SphereEntity
RealityKitCollisionGroups/Custom Entities/PlaneEntity.swift:13 PlaneEntity
RealityKitCollisionGroups/AppDelegate.swift:11 AppDelegate