Skip to content

apple/realitykitscripting

Repository files navigation

RealityKitScripting

JavaScript bindings for RealityKit with type-safe Swift interop.

RealityKitScripting enables scripting RealityKit entities using JavaScript. It provides a bridge between Swift and JavaScript, allowing you to write dynamic entity behaviors, expose custom components, and leverage the full power of RealityKit from JavaScript code.

For a full overview of concepts and API, see overview.md.

Beta Notice: This package is currently in beta. The public API is not yet stable and may change before the final release. We welcome bug reports and feedback via GitHub Issues, but are not accepting pull requests at this time.

Quick Start

Explains how to get started with integrating RealityKitScripting into your project.

1. Add RealityKitScripting as Dependency

To depend on RealityKitScripting in a SwiftPM package, add the following to your Package.swift.

dependencies: [
  .package(url: "https://github.com/apple/RealityKitScripting.git", from: "<#latest RealityKitScripting tag#>"),
],

To add RealityKitScripting as a dependency of your Xcode project, go to the Package Dependencies tab of your Xcode project, click the plus button and search for https://github.com/apple/RealityKitScripting.git.

2. Initialize RealityKitScripting

Initialize RealityKitScripting in your app entry point:

import RealityKitScripting

@main
struct MyApp: App {
    @MainActor
    init() {
        do {
            try RKS.initialize()
        } catch {
            fatalError("Failed to initialize RealityKitScripting runtime: \(error)")
        }
    }

    var body: some SwiftUI.Scene {
        WindowGroup {
            ContentView()
        }
    }
}

3. Attach a Script

Attach a script to any RealityKit entity using ScriptingComponent:

import RealityKit

struct ContentView: View {
    let script = """
        const RealityKit = require("RealityKit");
        const Math3D = require("Math3D");

        this.update = function(deltaTime) {
            const rotation = new Math3D.Quaternion(deltaTime * Math.PI, new Math3D.Vector3(0, 1, 0));
            this.entity.orientation.multiply(rotation);
        };

        this.didAdd = function() {
            console.log(`Script attached to: "${this.entity.name}"`);
        };
    """

    var body: some View {
        RealityView { content in
            let entity = ModelEntity(mesh: .generateBox(size: 0.2), materials: [SimpleMaterial(color: .blue, isMetallic: false)])
            entity.name = "Box"
            entity.components.set(ScriptingComponent(source: script))
            content.add(entity)
        }
        .scriptingSystem()
    }
}

4. Expose Custom Types

To expose your own Swift types to JavaScript, define schemas and register them via RKS.Configuration:

struct MyComponent: Component, Inspectable {
    var name: String
}

extension MyComponent {
    static let schema = TypeSchema<MyComponent>("MyComponent") {
        StoredProperty("name", keyPath: \.name)
        Constructor { MyComponent(name: "default") }
    }
}

@MainActor
init() {
    let config = RKS.Configuration(id: "MyApp")
        .onInitialize { _ in
            let module = Module("MyModule") {
                MyComponent.schema
            }
            return [module]
        }
        do {
            try RKS.initialize(with: config)
        } catch {
            fatalError("Failed to initialize RealityKitScripting runtime: \(error)")
        }
}

License

Please see LICENSE for more information.

About

JavaScript bindings for RealityKit with type-safe Swift interoperability

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Contributors