Skip to content

C# API differences to GDScript

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

General differences

As explained in General differences between C# and GDScript, PascalCase is used to access Godot APIs in C# instead of the snake_case used by GDScript and C++. Where possible, fields and getters/setters have been converted to properties. In general, the C# Godot API strives to be as idiomatic as is reasonably possible. See the C# style guide, which we encourage you to also use for your own C# code.

In GDScript, the setters/getters of a property can be called directly, although this is not encouraged. In C#, only the property is defined. For example, to translate the GDScript code x.set_name("Friend") to C#, write x.Name = "Friend";.

A C# IDE will provide intellisense, which is extremely useful when figuring out renamed C# APIs. The built-in Godot script editor has no support for C# intellisense, and it also doesn't provide many other C# development tools that are considered essential. See Configuring an external editor.

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

In C#, only primitive types can be constant. For example, the TAU constant is replaced by the Mathf.Tau constant, but the Vector2.RIGHT constant is replaced by the Vector2.Right read-only property. This behaves similarly to a constant, but can't be used in some contexts like switch statements.

Global enum constants were moved to their own enums. For example, ERR_* constants were moved to the Error enum.

Special cases:

GDScriptC#
TYPE_*Variant.Type enum
OP_*Variant.Operator enum

Math functions

Math global functions, like 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.

C# also provides static System.Math and System.MathF classes that may contain other useful mathematical operations.

Random functions

Random global functions, like rand_range and rand_seed, are located under GD. Example: GD.RandRange and GD.RandSeed.

Consider using System.Random or, if you need cryptographically strong randomness, System.Security.Cryptography.RandomNumberGenerator.

Other functions

Many other global functions like print and var_to_str are located under GD. Example: GD.Print and GD.VarToStr.

Exceptions:

GDScriptC#
weakref(obj)GodotObject.WeakRef(obj)
instance_from_id(id)GodotObject.InstanceFromId(id)
is_instance_id_valid(id)GodotObject.IsInstanceIdValid(id)
is_instance_valid(obj)GodotObject.IsInstanceValid(obj)

Tips

Sometimes it can be useful to use the using static directive. This directive allows to access the members and nested types of a class without specifying the class name.

Example:

csharp
using static Godot.GD;

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

Full list of equivalences

List of Godot's global scope functions and their equivalent in C#:

