Quick Start
Installation
Core package:
dotnet add package QfStudio.Godette.ReactiveUIOptional but recommended packages improve the development experience:
- GodotSharp.SourceGenerators --
[SceneTree]attribute for type-safe scene loading and strongly-typed node access withoutGetNodecalls. - ReactiveUI.SourceGenerators --
[Reactive]attribute to auto-generateRaiseAndSetIfChangedboilerplate for partial properties.
dotnet add package GodotSharp.SourceGenerators
dotnet add package ReactiveUI.SourceGeneratorsWith [SceneTree], annotate a .tscn root script to get:
- A
TscnFilePathstatic property for type-safe scene loading. - Strongly-typed fields for nodes marked
unique_name_in_owner-- noGetNodecalls needed.
// With [SceneTree] -- nodes are directly accessible as properties
[SceneTree(root: "_root")]
public partial class MyScene : Control
{
public override void _Ready()
{
BackButton.Pressed += () => GetTree().ChangeSceneToFile(HomeScene.TscnFilePath);
NameEdit.Text = "hello";
}
}// Without [SceneTree] -- use GetNode with string paths
public partial class MyScene : Control
{
public override void _Ready()
{
GetNode<Button>("BackButton").Pressed += () =>
GetTree().ChangeSceneToFile("res://Views/HomeScene.tscn");
GetNode<LineEdit>("NameEdit").Text = "hello";
}
}// With [Reactive]
public partial class MyViewModel : ReactiveObject
{
[Reactive] public partial string Name { get; set; } = "";
}// Without [Reactive] -- manual backing field + RaiseAndSetIfChanged
public class MyViewModel : ReactiveObject
{
private string _name = "";
public string Name
{
get => _name;
set => this.RaiseAndSetIfChanged(ref _name, value);
}
}Autoload Setup
Create a bootstrapper class to initialize ReactiveUI services and add it as an Autoload in Godot:
using Godot;
using QfStudio.Godette.ReactiveUI;
using ReactiveUI.Builder;
public partial class RxAppBootstrapper : Godot.Node
{
private readonly GodotFrameScheduler _processFrameScheduler = new();
private readonly GodotFrameScheduler _physicsFrameScheduler = new();
public RxAppBootstrapper()
{
RxAppBuilder.CreateReactiveUIBuilder()
.WithGodot(_processFrameScheduler, _physicsFrameScheduler)
.WithGodotConverters()
.WithGodotViewLocator(locator =>
{
locator.RegisterViewsFromAssemblyViaReflection(typeof(RxAppBootstrapper).Assembly, verbose: false);
})
.BuildApp();
}
public override void _Process(double delta) => _processFrameScheduler.NotifyProcess(delta);
public override void _PhysicsProcess(double delta) => _physicsFrameScheduler.NotifyProcess(delta);
}Each builder call does the following:
.WithGodot(_processFrameScheduler, _physicsFrameScheduler)sets up the Godot platform: it creates the main-thread scheduler (fromSynchronizationContext.Current), wires up the process/physics-frame schedulers you pass in, and registers the platform services needed for view activation, property binding, and command binding. It also prepares ReactiveUI's core services, so you do not callWithCoreServices()yourself..WithGodotConverters()(optional) registers the float↔double binding converters (FloatToDoubleConverter,DoubleToFloatConverter)..WithGodotViewLocator(locator => …)(optional) registers theGodotViewLocator; the callback is where you register your views — here, by reflecting the current assembly.
In Godot Editor, go to Project > Project Settings > Autoload and add this script as an Autoload with a name like RxAppBootstrapper.
NOTE
Without .WithGodotConverters() (which registers FloatToDoubleConverter/DoubleToFloatConverter), bindings between Godot controls that expose double properties (e.g. Range.Value, ColorPicker.Color) and ViewModel float properties will throw ConverterNotFoundException at bind time. The library also ships EnumToStringConverter<TEnum>, StringToEnumConverter<TEnum>, and Variant-to/from-primitive converters -- register whichever ones you need via .WithConverter(...) in the builder above.