C# API differences to GDScript
This is a (incomplete) list of API differences between C# and GDScript.
General differences
As explained in doc_c_sharp_general_differences, 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 doc_c_sharp_styleguide, 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 doc_c_sharp_setup_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:
======================= ===========================================================
GDScript C#
======================= ===========================================================
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:
============================ =======================================================
GDScript C#
============================ =======================================================
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:
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#:
=============================== ============================================================== GDScript C# =============================== ============================================================== abs Mathf.Abs absf Mathf.Abs absi Mathf.Abs acos Mathf.Acos acosh Mathf.Acosh angle_difference Mathf.AngleDifference asin Mathf.Asin asinh Mathf.Asinh atan Mathf.Atan atan2 Mathf.Atan2 atanh Mathf.Atanh bezier_derivative Mathf.BezierDerivative bezier_interpolate Mathf.BezierInterpolate bytes_to_var GD.BytesToVar bytes_to_var_with_objects GD.BytesToVarWithObjects ceil Mathf.Ceil ceilf Mathf.Ceil ceili Mathf.CeilToInt clamp Mathf.Clamp clampf Mathf.Clamp clampi Mathf.Clamp cos Mathf.Cos cosh Mathf.Cosh cubic_interpolate Mathf.CubicInterpolate cubic_interpolate_angle Mathf.CubicInterpolateAngle cubic_interpolate_angle_in_time Mathf.CubicInterpolateInTime cubic_interpolate_in_time Mathf.CubicInterpolateAngleInTime db_to_linear Mathf.DbToLinear deg_to_rad Mathf.DegToRad ease Mathf.Ease error_string Error.ToString exp Mathf.Exp floor Mathf.Floor floorf Mathf.Floor floori Mathf.FloorToInt fmod operator % fposmod Mathf.PosMod hash GD.Hash instance_from_id GodotObject.InstanceFromId inverse_lerp Mathf.InverseLerp is_equal_approx Mathf.IsEqualApprox is_finite Mathf.IsFinite or float.IsFinite or double.IsFinite is_inf Mathf.IsInf or float.IsInfinity or double.IsInfinity is_instance_id_valid GodotObject.IsInstanceIdValid is_instance_valid GodotObject.IsInstanceValid is_nan Mathf.IsNaN or float.IsNaN or double.IsNaN is_same operator == or object.ReferenceEquals is_zero_approx Mathf.IsZeroApprox lerp Mathf.Lerp lerp_angle Mathf.LerpAngle lerpf Mathf.Lerp linear_to_db Mathf.LinearToDb log Mathf.Log max Mathf.Max maxf Mathf.Max maxi Mathf.Max min Mathf.Min minf Mathf.Min mini Mathf.Min move_toward Mathf.MoveToward nearest_po2 Mathf.NearestPo2 pingpong Mathf.PingPong posmod Mathf.PosMod pow Mathf.Pow print GD.Print print_rich GD.PrintRich print_verbose Use OS.IsStdoutVerbose and GD.Print printerr GD.PrintErr printraw GD.PrintRaw prints GD.PrintS printt GD.PrintT push_error GD.PushError push_warning GD.PushWarning rad_to_deg Mathf.RadToDeg rand_from_seed GD.RandFromSeed randf GD.Randf randf_range GD.RandRange randfn GD.Randfn randi GD.Randi randi_range GD.RandRange randomize GD.Randomize remap Mathf.Remap rid_allocate_id N/A rid_from_int64 N/A rotate_toward Mathf.RotateToward round Mathf.Round roundf Mathf.Round roundi Mathf.RoundToInt seed GD.Seed sign Mathf.Sign signf Mathf.Sign signi Mathf.Sign sin Mathf.Sin sinh Mathf.Sinh smoothstep Mathf.SmoothStep snapped Mathf.Snapped snappedf Mathf.Snapped snappedi Mathf.Snapped sqrt Mathf.Sqrt step_decimals Mathf.StepDecimals str Use [ string interpolation) str_to_var GD.StrToVar tan Mathf.Tan tanh Mathf.Tanh type_convert Variant.As<T> or GD.Convert type_string Variant.Type.ToString typeof Variant.VariantType var_to_bytes GD.VarToBytes var_to_bytes_with_objects GD.VarToBytesWithObjects var_to_str GD.VarToStr weakref GodotObject.WeakRef wrap Mathf.Wrap wrapf Mathf.Wrap wrapi Mathf.Wrap =============================== ==============================================================
List of GDScript utility functions and their equivalent in C#:
======================= ==============================================================
GDScript C#
======================= ==============================================================
assert System.Diagnostics.Debug.Assert
char Use explicit conversion: (char)65
convert GD.Convert
dict_to_inst N/A
get_stack System.Environment.StackTrace
inst_to_dict N/A
len N/A
load GD.Load
preload N/A
print_debug N/A
print_stack GD.Print(System.Environment.StackTrace)
range GD.Range or System.Linq.Enumerable.Range
type_exists ClassDB.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:
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: doc_c_sharp_exports.
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.
[Signal]
delegate void MySignalEventHandler(string willSendAString);
See also: doc_c_sharp_signals.
@onready annotation
GDScript has the ability to defer the initialization of a member variable until the ready function
is called with @onready (cf. doc_gdscript_onready_annotation).
For example:
@onready var my_label = get_node("MyLabel")
However C# does not have this ability. To achieve the same effect you need to do this.
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:
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:
Input.Singleton.JoyConnectionChanged += Input_JoyConnectionChanged;
If you are developing main screen plugins, it is essential to note that
EditorInterface is not a static class in C#, unlike in GDScript.
Therefore, you must use the singleton pattern to obtain an instance of the
EditorInterface:
==================== ==============================================================
GDScript C#
==================== ==============================================================
EditorInterface EditorInterface.Singleton
==================== ==============================================================
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:
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#:
======================= ============================================================== GDScript C# ======================= ============================================================== begins_with string.StartsWith bigrams StringExtensions.Bigrams bin_to_int StringExtensions.BinToInt c_escape StringExtensions.CEscape c_unescape StringExtensions.CUnescape capitalize StringExtensions.Capitalize casecmp_to StringExtensions.CasecmpTo or StringExtensions.CompareTo (Consider using string.Equals or string.Compare) chr N/A contains string.Contains count StringExtensions.Count (Consider using RegEx) countn StringExtensions.CountN (Consider using RegEx) dedent StringExtensions.Dedent ends_with string.EndsWith erase string.Remove (Consider using StringBuilder to manipulate strings) find StringExtensions.Find (Consider using string.IndexOf or string.IndexOfAny) findn StringExtensions.FindN (Consider using string.IndexOf or string.IndexOfAny) format Use [ string interpolation) get_base_dir StringExtensions.GetBaseDir get_basename StringExtensions.GetBaseName get_extension StringExtensions.GetExtension get_file StringExtensions.GetFile get_slice N/A get_slice_count N/A get_slicec N/A hash StringExtensions.Hash (Consider using object.GetHashCode unless you need to guarantee the same behavior as in GDScript) hex_decode StringExtensions.HexDecode (Consider using System.Convert.FromHexString) hex_to_int StringExtensions.HexToInt (Consider using int.Parse or long.Parse with System.Globalization.NumberStyles.HexNumber) humanize_size N/A indent StringExtensions.Indent insert string.Insert (Consider using StringBuilder to manipulate strings) is_absolute_path StringExtensions.IsAbsolutePath is_empty string.IsNullOrEmpty or string.IsNullOrWhiteSpace is_relative_path StringExtensions.IsRelativePath is_subsequence_of StringExtensions.IsSubsequenceOf is_subsequence_ofn StringExtensions.IsSubsequenceOfN is_valid_filename StringExtensions.IsValidFileName is_valid_float StringExtensions.IsValidFloat (Consider using float.TryParse or double.TryParse) is_valid_hex_number StringExtensions.IsValidHexNumber is_valid_html_color StringExtensions.IsValidHtmlColor is_valid_identifier StringExtensions.IsValidIdentifier is_valid_int StringExtensions.IsValidInt (Consider using int.TryParse or long.TryParse) is_valid_ip_address StringExtensions.IsValidIPAddress join string.Join json_escape StringExtensions.JSONEscape left StringExtensions.Left (Consider using string.Substring or string.AsSpan) length string.Length lpad string.PadLeft lstrip string.TrimStart match StringExtensions.Match (Consider using RegEx) matchn StringExtensions.MatchN (Consider using RegEx) md5_buffer StringExtensions.Md5Buffer (Consider using System.Security.Cryptography.MD5.HashData) md5_text StringExtensions.Md5Text (Consider using System.Security.Cryptography.MD5.HashData with StringExtensions.HexEncode) naturalnocasecmp_to N/A (Consider using string.Equals or string.Compare) nocasecmp_to StringExtensions.NocasecmpTo or StringExtensions.CompareTo (Consider using string.Equals or string.Compare) num float.ToString or double.ToString num_int64 int.ToString or long.ToString num_scientific float.ToString or double.ToString num_uint64 uint.ToString or ulong.ToString pad_decimals StringExtensions.PadDecimals pad_zeros StringExtensions.PadZeros path_join StringExtensions.PathJoin repeat Use [string constructor](string constructor) or a StringBuilder replace string.Replace or RegEx replacen StringExtensions.ReplaceN (Consider using string.Replace or RegEx) reverse N/A rfind StringExtensions.RFind (Consider using string.LastIndexOf or string.LastIndexOfAny) rfindn StringExtensions.RFindN (Consider using string.LastIndexOf or string.LastIndexOfAny) right StringExtensions.Right (Consider using string.Substring or string.AsSpan) rpad string.PadRight rsplit N/A rstrip string.TrimEnd sha1_buffer StringExtensions.Sha1Buffer (Consider using System.Security.Cryptography.SHA1.HashData) sha1_text StringExtensions.Sha1Text (Consider using System.Security.Cryptography.SHA1.HashData with StringExtensions.HexEncode) sha256_buffer StringExtensions.Sha256Buffer (Consider using System.Security.Cryptography.SHA256.HashData) sha256_text StringExtensions.Sha256Text (Consider using System.Security.Cryptography.SHA256.HashData with StringExtensions.HexEncode) similarity StringExtensions.Similarity simplify_path StringExtensions.SimplifyPath split StringExtensions.Split (Consider using string.Split) split_floats StringExtensions.SplitFloat strip_edges StringExtensions.StripEdges (Consider using string.Trim, string.TrimStart or string.TrimEnd) strip_escapes StringExtensions.StripEscapes substr StringExtensions.Substr (Consider using string.Substring or string.AsSpan) to_ascii_buffer StringExtensions.ToAsciiBuffer (Consider using System.Text.Encoding.ASCII.GetBytes) to_camel_case StringExtensions.ToCamelCase to_float StringExtensions.ToFloat (Consider using float.TryParse or double.TryParse) to_int StringExtensions.ToInt (Consider using int.TryParse or long.TryParse) to_lower string.ToLower to_pascal_case StringExtensions.ToPascalCase to_snake_case StringExtensions.ToSnakeCase to_upper string.ToUpper to_utf16_buffer StringExtensions.ToUtf16Buffer (Consider using System.Text.Encoding.UTF16.GetBytes) to_utf32_buffer StringExtensions.ToUtf32Buffer (Consider using System.Text.Encoding.UTF32.GetBytes) to_utf8_buffer StringExtensions.ToUtf8Buffer (Consider using System.Text.Encoding.UTF8.GetBytes) to_wchar_buffer StringExtensions.ToUtf16Buffer in Windows and StringExtensions.ToUtf32Buffer in other platforms trim_prefix StringExtensions.TrimPrefix trim_suffix StringExtensions.TrimSuffix unicode_at string[int] indexer uri_decode StringExtensions.URIDecode (Consider using System.Uri.UnescapeDataString) uri_encode StringExtensions.URIEncode (Consider using System.Uri.EscapeDataString) validate_node_name StringExtensions.ValidateNodeName xml_escape StringExtensions.XMLEscape xml_unescape StringExtensions.XMLUnescape ======================= ==============================================================
List of Godot's PackedByteArray methods that create a String and their C# equivalent:
========================= ============================================================== GDScript C# ========================= ============================================================== get_string_from_ascii StringExtensions.GetStringFromAscii (Consider using System.Text.Encoding.ASCII.GetString) get_string_from_utf16 StringExtensions.GetStringFromUtf16 (Consider using System.Text.Encoding.UTF16.GetString) get_string_from_utf32 StringExtensions.GetStringFromUtf32 (Consider using System.Text.Encoding.UTF32.GetString) get_string_from_utf8 StringExtensions.GetStringFromUtf8 (Consider using System.Text.Encoding.UTF8.GetString) hex_encode StringExtensions.HexEncode (Consider using System.Convert.ToHexString) ========================= ==============================================================
.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 doc_data_paths.
NodePath
The following method was converted to a property with a different name:
==================== ==============================================================
GDScript C#
==================== ==============================================================
is_empty() IsEmpty
==================== ==============================================================
Signal
The following methods were converted to properties with their respective names changed:
==================== ==============================================================
GDScript C#
==================== ==============================================================
get_name() Name
get_object() Owner
==================== ==============================================================
The Signal type implements the awaitable pattern which means it can be used with
the await keyword. See doc_c_sharp_differences_await.
Instead of using the Signal type, the recommended way to use Godot signals in C# is
to use the generated C# events. See doc_c_sharp_signals.
Callable
The following methods were converted to properties with their respective names changed:
==================== ==============================================================
GDScript C#
==================== ==============================================================
get_object() Target
get_method() Method
==================== ==============================================================
Currently C# supports Callable if one of the following holds:
-
Callablewas created using the C#Callabletype. -
Callableis a basic version of the engine'sCallable. CustomCallable\ s are unsupported. ACallableis custom when any of the following holds:Callablehas bound information (Callable\ s created withbind/unbindare unsupported).Callablewas created from other languages through the GDExtension API.
Some methods such as bind and unbind are not implemented, use lambdas instead:
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:
==================== ==============================================================
GDScript C#
==================== ==============================================================
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:
==================== ==============================================================
GDScript C#
==================== ==============================================================
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:
==================== ==============================================================
GDScript C#
==================== ==============================================================
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:
==================== ==============================================================
GDScript C#
==================== ==============================================================
get_rotation() Rotation
get_scale() Scale
==================== ==============================================================
Rect2
The following field was converted to a property with a slightly different name:
================ ==================================================================
GDScript C#
================ ==================================================================
end End
================ ==================================================================
The following method was converted to a property with a different name:
================ ==================================================================
GDScript C#
================ ==================================================================
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:
================ ==================================================================
GDScript C#
================ ==================================================================
end End
================ ==================================================================
The following method was converted to a property with a different name:
================ ==================================================================
GDScript C#
================ ==================================================================
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:
================ ==================================================================
GDScript C#
================ ==================================================================
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:
==================== ==============================================================
GDScript C#
==================== ==============================================================
get_luminance() Luminance
==================== ==============================================================
The following method was converted to a method with a different name:
==================== ==============================================================
GDScript C#
==================== ==============================================================
html(String) FromHtml(ReadOnlySpan<char>)
==================== ==============================================================
The following methods are available as constructors:
==================== ==============================================================
GDScript C#
==================== ==============================================================
hex(int) Color(uint)
hex64(int) Color(ulong)
==================== ==============================================================
Array
The equivalent of packed arrays are System.Array.
See also PackedArray in C# .
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 in C# .
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 in C# .
Variant
Godot.Variant is used to represent Godot's native Variant type.
Any Variant-compatible type can be converted from/to it.
See also: doc_c_sharp_variant.
Communicating with other scripting languages
This is explained extensively in doc_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](TResult), [ValueTask](Task](TResult), [ValueTask), or ValueTask.
An expression t is awaitable if one of the following holds:
-
tis of compile-time typedynamic. -
thas an accessible instance or extension method calledGetAwaiterwith no parameters and no type parameters, and a return typeAfor which all of the following hold:Aimplements the interfaceSystem.Runtime.CompilerServices.INotifyCompletion.Ahas an accessible, readable instance propertyIsCompletedof typebool.Ahas an accessible instance methodGetResultwith 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:
public async Task SomeFunction()
{
await ToSignal(timer, Timer.SignalName.Timeout);
GD.Print("After timeout");
}