GDScriptC#
absMathf.Abs
absfMathf.Abs
absiMathf.Abs
acosMathf.Acos
acoshMathf.Acosh
angle_differenceMathf.AngleDifference
asinMathf.Asin
asinhMathf.Asinh
atanMathf.Atan
atan2Mathf.Atan2
atanhMathf.Atanh
bezier_derivativeMathf.BezierDerivative
bezier_interpolateMathf.BezierInterpolate
bytes_to_varGD.BytesToVar
bytes_to_var_with_objectsGD.BytesToVarWithObjects
ceilMathf.Ceil
ceilfMathf.Ceil
ceiliMathf.CeilToInt
clampMathf.Clamp
clampfMathf.Clamp
clampiMathf.Clamp
cosMathf.Cos
coshMathf.Cosh
cubic_interpolateMathf.CubicInterpolate
cubic_interpolate_angleMathf.CubicInterpolateAngle
cubic_interpolate_angle_in_timeMathf.CubicInterpolateInTime
cubic_interpolate_in_timeMathf.CubicInterpolateAngleInTime
db_to_linearMathf.DbToLinear
deg_to_radMathf.DegToRad
easeMathf.Ease
error_stringError.ToString
expMathf.Exp
floorMathf.Floor
floorfMathf.Floor
flooriMathf.FloorToInt
fmodoperator %
fposmodMathf.PosMod
hashGD.Hash
instance_from_idGodotObject.InstanceFromId
inverse_lerpMathf.InverseLerp
is_equal_approxMathf.IsEqualApprox
is_finiteMathf.IsFinite or float.IsFinite or double.IsFinite
is_infMathf.IsInf or float.IsInfinity or double.IsInfinity
is_instance_id_validGodotObject.IsInstanceIdValid
is_instance_validGodotObject.IsInstanceValid
is_nanMathf.IsNaN or float.IsNaN or double.IsNaN
is_sameoperator == or object.ReferenceEquals
is_zero_approxMathf.IsZeroApprox
lerpMathf.Lerp
lerp_angleMathf.LerpAngle
lerpfMathf.Lerp
linear_to_dbMathf.LinearToDb
logMathf.Log
maxMathf.Max
maxfMathf.Max
maxiMathf.Max
minMathf.Min
minfMathf.Min
miniMathf.Min
move_towardMathf.MoveToward
nearest_po2Mathf.NearestPo2
pingpongMathf.PingPong
posmodMathf.PosMod
powMathf.Pow
printGD.Print
print_richGD.PrintRich
print_verboseUse OS.IsStdoutVerbose and GD.Print
printerrGD.PrintErr
printrawGD.PrintRaw
printsGD.PrintS
printtGD.PrintT
push_errorGD.PushError
push_warningGD.PushWarning
rad_to_degMathf.RadToDeg
rand_from_seedGD.RandFromSeed
randfGD.Randf
randf_rangeGD.RandRange
randfnGD.Randfn
randiGD.Randi
randi_rangeGD.RandRange
randomizeGD.Randomize
remapMathf.Remap
rid_allocate_idN/A
rid_from_int64N/A
rotate_towardMathf.RotateToward
roundMathf.Round
roundfMathf.Round
roundiMathf.RoundToInt
seedGD.Seed
signMathf.Sign
signfMathf.Sign
signiMathf.Sign
sinMathf.Sin
sinhMathf.Sinh
smoothstepMathf.SmoothStep
snappedMathf.Snapped
snappedfMathf.Snapped
snappediMathf.Snapped
sqrtMathf.Sqrt
step_decimalsMathf.StepDecimals
strUse $ string interpolation
str_to_varGD.StrToVar
tanMathf.Tan
tanhMathf.Tanh
type_convertVariant.As<T> or GD.Convert
type_stringVariant.Type.ToString
typeofVariant.VariantType
var_to_bytesGD.VarToBytes
var_to_bytes_with_objectsGD.VarToBytesWithObjects
var_to_strGD.VarToStr
weakrefGodotObject.WeakRef
wrapMathf.Wrap
wrapfMathf.Wrap
wrapiMathf.Wrap

List of GDScript utility functions and their equivalent in C#:

GDScriptC#
assertSystem.Diagnostics.Debug.Assert
charUse explicit conversion: (char)65
convertGD.Convert
dict_to_instN/A
get_stackSystem.Environment.StackTrace
inst_to_dictN/A
lenN/A
loadGD.Load
preloadN/A
print_debugN/A
print_stackGD.Print(System.Environment.StackTrace)
rangeGD.Range or System.Linq.Enumerable.Range
type_existsClassDB.ClassExists(type)

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

@export annotation

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

Example:

csharp
using Godot;

public partial 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;
}

See also: C# exported properties.

signal keyword

