-
Xcode로 Reality Composer Pro 3 기능 확장하기
Reality Composer Pro 3로 어떻게 더 크고 야심 찬 공간 프로젝트를 빌드할 수 있는지 확인해 보세요. 맞춤형 구성요소를 편집할 수 있는 프로젝트별 플러그인을 생성하고, 맞춤형 시스템을 실행하며, 고유한 ScriptGraph 노드를 빌드하여 공간 제작 워크플로를 완벽하게 제어하는 방법을 알아보세요.
챕터
- 0:00 - Introduction
- 2:00 - Extending the editor
- 4:51 - Custom components and systems
- 10:32 - Controlling the water surface
- 13:19 - Custom animation actions
- 17:12 - Custom Script Graph nodes
- 21:16 - Next steps
리소스
관련 비디오
WWDC26
-
비디오 검색…
-
-
6:08 - Cauldron component
// Add a component to represent the water level import RealityKit public struct Cauldron: Component, Codable { public var waterLevel: Float enum CodingKeys: CodingKey { case waterLevel } } -
6:42 - CauldronSystem
// Add a system to control the water level import RealityKit public struct CauldronSystem: System { let query = EntityComponentQuery(Cauldron.self) public init(scene: Scene) {} public func update(context: SceneUpdateContext) { for (entity, cauldron) in context.entities(matching: query) { guard let water = entity.findEntity(named: "Cauldron_Water_mesh") else { continue } water.setPosition(SIMD3<Float>(0, 1, 0) * cauldron.waterLevel, relativeTo: entity) } } } -
7:00 - RCPCustomComponentsPlugin
// Make sure that Reality Composer Pro 3 knows about the Cauldron and CauldronSystem import RealityComposerPro final class RCPCustomComponentsPlugin: RealityComposerProPlugin { public func setup(context: any RealityComposerProContext) { context.registerComponent(Cauldron.self) context.registerSystem(CauldronSystem.self) } } @_cdecl("createRealityComposerProPlugin") public func createRealityComposerProPlugin() -> UnsafeMutableRawPointer { return RCPCustomComponentsPlugin().passRetained() } -
10:49 - Cauldron component with vortex properties
// Properties to control water surface import RealityKit public struct Cauldron: Component, Codable { public var waterLevel: Float public var rotationSpeed: Float public var minWaterLevel: Float public var maxWaterLevel: Float public var vortexCoeff: Float } -
11:05 - CauldronSystem update with ShaderGraph
public func update(context: SceneUpdateContext) { for (entity, cauldron) in context.entities(matching: query) { guard let water = entity.findEntity(named: "Cauldron_Water_mesh") else { continue } water.setPosition(SIMD3<Float>(0, 1, 0) * cauldron.waterLevel, relativeTo: entity) guard var model = water.components[ModelComponent.self] else { continue } guard var mat = model.materials.first as? ShaderGraphMaterial else { continue } let surface = computeSurface(cauldron: cauldron) try? mat.setParameter(name: "Level Radius", value: .float(surface.levelRadius)) try? mat.setParameter(name: "Lowest Point", value: .float(cauldron.waterLevel - surface.lowestPoint)) try? mat.setParameter(name: "Height Change", value: .float(surface.heightChange)) try? mat.setParameter(name: "Level Coeff", value: .float(surface.levelCoeff)) try? mat.setParameter(name: "Is Level", value: .bool(surface.isLevel)) model.materials[0] = mat water.components.set(model) } } -
13:25 - SetWaterLevelAction
// Custom action for setting the water level of the Cauldron import RealityKit public struct SetWaterLevelAction: EntityAction, Codable { // Parameters for the action public let startWaterLevel: Float public let endWaterLevel: Float // Required by EntityAction protocol public var animatedValueType: (any AnimatableData.Type)? { Transform.self } } -
14:05 - SetWaterLevelAction subscribe
extension SetWaterLevelAction { static func subscribe() { Task { @MainActor in SetWaterLevelAction.subscribe(to: .updated) { event in let normalizedTime = (event.playbackController.time - event.startTime) / event.duration let action = event.action let currentLevel = action.startWaterLevel + Float(normalizedTime) * (action.endWaterLevel - action.startWaterLevel) guard let entity = event.targetEntity else { return } guard var cauldron = entity.components[Cauldron.self] else { return } cauldron.waterLevel = currentLevel entity.components.set(cauldron) } } } } -
14:56 - RCPCustomComponentsPlugin with action
// Make sure that Reality Composer Pro 3 knows about the SetWaterLevelAction import RealityComposerPro final class RCPCustomComponentsPlugin: RealityComposerProPlugin { public func setup(context: any RealityComposerProContext) { context.registerComponent(Cauldron.self) context.registerSystem(CauldronSystem.self) context.registerAction(SetWaterLevelAction.self) SetWaterLevelAction.subscribe() } } @_cdecl("createRealityComposerProPlugin") public func createRealityComposerProPlugin() -> UnsafeMutableRawPointer { return RCPCustomComponentsPlugin().passRetained() } -
17:32 - Cauldron with @Scriptable macro
// Expose Cauldron to Script Graphs import RealityKit import RealityKitScripting import RealityKitScriptingMacros @Scriptable public struct Cauldron: Component, Codable { public var waterLevel: Float public var rotationSpeed: Float public var minWaterLevel: Float public var maxWaterLevel: Float public var vortexCoeff: Float } -
18:08 - Register scripting module
// Register scripting module public func setup(context: any RealityComposerProContext) { context.registerComponent(Cauldron.self) context.registerSystem(CauldronSystem.self) context.registerAction(SetWaterLevelAction.self) SetWaterLevelAction.subscribe() Task { @MainActor in let config = RKS.Configuration(id: "ChaparralVillage") .onInitialize { _ in [ Module("ChaparralVillage") { Cauldron.SchemaProvider.schema } ] } try! RKS.addConfiguration(config) } }
-
-
- 0:00 - Introduction
An overview of the Reality Composer Pro 3 plugin system, showing how Xcode and the editor share a project to let engineers and artists collaborate — with custom components, systems, animation actions, and Script Graph nodes all running live inside the editor.
- 2:00 - Extending the editor
Learn how the Reality Composer Pro 3 plugin system works: how the editor and Xcode share a single git repository, how custom Swift code is compiled into a dynamic library, and how the editor loads and trusts plugins at runtime.
- 4:51 - Custom components and systems
Build a Cauldron component and CauldronSystem using RealityKit, expose them to the editor via a RealityComposerProPlugin, and see the water level property update in real time as artists adjust values in the inspector.
- 10:32 - Controlling the water surface
Extend the Cauldron component with vortex shader properties and update the system to drive a ShaderGraphMaterial at runtime, enabling artists to control vortex depth and rotation speed directly from the Reality Composer Pro 3 inspector.
- 13:19 - Custom animation actions
Implement the EntityAction protocol to create a SetWaterLevelAction that animates the cauldron water level on the sequencer timeline, subscribe to animation update events to interpolate the level, and register the action with the editor plugin.
- 17:12 - Custom Script Graph nodes
Use the @Scriptable macro to expose a custom component to Reality Composer Pro 3 Script Graphs, register a scripting module in the plugin setup, and see the generated nodes appear in the Script Graph editor for no-code artist workflows.
- 21:16 - Next steps
Recap of the plugin capabilities covered — custom components, systems, animation actions, and Script Graph nodes — with recommendations to explore the Explore Advances in RealityKit and Supercharge Your Spatial Workflows sessions.