Fix C# examples in documentation

- Fix documentation after C# renames.
- Add missing `partial` in C# class declarations.
- Change `delta` parameter type to `double` in C#.
- Ensure parameters match base declaration.
- Use `$` string interpolation in C#.
- Fix invalid or outdated C# code.
- Changed some examples to follow our style guide more closely.
This commit is contained in:
Raul Santos 2023-01-31 18:21:09 +01:00
parent 8612c12be6
commit 7eb8325180
No known key found for this signature in database
GPG key ID: B532473AE3A803E4
35 changed files with 295 additions and 278 deletions

View file

@ -39,39 +39,38 @@
[/gdscript]
[csharp]
using Godot;
using System;
using System.Diagnostics;
public class Example : Node
public partial class MyNode : Node
{
public AESContext Aes = new AESContext();
private AesContext _aes = new AesContext();
public override void _Ready()
{
string key = "My secret key!!!"; // Key must be either 16 or 32 bytes.
string data = "My secret text!!"; // Data size must be multiple of 16 bytes, apply padding if needed.
// Encrypt ECB
Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8());
byte[] encrypted = Aes.Update(data.ToUTF8());
Aes.Finish();
_aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8());
byte[] encrypted = _aes.Update(data.ToUtf8());
_aes.Finish();
// Decrypt ECB
Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8());
byte[] decrypted = Aes.Update(encrypted);
Aes.Finish();
_aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8());
byte[] decrypted = _aes.Update(encrypted);
_aes.Finish();
// Check ECB
Debug.Assert(decrypted == data.ToUTF8());
Debug.Assert(decrypted == data.ToUtf8());
string iv = "My secret iv!!!!"; // IV must be of exactly 16 bytes.
// Encrypt CBC
Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8(), iv.ToUTF8());
encrypted = Aes.Update(data.ToUTF8());
Aes.Finish();
_aes.Start(AesContext.Mode.EcbEncrypt, key.ToUtf8(), iv.ToUtf8());
encrypted = _aes.Update(data.ToUtf8());
_aes.Finish();
// Decrypt CBC
Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8(), iv.ToUTF8());
decrypted = Aes.Update(encrypted);
Aes.Finish();
_aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8(), iv.ToUtf8());
decrypted = _aes.Update(encrypted);
_aes.Finish();
// Check CBC
Debug.Assert(decrypted == data.ToUTF8());
Debug.Assert(decrypted == data.ToUtf8());
}
}
[/csharp]

View file

@ -19,15 +19,16 @@
return min(0, abs(u - v) - 1)
[/gdscript]
[csharp]
public class MyAStar : AStar3D
public partial class MyAStar : AStar3D
{
public override float _ComputeCost(int u, int v)
public override float _ComputeCost(long fromId, long toId)
{
return Mathf.Abs(u - v);
return Mathf.Abs((int)(fromId - toId));
}
public override float _EstimateCost(int u, int v)
public override float _EstimateCost(long fromId, long toId)
{
return Mathf.Min(0, Mathf.Abs(u - v) - 1);
return Mathf.Min(0, Mathf.Abs((int)(fromId - toId)) - 1);
}
}
[/csharp]

View file

@ -233,7 +233,6 @@
<description>
Returns a new color from [param rgba], an HTML hexadecimal color string. [param rgba] is not case-sensitive, and may be prefixed by a hash sign ([code]#[/code]).
[param rgba] must be a valid three-digit or six-digit hexadecimal color string, and may contain an alpha channel value. If [param rgba] does not contain an alpha channel value, an alpha channel value of 1.0 is applied. If [param rgba] is invalid, returns an empty color.
[b]Note:[/b] In C#, this method is not implemented. The same functionality is provided by the Color constructor.
[codeblocks]
[gdscript]
var blue = Color.html("#0000ff") # blue is Color(0.0, 0.0, 1.0, 1.0)
@ -264,13 +263,13 @@
Color.html_is_valid("#55aaFF5") # Returns false
[/gdscript]
[csharp]
Color.IsHtmlValid("#55AAFF"); // Returns true
Color.IsHtmlValid("#55AAFF20"); // Returns true
Color.IsHtmlValid("55AAFF"); // Returns true
Color.IsHtmlValid("#F2C"); // Returns true
Color.HtmlIsValid("#55AAFF"); // Returns true
Color.HtmlIsValid("#55AAFF20"); // Returns true
Color.HtmlIsValid("55AAFF"); // Returns true
Color.HtmlIsValid("#F2C"); // Returns true
Color.IsHtmlValid("#AABBC"); // Returns false
Color.IsHtmlValid("#55aaFF5"); // Returns false
Color.HtmlIsValid("#AABBC"); // Returns false
Color.HtmlIsValid("#55aaFF5"); // Returns false
[/csharp]
[/codeblocks]
</description>

View file

@ -37,11 +37,11 @@
return typeof(data) == TYPE_DICTIONARY and data.has("expected")
[/gdscript]
[csharp]
public override bool CanDropData(Vector2 position, object data)
public override bool _CanDropData(Vector2 atPosition, Variant data)
{
// Check position if it is relevant to you
// Otherwise, just check data
return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("expected");
return data.VariantType == Variant.Type.Dictionary &amp;&amp; data.AsGodotDictionary().Contains("expected");
}
[/csharp]
[/codeblocks]
@ -57,17 +57,19 @@
[gdscript]
func _can_drop_data(position, data):
return typeof(data) == TYPE_DICTIONARY and data.has("color")
func _drop_data(position, data):
var color = data["color"]
[/gdscript]
[csharp]
public override bool CanDropData(Vector2 position, object data)
public override bool _CanDropData(Vector2 atPosition, Variant data)
{
return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("color");
return data.VariantType == Variant.Type.Dictionary &amp;&amp; dict.AsGodotDictionary().Contains("color");
}
public override void DropData(Vector2 position, object data)
public override void _DropData(Vector2 atPosition, Variant data)
{
Color color = (Color)(data as Godot.Collections.Dictionary)["color"];
Color color = data.AsGodotDictionary()["color"].AsColor();
}
[/csharp]
[/codeblocks]
@ -87,11 +89,11 @@
return mydata
[/gdscript]
[csharp]
public override object GetDragData(Vector2 position)
public override Variant _GetDragData(Vector2 atPosition)
{
object mydata = MakeData(); // This is your custom method generating the drag data.
SetDragPreview(MakePreview(mydata)); // This is your custom method generating the preview of the drag data.
return mydata;
var myData = MakeData(); // This is your custom method generating the drag data.
SetDragPreview(MakePreview(myData)); // This is your custom method generating the preview of the drag data.
return myData;
}
[/csharp]
[/codeblocks]
@ -121,10 +123,9 @@
[csharp]
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventMouseButton)
if (@event is InputEventMouseButton mb)
{
var mb = @event as InputEventMouseButton;
if (mb.ButtonIndex == (int)ButtonList.Left &amp;&amp; mb.Pressed)
if (mb.ButtonIndex == MouseButton.Left &amp;&amp; mb.Pressed)
{
GD.Print("I've been clicked D:");
}
@ -168,7 +169,7 @@
return label
[/gdscript]
[csharp]
public override Godot.Control _MakeCustomTooltip(String forText)
public override Control _MakeCustomTooltip(string forText)
{
var label = new Label();
label.Text = forText;
@ -185,7 +186,7 @@
return tooltip
[/gdscript]
[csharp]
public override Godot.Control _MakeCustomTooltip(String forText)
public override Control _MakeCustomTooltip(string forText)
{
Node tooltip = ResourceLoader.Load&lt;PackedScene&gt;("res://some_tooltip_scene.tscn").Instantiate();
tooltip.GetNode&lt;Label&gt;("Label").Text = forText;
@ -229,11 +230,11 @@
[/gdscript]
[csharp]
// Given the child Label node "MyLabel", override its font color with a custom value.
GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0))
GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0));
// Reset the font color of the child label.
GetNode&lt;Label&gt;("MyLabel").RemoveThemeColorOverride("font_color")
GetNode&lt;Label&gt;("MyLabel").RemoveThemeColorOverride("font_color");
// Alternatively it can be overridden with the default value from the Label type.
GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", GetThemeColor("font_color", "Label"))
GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", GetThemeColor("font_color", "Label"));
[/csharp]
[/codeblocks]
</description>
@ -542,12 +543,12 @@
[codeblocks]
[gdscript]
func _process(delta):
grab_click_focus() #when clicking another Control node, this node will be clicked instead
grab_click_focus() # When clicking another Control node, this node will be clicked instead.
[/gdscript]
[csharp]
public override void _Process(float delta)
public override void _Process(double delta)
{
GrabClickFocus(); //when clicking another Control node, this node will be clicked instead
GrabClickFocus(); // When clicking another Control node, this node will be clicked instead.
}
[/csharp]
[/codeblocks]
@ -812,16 +813,16 @@
[/gdscript]
[csharp]
[Export]
public Color Color = new Color(1, 0, 0, 1);
private Color _color = new Color(1, 0, 0, 1);
public override object GetDragData(Vector2 position)
public override Variant _GetDragData(Vector2 atPosition)
{
// Use a control that is not in the tree
var cpb = new ColorPickerButton();
cpb.Color = Color;
cpb.RectSize = new Vector2(50, 50);
cpb.Color = _color;
cpb.Size = new Vector2(50, 50);
SetDragPreview(cpb);
return Color;
return _color;
}
[/csharp]
[/codeblocks]

View file

@ -9,9 +9,11 @@
[codeblocks]
[gdscript]
extends Node
var crypto = Crypto.new()
var key = CryptoKey.new()
var cert = X509Certificate.new()
func _ready():
# Generate new RSA key.
key = crypto.generate_rsa(4096)
@ -35,35 +37,35 @@
[/gdscript]
[csharp]
using Godot;
using System;
using System.Diagnostics;
public class CryptoNode : Node
public partial class MyNode : Node
{
public Crypto Crypto = new Crypto();
public CryptoKey Key = new CryptoKey();
public X509Certificate Cert = new X509Certificate();
private Crypto _crypto = new Crypto();
private CryptoKey _key = new CryptoKey();
private X509Certificate _cert = new X509Certificate();
public override void _Ready()
{
// Generate new RSA key.
Key = Crypto.GenerateRsa(4096);
_key = _crypto.GenerateRsa(4096);
// Generate new self-signed certificate with the given key.
Cert = Crypto.GenerateSelfSignedCertificate(Key, "CN=mydomain.com,O=My Game Company,C=IT");
_cert = _crypto.GenerateSelfSignedCertificate(_key, "CN=mydomain.com,O=My Game Company,C=IT");
// Save key and certificate in the user folder.
Key.Save("user://generated.key");
Cert.Save("user://generated.crt");
_key.Save("user://generated.key");
_cert.Save("user://generated.crt");
// Encryption
string data = "Some data";
byte[] encrypted = Crypto.Encrypt(Key, data.ToUTF8());
byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8());
// Decryption
byte[] decrypted = Crypto.Decrypt(Key, encrypted);
byte[] decrypted = _crypto.Decrypt(_key, encrypted);
// Signing
byte[] signature = Crypto.Sign(HashingContext.HashType.Sha256, Data.SHA256Buffer(), Key);
byte[] signature = _crypto.Sign(HashingContext.HashType.Sha256, Data.Sha256Buffer(), _key);
// Verifying
bool verified = Crypto.Verify(HashingContext.HashType.Sha256, Data.SHA256Buffer(), signature, Key);
bool verified = _crypto.Verify(HashingContext.HashType.Sha256, Data.Sha256Buffer(), signature, _key);
// Checks
Debug.Assert(verified);
Debug.Assert(data.ToUTF8() == decrypted);
Debug.Assert(data.ToUtf8() == decrypted);
}
}
[/csharp]

