snippets

Pinned Entities

2026-03-02

import RealityKit

struct PinnedEntityComponent: Component {
    weak var pinnedto: Entity? = nil
    let pinName: String
    var transform: Transform = .identity
}

struct PinnedEntitySystem: System {
    static let query: EntityQuery = .init(where: .has(PinnedEntityComponent.self))
    init(scene: Scene) {
    }
    
    func update(context: SceneUpdateContext) {
        let entities = context.entities(matching: Self.query, updatingSystemWhen: .rendering)
        for entity in entities {
            guard let comp = entity.components[PinnedEntityComponent.self] else {
                continue
            }
            
            //if the entity we are pinned to is no longer available then remove
            //the pinned object from the scene
            guard let pinnedto = comp.pinnedto else {
                entity.removeFromParent()
                continue
            }
            
            guard let pin = pinnedto.pins[comp.pinName] else { continue }
            
            //pin position and orientation can actually be nil so ! is dangerous here
            entity.setPosition(
                pin.position(relativeTo: nil)!
                , relativeTo: nil)
            entity.setOrientation(
                pin.orientation(relativeTo: nil)! * comp.transform.rotation
                , relativeTo: nil)
        }
    }
}