Skip to content

Instantly share code, notes, and snippets.

@xxdocobxx
Last active May 16, 2025 02:20
Show Gist options
  • Save xxdocobxx/b3ce929bc2152a4dce09852df10a605b to your computer and use it in GitHub Desktop.
Save xxdocobxx/b3ce929bc2152a4dce09852df10a605b to your computer and use it in GitHub Desktop.
Godot 4 c# cheat sheet

Instancing scene

PackedScene scene = GD.Load<PackedScene>("res://MyScene.tscn");
Node instance = scene.Instantiate();
AddChild(instance);
// or perform a type cast as follows:
Sprite2D sprite = scene.Instantiate<Sprite2D>();
AddChild(sprite);

Wait for 1 frame

await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);

Wait for the first physics frame

public override void _Ready()
{
    // Make sure to not await during _Ready.
    Callable.From(ActorSetup).CallDeferred();
}

private async void ActorSetup()
{
    // Wait for the first physics frame.
    await ToSignal(GetTree(), SceneTree.SignalName.PhysicsFrame);

    // Do your stuff here.
}

Wait for 1 second

  • Bind to SceneTree.
    await ToSignal(GetTree().CreateTimer(1.0), SceneTreeTimer.SignalName.Timeout);
  • Bind to Node (if the node is paused, the timer will also be paused):
    await ToSignal(CreateTween().TweenInterval(1.0), Tween.SignalName.Finished);
  • Bind to Node and run on physics frames
    await ToSignal(
        CreateTween().SetProcessMode(Tween.TweenProcessMode.Physics).TweenInterval(1.0), 
        Tween.SignalName.Finished
    );

Wait for animation finished

await ToSignal(animatedSprite, AnimatedSprite2D.SignalName.AnimationFinished);

Custom resource

Using Godot;

[GlobalClass]
public partial class CustomData : Resource
{
    [Export] public int ID;
}

Pause a node

ProcessMode = ProcessModeEnum.Disabled;

To re-enable the disabled node:

ProcessMode = ProcessModeEnum.Inherit;

Callable

Callable.From(DoSomething);

private void DoSomething()
{
}

Callable with arguments

Callable.From<int>(DoSomething);

private void DoSomething(int value)
{
}

Connect to engine signal

GetNode<Timer>("Timer").Timeout += OnTimerTimeout;

Custom signal

According to https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_signals.html#signals-as-c-events , you will need to manually disconnect (using -=) all the custom signals you connected as C# events (using +=). So, it is safer to use Connect instead, which will disconnect automatically when nodes are freed.

// NodeA.cs
[Signal] public delegate void MySignalEventHandler();
[Signal] public delegate void MySignalWithArgumentEventHandler(string myString);

public void MyMethodEmittingSignals()
{
    EmitSignal(SignalName.MySignal);
    EmitSignal(SignalName.MySignalWithArgument, "World");
}

public void ConnectMySignal(Action action)
{
    Connect(SignalName.MySignal, Callable.From(action));
}

public void ConnectMySignalWithArgument(Action<string> action)
{
    Connect(SignalName.MySignalWithArgument, Callable.From<string>(action));
}

// NodeB.cs
public override void _Ready()
{
    NodeA nodeA = GetNode<NodeA>("NodeA");
    nodeA.ConnectMySignal(OnMySignalCallback);
    nodeA.ConnectMySignalWithArgument(OnMySignalWithArgumentCallback);
}

private void OnMySignalCallback()
{
}

private void OnMySignalWithArgumentCallback(string myString)
{
}

Load all files from a folder

string folderName = "res://Resources";
var folder = DirAccess.Open(folderName);
folder.ListDirBegin();
string filename = folder.GetNext();

while(filename != "")
{
    var resource = GD.Load<Resource>(string.Format("{0}/{1}", folderName, filename));
    filename = folder.GetNext();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment