C# API differences to GDScript

This is a (incomplete) list of API differences between C# and GDScript.

General differences

C# basics, C# generally uses PascalCase instead of the snake_case used in GDScript and C++.

Global scope

Global functions and some constants had to be moved to classes, since C# does not allow declaring them in namespaces. Most global constants were moved to their own enums.

Constants

ERR_* constants were moved to the Error enum. Special cases:

Math functions

abs, acos, asin, atan and atan2, are located under Mathf as Abs, Acos, Asin, Atan and Atan2. The PI constant can be found as Mathf.Pi.

Random functions

rand_range and rand_seed, are located under GD. Example: GD.RandRange and GD.RandSeed.

Other functions

print and var2str are located under GD. Example: GD.Print and GD.Var2Str. Exceptions:

Tips

using static directive. This directive allows to access the members and nested types of a class without specifying the class name. Example:

  1. using static Godot.GD;public class Test{ static Test() { Print("Hello"); // Instead of GD.Print("Hello"); }}

Export keyword

[Export] attribute instead of the GDScript export keyword. This attribute can also be provided with optional PropertyHint and hintString parameters. Default values can be set by assigning a value. Example:

  1. using Godot;public class MyNode : Node{ [Export] private NodePath _nodePath; [Export] private string _name = "default"; [Export(PropertyHint.Range, "0,100000,1000,or_greater")] private int _income; [Export(PropertyHint.File, "*.png,*.jpg")] private string _icon;}

Signal keyword

[Signal] attribute to declare a signal instead of the GDScript signal keyword. This attribute should be used on a delegate, whose name signature will be used to define the signal.

  1. [Signal]delegate void MySignal(string willSendsAString);

C# signals.

onready keyword

onready keyword). For example:

  1. onready var my_label = get_node("MyLabel")

However C# does not have this ability. To achieve the same effect you need to do this.

  1. private Label _myLabel;public override void _Ready(){ _myLabel = GetNode<Label>("MyLabel");}

Singletons

Instance property. Example:

  1. Input.IsActionPressed("ui_down")

Godot.Object, like Connect. For such use cases we provide a static property named Singleton that returns the singleton instance. The type of this instance is Godot.Object. Example:

  1. Input.Singleton.Connect("joy_connection_changed", this, nameof(Input_JoyConnectionChanged));

String

System.String (string). Most of Godot’s String methods are provided by the StringExtensions class as extension methods. Example:

  1. string upper = "I LIKE SALAD FORKS";string lower = upper.ToLower();

There are a few differences, though:

  • erase: Strings are immutable in C#, so we cannot modify the string passed to the extension method. For this reason, Erase was added as an extension method of StringBuilder instead of string. Alternatively, you can use string.Remove.
  • IsSubsequenceOf/IsSubsequenceOfi: An additional method is provided, which is an overload of IsSubsequenceOf, allowing you to explicitly specify case sensitivity:
    1. str.IsSubsequenceOf("ok"); // Case sensitivestr.IsSubsequenceOf("ok", true); // Case sensitivestr.IsSubsequenceOfi("ok"); // Case insensitivestr.IsSubsequenceOf("ok", false); // Case insensitive
  • Match/Matchn/ExprMatch: An additional method is provided besides Match and Matchn, which allows you to explicitly specify case sensitivity:
    1. str.Match("*.txt"); // Case sensitivestr.ExprMatch("*.txt", true); // Case sensitivestr.Matchn("*.txt"); // Case insensitivestr.ExprMatch("*.txt", false); // Case insensitive

    Basis

    new Basis() initializes all primitive members to their default value. Use Basis.Identity for the equivalent of Basis() in GDScript and C++. The following method was converted to a property with a different name:

    Transform2D

    new Transform2D() initializes all primitive members to their default value. Please use Transform2D.Identity for the equivalent of Transform2D() in GDScript and C++. The following methods were converted to properties with their respective names changed:

    Plane

    slightly different name:

    Rect2

    slightly different name: The following method was converted to a property with a different name:

    Quat

    new Quat() initializes all primitive members to their default value. Please use Quat.Identity for the equivalent of Quat() in GDScript and C++. The following methods were converted to a property with a different name:

    Array

    This is temporary. PoolArrays will need their own types to be used the way they are meant to. Godot.Collections.Array<T> is a type-safe wrapper around Godot.Collections.Array. Use the Godot.Collections.Array<T>(Godot.Collections.Array) constructor to create one.

    Dictionary

    Godot.Collections.Dictionary. Godot.Collections.Dictionary<T> is a type-safe wrapper around Godot.Collections.Dictionary. Use the Godot.Collections.Dictionary<T>(Godot.Collections.Dictionary) constructor to create one.

    Variant

    System.Object (object) is used instead of Variant.

    Communicating with other scripting languages

    Cross-language scripting.

    Yield

    yield with a single parameter can be achieved with C#’s yield keyword. Godot.Object.ToSignal. Example:
    1. await ToSignal(timer, "timeout");GD.Print("After timeout");

    Other differences

    preload, as it works in GDScript, is not available in C#. Use GD.Load or ResourceLoader.Load instead. Other differences: