-
Amplía la funcionalidad de Reality Composer Pro 3 con Xcode
Descubre cómo Reality Composer Pro 3 te permite crear proyectos espaciales más grandes y ambiciosos. Obtén información sobre cómo crear plug-ins específicos para proyectos que te permitan editar componentes personalizados, ejecutar sistemas personalizados y crear tus propios nodos de ScriptGraph, lo que te brinda un control total sobre tu flujo de trabajo de creación espacial.
Capítulos
- 0:00 - Introducción
- 2:00 - Ampliación del editor
- 4:51 - Componentes y sistemas personalizados
- 10:32 - Control de la superficie del agua
- 13:19 - Acciones de animación personalizadas
- 17:12 - Nodos personalizados de Script Graph
- 21:16 - Próximos pasos
Recursos
Videos relacionados
WWDC26
-
Buscar este video…
-
-
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) } }
-