{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-281", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/281", "wordCount": 3056, "segments": [{"start": 7.0, "text": "Hi, I'm Niklas."}, {"start": 9.0, "text": "In this session I'll show how you can extend Reality Composer Pro with plugi-ns"}, {"start": 13.0, "text": "to make it possible for artists and content creators to work"}, {"start": 16.0, "text": "with assets directly in the editor,"}, {"start": 18.0, "text": "iterate quickly, and build lots of interesting 3D apps and games."}, {"start": 22.0, "text": "This is a feature that will be available later this year."}, {"start": 26.0, "text": "This is Reality Composer Pro 3."}, {"start": 28.0, "text": "The latest version of Apple's game and 3D content editor for RealityKit."}, {"start": 33.0, "text": "This updated version comes with support for larger scenes,"}, {"start": 36.0, "text": "artist friendly workflows for quick iterations over content,"}, {"start": 39.0, "text": "and the ability to preview scenes in headset."}, {"start": 43.0, "text": "You can learn more about how to use Reality Composer Pro 3 in the session,"}, {"start": 48.0, "text": "\"Iterate your spatial scenes faster with Reality Composer Pro 3.\""}, {"start": 52.0, "text": "Another great session to check out is:"}, {"start": 55.0, "text": "\"Design no-code games with Reality Composer Pro 3.\""}, {"start": 59.0, "text": "That session shows how to build a game without writing any code"}, {"start": 62.0, "text": "by using Reality Composer Pro's visual scripting tool Script Graph."}, {"start": 67.0, "text": "In this presentation, I want to show what you can do with code."}, {"start": 71.0, "text": "I'll show how you can build plug-ins in Xcode"}, {"start": 74.0, "text": "that expose your project specific content to Reality Composer Pro 3."}, {"start": 79.0, "text": "Your custom components will appear inside the editor,"}, {"start": 83.0, "text": "where they can be tweaked by artists and designers."}, {"start": 86.0, "text": "For example, artists can change the water level"}, {"start": 89.0, "text": "or the rotation speed and see the cauldron react in real time,"}, {"start": 92.0, "text": "without having to build and deploy an app."}, {"start": 96.0, "text": "I'll first go through the general mechanism for extending the editor."}, {"start": 101.0, "text": "Then, I'll show how to use that"}, {"start": 103.0, "text": "to get custom components and custom systems running in the editor."}, {"start": 108.0, "text": "I'll also show how you can add your own custom animations"}, {"start": 112.0, "text": "to the sequencer timeline."}, {"start": 115.0, "text": "And finally, I'll show how to create your own custom nodes"}, {"start": 118.0, "text": "for the Script Graph."}, {"start": 119.0, "text": "I'll start by looking at the general mechanism"}, {"start": 122.0, "text": "for extending Reality Composer Pro"}, {"start": 124.0, "text": "and how that works when you're working on a team."}, {"start": 127.0, "text": "I will be working in the Chaparral Village game."}, {"start": 130.0, "text": "This game was made by a team of developers, artists, and designers."}, {"start": 135.0, "text": "The game has both a Reality Composer Pro project"}, {"start": 138.0, "text": "and an Xcode project."}, {"start": 140.0, "text": "The editor project is typically used by the artists and designers"}, {"start": 144.0, "text": "to create the content of your experience,"}, {"start": 146.0, "text": "while the Xcode project is used by engineers to build the final app"}, {"start": 150.0, "text": "as well as the plugin that lets artists create custom data in the editor."}, {"start": 156.0, "text": "The Reality Composer Pro project"}, {"start": 158.0, "text": "and the Xcode project are linked together"}, {"start": 161.0, "text": "so that you can launch the app directly from within the editor."}, {"start": 165.0, "text": "You can setup this linking for your own projects"}, {"start": 168.0, "text": "using the simulation bar at the top of the window."}, {"start": 172.0, "text": "The editor project and the Xcode project live together in the same git repository."}, {"start": 178.0, "text": "Artists and engineers make changes locally and then commit and push"}, {"start": 182.0, "text": "to share them with the rest of the team."}, {"start": 185.0, "text": "When you import a file into Reality Composer Pro 3,"}, {"start": 188.0, "text": "it gets converted to an internal data format"}, {"start": 191.0, "text": "and saved on disk as JSON files."}, {"start": 193.0, "text": "You can use git's built-in tools to merge your changes,"}, {"start": 197.0, "text": "but the editor also comes with a custom merge tool"}, {"start": 200.0, "text": "that can merge files with fewer conflicts than standard git merge."}, {"start": 204.0, "text": "To get data from Reality Composer Pro 3 into an app,"}, {"start": 208.0, "text": "you export it as a Reality File, the serialization format for RealityKit."}, {"start": 214.0, "text": "Here's an illustration of how all of this fits together."}, {"start": 218.0, "text": "The Xcode project is used to build the final game app"}, {"start": 221.0, "text": "as well as the plug-in framework for Reality Composer Pro 3."}, {"start": 226.0, "text": "Reality Composer Pro 3 is used to set up the different 3D scenes"}, {"start": 230.0, "text": "and objects in the game."}, {"start": 232.0, "text": "The RCPCustomComponents.framework makes the components"}, {"start": 235.0, "text": "and systems that the developers have created"}, {"start": 238.0, "text": "available in the editor"}, {"start": 240.0, "text": "so that the artists and level designers can edit them,"}, {"start": 243.0, "text": "see how they work, and improve the content interactively."}, {"start": 247.0, "text": "Finally, the scenes created in Reality Composer Pro 3"}, {"start": 251.0, "text": "are exported to a Reality File"}, {"start": 253.0, "text": "which is linked into and loaded by the app."}, {"start": 257.0, "text": "When the code is updated,"}, {"start": 259.0, "text": "the developers build a new plug-in framework"}, {"start": 261.0, "text": "for everybody on the team to use as well as a new app."}, {"start": 265.0, "text": "When the content is changed,"}, {"start": 266.0, "text": "a new reality file is exported to test in the final app."}, {"start": 271.0, "text": "The Xcode project has been set up with two different schemes."}, {"start": 274.0, "text": "ChaparralVillage which builds the actual app"}, {"start": 277.0, "text": "and RCPCustomComponents"}, {"start": 279.0, "text": "which builds the plugin for Reality Composer Pro 3."}, {"start": 283.0, "text": "All the custom components and custom systems in the project"}, {"start": 286.0, "text": "are shared between these two schemas."}, {"start": 289.0, "text": "Let's see how that works."}, {"start": 291.0, "text": "I'll use the plug-in system to create a custom component"}, {"start": 294.0, "text": "and expose it to Reality Composer Pro."}, {"start": 297.0, "text": "I want to work with the artists to create an effect for this cauldron."}, {"start": 302.0, "text": "In the game, the cauldron will be used for mixing potions"}, {"start": 305.0, "text": "and I want to be able to control the water level"}, {"start": 307.0, "text": "so that it can go up and down as ingredients are added."}, {"start": 311.0, "text": "I also want to add a swirling effect,"}, {"start": 313.0, "text": "so that you can see the water rotating when the potions are mixed,"}, {"start": 316.0, "text": "but let's start with just setting the water level."}, {"start": 320.0, "text": "I could do this with a Script Graph."}, {"start": 322.0, "text": "It would look something like this."}, {"start": 324.0, "text": "On an update, event I get the water surface entity,"}, {"start": 328.0, "text": "and move it to a specific position."}, {"start": 330.0, "text": "But if I wanted to do something more advanced,"}, {"start": 333.0, "text": "it might make sense to use a custom component"}, {"start": 335.0, "text": "instead of a Script Graph."}, {"start": 337.0, "text": "Script Graphs and custom Swift code can do similar things"}, {"start": 340.0, "text": "and often it's a personal preference what you want to use."}, {"start": 344.0, "text": "But really big Script Graphs can be hard to maintain,"}, {"start": 347.0, "text": "so that might be a good reason to switch to code."}, {"start": 350.0, "text": "Code also lets you interact with other Apple APIs"}, {"start": 353.0, "text": "that are not available in Script Graph such as SwiftUI."}, {"start": 357.0, "text": "For the cauldron,"}, {"start": 359.0, "text": "I ultimately want the water level to tie into other systems,"}, {"start": 362.0, "text": "such as ingredients floating on the surface,"}, {"start": 365.0, "text": "so writing code makes sense."}, {"start": 367.0, "text": "To do this, I start with creating a simple component"}, {"start": 370.0, "text": "to hold the water level of the cauldron."}, {"start": 372.0, "text": "It has a single property that stores the water level."}, {"start": 376.0, "text": "In addition to the Component protocol,"}, {"start": 379.0, "text": "the Cauldron also implements Codable."}, {"start": 381.0, "text": "This is needed to be able to represent this Component"}, {"start": 384.0, "text": "in Reality Composer Pro 3"}, {"start": 386.0, "text": "and serialize it to Reality Files."}, {"start": 389.0, "text": "For more advanced components"}, {"start": 390.0, "text": "that have runtime properties that shouldn't show up in the editor,"}, {"start": 393.0, "text": "it might also make sense to implement CodingKeys,"}, {"start": 396.0, "text": "but for this simple component"}, {"start": 398.0, "text": "we just want to serialize all properties,"}, {"start": 400.0, "text": "so that's not needed."}, {"start": 402.0, "text": "Next, I'll create a custom system for setting the water level."}, {"start": 407.0, "text": "In the system update I find the entities that have the Cauldron component."}, {"start": 412.0, "text": "Then, I look for the water mesh child entity"}, {"start": 415.0, "text": "and adjust the position of the water mesh"}, {"start": 417.0, "text": "based on the water level set in the Cauldron component."}, {"start": 421.0, "text": "After that, I need to make sure that Reality Composer Pro 3"}, {"start": 425.0, "text": "can use my custom component and the corresponding system."}, {"start": 428.0, "text": "To do this, I need to create a plugin class"}, {"start": 431.0, "text": "that implements the RealityComposerProPlugin protocol."}, {"start": 435.0, "text": "This protocol comes from the RealityComposerPro Swift package."}, {"start": 440.0, "text": "This package is automatically added to your Xcode project"}, {"start": 443.0, "text": "when you link it in the editor"}, {"start": 445.0, "text": "using the Run With Xcode option in the simulation toolbar."}, {"start": 449.0, "text": "In the setup method of this class,"}, {"start": 451.0, "text": "I use the context I get from Reality Composer Pro"}, {"start": 454.0, "text": "to register my components and systems."}, {"start": 456.0, "text": "This makes these components and systems usable by the editor."}, {"start": 461.0, "text": "I also need to make sure that Reality Composer Pro 3"}, {"start": 463.0, "text": "can create the plug-in."}, {"start": 465.0, "text": "I do that by implementing a createRealityComposerProPlugin() function"}, {"start": 470.0, "text": "that creates and returns my plug-in."}, {"start": 472.0, "text": "You'll notice that this function returns the class as a raw pointer,"}, {"start": 476.0, "text": "this is because I need this function to be exported in the DLL interface."}, {"start": 481.0, "text": "I also need to mark it as a C function"}, {"start": 483.0, "text": "and give it an exported name"}, {"start": 485.0, "text": "so that it can be found by the plug-in loader."}, {"start": 488.0, "text": "Let's see how all of this works in practice."}, {"start": 490.0, "text": "First, I'll create the Cauldron component with the waterLevel property."}, {"start": 502.0, "text": "Then, I'll add the system that positions the water plane"}, {"start": 505.0, "text": "based on the property's value."}, {"start": 511.0, "text": "Finally, let's register the component and the system"}, {"start": 515.0, "text": "with Reality Composer Pro."}, {"start": 522.0, "text": "Now, I can build the plug-in scheme to create the dynamic library."}, {"start": 533.0, "text": "Now I can open the project in the editor."}, {"start": 536.0, "text": "Since this project has plug-ins,"}, {"start": 537.0, "text": "Reality Composer Pro asks me if I trust it."}, {"start": 540.0, "text": "I select Trust to load the plug-ins."}, {"start": 544.0, "text": "Once I've accepted to load the plug-in,"}, {"start": 547.0, "text": "the editor will show me the component that was imported."}, {"start": 552.0, "text": "If I go to the project's build settings,"}, {"start": 554.0, "text": "the imported components and systems show up there too."}, {"start": 557.0, "text": "I can also use this settings panel to specify a custom plug-in directory."}, {"start": 565.0, "text": "The imported components are found"}, {"start": 566.0, "text": "in the Custom Components folder in the project."}, {"start": 569.0, "text": "Now that I've imported the component and Reality Composer Pro 3 knows about it,"}, {"start": 574.0, "text": "I can add it to my Cauldron entity."}, {"start": 582.0, "text": "As I change the water level property in the editor,"}, {"start": 585.0, "text": "you can see the surface reacting."}, {"start": 587.0, "text": "My custom system is running inside the editor"}, {"start": 589.0, "text": "through the plug-in mechanism"}, {"start": 591.0, "text": "and changing the water level based on the property value."}, {"start": 594.0, "text": "Artists and designers can use this to fine tune properties in the editor"}, {"start": 598.0, "text": "without having to rebuild and relaunch the app."}, {"start": 610.0, "text": "If I want to debug my system,"}, {"start": 612.0, "text": "I can set a breakpoint in the code"}, {"start": 614.0, "text": "and attach to the editor application."}, {"start": 621.0, "text": "When it runs my code,"}, {"start": 622.0, "text": "it will stop in the Xcode debugger,"}, {"start": 624.0, "text": "and I can check my logic."}, {"start": 629.0, "text": "Now that I have the basic water surface working,"}, {"start": 632.0, "text": "I want to take it to the next level by adding a swirling effect."}, {"start": 635.0, "text": "As the player stirs the cauldron to mix the potion"}, {"start": 637.0, "text": "I want the surface to bend into a vortex shape."}, {"start": 641.0, "text": "To change the surface shape,"}, {"start": 642.0, "text": "a tech artist has built this vortex shader"}, {"start": 645.0, "text": "using the Shader Graph system in Reality Composer Pro 3."}, {"start": 649.0, "text": "The Shader Graph has parameters for things like rotation speed"}, {"start": 652.0, "text": "and it will create the vortex shape based on those parameters."}, {"start": 656.0, "text": "I want to be able to control these parameters"}, {"start": 658.0, "text": "from my custom component."}, {"start": 660.0, "text": "To do that, I start by adding some properties"}, {"start": 663.0, "text": "to guide the shape of the vortex."}, {"start": 665.0, "text": "And then, I need to modify my cauldron system from before"}, {"start": 669.0, "text": "so that it propagates these parameters to the Shader Graph."}, {"start": 673.0, "text": "First, I retrieve the Shader Graph material."}, {"start": 677.0, "text": "Then, I use a helper function"}, {"start": 679.0, "text": "to compute the shape of the water surface"}, {"start": 682.0, "text": "based on the Cauldron properties."}, {"start": 684.0, "text": "I use the computed shape to set the Shader Graph parameters."}, {"start": 688.0, "text": "And finally, I assign this material back on the model."}, {"start": 693.0, "text": "Let's see how this works in practice."}, {"start": 695.0, "text": "First, I'll add my new properties to the Cauldron."}, {"start": 704.0, "text": "Then, I'll write a function to compute the water surface."}, {"start": 713.0, "text": "Finally, I'll update the system so that it sets the shader parameters"}, {"start": 717.0, "text": "and then rebuild the plug-in."}, {"start": 728.0, "text": "Whenever I rebuild the plug-in,"}, {"start": 729.0, "text": "I need to restart Reality Composer Pro to get the changes in."}, {"start": 733.0, "text": "Reality Composer Pro will again ask me if I trust the project."}, {"start": 737.0, "text": "If you don't want to see this dialog anymore"}, {"start": 739.0, "text": "you can check the \"Don't ask again\" checkbox."}, {"start": 744.0, "text": "Next, a dialog will appear that shows me the changes to my custom components."}, {"start": 749.0, "text": "These changes all look good to me, so I'll accept them."}, {"start": 759.0, "text": "If I go back to the Cauldron component,"}, {"start": 762.0, "text": "I will see the new properties there."}, {"start": 770.0, "text": "Let me set it up with some default values for the water level"}, {"start": 773.0, "text": "and vortex coefficient."}, {"start": 784.0, "text": "Now, let me try some different values for the rotation speed."}, {"start": 788.0, "text": "You can see that as I increase the rotation speed,"}, {"start": 791.0, "text": "the vortex gets deeper."}, {"start": 799.0, "text": "Next, I want to talk about how to use plug-ins in the animation system."}, {"start": 805.0, "text": "The animation sequencer supports custom animation actions"}, {"start": 808.0, "text": "that can be defined in the plugin"}, {"start": 810.0, "text": "and then added to the sequencer timeline."}, {"start": 813.0, "text": "I want to create a custom action that sets the water level of the cauldron."}, {"start": 817.0, "text": "To do this, I need to implement the EntityAction protocol."}, {"start": 821.0, "text": "And to be saved in a Reality File, it needs to be Codable."}, {"start": 825.0, "text": "My action takes two parameters:"}, {"start": 827.0, "text": "a start level and an end level for the water surface"}, {"start": 830.0, "text": "so that it can animate it between these two values."}, {"start": 834.0, "text": "For the EntityAction protocol"}, {"start": 836.0, "text": "I also need to return the animated value type as a Transform."}, {"start": 840.0, "text": "This is needed to access my entity in the animation executor."}, {"start": 845.0, "text": "I also to need to write the code that executes the action"}, {"start": 848.0, "text": "and updates the water level when the animation runs."}, {"start": 852.0, "text": "To do this, I create a static subscribe() function in my entity action"}, {"start": 856.0, "text": "that I will call from my plug-in loading code."}, {"start": 860.0, "text": "In this function,"}, {"start": 861.0, "text": "I use the subscribe method in EntityAction"}, {"start": 864.0, "text": "to subscribe to the .updated event"}, {"start": 866.0, "text": "that gets called when RealityKit runs animations."}, {"start": 869.0, "text": "I will use this to perform my custom animation action."}, {"start": 872.0, "text": "I'll get the elapsed animation time as a normalized number between 0 and 1."}, {"start": 878.0, "text": "Then I compute the current water level"}, {"start": 880.0, "text": "by using the normalized time"}, {"start": 882.0, "text": "to interpolate between the start and end water levels."}, {"start": 886.0, "text": "I get the cauldron component from the entity and update its water level."}, {"start": 891.0, "text": "And finally, I set the modified cauldron component back on the entity."}, {"start": 896.0, "text": "The final piece of the puzzle is to register this custom animation"}, {"start": 900.0, "text": "with Reality Composer Pro 3."}, {"start": 903.0, "text": "Just as with custom components and custom systems,"}, {"start": 907.0, "text": "I need to register the action with the context"}, {"start": 909.0, "text": "for the editor to be aware of it."}, {"start": 911.0, "text": "I also need to call the subscribe function I created earlier"}, {"start": 915.0, "text": "so that the action executes on animation updates."}, {"start": 919.0, "text": "Let's see how this works in practice."}, {"start": 921.0, "text": "First, I will define my custom entity action."}, {"start": 929.0, "text": "Then, I'll add the code that implements this action."}, {"start": 935.0, "text": "Finally, I'll register this action with the editor and rebuild the plug-in."}, {"start": 952.0, "text": "When I restart the editor and open the project"}, {"start": 955.0, "text": "it will show me that a new action was imported."}, {"start": 965.0, "text": "Let's create an animation that uses this action."}, {"start": 968.0, "text": "First, I'll create a new sequence in the editor."}, {"start": 978.0, "text": "Then, I'll open the sequence"}, {"start": 981.0, "text": "and set the root entity of my animation"}, {"start": 983.0, "text": "to be a scene that contains the cauldron."}, {"start": 986.0, "text": "I have prepared a scene called CauldronWorld for this purpose."}, {"start": 992.0, "text": "Next, I'll add an animation track to the sequence"}, {"start": 995.0, "text": "and pick the cauldron as the entity I want to use for this track."}, {"start": 1004.0, "text": "Now I can drag the SetWaterLevelAction from the left panel"}, {"start": 1007.0, "text": "into the timeline of my track to create an action that runs on the cauldron."}, {"start": 1012.0, "text": "I'll expand this action in the inspector"}, {"start": 1014.0, "text": "so that I can set its parameters:"}, {"start": 1016.0, "text": "the start and stop values for the cauldron's water level."}, {"start": 1019.0, "text": "I'll set the start value to 0.3 and the stop value to 0.5."}, {"start": 1024.0, "text": "Now, I can play back the animation"}, {"start": 1027.0, "text": "and see the water level change based on my custom action."}, {"start": 1032.0, "text": "Artists and designers can use Script Graphs"}, {"start": 1034.0, "text": "to create gameplay and interactivity"}, {"start": 1037.0, "text": "in Reality Composer Pro 3 projects without having to write any code."}, {"start": 1042.0, "text": "The built in script nodes go a long way"}, {"start": 1044.0, "text": "but if you want to take this to the next level"}, {"start": 1046.0, "text": "you can use a plug-in to add custom nodes"}, {"start": 1048.0, "text": "that the designers can make use of in their Script Graphs."}, {"start": 1052.0, "text": "The quickest way to expose a custom component to Script Graphs"}, {"start": 1055.0, "text": "is to use the @Scriptable macro."}, {"start": 1058.0, "text": "For this, I first need to import the RealityKitScripting"}, {"start": 1061.0, "text": "and RealityKitScriptingMacros modules."}, {"start": 1064.0, "text": "This is where this macro is defined."}, {"start": 1067.0, "text": "Just as the RealityComposerPro Swift package,"}, {"start": 1070.0, "text": "this package is automatically set up for you when you create your Xcode project"}, {"start": 1073.0, "text": "from within Reality Composer Pro."}, {"start": 1077.0, "text": "Then, I simply tag my component struct with the @Scriptable macro."}, {"start": 1081.0, "text": "This will expand to a schema variable"}, {"start": 1083.0, "text": "that describes the component"}, {"start": 1085.0, "text": "so that I can register it with the scripting system."}, {"start": 1089.0, "text": "Like all other registrations,"}, {"start": 1091.0, "text": "this happens in the setup function for the plug-in."}, {"start": 1094.0, "text": "Scripting modules need to be registered on the main thread."}, {"start": 1099.0, "text": "I first create a scripting configuration for my project."}, {"start": 1103.0, "text": "In the initializer for the configuration,"}, {"start": 1106.0, "text": "I need to return a list of all my scripting modules."}, {"start": 1110.0, "text": "I'll create a single module that holds my Cauldron schema."}, {"start": 1113.0, "text": "This schema is generated by the @Scriptable macro."}, {"start": 1117.0, "text": "And then I'll add my configuration to RealityKitScripting."}, {"start": 1123.0, "text": "Let's see how this works in practice."}, {"start": 1125.0, "text": "First, I'll import the scripting modules"}, {"start": 1127.0, "text": "and add the @Scriptable macro to the Cauldron component."}, {"start": 1150.0, "text": "Then, I'll add the code for registering the scripting module with the editor"}, {"start": 1154.0, "text": "and rebuild the plug-in."}, {"start": 1161.0, "text": "Let's create a Script Graph"}, {"start": 1163.0, "text": "that makes use of the new custom nodes for the Cauldron component."}, {"start": 1166.0, "text": "I'll start by adding a Scripting component to my Cauldron entity."}, {"start": 1183.0, "text": "I double click the new component to open the Script Graph editor."}, {"start": 1188.0, "text": "Let's make it so that when the user presses a key on the keyboard,"}, {"start": 1191.0, "text": "the water level changes."}, {"start": 1193.0, "text": "I'll start by adding an update node."}, {"start": 1195.0, "text": "This node fires every time the scene updates."}, {"start": 1206.0, "text": "Next, I'll add an If node and hook it up to a keypress"}, {"start": 1209.0, "text": "so that the node fires whenever the key is pressed."}, {"start": 1223.0, "text": "I'll hook up the true connector from the If node"}, {"start": 1225.0, "text": "to set the water level of the cauldron."}, {"start": 1233.0, "text": "Now, when the \"a\" key is pressed,"}, {"start": 1235.0, "text": "the water level of the cauldron will be set to 0.25."}, {"start": 1239.0, "text": "I'll hook up another key to set a different water level."}, {"start": 1242.0, "text": "To do that, let me just copy and paste the whole graph."}, {"start": 1251.0, "text": "Then, in the copy, I'll change the key to \"z\" and the water level to 0.5."}, {"start": 1262.0, "text": "I can test this out by opening a simulation view."}, {"start": 1265.0, "text": "As I press the \"a\" and \"z\" keys the water level goes up and down."}, {"start": 1276.0, "text": "That was a lot of ground I covered in this session."}, {"start": 1279.0, "text": "I showed you how to create some simple plug-ins using Xcode"}, {"start": 1282.0, "text": "and extend the functionality of the editor"}, {"start": 1284.0, "text": "to work with your apps data and even run your code inside the editor."}, {"start": 1289.0, "text": "To learn more, I suggest checking out"}, {"start": 1291.0, "text": "the \"Explore advances in RealityKit\" session"}, {"start": 1294.0, "text": "to find out about the latest additions to RealityKit."}, {"start": 1297.0, "text": "I also recommend going through"}, {"start": 1298.0, "text": "the \"Supercharge your spatial workflows with Reality Composer Pro 3\" session"}, {"start": 1303.0, "text": "that covers how to improve your productivity with the editor."}, {"start": 1306.0, "text": "I look forward to see what amazing experiences"}, {"start": 1309.0, "text": "you will create with the new Reality Composer Pro 3."}, {"start": 1312.0, "text": "Thanks for watching!"}]}