GodotExt 0.2.0
dotnet add package GodotExt --version 0.2.0
NuGet\Install-Package GodotExt -Version 0.2.0
<PackageReference Include="GodotExt" Version="0.2.0" />
paket add GodotExt --version 0.2.0
#r "nuget: GodotExt, 0.2.0"
// Install GodotExt as a Cake Addin #addin nuget:?package=GodotExt&version=0.2.0 // Install GodotExt as a Cake Tool #tool nuget:?package=GodotExt&version=0.2.0
GodotExt - Extension methods for the Godot C# API
This library contains a set of useful extension methods that augment Godot's C# API to make it easier to use and more type-safe. The extension methods are defined for a handful of types.
Installation
GodotExt is published on NuGet. To add it use this command line command (or the NuGet facilities of your IDE):
dotnet add package GodotExt --version 0.2.0
If you are targeting netstandard2.1
also add the following lines to your .csproj
file to make it work with Godot:
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
What's inside
Finding nodes
You can use the AtPath
and WithName
extension methods as a type-safe and verified replacement for Godot's GetNode
and FindNode
methods. Both replacements will verify that the node exists and throw an exception if it doesn't.
var button = GetNode<Button>("Some/Path/To/Button");
// becomes
var button = this.AtPath<Button>("Some/Path/to/Button");
var button = FindNode<Button>("Button", true, false);
// becomes
var button = this.WithName<Button>("Button");
You can use FindAllDescendants
and FindClosestDescendants
to find all nodes in a subtree that are of a certain type and match additional criteria.
// find the red buttons below the current node
var allRedButtons = FindAllDescendants<Button>(b => b.GetColor() == Color.Red);
// find the outermost containers that are in the "Alpha" group
var allContainersInGroupAlpha = FindClosestDescendants<Container>(c => c.IsInGroup("Alpha"));
The difference between FindAllDescendants
and FindClosestDescendants
is that FindAllDescendants
will return all nodes in the whole sub-tree that match the criteria, while FindClosestDescendants
will return the first node in each branch of the sub-tree that matches the criteria (e.g. FindClosestDescendants
will stop searching a branch when it has found a match).
Also, be aware that these functions traverse the node tree so they can be expensive and should not be used in tight loops. Their main use case is for saving games where they allow you to quickly find interesting nodes in the tree that need saving and where it is ok to wait a few milliseconds for the result.
Parent-child relationships
GetChildNodes<T>
is a type-safe replacement for GetChildren
. It will only return nodes of the given type back:
foreach(var child in this.GetChildren()) {
if (child is Button button) {
button.Disabled = true;
}
}
// becomes
foreach(var button in this.GetChildNodes<Button>()) {
button.Disabled = true;
}
MoveToNewParent
moves a node to a new parent:
if (player.GetParent() != null) {
player.GetParent().RemoveChild(player);
}
airship.AddChild(player);
// becomes
player.MoveToNewParent(airship);
RemoveFromParent
removes a node from its parent:
if (node.GetParent() != null) {
node.GetParent().RemoveChild(node);
}
// becomes
node.RemoveFromParent();
RemoveAndFree
is a safer alternative to QueueFree
. It ensures the node is actually removed from the tree before QueueFree
is called, which helps avoiding strange behaviour when the node is still in the tree for the remainder of the current frame:
if (node.GetParent() != null) {
node.GetParent().RemoveChild(node);
}
node.QueueFree();
// becomes
node.RemoveAndFree();
Nodes in groups
FindBelowInGroup
finds all nodes below a given node that are in a given group:
var myNode = ...; // this is the node below which we want to find all nodes that are in a certain group
var nodesInGroup = GetTree().GetNodesInGroup("SomeGroup");
var result = new List<Node>();
foreach (var node in nodesInGroup) {
if (myNode.IsAParentOf(node)) {
result.Add(node);
}
}
// becomes
var nodesInGroup = myNode.FindBelowInGroup("SomeGroup");
GetNodesInGroup
gets an override that will filter the group nodes to only return nodes of the given type:
var enemies = GetTree().GetNodesInGroup("SomeGroup")
.OfType<Enemy>();
// becomes
var enemies = GetTree().GetNodesInGroup<Enemy>("SomeGroup");
Signals
FiresSignal
provides a better-readable alternative to the built-in ToSignal
when you want to wait for a certain signal with await
.
await ToSignal(timer,"timeout");
// becomes
await timer.FiresSignal("timeout");
Timers and Tweens
For timers and tweens there are additional methods that make using them easier:
// make a one-off 500ms timer and wait on it
await ToSignal(GetTree().CreateTimer(0.5), "timeout");
// becomes
await this.Sleep(0.5);
await ToSignal(timer, "timeout");
// becomes
await timer.Timeout();
await ToSignal(tween, "tween_completed");
// becomes
await tween.IsCompleted();
Fluent API for signal connections
Connect
gets an override which allows you to fluently create signal connections:
button
.Connect(
"pressed",
this, nameof(OnButtonPressed)
);
// becomes
button
.Connect("pressed")
.To(this, nameof(OnButtonPressed));
In addition to the vanilla API it also directly checks for errors during binding and throws an exception if the binding fails instead of silently failing. Also, this API allows for easier additional binds and binding flags, which can use the actual enum's instead of uint
s and don't require you to manually create Godot's Array
instances:
button.Connect(
"pressed",
this, nameof(OnButtonPressed),
new Array(button),
((uint) ConnectFlags.Deferred) | ((uint) ConnectFlags.OneShot)));
// becomes
button
.Connect("pressed")
.WithBinds(button)
.WithFlags(ConnectFlags.Deferred, ConnectFlags.OneShot)
.To(this, nameof(OnButtonPressed))
The fluent API also returns a binding object which allows you to easily disconnect the binding again without having to write all the parameters again:
button.Connect("pressed", this, nameof(OnButtonPressed));
// later...
button.Disconnect("pressed", this, nameof(OnButtonPressed));
// becomes
var connection = button
.Connect("pressed")
.To(this, nameof(OnButtonPressed));
// later...
connection.Disconnect();
Miscellaneous
Type-safe cloning of nodes
Clone
is a type-safe variant of Duplicate
:
var monsterClone = monster.Duplicate() as Monster;
// becomes
var monsterClone = monster.Clone(); // no casting necessary
Snake-case conversion for CallDeferred
When calling Godot-API through CallDeferred
you need to translate the method name into snake-case. This can easily introduce typos. Therefore string
gets an extension method that converts the string to snake-case:
someNode.CallDeferred("someMethod", new Array(1, 2, 3));
// becomes
someNode.CallDeferred(nameof(SomeNode.SomeMethod).ToSnakeCase(), new Array(1, 2, 3));
As an additional bonus the deferred call will now also appear in the usage search of your IDE.
2D World-Screen transformations on ViewPort
Viewport
has some extensions that allow you to quickly transform screen coordinates to a world coordinates:
var worldCoordinates = GetGlobalMousePosition() * viewport.CanvasTransform;
// becomes
var worldCoordinates = viewport.ScreenToWorld(GetGlobalMousePosition());
and the reverse is also possible:
var playerPositionOnScreen = viewport.CanvasTransform * player.position;
// becomes
var playerPositionOnScreen = viewport.WorldToScreen(player.position);
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
.NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- JetBrains.Annotations (>= 2022.1.0)
-
.NETStandard 2.1
- JetBrains.Annotations (>= 2022.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on GodotExt:
Repository | Stars |
---|---|
derkork/openscad-graph-editor
OpenSCAD Graph Editor
|
This is an early version. While it is working API may change.