View file

@ -38,45 +38,46 @@
p.put_packet("Hello DTLS client".to_utf8())
[/gdscript]
[csharp]
using Godot;
using System;
// ServerNode.cs
public class ServerNode : Node
using Godot;
public partial class ServerNode : Node
{
public DTLSServer Dtls = new DTLSServer();
public UDPServer Server = new UDPServer();
public Godot.Collections.Array&lt;PacketPeerDTLS&gt; Peers = new Godot.Collections.Array&lt;PacketPeerDTLS&gt;();
private DtlsServer _dtls = new DtlsServer();
private UdpServer _server = new UdpServer();
private Godot.Collections.Array&lt;PacketPeerDTLS&gt; _peers = new Godot.Collections.Array&lt;PacketPeerDTLS&gt;();
public override void _Ready()
{
Server.Listen(4242);
_server.Listen(4242);
var key = GD.Load&lt;CryptoKey&gt;("key.key"); // Your private key.
var cert = GD.Load&lt;X509Certificate&gt;("cert.crt"); // Your X509 certificate.
Dtls.Setup(key, cert);
_dtls.Setup(key, cert);
}
public override void _Process(float delta)
public override void _Process(double delta)
{
while (Server.IsConnectionAvailable())
{
PacketPeerUDP peer = Server.TakeConnection();
PacketPeerDTLS dtlsPeer = Dtls.TakeConnection(peer);
if (dtlsPeer.GetStatus() != PacketPeerDTLS.Status.Handshaking)
PacketPeerUDP peer = _server.TakeConnection();
PacketPeerDTLS dtlsPeer = _dtls.TakeConnection(peer);
if (dtlsPeer.GetStatus() != PacketPeerDtls.Status.Handshaking)
{
continue; // It is normal that 50% of the connections fails due to cookie exchange.
}
GD.Print("Peer connected!");
Peers.Add(dtlsPeer);
_peers.Add(dtlsPeer);
}
foreach (var p in Peers)
foreach (var p in _peers)
{
p.Poll(); // Must poll to update the state.
if (p.GetStatus() == PacketPeerDTLS.Status.Connected)
if (p.GetStatus() == PacketPeerDtls.Status.Connected)
{
while (p.GetAvailablePacketCount() &gt; 0)
{
GD.Print("Received Message From Client: " + p.GetPacket().GetStringFromUTF8());
p.PutPacket("Hello Dtls Client".ToUTF8());
GD.Print($"Received Message From Client: {p.GetPacket().GetStringFromUtf8()}");
p.PutPacket("Hello DTLS Client".ToUtf8());
}
}
}
@ -108,34 +109,36 @@
connected = true
[/gdscript]
[csharp]
// ClientNode.cs
using Godot;
using System.Text;
// ClientNode.cs
public class ClientNode : Node
public partial class ClientNode : Node
{
public PacketPeerDTLS Dtls = new PacketPeerDTLS();
public PacketPeerUDP Udp = new PacketPeerUDP();
public bool Connected = false;
private PacketPeerDtls _dtls = new PacketPeerDtls();
private PacketPeerUdp _udp = new PacketPeerUdp();
private bool _connected = false;
public override void _Ready()
{
Udp.ConnectToHost("127.0.0.1", 4242);
Dtls.ConnectToPeer(Udp, false); // Use true in production for certificate validation!
_udp.ConnectToHost("127.0.0.1", 4242);
_dtls.ConnectToPeer(_udp, validateCerts: false); // Use true in production for certificate validation!
}
public override void _Process(float delta)
public override void _Process(double delta)
{
Dtls.Poll();
if (Dtls.GetStatus() == PacketPeerDTLS.Status.Connected)
_dtls.Poll();
if (_dtls.GetStatus() == PacketPeerDtls.Status.Connected)
{
if (!Connected)
if (!_connected)
{
// Try to contact server
Dtls.PutPacket("The Answer Is..42!".ToUTF8());
_dtls.PutPacket("The Answer Is..42!".ToUtf8());
}
while (Dtls.GetAvailablePacketCount() &gt; 0)
while (_dtls.GetAvailablePacketCount() &gt; 0)
{
GD.Print("Connected: " + Dtls.GetPacket().GetStringFromUTF8());
Connected = true;
GD.Print($"Connected: {_dtls.GetPacket().GetStringFromUtf8()}");
_connected = true;
}
}
}

View file

@ -51,7 +51,7 @@
[csharp]
[Export(PropertyHint.Enum, "White,Yellow,Orange")]
public string MyColor { get; set; }
public Godot.Collections.Dictionary pointsDict = new Godot.Collections.Dictionary
private Godot.Collections.Dictionary _pointsDict = new Godot.Collections.Dictionary
{
{"White", 50},
{"Yellow", 75},
@ -60,7 +60,7 @@
public override void _Ready()
{
int points = (int)pointsDict[MyColor];
int points = (int)_pointsDict[MyColor];
}
[/csharp]
[/codeblocks]

View file

@ -44,11 +44,11 @@
{
if (dir.CurrentIsDir())
{
GD.Print("Found directory: " + fileName);
GD.Print($"Found directory: {fileName}");
}
else
{
GD.Print("Found file: " + fileName);
GD.Print($"Found file: {fileName}");
}
fileName = dir.GetNext();
}

View file

@ -48,61 +48,67 @@
[/gdscript]
[csharp]
using Godot;
using System;
public class MySpecialPlugin : EditorImportPlugin
public partial class MySpecialPlugin : EditorImportPlugin
{
public override String GetImporterName()
public override string _GetImporterName()
{
return "my.special.plugin";
}
public override String GetVisibleName()
public override string _GetVisibleName()
{
return "Special Mesh";
}
public override Godot.Collections.Array GetRecognizedExtensions()
public override string[] _GetRecognizedExtensions()
{
return new Godot.Collections.Array{"special", "spec"};
return new string[] { "special", "spec" };
}
public override String GetSaveExtension()
public override string _GetSaveExtension()
{
return "mesh";
}
public override String GetResourceType()
public override string _GetResourceType()
{
return "Mesh";
}
public override int GetPresetCount()
public override int _GetPresetCount()
{
return 1;
}
public override String GetPresetName(int i)
public override string _GetPresetName(int presetIndex)
{
return "Default";
}
public override Godot.Collections.Array GetImportOptions(int i)
public override Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt; _GetImportOptions(string path, int presetIndex)
{
return new Godot.Collections.Array{new Godot.Collections.Dictionary{{"name", "myOption"}, {"defaultValue", false}}};
return new Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt;
{
new Godot.Collections.Dictionary
{
{ "name", "myOption" },
{ "defaultValue", false },
}
};
}
public override int Import(String sourceFile, String savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles)
public override int _Import(string sourceFile, string savePath, Godot.Collections.Dictionary options, Godot.Collections.Array&lt;string&gt; platformVariants, Godot.Collections.Array&lt;string&gt; genFiles)
{
var file = new File();
if (file.Open(sourceFile, File.ModeFlags.Read) != Error.Ok)
using var file = FileAccess.Open(sourceFile, FileAccess.ModeFlags.Read);
if (file.GetError() != Error.Ok)
{
return (int)Error.Failed;
}
var mesh = new ArrayMesh();
// Fill the Mesh with data read in "file", left as an exercise to the reader.
String filename = savePath + "." + GetSaveExtension();
string filename = $"{savePath}.{_GetSaveExtension()}";
return (int)ResourceSaver.Save(mesh, filename);
}
}

View file

@ -69,21 +69,22 @@
return EditorPlugin.AFTER_GUI_INPUT_PASS
[/gdscript]
[csharp]
public override void _Forward3dDrawOverViewport(Godot.Control overlay)
public override void _Forward3DDrawOverViewport(Control viewportControl)
{
// Draw a circle at cursor position.
overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
viewportControl.DrawCircle(viewportControl.GetLocalMousePosition(), 64, Colors.White);
}
public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Godot.Camera3D camera, InputEvent @event)
public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D viewportCamera, InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
// Redraw viewport when cursor is moved.
UpdateOverlays();
return EditorPlugin.AFTER_GUI_INPUT_STOP;
return EditorPlugin.AfterGuiInput.Stop;
}
return EditorPlugin.AFTER_GUI_INPUT_PASS;
return EditorPlugin.AfterGuiInput.Pass;
}
[/csharp]
[/codeblocks]
</description>
@ -111,9 +112,9 @@
[/gdscript]
[csharp]
// Prevents the InputEvent from reaching other Editor classes.
public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Camera3D camera, InputEvent @event)
public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D camera, InputEvent @event)
{
return EditorPlugin.AFTER_GUI_INPUT_STOP;
return EditorPlugin.AfterGuiInput.Stop;
}
[/csharp]
[/codeblocks]
@ -127,9 +128,9 @@
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Camera3D camera, InputEvent @event)
public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D camera, InputEvent @event)
{
return @event is InputEventMouseMotion ? EditorPlugin.AFTER_GUI_INPUT_STOP : EditorPlugin.AFTER_GUI_INPUT_PASS;
return @event is InputEventMouseMotion ? EditorPlugin.AfterGuiInput.Stop : EditorPlugin.AfterGuiInput.Pass;
}
[/csharp]
[/codeblocks]
@ -154,13 +155,13 @@
return false
[/gdscript]
[csharp]
public override void ForwardCanvasDrawOverViewport(Godot.Control overlay)
public override void _ForwardCanvasDrawOverViewport(Control viewportControl)
{
// Draw a circle at cursor position.
overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
viewportControl.DrawCircle(viewportControl.GetLocalMousePosition(), 64, Colors.White);
}
public override bool ForwardCanvasGuiInput(InputEvent @event)
public override bool _ForwardCanvasGuiInput(InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
@ -169,6 +170,7 @@
return true;
}
return false;
}
[/csharp]
[/codeblocks]
</description>
@ -213,12 +215,13 @@
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
public override bool ForwardCanvasGuiInput(InputEvent @event)
public override bool _ForwardCanvasGuiInput(InputEvent @event)
{
if (@event is InputEventMouseMotion) {
if (@event is InputEventMouseMotion)
{
return true;
}
return false
return false;
}
[/csharp]
[/codeblocks]
@ -245,7 +248,7 @@
return get_editor_interface().get_base_control().get_theme_icon("Node", "EditorIcons")
[/gdscript]
[csharp]
public override Texture2D GetPluginIcon()
public override Texture2D _GetPluginIcon()
{
// You can use a custom icon:
return ResourceLoader.Load&lt;Texture2D&gt;("res://addons/my_plugin/my_plugin_icon.svg");

View file

@ -10,12 +10,14 @@
[gdscript]
@tool # Needed so it runs in editor.
extends EditorScenePostImport
# This sample changes all node names.
# Called right after the scene is imported and gets the root node.
func _post_import(scene):
# Change all node names to "modified_[oldnodename]"
iterate(scene)
return scene # Remember to return the imported scene
func iterate(node):
if node != null:
node.name = "modified_" + node.name
@ -30,17 +32,18 @@
[Tool]
public partial class NodeRenamer : EditorScenePostImport
{
public override Object _PostImport(Node scene)
public override GodotObject _PostImport(Node scene)
{
// Change all node names to "modified_[oldnodename]"
Iterate(scene);
return scene; // Remember to return the imported scene
}
public void Iterate(Node node)
{
if (node != null)
{
node.Name = "modified_" + node.Name;
node.Name = $"modified_{node.Name}";
foreach (Node child in node.GetChildren())
{
Iterate(child);

View file

@ -17,10 +17,9 @@
[/gdscript]
[csharp]
using Godot;
using System;
[Tool]
public class HelloEditor : EditorScript
public partial class HelloEditor : EditorScript
{
public override void _Run()
{

View file

@ -22,7 +22,7 @@
settings.SetSetting("some/property", Value);
// `settings.get("some/property", value)` also works as this class overrides `_get()` internally.
settings.GetSetting("some/property");
Godot.Collections.Array listOfSettings = settings.GetPropertyList();
Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt; listOfSettings = settings.GetPropertyList();
[/csharp]
[/codeblocks]
[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings].

View file

@ -27,27 +27,25 @@
[/gdscript]
[csharp]
using Godot;
using System;
[Tool]
public class CustomParser : EditorTranslationParserPlugin
public partial class CustomParser : EditorTranslationParserPlugin
{
public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural)
public override void _ParseFile(string path, Godot.Collections.Array&lt;string&gt; msgids, Godot.Collections.Array&lt;Godot.Collections.Array&gt; msgidsContextPlural)
{
var file = new File();
file.Open(path, File.ModeFlags.Read);
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
string text = file.GetAsText();
string[] splitStrs = text.Split(",", false);
foreach (var s in splitStrs)
string[] splitStrs = text.Split(",", allowEmpty: false);
foreach (string s in splitStrs)
{
msgids.Add(s);
//GD.Print("Extracted string: " + s)
//GD.Print($"Extracted string: {s}");
}
}
public override Godot.Collections.Array GetRecognizedExtensions()
public override string[] _GetRecognizedExtensions()
{
return new Godot.Collections.Array{"csv"};
return new string[] { "csv" };
}
}
[/csharp]
@ -84,16 +82,16 @@
return ["gd"]
[/gdscript]
[csharp]
public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural)
public override void _ParseFile(string path, Godot.Collections.Array&lt;string&gt; msgids, Godot.Collections.Array&lt;Godot.Collections.Array&gt; msgidsContextPlural)
{
var res = ResourceLoader.Load&lt;Script&gt;(path, "Script");
string text = res.SourceCode;
// Parsing logic.
}
public override Godot.Collections.Array GetRecognizedExtensions()
public override string[] _GetRecognizedExtensions()
{
return new Godot.Collections.Array{"gd"};
return new string[] { "gd" };
}
[/csharp]
[/codeblocks]

View file

@ -24,7 +24,7 @@
$LineEdit.text = str(result)
[/gdscript]
[csharp]
public Expression expression = new Expression();
private Expression _expression = new Expression();
public override void _Ready()
{
@ -33,14 +33,14 @@
private void OnTextEntered(string command)
{
Error error = expression.Parse(command);
Error error = _expression.Parse(command);
if (error != Error.Ok)
{
GD.Print(expression.GetErrorText());
GD.Print(_expression.GetErrorText());
return;
}
object result = expression.Execute();
if (!expression.HasExecuteFailed())
Variant result = _expression.Execute();
if (!_expression.HasExecuteFailed())
{
GetNode&lt;LineEdit&gt;("LineEdit").Text = result.ToString();
}

View file

@ -348,8 +348,8 @@
f.Seek(0); // Go back to start to read the stored value.
ushort read1 = f.Get16(); // 65494
ushort read2 = f.Get16(); // 121
short converted1 = BitConverter.ToInt16(BitConverter.GetBytes(read1), 0); // -42
short converted2 = BitConverter.ToInt16(BitConverter.GetBytes(read2), 0); // 121
short converted1 = (short)read1; // -42
short converted2 = (short)read2; // 121
}
[/csharp]
[/codeblocks]

View file

@ -160,14 +160,13 @@
var polygon = PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, 100), Vector2(0, 100)])
var offset = Vector2(50, 50)
polygon = Transform2D(0, offset) * polygon
print(polygon) # prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)]
print(polygon) # prints [(50, 50), (150, 50), (150, 150), (50, 150)]
[/gdscript]
[csharp]
var polygon = new Vector2[] { new Vector2(0, 0), new Vector2(100, 0), new Vector2(100, 100), new Vector2(0, 100) };
var offset = new Vector2(50, 50);
// TODO: This code is not valid right now. Ping @aaronfranke about it before Godot 4.0 is out.
//polygon = (Vector2[]) new Transform2D(0, offset).Xform(polygon);
//GD.Print(polygon); // prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)]
polygon = new Transform2D(0, offset) * polygon;
GD.Print((Variant)polygon); // prints [(50, 50), (150, 50), (150, 150), (50, 150)]
[/csharp]
[/codeblocks]
</description>

View file

@ -72,8 +72,9 @@
return from != to
[/gdscript]
[csharp]
public override bool _IsNodeHoverValid(String from, int fromSlot, String to, int toSlot) {
return from != to;
public override bool _IsNodeHoverValid(StringName fromNode, int fromPort, StringName toNode, int toPort)
{
return fromNode != toNode;
}
[/csharp]
[/codeblocks]

View file

@ -26,25 +26,24 @@
[/gdscript]
[csharp]
using Godot;
using System;
using System.Diagnostics;
public class CryptoNode : Node
public partial class MyNode : Node
{
private HMACContext ctx = new HMACContext();
private HmacContext _ctx = new HmacContext();
public override void _Ready()
{
byte[] key = "supersecret".ToUTF8();
Error err = ctx.Start(HashingContext.HashType.Sha256, key);
byte[] key = "supersecret".ToUtf8();
Error err = _ctx.Start(HashingContext.HashType.Sha256, key);
Debug.Assert(err == Error.Ok);
byte[] msg1 = "this is ".ToUTF8();
byte[] msg2 = "super duper secret".ToUTF8();
err = ctx.Update(msg1);
byte[] msg1 = "this is ".ToUtf8();
byte[] msg2 = "super duper secret".ToUtf8();
err = _ctx.Update(msg1);
Debug.Assert(err == Error.Ok);
err = ctx.Update(msg2);
err = _ctx.Update(msg2);
Debug.Assert(err == Error.Ok);
byte[] hmac = ctx.Finish();
byte[] hmac = _ctx.Finish();
GD.Print(hmac.HexEncode());
}
}

View file

@ -105,7 +105,7 @@
[/gdscript]
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
string queryString = new HTTPClient().QueryStringFromDict(fields);
string queryString = httpClient.QueryStringFromDict(fields);
// Returns "username=user&amp;password=pass"
[/csharp]
[/codeblocks]
@ -117,8 +117,13 @@
# Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/gdscript]
[csharp]
var fields = new Godot.Collections.Dictionary{{"single", 123}, {"notValued", null}, {"multiple", new Godot.Collections.Array{22, 33, 44}}};
string queryString = new HTTPClient().QueryStringFromDict(fields);
var fields = new Godot.Collections.Dictionary
{
{ "single", 123 },
{ "notValued", default },
{ "multiple", new Godot.Collections.Array { 22, 33, 44 } },
};
string queryString = httpClient.QueryStringFromDict(fields);
// Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/csharp]
[/codeblocks]
@ -151,7 +156,7 @@
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
string queryString = new HTTPClient().QueryStringFromDict(fields);
string[] headers = {"Content-Type: application/x-www-form-urlencoded", "Content-Length: " + queryString.Length};
string[] headers = { "Content-Type: application/x-www-form-urlencoded", $"Content-Length: {queryString.Length}" };
var result = new HTTPClient().Request(HTTPClient.Method.Post, "index.php", headers, queryString);
[/csharp]
[/codeblocks]

View file

@ -57,7 +57,7 @@
// Perform a POST request. The URL below returns JSON as of writing.
// Note: Don't make simultaneous requests using a single HTTPRequest node.
// The snippet below is provided for reference only.
string body = new JSON().Stringify(new Godot.Collections.Dictionary
string body = new Json().Stringify(new Godot.Collections.Dictionary
{
{ "name", "Godette" }
});
@ -69,14 +69,14 @@
}
// Called when the HTTP request is completed.
private void HttpRequestCompleted(int result, int responseCode, string[] headers, byte[] body)
private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
var json = new JSON();
json.Parse(body.GetStringFromUTF8());
var response = json.GetData() as Godot.Collections.Dictionary;
var json = new Json();
json.Parse(body.GetStringFromUtf8());
var response = json.GetData().AsGodotDictionary();
// Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
GD.Print((response["headers"] as Godot.Collections.Dictionary)["User-Agent"]);
GD.Print((response["headers"].AsGodotDictionary())["User-Agent"]);
}
[/csharp]
[/codeblocks]
@ -128,9 +128,9 @@
}
// Called when the HTTP request is completed.
private void HttpRequestCompleted(int result, int responseCode, string[] headers, byte[] body)
private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
if (result != (int)HTTPRequest.Result.Success)
if (result != (long)HTTPRequest.Result.Success)
{
GD.PushError("Image couldn't be downloaded. Try a different image.");
}

View file

@ -8,7 +8,7 @@
The [enum HashType] enum shows the supported hashing algorithms.
[codeblocks]
[gdscript]
const CHUNK_SIZE = 102
const CHUNK_SIZE = 1024
func hash_file(path):
# Check that file exists.
@ -32,17 +32,16 @@
public void HashFile(string path)
{
var ctx = new HashingContext();
var file = new File();
// Start a SHA-256 context.
ctx.Start(HashingContext.HashType.Sha256);
// Check that file exists.
if (!file.FileExists(path))
if (!FileAccess.FileExists(path))
{
return;
}
// Start a SHA-256 context.
var ctx = new HashingContext();
ctx.Start(HashingContext.HashType.Sha256);
// Open the file to hash.
file.Open(path, File.ModeFlags.Read);
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
// Update the context after reading each chunk.
while (!file.EofReached())
{
@ -51,8 +50,7 @@
// Get the computed hash.
byte[] res = ctx.Finish();
// Print the result as hex string and array.
GD.PrintT(res.HexEncode(), res);
GD.PrintT(res.HexEncode(), (Variant)res);
}
[/csharp]
[/codeblocks]

View file

@ -35,9 +35,9 @@
GD.Print(OS.GetConnectedMidiInputs());
}
public override void _Input(InputEvent inputEvent)
public override void _Input(InputEvent @event)
{
if (inputEvent is InputEventMIDI midiEvent)
if (@event is InputEventMIDI midiEvent)
{
PrintMIDIInfo(midiEvent);
}
@ -46,14 +46,14 @@
private void PrintMIDIInfo(InputEventMIDI midiEvent)
{
GD.Print(midiEvent);
GD.Print("Channel " + midiEvent.Channel);
GD.Print("Message " + midiEvent.Message);
GD.Print("Pitch " + midiEvent.Pitch);
GD.Print("Velocity " + midiEvent.Velocity);
GD.Print("Instrument " + midiEvent.Instrument);
GD.Print("Pressure " + midiEvent.Pressure);
GD.Print("Controller number: " + midiEvent.ControllerNumber);
GD.Print("Controller value: " + midiEvent.ControllerValue);
GD.Print($"Channel {midiEvent.Channel}");
GD.Print($"Message {midiEvent.Message}");
GD.Print($"Pitch {midiEvent.Pitch}");
GD.Print($"Velocity {midiEvent.Velocity}");
GD.Print($"Instrument {midiEvent.Instrument}");
GD.Print($"Pressure {midiEvent.Pressure}");
GD.Print($"Controller number: {midiEvent.ControllerNumber}");
GD.Print($"Controller value: {midiEvent.ControllerValue}");
}
[/csharp]
[/codeblocks]

View file

@ -29,29 +29,28 @@
[/gdscript]
[csharp]
using Godot;
using System;
public class CustomMainLoop : MainLoop
public partial class CustomMainLoop : MainLoop
{
public float TimeElapsed = 0;
private double _timeElapsed = 0;
public override void _Initialize()
{
GD.Print("Initialized:");
GD.Print($" Starting Time: {TimeElapsed}");
GD.Print($" Starting Time: {_timeElapsed}");
}
public override bool _Process(float delta)
public override bool _Process(double delta)
{
TimeElapsed += delta;
_timeElapsed += delta;
// Return true to end the main loop.
return Input.GetMouseButtonMask() != 0 || Input.IsKeyPressed((int)KeyList.Escape);
return Input.GetMouseButtonMask() != 0 || Input.IsKeyPressed(Key.Escape);
}
private void _Finalize()
{
GD.Print("Finalized:");
GD.Print($" End Time: {TimeElapsed}");
GD.Print($" End Time: {_timeElapsed}");
}
}
[/csharp]

View file

@ -110,7 +110,7 @@
[/gdscript]
[csharp]
[Tool]
public class MyNode2D : Node2D
public partial class MyNode2D : Node2D
{
private bool _holdingHammer;
@ -433,9 +433,9 @@
var button = new Button();
// Option 1: In C#, we can use signals as events and connect with this idiomatic syntax:
button.ButtonDown += OnButtonDown;
// Option 2: Object.Connect() with a constructed Callable from a method group.
// Option 2: GodotObject.Connect() with a constructed Callable from a method group.
button.Connect(Button.SignalName.ButtonDown, Callable.From(OnButtonDown));
// Option 3: Object.Connect() with a constructed Callable using a target object and method name.
// Option 3: GodotObject.Connect() with a constructed Callable using a target object and method name.
button.Connect(Button.SignalName.ButtonDown, new Callable(this, MethodName.OnButtonDown));
}
@ -700,10 +700,10 @@
sprite2d.is_class("Node3D") # Returns false
[/gdscript]
[csharp]
var sprite2d = new Sprite2D();
sprite2d.IsClass("Sprite2D"); // Returns true
sprite2d.IsClass("Node"); // Returns true
sprite2d.IsClass("Node3D"); // Returns false
var sprite2D = new Sprite2D();
sprite2D.IsClass("Sprite2D"); // Returns true
sprite2D.IsClass("Node"); // Returns true
sprite2D.IsClass("Node3D"); // Returns false
[/csharp]
[/codeblocks]
[b]Note:[/b] This method ignores [code]class_name[/code] declarations in the object's script.
@ -747,10 +747,10 @@
player.SetScript(GD.Load("res://player.gd"));
player.Notification(NotificationEnterTree);
// The call order is Object -&gt; Node -&gt; Node2D -&gt; player.gd.
// The call order is GodotObject -&gt; Node -&gt; Node2D -&gt; player.gd.
player.notification(NotificationEnterTree, true);
// The call order is player.gd -&gt; Node2D -&gt; Node -&gt; Object.
player.Notification(NotificationEnterTree, true);
// The call order is player.gd -&gt; Node2D -&gt; Node -&gt; GodotObject.
[/csharp]
[/codeblocks]
</description>

View file

@ -1743,7 +1743,7 @@
[/gdscript]
[csharp]
// Set the default gravity strength to 980.
PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.Gravity, 980);
PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2D().Space, PhysicsServer2D.AreaParameter.Gravity, 980);
[/csharp]
[/codeblocks]
</member>
@ -1757,7 +1757,7 @@
[/gdscript]
[csharp]
// Set the default gravity direction to `Vector2(0, 1)`.
PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.GravityVector, Vector2.Down)
PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2D().Space, PhysicsServer2D.AreaParameter.GravityVector, Vector2.Down)
[/csharp]
[/codeblocks]
</member>

