{"id":21864615,"url":"https://github.com/ninetailsrabbit/godotextensionator","last_synced_at":"2025-08-01T15:03:32.237Z","repository":{"id":241863339,"uuid":"808053315","full_name":"ninetailsrabbit/GodotExtensionator","owner":"ninetailsrabbit","description":"Speed up your Godot development with GodotExtensionator which adds a number of functionalities to the base nodes.","archived":false,"fork":false,"pushed_at":"2024-10-27T12:36:33.000Z","size":573,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T09:11:16.570Z","etag":null,"topics":["csharp","extensions","gamedev","godot","plugin"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/Ninetailsrabbit.GodotExtensionator","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/ninetailsrabbit.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":"2024-05-30T09:37:30.000Z","updated_at":"2024-11-11T06:44:19.000Z","dependencies_parsed_at":"2024-08-16T10:56:25.014Z","dependency_job_id":null,"html_url":"https://github.com/ninetailsrabbit/GodotExtensionator","commit_stats":null,"previous_names":["ninetailsrabbit/godot-xtension-pack","ninetailsrabbit/godotextensionator"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninetailsrabbit%2FGodotExtensionator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninetailsrabbit%2FGodotExtensionator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninetailsrabbit%2FGodotExtensionator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ninetailsrabbit%2FGodotExtensionator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ninetailsrabbit","download_url":"https://codeload.github.com/ninetailsrabbit/GodotExtensionator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248961186,"owners_count":21189991,"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","extensions","gamedev","godot","plugin"],"created_at":"2024-11-28T04:10:31.040Z","updated_at":"2025-04-14T20:57:35.117Z","avatar_url":"https://github.com/ninetailsrabbit.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GodotExtensionator\n\n![license](https://badgen.net/static/License/MIT/yellow)\n[![readme](https://badgen.net/static/README/📃/yellow)](https://github.com/ninetailsrabbit/GodotExtensionator/README.md)\n![csharp](https://img.shields.io/badge/C%23-239120?style//for-the-badge\u0026logo//c-sharp\u0026logoColor//white)\n\nSpeed up your Godot development with GodotExtensionator which adds a number of functionalities to the base nodes.\n\n---\n\n\u003cp align=\"center\"\u003e\n\u003cimg alt=\"GodotExtensionator\" src=\"GodotExtensionator/icon.png\" width=\"200\"\u003e\n\u003c/p\u003e\n\n---\n\n- [GodotExtensionator](#godotextensionator)\n  - [Getting started](#getting-started)\n    - [.csproj](#csproj)\n    - [Installation via CLI](#installation-via-cli)\n  - [Usage](#usage)\n    - [General](#general)\n    - [GenericGodotWrapper](#genericgodotwrapper)\n    - [Singleton](#singleton)\n    - [Identity Resource](#identity-resource)\n    - [AudioStreamPlayer](#audiostreamplayer)\n    - [Camera 3D](#camera-3d)\n    - [Color](#color)\n    - [Control](#control)\n    - [Input](#input)\n    - [Math](#math)\n    - [String](#string)\n    - [Mesh](#mesh)\n    - [Node](#node)\n    - [Node2D](#node2d)\n    - [Node 3D](#node-3d)\n    - [Scene Tree](#scene-tree)\n    - [Viewport](#viewport)\n    - [Vector](#vector)\n    - [OSExtension](#osextension)\n    - [Polygon2D](#polygon2d)\n    - [Rect2](#rect2)\n    - [Texture](#texture)\n    - [Transform3D](#transform3d)\n  - [Functionalities that can be used without an instance](#functionalities-that-can-be-used-without-an-instance)\n    - [OSExtension](#osextension-1)\n    - [Get autoload singleton on any place](#get-autoload-singleton-on-any-place)\n    - [Getting random enum value](#getting-random-enum-value)\n    - [Getting a random color](#getting-a-random-color)\n    - [Input related methods](#input-related-methods)\n    - [Common use characters](#common-use-characters)\n    - [Mathematical constants](#mathematical-constants)\n\n## Getting started\n\nUnlocks a new level of functionality for your Godot projects. This comprehensive collection of C# extensions seamlessly integrates with the existing Godot classes, empowering you to streamline development, enhance game mechanics, and unleash your creative vision. Whether you're a seasoned Godot developer or just starting out, `GodotExtensionator` provides the tools you need to elevate your c# games to the next level.\n\n### .csproj\n\nAdd the package directly into your .csproj\n\n```xml\n\n\n\u003cItemGroup\u003e\n## Latest stable release\n  \u003cPackageReference Include=\"Ninetailsrabbit.GodotExtensionator\"/\u003e\n\n## Manual version\n  \u003cPackageReference Include=\"Ninetailsrabbit.GodotExtensionator\" Version=\"0.4.1\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\n### Installation via CLI\n\nFurther information can be found on the [official microsoft documentation](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-nuget-cli)\n\n```sh\nnuget install Ninetailsrabbit.GodotExtensionator\n\n# Or choosing version\n\nnuget install Ninetailsrabbit.GodotExtensionator -Version 0.4.1\n\n# Using dotnet\ndotnet add package Ninetailsrabbit.GodotExtensionator --version 0.4.1\n```\n\n## Usage\n\nSince these functions are C# extension methods, they become available directly on the types they extend. You only need to call them on instances of those types in your code, simplifying the syntax\n\n### General\n\nThis extensions do not have a dependency on godot and are therefore considered to be of the system.\n\n```csharp\n// \"In\" feature for any value in your project\n\nvar piece = new Piece(\"circle\", Piece.TYPES.NORMAL);\n\n// Parameters as enumerable\npiece.Type.In([Piece.TYPES.NORMAL, Piece.TYPES.OBSTACLE]); // true\n\n// Normal parameters\npiece.Type.In(Piece.TYPES.NORMAL, Piece.TYPES.OBSTACLE); // True\n\n2.In(3, 4, 5, 6, 2); // True\n10.In([5, 9, 11]); // False\n\n\n// Generates a random float value within a specified range (inclusive)\n// This extension method provides a way to generate random floats within a specific range, similar to how `Random.Next` works with integers\nRandom rng = new();\n\nrng.NextFloat(5.3f, 10.8f);\n\n\n// Get the last index from any structure that inherit from IEnumerable\nint [] numbers = [100, 500, 400, 500];\nList\u003cPiece\u003e Pieces = new() { new Piece(\"triangle\"), new Piece(\"triangle\") };\n\nnumbers.LastIndex(); // 3\npieces.LastIndex(); // 1\n\n// Retrieve the middle element while the sequence contains 3 or more elements\n// An ArgumentException is throw when sequence contains less than 3 elements\nint [] numbers = [1, 2, 3, 4, 5];\n\nnumbers.MiddleElement(); // 3\n\nstring[] names = [\"laura\", \"bustamante\"];\n\nnames.MiddleElement(); // Raises ArgumentException\n\n// Shortcuts to remove duplicates or nullables\nint [] numbers = [100, 100, 400, 500, 400, 500];\nnumbers.RemoveDuplicates(); // [100, 400, 500]\nnumbers.RemoveNullables();\n\n\n// Shuffle any structure that inherit from IEnumerable\n// This method alters the original Enumerable\nnumbers.Shuffle();\n\n// Retrieve random elements from enumerables\n\n// Single element\nnumbers.RandomElement();\nnumbers.RandomElementUsing(new Random(42));\n\n// Multiple elements\nnumbers.RandomElements(3);\nnumbers.RandomElementsUsing(new Random(42), 5);\n\n// Pop elements\n\nstring[] superheros = [\"saitama\", \"wonder woman\", \"spiderman\", \"captain-america\"]\n\n// Get and remove the first element from the list\nsuperheros.PopFront(); // \"saitama\" --\u003e  [\"wonder woman\", \"spiderman\", \"captain-america\"]\n\n// Get and remove the last element from the list\nsuperheros.PopBack(); // \"captain america\" --\u003e  [\"saitama\", \"wonder woman\", \"spiderman\"]\n\n// Get and remove the selected index element from the list\nsuperheros.PopAt(2) // \"spiderman\" --\u003e [\"saitama\", \"wonder woman\", \"captain-america\"]\n```\n\n### GenericGodotWrapper\n\nThis class allows to wrap your custom class who do not inherit from `Godot.Object` to be able to pass it on Godot Signals.\n\n```csharp\n\npublic class Sequence {\n  //....\n}\n\n[Signal]\npublic delegate void ConsumedSequenceEventHandler(GenericGodotWrapper\u003cSequence\u003e sequence);\n\n\npublic void ConsumeSequence(Sequence sequence) {\n  sequence.Consume();\n\n  EmitSignal(SignalName.ConsumedSequence, new GenericGodotWrapper\u003cSequence\u003e(sequence));\n}\n\nprivate void OnConsumedSequence(GenericGodotWrapper\u003cSequence\u003e sequenceWrapper) {\n    Sequence sequence = sequenceWrapper.Value;\n\n    //...\n}\n\n```\n\n### Singleton\n\nEasily convert any class to a singleton using `SingletonBase` class\n\n```csharp\n\npublic sealed class Preloader : SingletonBase\u003cPreloader\u003e {\n\n   public readonly CompressedTexture2D OrangeSelectedTileTexture = GD.Load\u003cCompressedTexture2D\u003e(\"res://scenes/components/cells/assets/1.png\");\n\n }\n\n\n// Access the instance properties \u0026 methods with\n\nPreloader.Instance.OrangeSelectedTileTexture\n```\n\n### Identity Resource\n\nCreate resources that need a unique identifier by inheriting from this class and calling its base constructor\n\n```csharp\n public class WeaponResource : IdentityResource {\n\n     [Export] public int Damage;\n\n     public WeaponResource(): base() {}\n }\n\n\n //Access ID with\n WeaponResource spear = new WeaponResource();\n spear.GetId(); // 0f8fad5b-d9cb-469f-a165-70867728950e\n```\n\n### AudioStreamPlayer\n\nThese extension methods offer convenient ways to manipulate audio streams with features like pitch adjustment and ease curves. Their functionality is identical for both `AudioStreamPlayer2D` and `AudioStreamPlayer3D` nodes.\n\nIf an `AudioStreamPlayer` instance doesn't have an attached `AudioStream`, calling these extension methods will not produce any effect _(no playback or modification)_. Additionally, no errors will be thrown in this scenario.\n\n```csharp\npublic partial class MyScene : Node {\n\n  public AudioStreamPlayer audioPlayer;\n\n  public override void _Ready() {\n    audioPlayer = GetNode\u003cAudioStreamPlayer\u003e(\"AudioStreamPlayer\");\n\n    // A pitch scale of 1.2f\n    audioPlayer.PlayWithPitch(1.2f);\n    // A random value from the range provided\n    audioPlayer.PlayWithPitchRange(.9f, 1.2f);\n\n    //Play the sound or music smoothly setting the duration until reach the player bus volume\n    audioPlayer.PlayEase(1.5f);\n\n    //First parameter is the duration in this case.\n    audioPlayer.PlayEaseWithPitch(1.5f, 1.2f);\n    audioPlayer.PlayEaseWithPitchRange(1.5f, .9f, 1.2f);\n\n    //Shortcut to check if an audio player has an stream.\n    audioPlayer.HasStream(); // true or false\n  }\n\n}\n\n```\n\n### Camera 3D\n\nMostly shorcuts to access common information when using 3D cameras\n\n```csharp\npublic partial class MyScene : Node {\n\n  public override void _Ready() {\n    Camera3D camera = GetViewport().Camera3D();\n\n    // / Gets the world-space origin of the ray projected from the center of the camera's viewport\n    Vector3 center = camera.CenterByRayOrigin();\n\n    // A shortcut for camera.GlobalTransform.Origin\n    Vector3 center = camera.CenterByOrigin();\n\n    // Retrieves the current forward direction where the camera is looking at\n    // Useful for example to throw objects in the direction the camera is facing.\n    Vector3 forwardDirection = camera.ForwardDirection();\n\n    // If you want to detect whether an object is looking in the direction of the camera\n    camera.IsFacingCamera(other3DNode); // true or false\n  }\n\n}\n```\n\n### Color\n\nIf you want to manage colours through code here are some functions that will be useful for you\n\n```csharp\n  var green = Colors.Green;\n  var blue = Colors.Blue;\n\n  // Returns the color in Vector3(r, g, b) format\n  color.Vector3();\n\n  // Returns the color with transparency value in Vector3(r, g, b, a) format\n  color.Vector4();\n\n  // Same as above but in HSV format Vector3(h, s, v)\n  color.Vector3Hsv();\n  color.Vector4Hsv(); // Vector3(h, s, v, a)\n\n  //Checks if two colors are considered similar within a specified tolerance\n  green.SimilarTo(blue, 95);\n\n```\n\n### Control\n\nSimply extensions for nodes that inherit from `Control`\n\n```csharp\npublic partial class MyUIScene : Control {\n\n  public override void _Ready() {\n      // Centers the current pivot offset\n      this.CenterPivotOffset();\n\n      // Change the mouse filters quickly\n      this.IgnoreMouseEvents();\n      this.StopMouseEvents();\n      this.PassMouseEvents();\n  }\n\n}\n\n```\n\n### Input\n\nHelpers to detect inputs in your game more easily and make them readable for humans.\n\n```csharp\npublic override _Input(InputEvent @event) {\n\n  // Detect if mouse button is clicked (one press)\n  @event.IsMouseRightClick();\n  @event.IsMouseLeftClick();\n\n  // Detect if mouse button keeps pressed.\n  @event.IsMouseRightButtonPressed();\n  @event.IsMouseLeftButtonPressed();\n\n  // Detect if the input was made on a gamepad.\n  @event.IsControllerButton();\n  @event.IsControllerAxis();\n  @event.IsGamepadInput();\n\n  // Detect if a numeric key is pressed (include numpad keys)\n  @event.NumericKeyPressed();\n\n  // Return the key on human readable format\n  // Ctrl + X, Alt + Shift + 1 ...\n  // Is this event is not InputEventKey a empty string is returned\n  @event.ReadableKey()\n\n  // Or you can do the check manually\n  if (@event is InputEventKey eventKey) {\n    event.ReadableKey();\n  }\n}\n\n```\n\n### Math\n\nIncludes a lot of useful functions to speed up common calculations on game development. It uses the `Mathf` class from Godot so it's not full pure C#.\n\n```csharp\n// Normalize a float that represents an angle so it never goes beyond a full circle range.\n720.NormalizeDegreesAngle(); // Becomes 360\n12.56.NormalizeRadiansAngle() // Becomes TAU or 6.28..\n\n\n// Syntactic sugar for check simple ranges. By default the min \u0026 max are inclusive\n5.IsBetween(2, 6) // True\n5.IsBetween(6, 2) // It works on the opposite way too\n5.IsBetween(3, 5, false) // False, not inclusive\n7.5f.IsBetween(7.6f, 12f) // False\n\n// Convert an integer into his hexadecimal representation\n13531865.Hexadecimal() //CE7AD9\n\"CE7AD9\".DecimalFromHex() // This is part of StringExtension\n\n\n// Separate a big number, the default separator it's a comma \",\"\n1200000000.ThousandSeparator(\".\") // 1.200.000.000\n\n// Round big numbers\n1234567890.BigRound()  // Output: 1000000000\n987654321.BigRound()  // Output: 987000000\n\n\n// Applies a bias to a float value using a cubic function. It receives a factor between 0 and 1 and by adjusting the bias value, you can control for example, how much the dice is skewed towards higher numbers. A bias of 0.5 would result in a fair die roll. A bias closer to 1 would make it more likely to roll higher numbers\n\nint diceSides = 6;\nvar randomValue = GD.Randf();\nvar biasedValue = randomValue.Bias(0.7f)\n\nint rolledValue = Mathf.Floor(biasedValue * diceSides) + 1;\n\n// The sigmoid function acts like a translator, taking any real number (x) as input and transforming it into a value between 0 and 1 (but never exactly 0 or 1). Think of it as a dimmer switch for number.\n\n//The scaling factor allows you to adjust the steepness of the sigmoid curve, controlling how quickly it transitions between its output values of 0 and 1. This can be helpful for fine-tuning the behavior of the sigmoid function in different applications.\n\n150.Sigmoid();\n3500.Sigmoid(1.2f); // 1.2 scaling factor\n\n\n// This function calculates the factorial of a given non-negative integer number and it uses a recursive approach\n5.Factorial() // 120 --\u003e 5! = 5 * 4 * 3 * 2 * 1\n\nFactorialsFrom(5) // [1, 1, 2, 6, 24, 120]\n/*\n0! = 1 (by definition)\n1! = 1 (by definition)\n2! = 2 * 1 = 2\n3! = 3 * 2 * 1 = 6\n4! = 4 * 3 * 2 * 1 = 24\n5! = 5 * 4 * 3 * 2 * 1 = 120\n*/\n\nFactorialsFrom(7) // [1, 1, 2, 6, 24, 120, 720, 5040]\n\n// Conversions for Roman Numbers, only works for integers\n\n// Integer to Roman Numeral Examples:\n3.ToRomanNumber()  // III\n47.ToRomanNumber()  // XLVII\n1999.ToRomanNumber() // MCMXCIX\n3549.ToRomanNumber() // MMMDXLIX\n2024.ToRomanNumber() // MMXXIV\n\n// Roman Numeral to Integer Examples (this is part from the StringExtension):\n\"III\".RomanNumberToInteger() // 3\n\"XLVII\".RomanNumberToInteger() // 47\n\"MCMXCIX\".RomanNumberToInteger() // 1999\n\"MMMDXLIX\".RomanNumberToInteger() // 3549\n\"MMXXIV\".RomanNumberToInteger() // 2024\n\n// Convert a number into its ordinal representation\n// Useful for display position on leaderboards\n1.ToOrdinal() // 1st\n2.ToOrdinal() // 2nd\n3.ToOrdinal() // 3rd\n4.ToOrdinal() // 4th\n21.ToOrdinal() //Output: 21st\n32.ToOrdinal() //Output: 32nd\n43.ToOrdinal() //Output: 43rd\n54.ToOrdinal() //Output: 54th\n101.ToOrdinal() //Output: 101st\n111.ToOrdinal() //Output: 111th\n212.ToOrdinal()\n\n//Human readable format for big numbers\n1234.56.PrettyNumber() // 1.2K\n1234567.89.PrettyNumber() // 1.2M\n1234567890.123.PrettyNumber() // 1.2B\n\n// It allows to pass more suffixes in string[] format. They are sorted by exponent, so later suffixes are applied on larger exponents\n1234567890.123.PrettyNumber([\"\", \"K\", \"M\", \"BL\", \"T\"]); // 1.2BL\n\n// Binary string representation of a number\n5.ToBinary() // \"101\"\n13.ToBinary() // \"1101\"\n255.ToBinary() // \"11111111\"\n\n// Formatted seconds, A string representation of the formatted time in the format \"MM:SS\" or \"MM:SS:mm\", depending on the value of UseMilliseconds\n\n// Without milliseconds\n123.456.ToFormattedSeconds(); // Result: \"02:03\"\n\n// With milliseconds\n123.456.ToFormattedSeconds(true); // Result: \"02:03:45\"\n\n// Delta value to seconds. Assumes that the value is delta.\n\npublic override _Process(double delta) {\n  var timeElapsedInSeconds = delta.DeltaToTime();\n}\n\n\n```\n\n### String\n\nThis extensions provides helpful functions for manipulate or generate strings.\n\n```csharp\n\n// Detect if a url is valid\n\"https://google.es\".IsValidUrl() // true\n\"http://api.local.dev\".IsValidUrl() // true\n\"api.local.dev\".IsValidUrl() // false\n\n// Strip the BBCode from a text\n\"game [color=yellow]development[/color] it's hard\".StripBBcode() // game development is hard\n\n// Strip html from text\n\"\u003cp\u003emy html paragraph\u003c/p\u003e\".StripHtml(); //my html paragraph\n\n// Removes any text starting with \"res://\" followed by one or more non-space characters.\n\"res://assets/icons\".StripGodotPath() // \"assets/icons/\"\n\"res ://  assets/icons\".StripGodotPath() // \"assets/icons/\"\n\n// Shortcuts for string.IsNullOrEmpty and string.IsNullOrWhitespace\n\"\".IsNullOrEmpty() // true\n\" \".IsNullOrWhitespace() // true\n\n\n// Check if the absolute file path is valid and the resource exists\n\n\"res://skills/resources/fire.tres\".FilePathIsValid() // true\n\"resources/fire.tres\".FilePathIsValid() // false, the path needs to be absolute\n\n// Check if the absolute dir path is valid\n\n\"res://skills/resources\".DirPathIsValid() // true\n\"resources\".DirPathIsValid() // false, the path needs to be absolute\n\n// Check if the directory exists on the godot executable path\n\n\"user://game/settings.ini\".DirExistOnExecutablePath() // true if the executable is on \"user://game\" on the running computer.\n\n// Shorcut to check equality ignoring case\n\".PNg\".EqualsIgnoreCase(\".png\") // true\n\"Björk\".EqualsCultureIgnoreCase(\"bjOrk\") // true\n\n// Convert text to TitleCase based on iso, by default uses 'en-US'\n\n \"wAr aNd pEaCe\".ToTitleCase(); // \"War And Peace\"\n\n// Truncates the specified string to the given maximum length and adds a suffix if necessary, default suffix it's '...'\n\"my super longer text that needs to be truncated\".Truncate(20); // my super longer text...\n\"my super longer text that needs to be truncated\".Truncate(25, \"---\"); // my super longer text that---\n\n// Repeat a string\n\"*\".Repeat(5) // \"*****\"\n\n// Check if a string is upper or lower\n\n\"IM SUPER UPPER\".IsUpper() // True\n\"im lower\".IsLower() // True\n\n\"HeY ComES the CHEF!\".IsUpper(); // False\n\"HeY ComES the CHEF!\".IsLower(); // False\n\n\n```\n\n### Mesh\n\nMethods to shortcut some operations with meshes\n\n```csharp\n\n// If no Mesh shape is defined yet, a Vector3.Zero is returned.\n\npublic Vector3 RandomSurfacePosition(MeshInstance3D meshInstance) {\n\n    // Returns a random point in the mesh surface\n    return meshInstance.GetRandomSurfacePosition();\n\n    // Can be used on Mesh class\n    return meshInstance.Mesh.GetRandomSurfacePosition();\n}\n\n// Syntatic sugar to detect the mesh shape\nmeshInstance.HasMesh();\n```\n\n### Node\n\nAll the Godot nodes can use this extension methods, below you have the specific definitions for 2D and 3D ones.\n\n```csharp\n// Change the process mode easily with:\nnode.Enable()\nnode.Disable()\nnode.AlwaysProcess()\nnode.ProcessWhenPaused()\n\n// Shortcut to get autoload nodes from the root\n\npublic partial class MySceneNode : Node {\n\n  public GameGlobals GameGlobals;\n\n  public override void _Ready() {\n      GameGlobals = this.GetAutoloadNode\u003cGameGlobals\u003e();\n      // You can pass a string name if the class name is not the same as the node name\n      GameGlobals = this.GetAutoloadNode\u003cGameGlobals\u003e(\"RootGameGlobals\");\n  }\n}\n\n// Get children nodes recursively of custom class\nvar cells = node.GetNodesByClass\u003cGridCell\u003e();\n\n// Get children nodes recursively of Godot type\nvar sprites = node.GetNodesByType\u003cSprite3D\u003e();\n\n// Get the first encountered node of custom class\nnode.FirstNodeOfClass\u003cBoard\u003e();\n\n// Get the first encountered node of Godot type\nnode.FirstNodeOfType\u003cAnimatedSprite2D\u003e();\n\n\n// Retrieves the last child of this node or null\nnode.GetLastChild();\n\n// Get all the ancestors from the node\nnode.GetAllAncestors();\n\n// Get only the ancestors from the node\nnode.GetAllAncestors\u003cNode2D\u003e();\n\n// Get all the childrens recursively from the node\nnode.GetAllChildren();\n\n// Get all the childrens recursively of the type defined from the node\nnode.GetAllChildren\u003cMeshInstance2D\u003e();\n\n//Check if a node is valid to apply operations on it.\nnode.IsValid();\n\n// Remove a node safely\n// Takes into account if it is not queued for deletion, if it is within the scene tree, etc.\n\nnode.Remove();\n\n// Remove and queue free children, uses the above safely remove.\nnode.RemoveAndQueueFreeChildren();\n\n// Queue free children, uses the above safely remove.\nnode.QueueFreeChildren();\n\n// Shortcut to set owner to edited scene root, useful for tool scripts\nnode.SetOwnerToEditedSceneRoot();\n\n// Get the current tree depth for the node\nnode.GetTreeDepth(); // 2 means that has 2 parents above until the root scene where it lives.\n\n// Emit a signal safe only if exists without raising errors.\nnode.EmitSignalSafe();\n```\n\n### Node2D\n\n```csharp\nvar sprite = new Sprite2D();\nvar anotherSprite = new Sprite2D();\n\n// Get the current direction from this node to the mouse in the screen.\nsprite.GetMouseDirection();\n\n// Shortcuts for distance calculations\nsprite.GlobalDistanceTo(anotherSprite);\nsprite.LocalDistanceTo(anotherSprite);\n\n// Shortcuts for direction calculations\nsprite.GlobalDirectionTo(anotherSprite);\nsprite.LocalDirectionTo(anotherSprite);\n\n// Godot offers two types of z-index behavior:\n//Relative: The z-index only affects the layering within its immediate parent node.\n\n//Absolute: The z-index is considered relative to the entire scene root, making it independent of parent nodes.\n\n//While individual nodes have their own z-index values, the function calculates the absolute z-index, which reflects the node's final position in the overall stacking order.\n//By knowing the absolute z-index, you can ensure that specific nodes are always drawn on top of others, regardless of their parent-child relationships\n\n// Get the absolute z-index for this node on the screen while the parent node has Z as relative.\nsprite.GetAbsoluteZIndex();\n\n\n// Get nearest node by distance\n\n// These functions help you locate nodes within a specific distance range relative to a given point.\n// Null is returned if no node was found in the selected distance\n\n// Default distance range is between 0 and 9999\nNode? nearestNode = sprite.GetNearestNodeByDistance([anotherSprite, Marker, OtherNode]);\n\n// Define the distance range to check\nNode? nearestNode = sprite.GetNearestNodeByDistance([anotherSprite, Marker, OtherNode], 30f, 1500f);\n\n// Same to get farthest node\nNode? nearestNode = sprite.GetFarthestNodeByDistance([anotherSprite, Marker, OtherNode]);\nNode? nearestNode = sprite.GetFarthestNodeByDistance([anotherSprite, Marker, OtherNode], 30f, 1500f);\n\n// Screen position in world coordinates\nsprite.ScreenPosition() // Vector2(250, 100)\n\n// Detects if the node is on the current visible in-game screen.\nsprite.OnScreen()// true or false\n\n// An optional margin (in pixels) to consider around the screen edges (default: 16.0f)\nsprite.OnScreen(32f) // true or false\n\n```\n\n### Node 3D\n\nHas available all the above `Node2D` methods except for the screen position ones.\n\n```csharp\n// You can detect if the current node 3D is facing another node\n\nGetNode\u003cMeshInstance3D\u003e(\"MeshInTheWorld\").IsFacing(otherNode3D);\n\n```\n\n### Scene Tree\n\n```csharp\n//The node extension actually uses the method from SceneTree to get autoload nodes so you can use this method from the tree.\n\npublic partial class MySceneNode : Node {\n\n  public GameGlobals GameGlobals;\n\n  public override void _Ready() {\n      GameGlobals = this.GetTree().GetAutoloadNode\u003cGameGlobals\u003e();\n      // You can pass a string name if the class name is not the same as the node name\n      GameGlobals = this.GetTree().GetAutoloadNode\u003cGameGlobals\u003e(\"RootGameGlobals\");\n  }\n}\n\n//Shortcut to remove nodes safely from group\nvar tree = GetTree();\n\ntree.RemoveNodesFromGroup(\"bullets\");\n\n// You can use this shorcut to await for the next frame to be processed\nawait tree.NextIdle // Process\nawait tree.NextPhysicsIdle //Physic Process\n\n\n// Run a frame freeze effect in your game from the tree\ntree.FrameFreeze(0.5f, 1.5f); // Slow on 0.5 time scale for 1.5 seconds\n\n// Don't apply time scale changes on AudioServer\ntree.FrameFreeze(0.5f, 1.5f, false);\n\n// Gets the final transformation applied to the root node of the SceneTree, Useful to fix mouse handling when viewport it's stretched\n\ntree.FinalTransform(); // Returns Transform2D\n\n// Methods to quit, pause or resume the game.\ntree.QuitGame();\ntree.PauseGame();\ntree.ResumeGame();\n```\n\n### Viewport\n\n```csharp\npublic partial class MyScene: Node {\n\n  public override void _Ready() {\n      Viewport viewport = this.GetTree().GetViewport();\n\n    //Gets the camera frame in 2D coordinates for the specified viewport\n    // If no Camera2D exists, the visible rect from viewport is returned instead\n      viewport.GetCamera2DFrame();\n\n    // Converts a screen position (in normalized coordinates) to its corresponding world space position within the viewport\n    Vector2 worldPosition = viewport.ScreenToWorld(new Vector2(200, 200));\n\n    // Converts a world space position to its corresponding screen position (in normalized coordinates) within the viewport.\n    viewport.WorldToScreen(worldPosition);\n\n    // Screenshot related, this are similar to texture extensions\n    viewport.Screenshot();\n    viewport.ScreenshotToTextureRect();\n\n\n    //Gets the current screen position of the mouse relative to the top-left corner of the Viewport.\n    viewport.MouseScreenPosition();\n    // This provides a position relative to the Viewport itself, independent of screen resolution, normalized between 0.0 and 1.0\n    viewport.MouseScreenRelativePosition();\n\n    //Gets the vector from the Viewport's center to the current mouse screen position\n    viewport.MousePositionFromCenter();\n\n    // Gets the mouse position relative to the Viewport's center, normalized between -1.0 and 1.0 on both axes\n    viewport.MouseRelativeFromCenter();\n  }\n}\n```\n\n### Vector\n\nThis is the biggest one because in videogame development we are constantly working with vectors. Most of them works for both `Vector2` and `Vector3` unless otherwise defined.\n\n```csharp\n// Methods to get the opposite vector from the UpDirection of CharacterBody3D\n\nVector2.Right.UpDirectionOpposite() // Vector2.Left\nVector2.Up.UpDirectionOpposite() // Vector2.Down\n\nVector3.Right.UpDirectionOpposite() // Vector3.Left\nVector3.Forward.UpDirectionOpposite() // Vector3.Back\n\n// It's useful for example to apply the gravity force depending where the up direction is pointing.\npublic void ApplyGravity(CharacterBody3D character, float force ) {\n  character.Velocity += character.UpDirection.UpDirectionOpposite() * force * delta\n\n  // You can use it from the character body also\n  character.Velocity += character.UpDirectionOpposite() * force * delta\n}\n\n//  Limits the horizontal angle in radians of a Vector2 direction within a specified range.\n\n// Imagine you have a character aiming a weapon with a limited horizontal firing range. This function can be used to ensure the aiming direction stays within the allowed range while preserving the vertical direction\n\nVector2 aiminDirection = Vector2(1, -0.5)  // Extracting direction from vector\n\nfloat MaxHorizontalAngle = Mathf.PI / 3  // Limit angle to 60 degrees\n\nVector2 limitedDirection = MaxHorizontalAngle.LimitHorizontalAngle(aiminDirection);\n// Output: (0.5, -0.866)\n\n\n// Rotate vertically or horizontally a Vector3 with a random value\nVector3.One.RotateHorizontalRandom();\nVector3.One.RotateVerticalRandom();\n\n// System numerics Vector2 to Godot.Vector2 and viceversa\nSystem.Numerics.Vector2 numericVector = new Vector2(3, 5)\nGodot.Vector2 godotVector = new Godot.Vector2(5, 5);\n\nnumericVector.ToGodotVector();\nnumericVector.ToGodotVectorI();\n\ngodotVector.ToNumericVector();\n\n// System numerics Vector3 to Godot.Vector3 and viceversa\nSystem.Numerics.Vector2 numericVector = new Vector2(3, 5, 8);\nGodot.Vector2 godotVector = new Godot.Vector3(5, 5, 10);\n\nnumericVector.ToGodotVector();\nnumericVector.ToGodotVectorI();\n\ngodotVector.ToNumericVector();\n\n\n// Flip a vector on a human-readable way\n// This is exactly the same as prefix with -\nvar vector = Vector2.Right // (1, 0)\nvector.Flip(); // (-1, 0)\n\nvar vector = Vector3.Up // (0, 1, 0)\nvector.Flip() // (0, -1, 0)\n\n// Reverse is also available\nVector2(3, 5).Reverse() // Vector2(5, 3)\nVector3(3, 5, 7).Reverse() // Vector2(7, 5, 3)\n\n// Get a topdown Vector2 from a Vector3\n// This function can be used to convert 3D positions of objects (represented by Vector3) to their corresponding 2D coordinates on the screen (represented by Vector2).\nVector3(100, 40, 150).GetTopdownVector(); // Vector2(100, 150)\n\n// Extends a Vector in a specified direction by a given amount.\nfloat jumpForce = 10f;\n\nVector3 jumpDirection = Vector3.Up.Extend(Mathf.Pi, jumpForce);\n\n// Shorcut version to !IsZeroApprox()\nnew Vector2(0, 1).IsNotZeroApprox(); // true\nVector3.Zero.IsNotZeroApprox(); // false\n\n\n//  Calculating the squared distance is computationally cheaper than calculating the actual distance using a square root operation. This can be beneficial for performance optimization when checking distances frequently\n\n// While using squared distances offers a performance benefit, keep in mind that it doesn't give you the actual distance between the points. If you need the actual distance for calculations or other purposes, you'll need to perform a square root operation on the result\n\nVector2 from = new (3, 0),\nVector2 to = new(5, 2);\n\nbool isOnDistance = from.IsWithinDistanceSquared(to, 5f); // true\n\nMathf.Sqrt(isOnDistance); // 2.8284271247461903\n\n\n// TODO - CONTINUE WITH THE DOCUMENTATION\n```\n\n### OSExtension\n\nGeneral utilities that does not belongs to a particular place or uses `OS` singleton\n\n```csharp\n// Detect if the current build is running on a mobile\nOSExtension.IsMobile();\n\n// Detect if the current build is running on a SteamDeck\nOSExtension.IsSteamDeck();\n\n// Detect if multi threading is enabled on this project\nOSExtension.IsMultithreadingEnabled();\n\n// Open a external link if the url is valid. The url is encoded before opening it when web platform is detected\nOSExtension.OpenExternalLink(\"https://github.com/ninetailsrabbit\");\n\n// Generate a random ID using the current unix time\nOSExtension.GenerateRandomIdFromUnixTime();\n```\n\n### Polygon2D\n\nShortcuts to draw basic geometry shapes more quickly in a polygon.\nThe polygon points are cleared each time an extension function is called so only once shape can be draw each time.\n\n```csharp\n\nvar polygon = new Polygon2D();\n\npolygon.Circle();\npolygon.PartialCircle();\npolygon.Donut();\npolygon.Rectangle();\npolygon.RoundedRectangle();\n\n```\n\n### Rect2\n\nUseful extensions to work with Rectangles\n\n```csharp\nvar sprite = GetNode\u003cSprite2D\u003e(\"Map\");\nvar rect2 = sprite.texture.GetImage().GetUsedRect();\n\nVector2 mapPoint = rect2.RandomPoint();\n```\n\n### Texture\n\nUseful methods to work with texture dimensions\n\n```csharp\n// Shortcut to get the Rect from a texture\nsprite.texture.Dimensions();\n\n// Gets the scaled dimensions of a TextureRect considering the texture's used rectangle and the scale applied.\nvar textureRect = new TextureRect(){Texture = \"image.png\"};\ntextureRect.Dimensions();\n\n// This can used also on sprites\nsprite.Dimensions();\n\n// Get the real png Rect2I from png texture ignoring the transparent pixels. If the extension of the texture is not png, a Rect2 zero is returned.\ntextureRect.texture.GetPngRect();\n\n```\n\n### Transform3D\n\nGet directions from a transform in a more human-readable way.\n\n```csharp\n\nvar character = new CharacterBody3D();\n\n// Access directions in the 3D space from a transform\nVector3 direction = character.GlobalTransform.Back();\nVector3 direction = character.GlobalTransform.Forward();\nVector3 direction = character.GlobalTransform.Left();\nVector3 direction = character.GlobalTransform.Right();\nVector3 direction = character.GlobalTransform.Up();\nVector3 direction = character.GlobalTransform.Down();\n\n// Align directions easily on a Node3D\nTransform3D newTransform = character.GlobalTransform.AlignUp();\nTransform3D newTransform = character.GlobalTransform.AlignDown();\nTransform3D newTransform = character.GlobalTransform.AlignRight();\nTransform3D newTransform = character.GlobalTransform.AlignLeft();\nTransform3D newTransform = character.GlobalTransform.AlignUp();\n\n// Aligns the transform's rotation to face a target direction from a specified current direction. Useful for example to rotate smoothly a space ship\n\npublic class Spaceship : Node3D\n{\n    public Node3D Enemy; // Reference to the enemy Node3D\n\n    public override void _Process(float delta)\n    {\n        if (Enemy is not null)\n        {\n        // Get current forward direction of the spaceship\n        Vector3 currentDirection = Transform.basis.z;\n\n        // Get direction from spaceship to enemy\n        Vector3 targetDirection = this.GlobalDirectionTo(Enemy);\n\n        // Align the spaceship towards the enemy\n        Transform = this.Align(Transform, currentDirection, targetDirection);\n        }\n    }\n}\n\n// A more precise method to checks if two Transform3D objects are approximately equal in terms of their rotation and position\n\ncharacter.GlobalTransform.EqualTransformApprox(Enemy.GlobalTransform);\n\n\n```\n\n## Functionalities that can be used without an instance\n\nSome extension variables or methods does not need an instance to be used. This means you can call them directly using the type name without needing an instance of the type. These are typically utility methods that don't require specific object state.\n\n#### OSExtension\n\nAs the `OS` class from Godot is static, extensions cannot be added as we will never have an instance. In this case all its functions can be called statically.\n\n#### Get autoload singleton on any place\n\nAccess your autoloads without needing to be within the scene tree, it works exactly as the `GetAutoloadNode` method from the scene tree instance.\n\nThis means that you can access the information for example on Resources. This is an alternative if you want to continue using the Godot workflow. If not, you can always create your own singleton in C#.\n\n```csharp\nSceneTreeExtension.GetAutoloadSingleton\u003cGameGlobals\u003e();\n\nSceneTreeExtension.GetAutoloadSingleton\u003cMusicManager\u003e();\n\n// ...\n```\n\n#### Getting random enum value\n\n```csharp\n// Get a random value from the enum passed as parameter.\nEnumExtension.RandomEnum(Input.MouseModeEnum);\n```\n\n#### Getting a random color\n\n```csharp\n//A random color that can receive alpha as parameter where 255 is no transparency and 0 fully transparent.\nColorExtension.RandomColor(255);\n```\n\n#### Input related methods\n\n```csharp\nInputExtension.ShowMouseCursor()\nInputExtension.ShowMouseCursorConfined()\nInputExtension.HideMouseCursor()\nInputExtension.HideMouseCursorConfined()\nInputExtension.CaptureMouse()\n\nInputExtension.IsMouseVisible()\n\nInputExtension.GetAllInputsForAction(\"your-action\")\nInputExtension.GetKeyboardInputsForAction(\"your-action\"))\nInputExtension.GetJoypadInputsForAction(\"your-action\"))\n```\n\n#### Common use characters\n\n```csharp\nStringExtension.HEX_CHARACTERS // \"0123456789ABCDEF\";\nStringExtension.ASCII_ALPHANUMERIC // \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\nStringExtension.ASCII_LETTERS // \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nStringExtension.ASCII_LOWERCASE // \"abcdefghijklmnopqrstuvwxyz\";\nStringExtension.ASCII_UPPERCASE // \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nStringExtension.ASCII_DIGITS // \"0123456789\";\nStringExtension.ASCII_PUNCTUATION // \"!\\\"#$%\u0026'()*+, -./:;\u003c//\u003e?@[\\\\]^_`{|}~\";\n```\n\n#### Mathematical constants\n\n```csharp\nMath.Extension.COMMON_EPSILON // 0.000001f;  // 1.0e-6\nMathExtension.PRECISE_EPSILON // 0.00000001f; // 1.0e-8\nMathExtension.E // 2.71828182845904523536f;\nMathExtension.Delta // 4.6692016091f;  // FEIGENBAUM CONSTANT\nMathExtension.FeigenbaumAlpha // 2.5029078750f;\nMathExtension.AperyConstant // 1.2020569031f;\nMathExtension.GoldenRatio // 1.6180339887f;\nMathExtension.EulerMascheroniConstant // 0.5772156649f;\nMathExtension.KhinchinsConstant // 2.6854520010f;\nMathExtension.GaussKuzminWirsingConstant // 0.3036630028f;\nMathExtension.BernsteinsConstant // 0.2801694990f;\nMathExtension.HafnerSarnakMcCurleyConstant // 0.3532363718f;\nMathExtension.MeisselMertensConstant // 0.2614972128f;\nMathExtension.GlaisherKinkelinConstant // 1.2824271291f;\nMathExtension.OmegaConstant // 0.5671432904f;\nMathExtension.GolombDickmanConstant // 0.6243299885f;\nMathExtension.CahensConstant // 0.6434105462f;\nMathExtension.TwinPrimeConstant // 0.6601618158f;\nMathExtension.LaplaceLimit // 0.6627434193f;\nMathExtension.LandauRamanujanConstant // 0.7642236535f;\nMathExtension.CatalansConstant // 0.9159655941f;\nMathExtension.ViswanathsConstant // 1.13198824f;\nMathExtension.ConwaysConstant // 1.3035772690f;\nMathExtension.MillsConstant // 1.3063778838f;\nMathExtension.PlasticConstant // 1.3247179572f;\nMathExtension.RamanujanSoldnerConstant // 1.4513692348f;\nMathExtension.BackhouseConstant // 1.4560749485f;\nMathExtension.PortersConstant // 1.4670780794f;\nMathExtension.LiebsSquareIceConstant // 1.5396007178f;\nMathExtension.ErdosBorweinConstant // 1.6066951524f;\nMathExtension.NivensConstant // 1.7052111401f;\nMathExtension.UniversalParabolicConstant // 2.2955871493f;\nMathExtension.SierpinskisConstant // 2.5849817595f;\nMathExtension.FransenRobinsonConstant // 2.807770f;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fninetailsrabbit%2Fgodotextensionator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fninetailsrabbit%2Fgodotextensionator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fninetailsrabbit%2Fgodotextensionator/lists"}