{"id":26022020,"url":"https://github.com/Cat-Lips/GodotSharp.SourceGenerators","last_synced_at":"2025-03-06T09:54:12.076Z","repository":{"id":43061772,"uuid":"329297875","full_name":"Cat-Lips/GodotSharp.SourceGenerators","owner":"Cat-Lips","description":"C# source generators for the Godot Game Engine","archived":false,"fork":false,"pushed_at":"2025-02-11T00:57:39.000Z","size":437,"stargazers_count":147,"open_issues_count":3,"forks_count":15,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-03T14:46:17.705Z","etag":null,"topics":["csharp","csharp-sourcegenerator","godot"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cat-Lips.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-13T12:15:17.000Z","updated_at":"2025-03-02T05:15:10.000Z","dependencies_parsed_at":"2024-04-19T03:25:06.945Z","dependency_job_id":"929917fe-91ac-455a-a9b1-e97a804b1d1d","html_url":"https://github.com/Cat-Lips/GodotSharp.SourceGenerators","commit_stats":{"total_commits":57,"total_committers":1,"mean_commits":57.0,"dds":0.0,"last_synced_commit":"6876ee3595bc25550694c527246ed3bae7801e28"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cat-Lips%2FGodotSharp.SourceGenerators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cat-Lips%2FGodotSharp.SourceGenerators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cat-Lips%2FGodotSharp.SourceGenerators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cat-Lips%2FGodotSharp.SourceGenerators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cat-Lips","download_url":"https://codeload.github.com/Cat-Lips/GodotSharp.SourceGenerators/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242187641,"owners_count":20086217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","csharp-sourcegenerator","godot"],"created_at":"2025-03-06T09:54:10.787Z","updated_at":"2025-03-06T09:54:12.052Z","avatar_url":"https://github.com/Cat-Lips.png","language":"C#","readme":"# GodotSharp.SourceGenerators\n\nC# Source Generators for use with the Godot Game Engine (supports Godot 4 and .NET 9!)\n* `SceneTree` class attribute:\n  * Generates class property for uniquely named nodes\n  * Provides strongly typed access to the scene hierarchy (via `_` operator)\n  * NEW: TscnFilePath for static access to tscn file\n* `GodotOverride` method attribute:\n  * Allows use of On*, instead of virtual _* overrides\n  * (Requires partial method declaration for use with Godot 4)\n* `Notify` property attribute:\n  * Generates boiler plate code, triggering only when values differ\n  * (Automagically triggers nested changes for Resource and Resource[])\n* `InputMap` class attribute:\n  * Provides strongly typed access to input actions defined in godot.project\n* `LayerNames` class attribute:\n  * Provide strongly typed access to layer names defined in godot.project\n* NEW: `Autoload`/`AutoloadRename` class attribute:\n  * Provide strongly typed access to autoload nodes defined in godot.project\n* `CodeComments` class attribute:\n  * Provides a nested static class to access property comments from code (useful for in-game tooltips, etc)\n* `OnInstantiate` method attribute:\n  * Generates a static Instantiate method with matching args that calls attributed method as part of the instantiation process\n  * (Also generates a protected constructor to ensure proper initialisation - can be deactivated via attribute)\n* `OnImport` method attribute (GD4 only):\n  * Generates default plugin overrides and options to make plugin class cleaner (inherit from OnImportEditorPlugin)\n* Includes base classes/helpers to create project specific source generators\n\n- Version 1.x supports Godot 3 only\n- Version 2.x supports Godot 3 \u0026 4\n- Version 3.x will support Godot 4 only\n  - `Notify` will be improved\n  - `OnImport` will be removed\n  - `SceneTree` caching will be removed (+ other ideas)\n  - Post comments/questions/suggestions as issues - open discussions welcome\n    - eg, should `_` operator be replaced to avoid conflict with C# discard operator?\n\n(See [GodotSharp.BuildingBlocks][1] or local tests for example usage patterns)\n\n[1]: https://github.com/Cat-Lips/GodotSharp.BuildingBlocks\n\n## Table of Contents\n- [GodotSharp.SourceGenerators](#godotsharpsourcegenerators)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [Attributes](#attributes)\n    - [`SceneTree`](#scenetree)\n    - [`GodotOverride`](#godotoverride)\n    - [`Notify`](#notify)\n    - [`InputMap`](#inputmap)\n    - [`LayerNames`](#layernames)\n    - [`Autoload`/`AutoloadRename`](#autoload/autoloadrename)\n    - [`CodeComments`](#codecomments)\n    - [`OnInstantiate`](#oninstantiate)\n    - [`OnImport`](#onimport)\n\n## Installation\nInstall via [NuGet](https://www.nuget.org/packages/GodotSharp.SourceGenerators)\n\n## Attributes\n\n### `SceneTree`\n  * Class attribute\n  * Generates class properties for uniquely named nodes\n  * Generates a static property to retrieve tscn resource (TscnFilePath)\n  * Provides strongly typed access to the scene hierarchy (via `_` operator)\n  * Nodes are cached on first retrieval to avoid interop overhead\n  * Advanced options available as attribute arguments\n    * tscnRelativeToClassPath: (default null) Specify path to tscn relative to current class\n    * traverseInstancedScenes: (default false) Include instanced scenes in the generated hierarchy\n    * root: (default _) Provide alternative to `_` operator (eg, to allow use of C# discard variable)\n```cs\n// Attach a C# script on the root node of the scene with the same name.\n// [SceneTree] will generate the members as the scene hierarchy.\n[SceneTree]\n//[SceneTree(root: \"ME\")]                       // Use this for alternative to `_`\n//[SceneTree(\"my_scene.tscn\")]                  // Use this if tscn has different name\n//[SceneTree(\"../Scenes/MyScene.tscn\")]         // Use relative path if tscn located elsewhere\n//[SceneTree(traverseInstancedScenes: true)]    // Use this to include instanced scenes in current hierarchy\npublic partial class MyScene : Node2D \n{\n    public override void _Ready() \n    {\n        // You can access the node via '_' object.\n        GD.Print(_.Node1.Node11.Node12.Node121);\n        GD.Print(_.Node4.Node41.Node412);\n\n        // You can also directly access nodes marked as having a unique name in the editor\n        GD.Print(MyNodeWithUniqueName);\n        GD.Print(_.Path.To.MyNodeWithUniqueName); // Long equivalent\n\n        // Only leaf nodes are Godot types (call .Get() on branch nodes)\n        // Lets say you have _.Node1.Node2, observe the following code\n        GD.Print(_.Node1.Name); // invalid\n        GD.Print(_.Node1.Get().Name); // valid\n        Node node1 = _.Node1; // implicit conversion also possible!\n        GD.Print(node1.Name); // valid\n        GD.Print(_.Node1.Node2.Name); // valid\n    }\n}\n\n...\n\n// (elsewhere)\npublic void NextScene()\n    =\u003e GetTree().ChangeSceneToFile(MyScene.TscnFilePath);\n```\n### `GodotOverride`\n  * Method attribute\n  * Allows use of On*, instead of virtual _* overrides\n  * (Requires partial method declaration for use with Godot 4.0)\n  * Advanced options available as attribute arguments\n    * replace: (default false) Skip base call generation (ie, override will replace base)\n```cs\npublic partial class MyNode : Node2D \n{\n    [GodotOverride]\n    protected virtual void OnReady()\n        =\u003e GD.Print(\"Ready\");\n\n    [GodotOverride(replace: true)]\n    private void OnProcess(double delta)\n        =\u003e GD.Print(\"Processing\");\n\n    // Requires partial method declaration for use with Godot 4.0\n    public override partial void _Ready(); \n    public override partial void _Process(double delta); \n}\n```\nGenerates:\n```cs\n    public override void _Ready()\n    {\n        base._Ready();\n        OnReady();\n    }\n\n    public override _Process(double delta)\n        =\u003e OnProcess(delta);\n```\n### `Notify`\n  * Property attribute\n  * Generates public events Value1Changed \u0026 Value1Changing and a private class to manage field and event delivery\n  * (Automagically triggers nested changes for Resource and Resource[])\n  * Events are triggered only if value is different\n  * Initial value can be set without triggering update (useful when using a non-nullable reference type)\n  * [NEW] Supports partial properties!\n```cs\npublic partial class NotifyTest : Node\n{\n    [Notify] public partial int Value { get; set; } // [NEW] Partial properties now supported\n\n    [Notify]\n    public float Value1\n    {\n        get =\u003e _value1.Get();\n        set =\u003e _value1.Set(value); // You can also pass onchanged event handler here\n    }\n\n    public override void _Ready()\n    {\n        Value1Changing += () =\u003e GD.Print(\"Value1Changing raised before value is changed\");\n        Value1Changed += () =\u003e GD.Print(\"Value1Changed raised after value is changed\");\n\n        // You can also subscribe to private events if needed \n        //   _value1.Changing += OnValue1Changing;\n        //   _value1.Changed += OnValue1Changed;\n        // This might be useful... erm... if you need to clear the public listeners for some reason...?\n\n        Value1 = 1; // Raise Value1Changing and Value1Changed\n        Value1 = 2; // Raise Value1Changing and Value1Changed\n        Value1 = 2; // No event is raised since value is the same\n    }\n\n    public NotifyTest()\n        =\u003e InitValue1(7); // Set initial value without triggering events (optional)\n}\n```\n### `InputMap`\n  * Class attribute\n  * Provides strongly typed access to input actions defined in godot.project (set via editor)\n  * If you want access to built-in actions, see [BuiltinInputActions.cs](https://gist.github.com/qwe321qwe321qwe321/bbf4b135c49372746e45246b364378c4)\n```cs\n[InputMap]\npublic static partial class MyInput;\n```\nEquivalent (for defined input actions) to:\n```cs\n// (static optional)\n// (string rather than StringName for Godot 3)\n// (does not provide access to built-in actions)\npartial static class MyInput\n{\n    public static readonly StringName MoveLeft = \"move_left\";\n    public static readonly StringName MoveRight = \"move_right\";\n    public static readonly StringName MoveUp = \"move_up\";\n    public static readonly StringName MoveDown = \"move_down\";\n}\n```\n### `LayerNames`\n  * Class attribute\n  * Provides strongly typed access to layer names defined in godot.project (set via editor)\n```cs\n[LayerNames]\npublic static partial class MyLayers;\n```\nEquivalent (for defined layers) to:\n```cs\n// (static optional)\npublic static partial class MyLayers\n{\n    public static class Render2D\n    {\n        public const int MyLayer1 = 0; // Yes, layers start at 1 in editor, but 0 in code\n        public const int MyLayer2 = 1;\n        public const int MyLayer7 = 6;\n        public const int _11reyaLyM = 10; // Yes, we will append an underscore if required...\n\n        public static class Mask\n        {\n            public const uint MyLayer1 = 1 \u003c\u003c 0;\n            public const uint MyLayer2 = 1 \u003c\u003c 1;\n            public const uint MyLayer7 = 1 \u003c\u003c 6;\n            public const uint _11reyaLyM = 1 \u003c\u003c 10;\n        }\n    }\n    public static class Render3D\n    {\n        public const int MyLayer1 = 0;\n\n        public static class Mask\n        {\n            public const uint MyLayer1 = 1 \u003c\u003c 0;\n        }\n    }\n    // Also for Physics2D, Physics3D, Navigation2D, Navigation3D, Avoidance, etc...\n}\n```\n### `Autoload`/`AutoloadRename`\n  * `Autoload` is a generated class (ie, not attribute) in Godot namespace\n    * Provides strongly typed access to autoload nodes defined in editor project settings\n    * Supports tscn nodes \u0026 gd/cs scripts with C# compatible types inferred wherever possible\n  * `AutoloadRename` is an additional attribute that can be used to provide C# friendly names\n#### Examples:\nFor the following autoloads (defined in project.godot):\n```project.godot\n[autoload]\n\ngd_utils=\"*res://addons/handy_utils/gd_utils.gd\"\ncs_utils=\"*res://addons/silly_sausage/MyUtils.cs\"\nDebugMenu=\"*res://addons/debug_menu/debug_menu.tscn\"\n```\nWith the following renames (optionally defined in your project):\n```cs\nnamespace Godot;\n\n[AutoloadRename(\"UtilsGD\", \"gd_utils\")]\n[AutoloadRename(\"UtilsCS\", \"cs_utils\")]\nstatic partial class Autoload;\n```\nThe following class is generated:\n```cs\nnamespace Godot;\n\nstatic partial class Autoload\n{\n    private static Node root = (Engine.GetMainLoop() as SceneTree)?.Root;\n\n    /// \u003csummary\u003eAutoload: gd_utils\u003c/summary\u003e\n    public static Node UtilsGD =\u003e field ??= root?.GetNodeOrNull\u003cNode\u003e(\"gd_utils\");\n\n    /// \u003csummary\u003eAutoload: cs_utils\u003c/summary\u003e\n    public static MyUtils UtilsCS =\u003e field ??= root?.GetNodeOrNull\u003cMyUtils\u003e(\"cs_utils\");\n\n    /// \u003csummary\u003eAutoload: DebugMenu\u003c/summary\u003e\n    public static CanvasLayer DebugMenu =\u003e field ??= root?.GetNodeOrNull\u003cCanvasLayer\u003e(\"DebugMenu\");\n}\n```\n### `CodeComments`\n  * Class attribute\n  * Provides a nested static class to access property comments from code\n  * Advanced options available as attribute arguments\n    * strip: (default \"// \") The characters to remove from the start of each line\n```cs\n[CodeComments]\npublic partial class CodeCommentsTest : Node\n{\n    // This a comment for Value1\n    // [CodeComments] only works with Property\n    [Export] public float Value1 { get; set; }\n\n    // Value 2 is a field so no comment\n    [Export] public float value2;\n\n    public override void _Ready() \n    {\n        GD.Print(GetComment(nameof(Value1))); // output: \"This a comment for Value1\\n[CodeComments] only works with Property\"\n        GD.Print(GetComment(nameof(value2))); // output: \"\" (No output for fields, but could be added if needed)\n    }\n}\n```\n### `OnInstantiate`\n  * Method attribute\n  * Generates a static Instantiate method with matching args that calls attributed method as part of the instantiation process\n  * (Also generates a protected constructor to ensure proper initialisation - can be deactivated via attribute)\n  * Advanced options available as attribute arguments\n    * ctor: (default \"protected\") Scope of generated constructor (null, \"\" or \"none\" to skip)\n```cs\n// Initialise can be public or protected if required; args also optional\n// Currently assumes tscn is in same folder with same name\n// Obviously only valid for root nodes\npublic partial class MyScene : Node\n{\n    [OnInstantiate]\n    private void Initialise(string myArg1, int myArg2)\n        =\u003e GD.PrintS(\"Init\", myArg1, myArg2);\n}\n```\nGenerates (simplified):\n```cs\n    private static PackedScene __scene__;\n    private static PackedScene __Scene__ =\u003e __scene__ ??= GD.Load\u003cPackedScene\u003e(\"res://Path/To/MyScene.tscn\");\n\n    public static MyScene Instantiate(string myArg1, int myArg2)\n    {\n        var scene = __Scene__.Instantiate\u003cMyScene\u003e();\n        scene.Initialise(myArg1, myArg2);\n        return scene;\n    }\n\n    private Test3Arg() {}\n```\nUsage:\n```cs\n    // ... in some class\n    private void AddSceneToWorld()\n    {\n        var myScene = MyScene.Instantiate(\"str\", 3);\n        MyWorld.AddChild(myScene);\n    }\n```\n### `OnImport`\n  * Method attribute (GD4 only)\n  * Generates default plugin overrides and options to make plugin class cleaner (inherit from OnImportEditorPlugin)\n  * Includes base classes/helpers to create project specific source generators\n  * (Not that useful unless writing lots of plugins - might remove in v3)\n","funding_links":[],"categories":["C# #","Development Tools / Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCat-Lips%2FGodotSharp.SourceGenerators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCat-Lips%2FGodotSharp.SourceGenerators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCat-Lips%2FGodotSharp.SourceGenerators/lists"}