View Categories

World Builder – Runtime Scripting Documentation

1 min read

Introduction to Runtime Scripting #

WorldBuilder’s runtime scripting system enables the creation of custom interactive components directly within the application environment using C# programming language.

Technical Framework #

The runtime scripting implementation in WorldBuilder utilizes C# and the Unity engine’s core functionality. Components are created following a structured inheritance pattern:

  1. Each component inherits from DataComponentBase
  2. Properties are serialized using Newtonsoft.Json’s [JsonProperty] attributes
  3. Components leverage Unity’s lifecycle methods (Start(), Update())
  4. Inspector views are created separately to manage the component’s visual editing interface

Component Structure #

A runtime component consists of two primary files:

  1. Component Implementation File: Defines behavior using C# and Unity libraries
  2. Inspector View File: Provides the interface for modifying component properties

Component Implementation Example #

public class MyHoverComponent: DataComponentBase
{
    [JsonProperty("Speed")]
    public float Speed = 1.0f;

    [JsonProperty("Height")]
    public float Height = 2.0f;

    private Vector3 m_InitialPosition;

    void Start()
    {
        m_InitialPosition = transform.position;
    }

    void Update()
    {
        float newY = Mathf.Sin(Time.time * Speed) * Height + m_InitialPosition.y;
        transform.position = new Vector3(transform.position.x, newY, transform.position.z);
    }

    public override List<string> GetAssetReferences() { return null; }
    public override void AfterDeserialization() { }
}

Inspector View Example #

public class MyHoverComponentInspectorView : DataComponentInspectorViewBase
{
    public override Type TypeOfDataComponent { get => typeof(MyHoverComponent); }

    public override void CreateInspectorEntries(VisualElement window, IReferenceProvider referenceProvider, IUIElementFactory elementFactory, object instance)
    {
        var hoverComponent = instance as MyHoverComponent;
        elementFactory.CreateInspectorFloatField(window, "Speed", hoverComponent.Speed, (oldValue, newValue) =>
        {
            hoverComponent.Speed = newValue;
        });

        elementFactory.CreateInspectorFloatField(window, "Height", hoverComponent.Height, (oldValue, newValue) =>
        {
            hoverComponent.Height = newValue;
        });
    }
}

Automatic Inspector Generation #

WorldBuilder provides automatic inspector view generation for common data types:

  • Integer Fields
  • Float Fields
  • String Fields

For components that want to expose more complex data types in the editor need to write a custom inspector view. Inheriting from DataComponentInspectorViewBase. In the examples you can find some basic custom inspector views.

Creating Custom Components: A Tutorial #

Step 1: Define Component Behavior #

Create a new C# script that inherits from DataComponentBase. Define serializable properties using [JsonProperty] attributes. Implement Unity’s lifecycle methods (Start(), Update()) to control behavior.

Step 2: Create Inspector View #

Create a corresponding inspector view class that inherits from DataComponentInspectorViewBase. Implement the CreateInspectorEntries() method to generate UI controls for each property using the appropriate element factory methods.

Step 3: Access Unity Libraries #

Utilize Unity’s classes and functions (e.g., Vector3, Transform, Mathf, Time) for movement, calculations, and object manipulation.

Step 4: Implement Required Methods #

All components must implement GetAssetReferences() and AfterDeserialization() methods to conform to the DataComponentBase contract.

Component Types and Applications #

WorldBuilder’s example components demonstrate various interaction patterns:

  • MyHoverComponent: Creates oscillating vertical movement using sine waves
  • MyInteractivePulseComponent: Adjusts object scale rhythmically
  • MyLookAtComponent: Orients objects toward specified targets
  • MyOrbitComponent: Creates circular movement around target objects

Advanced Techniques #

Components can reference other scene objects by name:

[JsonProperty("TargetObjectName")]
public string TargetObjectName;

void Start()
{
    var target = GameObject.Find(TargetObjectName);
    if (target)
        m_TargetTransform = target.transform;
}

This allows for complex interactions between objects in educational scenarios.