View file

@ -13,7 +13,7 @@
[/gdscript]
[csharp]
// The RichTextEffect will be usable like this: `[example]Some text[/example]`
public string bbcode = "example";
string bbcode = "example";
[/csharp]
[/codeblocks]
[b]Note:[/b] As soon as a [RichTextLabel] contains at least one [RichTextEffect], it will continuously process the effect unless the project is paused. This may impact battery life negatively.

View file

@ -74,10 +74,10 @@
print("end")
[/gdscript]
[csharp]
public async void SomeFunction()
public async Task SomeFunction()
{
GD.Print("start");
await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
await ToSignal(GetTree().CreateTimer(1.0f), SceneTreeTimer.SignalName.Timeout);
GD.Print("end");
}
[/csharp]

View file

@ -14,10 +14,10 @@
print("Timer ended.")
[/gdscript]
[csharp]
public async void SomeFunction()
public async Task SomeFunction()
{
GD.Print("Timer started.");
await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
await ToSignal(GetTree().CreateTimer(1.0f), SceneTreeTimer.SignalName.Timeout);
GD.Print("Timer ended.");
}
[/csharp]

View file

@ -23,11 +23,11 @@
print("A click!")
[/gdscript]
[csharp]
public override void _Input(InputEvent inputEvent)
public override void _Input(InputEvent @event)
{
if (inputEvent is InputEventMouseButton inputEventMouse)
if (@event is InputEventMouseButton inputEventMouse)
{
if (inputEventMouse.Pressed &amp;&amp; inputEventMouse.ButtonIndex == (int)ButtonList.Left)
if (inputEventMouse.Pressed &amp;&amp; inputEventMouse.ButtonIndex == MouseButton.Left)
{
if (GetRect().HasPoint(ToLocal(inputEventMouse.Position)))
{

View file

@ -223,7 +223,7 @@
put_data("Hello world".to_utf8())
[/gdscript]
[csharp]
PutData("Hello World".ToUTF8());
PutData("Hello World".ToUtf8());
[/csharp]
[/codeblocks]
</description>

View file

@ -77,13 +77,13 @@
tween = create_tween()
[/gdscript]
[csharp]
private Tween tween;
private Tween _tween;
public void Animate()
{
if (tween != null)
tween.Kill(); // Abort the previous animation
tween = CreateTween();
if (_tween != null)
_tween.Kill(); // Abort the previous animation
_tween = CreateTween();
}
[/csharp]
[/codeblocks]

View file

@ -9,7 +9,8 @@
Below a small example of how it can be used:
[codeblocks]
[gdscript]
class_name Server
# server_node.gd
class_name ServerNode
extends Node
var server := UDPServer.new()
@ -34,35 +35,35 @@
pass # Do something with the connected peers.
[/gdscript]
[csharp]
// ServerNode.cs
using Godot;
using System;
using System.Collections.Generic;
public class Server : Node
public partial class ServerNode : Node
{
public UDPServer Server = new UDPServer();
public List&lt;PacketPeerUDP&gt; Peers = new List&lt;PacketPeerUDP&gt;();
private UdpServer _server = new UdpServer();
private List&lt;PacketPeerUdp&gt; _peers = new List&lt;PacketPeerUdp&gt;();
public override void _Ready()
{
Server.Listen(4242);
_server.Listen(4242);
}
public override void _Process(float delta)
public override void _Process(double delta)
{
Server.Poll(); // Important!
if (Server.IsConnectionAvailable())
_server.Poll(); // Important!
if (_server.IsConnectionAvailable())
{
PacketPeerUDP peer = Server.TakeConnection();
PacketPeerUdp peer = _server.TakeConnection();
byte[] packet = peer.GetPacket();
GD.Print($"Accepted Peer: {peer.GetPacketIp()}:{peer.GetPacketPort()}");
GD.Print($"Received Data: {packet.GetStringFromUTF8()}");
GD.Print($"Accepted Peer: {peer.GetPacketIP()}:{peer.GetPacketPort()}");
GD.Print($"Received Data: {packet.GetStringFromUtf8()}");
// Reply so it knows we received the message.
peer.PutPacket(packet);
// Keep a reference so we can keep contacting the remote peer.
Peers.Add(peer);
_peers.Add(peer);
}
foreach (var peer in Peers)
foreach (var peer in _peers)
{
// Do something with the peers.
}
@ -72,7 +73,8 @@
[/codeblocks]
[codeblocks]
[gdscript]
class_name Client
# client_node.gd
class_name ClientNode
extends Node
var udp := PacketPeerUDP.new()
@ -90,30 +92,30 @@
connected = true
[/gdscript]
[csharp]
// ClientNode.cs
using Godot;
using System;
public class Client : Node
public partial class ClientNode : Node
{
public PacketPeerUDP Udp = new PacketPeerUDP();
public bool Connected = false;
private PacketPeerUdp _udp = new PacketPeerUdp();
private bool _connected = false;
public override void _Ready()
{
Udp.ConnectToHost("127.0.0.1", 4242);
_udp.ConnectToHost("127.0.0.1", 4242);
}
public override void _Process(float delta)
public override void _Process(double delta)
{
if (!Connected)
if (!_connected)
{
// Try to contact server
Udp.PutPacket("The Answer Is..42!".ToUTF8());
_udp.PutPacket("The Answer Is..42!".ToUtf8());
}
if (Udp.GetAvailablePacketCount() &gt; 0)
if (_udp.GetAvailablePacketCount() &gt; 0)
{
GD.Print($"Connected: {Udp.GetPacket().GetStringFromUTF8()}");
Connected = true;
GD.Print($"Connected: {_udp.GetPacket().GetStringFromUtf8()}");
_connected = true;
}
}
}

View file

@ -27,11 +27,11 @@
undo_redo.commit_action()
[/gdscript]
[csharp]
public UndoRedo UndoRedo;
private UndoRedo _undoRedo;
public override void _Ready()
{
UndoRedo = GetUndoRedo(); // Method of EditorPlugin.
_undoRedo = GetUndoRedo(); // Method of EditorPlugin.
}
public void DoSomething()
@ -47,12 +47,12 @@
private void OnMyButtonPressed()
{
var node = GetNode&lt;Node2D&gt;("MyNode2D");
UndoRedo.CreateAction("Move the node");
UndoRedo.AddDoMethod(this, MethodName.DoSomething);
UndoRedo.AddUndoMethod(this, MethodName.UndoSomething);
UndoRedo.AddDoProperty(node, Node2D.PropertyName.Position, new Vector2(100, 100));
UndoRedo.AddUndoProperty(node, Node2D.PropertyName.Position, node.Position);
UndoRedo.CommitAction();
_undoRedo.CreateAction("Move the node");
_undoRedo.AddDoMethod(new Callable(this, MethodName.DoSomething));
_undoRedo.AddUndoMethod(new Callable(this, MethodName.UndoSomething));
_undoRedo.AddDoProperty(node, "position", new Vector2(100, 100));
_undoRedo.AddUndoProperty(node, "position", node.Position);
_undoRedo.CommitAction();
}
[/csharp]
[/codeblocks]

View file

@ -7,7 +7,7 @@ namespace Godot
/// <summary>
/// Instantiates the scene's node hierarchy, erroring on failure.
/// Triggers child scene instantiation(s). Triggers a
/// <see cref="Node.NotificationInstanced"/> notification on the root node.
/// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node.
/// </summary>
/// <seealso cref="InstantiateOrNull{T}(GenEditState)"/>
/// <exception cref="InvalidCastException">
@ -23,7 +23,7 @@ namespace Godot
/// <summary>
/// Instantiates the scene's node hierarchy, returning <see langword="null"/> on failure.
/// Triggers child scene instantiation(s). Triggers a
/// <see cref="Node.NotificationInstanced"/> notification on the root node.
/// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node.
/// </summary>
/// <seealso cref="Instantiate{T}(GenEditState)"/>
/// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>