{ "$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/session.schema.json", "schemaVersion": 1, "id": "wwdc2026-281", "event": "wwdc2026", "eventName": "WWDC26", "year": 2026, "eventContentId": 281, "title": "Extend Reality Composer Pro 3 functionality with Xcode", "description": "Discover how Reality Composer Pro 3 empowers you to build bigger, more ambitious spatial projects. Learn about creating project-specific plugins that let you edit custom components, run custom systems, and build your own ScriptGraph nodes—giving you complete control over your spatial authoring workflow.", "url": "https://developer.apple.com/videos/play/wwdc2026/281", "sosumiURL": "https://sosumi.ai/videos/play/wwdc2026/281", "type": "Video", "publishedAt": "2026-06-08T14:00:00-07:00", "platforms": [ "visionOS" ], "keywords": [ "3d", "game", "plugin", "reality composer pro", "realitykit", "scene", "scripting", "spatial computing", "swift", "visionos", "xcode" ], "topics": [ "Graphics & Games", "Spatial Computing" ], "primaryTopic": "Spatial Computing", "duration": 1322, "hasTranscript": true, "transcriptWordCount": 3056, "availableLanguages": [ "eng", "fra", "jpn", "kor", "por", "spa", "zho" ], "media": { "hls": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/281/6/1aef704f-ccc6-4c1d-b7b7-94da42d29609/cmaf.m3u8", "downloadHLS": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/281/6/1aef704f-ccc6-4c1d-b7b7-94da42d29609/cmaf-download.m3u8", "downloadSD": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/281/6/1aef704f-ccc6-4c1d-b7b7-94da42d29609/downloads/wwdc2026-281_sd.mp4", "downloadHD": "https://devstreaming-cdn.apple.com/videos/wwdc/2026/281/6/1aef704f-ccc6-4c1d-b7b7-94da42d29609/downloads/wwdc2026-281_hd.mp4", "duration": 1322 }, "codeSnippets": [ { "title": "Cauldron component", "language": "swift", "startTimeSeconds": 368, "code": "// Add a component to represent the water level\n\nimport RealityKit\n\npublic struct Cauldron: Component, Codable {\n public var waterLevel: Float\n\n enum CodingKeys: CodingKey {\n case waterLevel\n }\n}" }, { "title": "CauldronSystem", "language": "swift", "startTimeSeconds": 402, "code": "// Add a system to control the water level\n\nimport RealityKit\n\npublic struct CauldronSystem: System {\n let query = EntityComponentQuery(Cauldron.self)\n public init(scene: Scene) {}\n\n public func update(context: SceneUpdateContext) {\n for (entity, cauldron) in context.entities(matching: query) {\n guard let water = entity.findEntity(named: \"Cauldron_Water_mesh\")\n else { continue }\n water.setPosition(SIMD3(0, 1, 0) * cauldron.waterLevel, relativeTo: entity)\n }\n }\n}" }, { "title": "RCPCustomComponentsPlugin", "language": "swift", "startTimeSeconds": 420, "code": "// Make sure that Reality Composer Pro 3 knows about the Cauldron and CauldronSystem\n\nimport RealityComposerPro\n\nfinal class RCPCustomComponentsPlugin: RealityComposerProPlugin {\n public func setup(context: any RealityComposerProContext) {\n context.registerComponent(Cauldron.self)\n context.registerSystem(CauldronSystem.self)\n }\n}\n\n@_cdecl(\"createRealityComposerProPlugin\")\npublic func createRealityComposerProPlugin() -> UnsafeMutableRawPointer {\n return RCPCustomComponentsPlugin().passRetained()\n}" }, { "title": "Cauldron component with vortex properties", "language": "swift", "startTimeSeconds": 649, "code": "// Properties to control water surface\n\nimport RealityKit\n\npublic struct Cauldron: Component, Codable {\n public var waterLevel: Float\n public var rotationSpeed: Float\n public var minWaterLevel: Float\n public var maxWaterLevel: Float\n public var vortexCoeff: Float\n}" }, { "title": "CauldronSystem update with ShaderGraph", "language": "swift", "startTimeSeconds": 665, "code": "public func update(context: SceneUpdateContext) {\n for (entity, cauldron) in context.entities(matching: query) {\n guard let water = entity.findEntity(named: \"Cauldron_Water_mesh\") else { continue }\n water.setPosition(SIMD3(0, 1, 0) * cauldron.waterLevel, relativeTo: entity)\n\n guard var model = water.components[ModelComponent.self] else { continue }\n guard var mat = model.materials.first as? ShaderGraphMaterial else { continue }\n let surface = computeSurface(cauldron: cauldron)\n try? mat.setParameter(name: \"Level Radius\", value: .float(surface.levelRadius))\n try? mat.setParameter(name: \"Lowest Point\",\n value: .float(cauldron.waterLevel - surface.lowestPoint))\n try? mat.setParameter(name: \"Height Change\", value: .float(surface.heightChange))\n try? mat.setParameter(name: \"Level Coeff\", value: .float(surface.levelCoeff))\n try? mat.setParameter(name: \"Is Level\", value: .bool(surface.isLevel))\n model.materials[0] = mat\n water.components.set(model)\n }\n}" }, { "title": "SetWaterLevelAction", "language": "swift", "startTimeSeconds": 805, "code": "// Custom action for setting the water level of the Cauldron\n\nimport RealityKit\n\npublic struct SetWaterLevelAction: EntityAction, Codable {\n // Parameters for the action\n public let startWaterLevel: Float\n public let endWaterLevel: Float\n\n // Required by EntityAction protocol\n public var animatedValueType: (any AnimatableData.Type)? { Transform.self }\n}" }, { "title": "SetWaterLevelAction subscribe", "language": "swift", "startTimeSeconds": 845, "code": "extension SetWaterLevelAction {\n static func subscribe() {\n Task { @MainActor in\n SetWaterLevelAction.subscribe(to: .updated) { event in\n let normalizedTime = (event.playbackController.time - event.startTime) /\n event.duration\n let action = event.action\n let currentLevel = action.startWaterLevel +\n Float(normalizedTime) * (action.endWaterLevel - action.startWaterLevel)\n guard let entity = event.targetEntity else { return }\n guard var cauldron = entity.components[Cauldron.self] else { return }\n cauldron.waterLevel = currentLevel\n entity.components.set(cauldron)\n }\n }\n }\n}" }, { "title": "RCPCustomComponentsPlugin with action", "language": "swift", "startTimeSeconds": 896, "code": "// Make sure that Reality Composer Pro 3 knows about the SetWaterLevelAction\n\nimport RealityComposerPro\n\nfinal class RCPCustomComponentsPlugin: RealityComposerProPlugin {\n public func setup(context: any RealityComposerProContext) {\n context.registerComponent(Cauldron.self)\n context.registerSystem(CauldronSystem.self)\n\n context.registerAction(SetWaterLevelAction.self)\n SetWaterLevelAction.subscribe()\n }\n}\n\n@_cdecl(\"createRealityComposerProPlugin\")\npublic func createRealityComposerProPlugin() -> UnsafeMutableRawPointer {\n return RCPCustomComponentsPlugin().passRetained()\n}" }, { "title": "Cauldron with @Scriptable macro", "language": "swift", "startTimeSeconds": 1052, "code": "// Expose Cauldron to Script Graphs\n\nimport RealityKit\nimport RealityKitScripting\nimport RealityKitScriptingMacros\n\n@Scriptable\npublic struct Cauldron: Component, Codable {\n public var waterLevel: Float\n public var rotationSpeed: Float\n public var minWaterLevel: Float\n public var maxWaterLevel: Float\n public var vortexCoeff: Float\n}" }, { "title": "Register scripting module", "language": "swift", "startTimeSeconds": 1088, "code": "// Register scripting module\n\npublic func setup(context: any RealityComposerProContext) {\n context.registerComponent(Cauldron.self)\n context.registerSystem(CauldronSystem.self)\n\n context.registerAction(SetWaterLevelAction.self)\n SetWaterLevelAction.subscribe()\n\n Task { @MainActor in\n let config = RKS.Configuration(id: \"ChaparralVillage\")\n .onInitialize { _ in\n [\n Module(\"ChaparralVillage\") {\n Cauldron.SchemaProvider.schema\n }\n ]\n }\n try! RKS.addConfiguration(config)\n }\n}" } ], "resources": [], "path": "sessions/wwdc2026/281-extend-reality-composer-pro-3-functionality-with-xcode/", "files": { "metadata": "sessions/wwdc2026/281-extend-reality-composer-pro-3-functionality-with-xcode/metadata.json", "readme": "sessions/wwdc2026/281-extend-reality-composer-pro-3-functionality-with-xcode/README.md", "transcript": "sessions/wwdc2026/281-extend-reality-composer-pro-3-functionality-with-xcode/transcript.md", "transcriptJSON": "sessions/wwdc2026/281-extend-reality-composer-pro-3-functionality-with-xcode/transcript.json" } }