Use the [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. The delegate must have the EventHandler suffix, an event will be generated in the class with the same name but without the suffix, use that event's name with EmitSignal.

csharp
[Signal]
delegate void MySignalEventHandler(string willSendAString);

See also: C# signals.

@onready annotation

GDScript has the ability to defer the initialization of a member variable until the ready function is called with @onready (cf. @onready annotation). For example:

gdscript
@onready var my_label = get_node("MyLabel")

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

csharp
private Label _myLabel;

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

Singletons

Singletons are available as static classes rather than using the singleton pattern. This is to make code less verbose than it would be with an Instance property.

Example:

csharp
Input.IsActionPressed("ui_down")

However, in some very rare cases this is not enough. For example, you may want to access a member from the base class GodotObject, like Connect. For such use cases we provide a static property named Singleton that returns the singleton instance. The type of this instance is GodotObject.

Example:

csharp
Input.Singleton.JoyConnectionChanged += Input_JoyConnectionChanged;

String

Use System.String (string). Most of Godot's String methods have an equivalent in System.String or are provided by the StringExtensions class as extension methods.

Example:

csharp
string text = "Get up!";
string[] bigrams = text.Bigrams(); // ["Ge", "et", "t ", " u", "up", "p!"]

Strings are immutable in .NET, so all methods that manipulate a string don't modify the original string and return a newly created string with the modifications applied. To avoid creating multiple string allocations consider using a StringBuilder.

List of Godot's String methods and their equivalent in C#:

GDScriptC#
begins_withstring.StartsWith
bigramsStringExtensions.Bigrams
bin_to_intStringExtensions.BinToInt
c_escapeStringExtensions.CEscape
c_unescapeStringExtensions.CUnescape
capitalizeStringExtensions.Capitalize
casecmp_toStringExtensions.CasecmpTo or StringExtensions.CompareTo (Consider using string.Equals or string.Compare)
chrN/A
containsstring.Contains
countStringExtensions.Count (Consider using RegEx)
countnStringExtensions.CountN (Consider using RegEx)
dedentStringExtensions.Dedent
ends_withstring.EndsWith
erasestring.Remove (Consider using StringBuilder to manipulate strings)
findStringExtensions.Find (Consider using string.IndexOf or string.IndexOfAny)
findnStringExtensions.FindN (Consider using string.IndexOf or string.IndexOfAny)
formatUse $ string interpolation
get_base_dirStringExtensions.GetBaseDir
get_basenameStringExtensions.GetBaseName
get_extensionStringExtensions.GetExtension
get_fileStringExtensions.GetFile
get_sliceN/A
get_slice_countN/A
get_slicecN/A
hashStringExtensions.Hash (Consider using object.GetHashCode unless you need to guarantee the same behavior as in GDScript)
hex_decodeStringExtensions.HexDecode (Consider using System.Convert.FromHexString)
hex_to_intStringExtensions.HexToInt (Consider using int.Parse or long.Parse with System.Globalization.NumberStyles.HexNumber)
humanize_sizeN/A
indentStringExtensions.Indent
insertstring.Insert (Consider using StringBuilder to manipulate strings)
is_absolute_pathStringExtensions.IsAbsolutePath
is_emptystring.IsNullOrEmpty or string.IsNullOrWhiteSpace
is_relative_pathStringExtensions.IsRelativePath
is_subsequence_ofStringExtensions.IsSubsequenceOf
is_subsequence_ofnStringExtensions.IsSubsequenceOfN
is_valid_filenameStringExtensions.IsValidFileName
is_valid_floatStringExtensions.IsValidFloat (Consider using float.TryParse or double.TryParse)
is_valid_hex_numberStringExtensions.IsValidHexNumber
is_valid_html_colorStringExtensions.IsValidHtmlColor
is_valid_identifierStringExtensions.IsValidIdentifier
is_valid_intStringExtensions.IsValidInt (Consider using int.TryParse or long.TryParse)
is_valid_ip_addressStringExtensions.IsValidIPAddress
joinstring.Join
json_escapeStringExtensions.JSONEscape
leftStringExtensions.Left (Consider using string.Substring or string.AsSpan)
lengthstring.Length
lpadstring.PadLeft
lstripstring.TrimStart
matchStringExtensions.Match (Consider using RegEx)
matchnStringExtensions.MatchN (Consider using RegEx)
md5_bufferStringExtensions.Md5Buffer (Consider using System.Security.Cryptography.MD5.HashData)
md5_textStringExtensions.Md5Text (Consider using System.Security.Cryptography.MD5.HashData with StringExtensions.HexEncode)
naturalnocasecmp_toN/A (Consider using string.Equals or string.Compare)
nocasecmp_toStringExtensions.NocasecmpTo or StringExtensions.CompareTo (Consider using string.Equals or string.Compare)
numfloat.ToString or double.ToString
num_int64int.ToString or long.ToString
num_scientificfloat.ToString or double.ToString
num_uint64uint.ToString or ulong.ToString
pad_decimalsStringExtensions.PadDecimals
pad_zerosStringExtensions.PadZeros
path_joinStringExtensions.PathJoin
repeatUse string constructor or a StringBuilder
replacestring.Replace or RegEx
replacenStringExtensions.ReplaceN (Consider using string.Replace or RegEx)
reverseN/A
rfindStringExtensions.RFind (Consider using string.LastIndexOf or string.LastIndexOfAny)
rfindnStringExtensions.RFindN (Consider using string.LastIndexOf or string.LastIndexOfAny)
rightStringExtensions.Right (Consider using string.Substring or string.AsSpan)
rpadstring.PadRight
rsplitN/A
rstripstring.TrimEnd
sha1_bufferStringExtensions.Sha1Buffer (Consider using System.Security.Cryptography.SHA1.HashData)
sha1_textStringExtensions.Sha1Text (Consider using System.Security.Cryptography.SHA1.HashData with StringExtensions.HexEncode)
sha256_bufferStringExtensions.Sha256Buffer (Consider using System.Security.Cryptography.SHA256.HashData)
sha256_textStringExtensions.Sha256Text (Consider using System.Security.Cryptography.SHA256.HashData with StringExtensions.HexEncode)
similarityStringExtensions.Similarity
simplify_pathStringExtensions.SimplifyPath
splitStringExtensions.Split (Consider using string.Split)
split_floatsStringExtensions.SplitFloat
strip_edgesStringExtensions.StripEdges (Consider using string.Trim, string.TrimStart or string.TrimEnd)
strip_escapesStringExtensions.StripEscapes
substrStringExtensions.Substr (Consider using string.Substring or string.AsSpan)
to_ascii_bufferStringExtensions.ToAsciiBuffer (Consider using System.Text.Encoding.ASCII.GetBytes)
to_camel_caseStringExtensions.ToCamelCase
to_floatStringExtensions.ToFloat (Consider using float.TryParse or double.TryParse)
to_intStringExtensions.ToInt (Consider using int.TryParse or long.TryParse)
to_lowerstring.ToLower
to_pascal_caseStringExtensions.ToPascalCase
to_snake_caseStringExtensions.ToSnakeCase
to_upperstring.ToUpper
to_utf16_bufferStringExtensions.ToUtf16Buffer (Consider using System.Text.Encoding.UTF16.GetBytes)
to_utf32_bufferStringExtensions.ToUtf32Buffer (Consider using System.Text.Encoding.UTF32.GetBytes)
to_utf8_bufferStringExtensions.ToUtf8Buffer (Consider using System.Text.Encoding.UTF8.GetBytes)
to_wchar_bufferStringExtensions.ToUtf16Buffer in Windows and StringExtensions.ToUtf32Buffer in other platforms
trim_prefixStringExtensions.TrimPrefix
trim_suffixStringExtensions.TrimSuffix
unicode_atstring[int] indexer
uri_decodeStringExtensions.URIDecode (Consider using System.Uri.UnescapeDataString)
uri_encodeStringExtensions.URIEncode (Consider using System.Uri.EscapeDataString)
validate_node_nameStringExtensions.ValidateNodeName
xml_escapeStringExtensions.XMLEscape
xml_unescapeStringExtensions.XMLUnescape

List of Godot's PackedByteArray methods that create a String and their C# equivalent:

GDScriptC#
get_string_from_asciiStringExtensions.GetStringFromAscii (Consider using System.Text.Encoding.ASCII.GetString)
get_string_from_utf16StringExtensions.GetStringFromUtf16 (Consider using System.Text.Encoding.UTF16.GetString)
get_string_from_utf32StringExtensions.GetStringFromUtf32 (Consider using System.Text.Encoding.UTF32.GetString)
get_string_from_utf8StringExtensions.GetStringFromUtf8 (Consider using System.Text.Encoding.UTF8.GetString)
hex_encodeStringExtensions.HexEncode (Consider using System.Convert.ToHexString)

INFO

.NET provides path utility methods under the System.IO.Path class. They can only be used with native OS paths, not Godot paths (paths that start with res:// or user://). See File paths in Godot projects.

[HyperlinkTarget id:2196 children:0 label:"string[int]" target:"https://learn.microsoft.com/en-us/dotnet/api/system.string.chars" resolvedUrl:"https://learn.microsoft.com/en-us/dotnet/api/system.string.chars"]: #

NodePath

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

GDScriptC#
is_empty()IsEmpty

Signal

The following methods were converted to properties with their respective names changed:

GDScriptC#
get_name()Name
get_object()Owner

The Signal type implements the awaitable pattern which means it can be used with the await keyword. See await keyword.

Instead of using the Signal type, the recommended way to use Godot signals in C# is to use the generated C# events. See C# signals.

Callable

The following methods were converted to properties with their respective names changed:

GDScriptC#
get_object()Target
get_method()Method

Currently C# supports Callable if one of the following holds:

  • Callable was created using the C# Callable type.

  • Callable is a basic version of the engine's Callable. Custom Callables are unsupported. A Callable is custom when any of the following holds:

    • Callable has bound information (Callables created with bind/unbind are unsupported).

    • Callable was created from other languages through the GDExtension API.

Some methods such as bind and unbind are not implemented, use lambdas instead:

csharp
string name = "John Doe";
Callable callable = Callable.From(() => SayHello(name));

void SayHello(string name)
{
    GD.Print($"Hello {name}");
}

The lambda captures the name variable so it can be bound to the SayHello method.

RID

This type is named Rid in C# to follow the .NET naming convention.

The following methods were converted to properties with their respective names changed:

GDScriptC#
get_id()Id
is_valid()IsValid

Basis

Structs cannot have parameterless constructors in C#. Therefore, 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:

GDScriptC#
get_scale()Scale

Transform2D

Structs cannot have parameterless constructors in C#. Therefore, 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:

GDScriptC#
get_rotation()Rotation
get_scale()Scale
get_skew()Skew

Transform3D

Structs cannot have parameterless constructors in C#. Therefore, new Transform3D() initializes all primitive members to their default value. Please use Transform3D.Identity for the equivalent of Transform3D() in GDScript and C++.

The following methods were converted to properties with their respective names changed:

GDScriptC#
get_rotation()Rotation
get_scale()Scale

Rect2

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

GDScriptC#
endEnd

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

GDScriptC#
get_area()Area

Rect2i

This type is named Rect2I in C# to follow the .NET naming convention.

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

GDScriptC#
endEnd

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

GDScriptC#
get_area()Area

AABB

This type is named Aabb in C# to follow the .NET naming convention.

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

GDScriptC#
get_volume()Volume

Quaternion

Structs cannot have parameterless constructors in C#. Therefore, new Quaternion() initializes all primitive members to their default value. Please use Quaternion.Identity for the equivalent of Quaternion() in GDScript and C++.

Projection

Structs cannot have parameterless constructors in C#. Therefore, new Projection() initializes all primitive members to their default value. Please use Projection.Identity for the equivalent of Projection() in GDScript and C++.

Color

Structs cannot have parameterless constructors in C#. Therefore, new Color() initializes all primitive members to their default value (which represents the transparent black color). Please use Colors.Black for the equivalent of Color() in GDScript and C++.

The global Color8 method to construct a Color from bytes is available as a static method in the Color type.

The Color constants are available in the Colors static class as readonly properties.

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

GDScriptC#
get_luminance()Luminance

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

GDScriptC#
html(String)FromHtml(ReadOnlySpan<char>)

The following methods are available as constructors:

GDScriptC#
hex(int)Color(uint)
hex64(int)Color(ulong)

Array

The equivalent of packed arrays are System.Array.

See also PackedArray.

Use Godot.Collections.Array for an untyped Variant array. Godot.Collections.Array<T> is a type-safe wrapper around Godot.Collections.Array.

See also Array.

Dictionary

Use Godot.Collections.Dictionary for an untyped Variant dictionary. Godot.Collections.Dictionary<TKey, TValue> is a type-safe wrapper around Godot.Collections.Dictionary.

See also Dictionary.

Variant

Godot.Variant is used to represent Godot's native Variant type. Any Variant-compatible types can be converted from/to it.

See also: C# Variant.

Communicating with other scripting languages

This is explained extensively in Cross-language scripting.

await keyword

Something similar to GDScript's await keyword can be achieved with C#'s await keyword.

The await keyword in C# can be used with any awaitable expression. It's commonly used with operands of the types Task, Task, ValueTask, or ValueTask.

An expression t is awaitable if one of the following holds:

  • t is of compile-time type dynamic.

  • t has an accessible instance or extension method called GetAwaiter with no parameters and no type parameters, and a return type A for which all of the following hold:

    • A implements the interface System.Runtime.CompilerServices.INotifyCompletion.

    • A has an accessible, readable instance property IsCompleted of type bool.

    • A has an accessible instance method GetResult with no parameters and no type parameters.

An equivalent of awaiting a signal in GDScript can be achieved with the await keyword and GodotObject.ToSignal.

Example:

csharp
public async Task SomeFunction()
{
    await ToSignal(timer, Timer.SignalName.Timeout);
    GD.Print("After timeout");
}