GDMechanic 1.0.0-alpha3

This is a prerelease version of GDMechanic.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package GDMechanic --version 1.0.0-alpha3                
NuGet\Install-Package GDMechanic -Version 1.0.0-alpha3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GDMechanic" Version="1.0.0-alpha3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add GDMechanic --version 1.0.0-alpha3                
#r "nuget: GDMechanic, 1.0.0-alpha3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install GDMechanic as a Cake Addin
#addin nuget:?package=GDMechanic&version=1.0.0-alpha3&prerelease

// Install GDMechanic as a Cake Tool
#tool nuget:?package=GDMechanic&version=1.0.0-alpha3&prerelease                

GDMechanic

An API designed to streamline C# with Godot Engine without changing any fundamentals. It utilizes cached reflection for optimal performance, and provides power to easily extend the API with your own attributes.

Install Package from NuGet: NuGet

Status

GDMechanic is functionally complete, but a few features are not fully tested.

Most documentation is provided, but extensions are not yet documented.

GDMechanic was created with Godot 3.1 alpha, and does not work in earlier versions due to namespace changes between 3.0.6 and 3.1 in GodotSharp.

Until C# support in Godot is finalized, GDMechanic will be considered to be in an alpha state.

Wiring

GDMechanic provides a set of core attributes for wiring fields, properties, and methods.

Activation

Call this.Wire() in the node's _Ready() method.

public override void _Ready()
{
	this.Wire();
	...
}

It is recommended to create a template for wired nodes, like the below.

using Godot;
using GDMechanic.Wiring;
using GDMechanic.Wiring.Attributes;

public class %CLASS% : %BASE%
{
	
	
	
	public override void _Ready()
	{
		this.Wire();
	}
}

You can place this template in Godot's "script_templates" folder in order for the IDE to pick it up.

Core Attributes

Node

Returns a reference to a node based on the provided node path.

[Node("UI/Score")] private RichTextLabel _scoreText;
Child

Returns a reference to a child based on match type.

[Child] private Player _player;
// or
[Child(Matchtypes.Name)] private Player _player;

[Child(MatchTypes.Type)] private RichTextLabel _score;
Sibling

Returns a reference to a sibling based on match type.

Parent

Returns a reference to the node's parent.

[Parent] private Mommy _mommy;
Group

Adds this node to the specified group.

[Group("Huggables")]
public class Teddy : Node2D
{
	...
}
SignalReceiver

Connects the specified signal from the specified source. The source can either be a node path or a reference from a field on the same node.

[Child] private Button _button2;

[SignalReceiver("Button", "pressed")]
public void OnButtonPressed()
{
	...
}

[SignalReceiver("_button2", "pressed", SourceTypes.Reference)]
public void OnButton2Pressed()
{
	...
}
Timer

Adds a child Timer node with the specified criteria, and assigns a reference to it to the field.

[Timer(nameof(OnTimerTimeout), waitTime: 1.5f, oneShot: true)]
private Timer _timer;
Starting Timer with Custom Wait Time

GDMechanic provides an extension method to Timer that makes it easy to start a timer with a different wait time, without overriding the default.

_timer.Start(6f);

Custom Attributes

You can create your own attributes quite easily. Create a class that extends Attribute and implement IStateWirer, IMethodWirer, or IClassWirer. Also, be sure to add the corresponding attribute targets to the attribute via AttributeUsage.

IStateWirer: AttributeTargets.Field | AttributeTargets.Property

IMethodWirer: AttributeTargets.Method

IClassWirer: AttributeTargets.Class

Then implement the necessary methods. GDMechanic will automatically be able to use it.

Example from NodeAttribute:

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class NodeAttribute : MechanicAttribute, IStateWirer
{

	private readonly string _path;

	/// <summary>
	/// Returns a reference to a node based on the provided node path.
	/// </summary>
	/// <param name="path"></param>
	public NodeAttribute(string path) {
		_path = path;
	}

	public void Wire(Node node, CachedNodeStateInfo state)
	{
		state.SetValue(node, node.GetNode(_path));
	}
}

Extensions

GDMechanic provides extension methods for various nodes. Here are some examples.

public static T InstanceToParent<T>(this PackedScene packedScene, Node parent) where T: Node
public static IEnumerable<object> GetNodesOfType<T>(this SceneTree sceneTree) where T : Node
public static void TranslateX(this Node2D node, float xDisplacement)

Rng

Reimplementation of GDScript's "rand" functions. It uses System.Random under the hood, so it will not have the same output as GDScript's "rand" functions.

Rng.RandRange(0f, 6f);

Rng.Chance

Randomly returns true or false, based on the specified ratio.

if (Rng.Chance(0.05f))
{
	GD.Print("Critical hit!");
}

TimerSystem

Node that organizes a collection of timers for easy access through delegates. It is designed to be used with TimerSystemAttribute and TimerReceiverAttribute, although it is fully functional on its own.

[TimerSystem]
private TimerSystem _timerSystem;

public void StartTimer() {
	_timerSystem.Start(OnTimerTimeout);
}
[TimerReceiver(waitTime: 0.25f, oneShot: true)]
public void OnTimerTimeout()
{
	...
}

[TimerReceiver(waitTime: 3f, oneShot: true)]
public void OnDeathTimeout()
{
	...
}

Alternatively you can place TimerReceiverAttribute on the same field as the TimerSystem reference.

[TimerSystem]
[TimerReceiver(nameof(OnTimerTimeout), waitTime: 0.25f, oneShot: true)]
private TimerSystem _timerSystem;

public void StartTimer() {
	_timerSystem.Start(OnTimerTimeout);
}

public void OnTimerTimeout()
{
	...
}

[TimerReceiver(waitTime: 3f, oneShot: true)]
public void OnDeathTimeout()
{
	...
}
Product Compatible and additional computed target framework versions.
.NET Framework net is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-alpha4 647 9/22/2018
1.0.0-alpha3 551 9/15/2018
1.0.0-alpha2 587 9/9/2018
1.0.0-alpha 584 9/9/2018

New TreeNode (for early prototyping purposes,
more extension methods for AnimatedSprite,
and a fix for caching properties with no getters or setters.
If you are updating from 1.0.0-alpha(1), make sure to reimport GodotSharp. This only applies to alpha(1).