{"id":14961014,"url":"https://github.com/mygamedevtools/extensions","last_synced_at":"2025-07-29T05:33:12.001Z","repository":{"id":179590993,"uuid":"536346398","full_name":"mygamedevtools/extensions","owner":"mygamedevtools","description":"A personal collection of Unity Engine tools, extensions, and helpers.","archived":false,"fork":false,"pushed_at":"2024-01-04T19:16:15.000Z","size":99,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-10T20:18:29.284Z","etag":null,"topics":["editor","editor-plugin","package","unity","unity-editor","unity-package","unity3d","unity3d-plugin","unityeditor","upm","upm-package"],"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/mygamedevtools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-09-13T23:48:45.000Z","updated_at":"2025-04-28T09:22:26.000Z","dependencies_parsed_at":"2024-01-04T20:28:54.945Z","dependency_job_id":"60058f7a-fcae-4dbf-8989-77e7ca723b75","html_url":"https://github.com/mygamedevtools/extensions","commit_stats":{"total_commits":39,"total_committers":2,"mean_commits":19.5,"dds":0.05128205128205132,"last_synced_commit":"dfd5e3ae060b155b5c6481d2137678d244690ac9"},"previous_names":["mygamedevtools/extensions"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/mygamedevtools/extensions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mygamedevtools%2Fextensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mygamedevtools%2Fextensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mygamedevtools%2Fextensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mygamedevtools%2Fextensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mygamedevtools","download_url":"https://codeload.github.com/mygamedevtools/extensions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mygamedevtools%2Fextensions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267633670,"owners_count":24118777,"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","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["editor","editor-plugin","package","unity","unity-editor","unity-package","unity3d","unity3d-plugin","unityeditor","upm","upm-package"],"created_at":"2024-09-24T13:23:38.289Z","updated_at":"2025-07-29T05:33:11.510Z","avatar_url":"https://github.com/mygamedevtools.png","language":"C#","readme":"\u003ch1 align = center\u003e\nExtensions\n\u003c/h1\u003e\n\n\u003cp align=center\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/mygamedevtools/extensions?color=5189bd\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/mygamedevtools/extensions/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/mygamedevtools/extensions?color=5189bd\u0026sort=semver\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://openupm.com/packages/com.mygamedevtools.extensions/\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/com.mygamedevtools.extensions?color=5189bd\u0026label=openupm\u0026registry_uri=https://package.openupm.com\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://openupm.com/packages/com.mygamedevtools.extensions/\"\u003e\u003cimg src=\"https://img.shields.io/badge/dynamic/json?color=5189bd\u0026label=downloads\u0026query=%24.downloads\u0026suffix=%2Fmonth\u0026url=https%3A%2F%2Fpackage.openupm.com%2Fdownloads%2Fpoint%2Flast-month%2Fcom.mygamedevtools.extensions\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=center\u003e\n  \u003ca href=\"https://codecov.io/github/mygamedevtools/extensions\"\u003e\u003cimg src=\"https://codecov.io/github/mygamedevtools/extensions/branch/main/graph/badge.svg?token=J4ISVSF390\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/mygamedevtools/extensions/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/mygamedevtools/extensions/actions/workflows/test.yml/badge.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/mygamedevtools/extensions/actions/workflows/release.yml\"\u003e\u003cimg src=\"https://github.com/mygamedevtools/extensions/actions/workflows/release.yml/badge.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003e\u003cimg src=\"https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=center\u003e\u003ci\u003e\nA personal collection of Unity Engine tools, extensions, and helpers.\n\u003c/i\u003e\u003c/p\u003e\n\nInstallation\n---\n\n### OpenUPM\n\nThis package is available on the [OpenUPM](https://openupm.com/packages/com.mygamedevtools.extensions) registry. Add the package via the [openupm-cli](https://github.com/openupm/openupm-cli):\n\n```\nopenupm add com.mygamedevtools.extensions\n```\n\n### [Installing from Git](https://docs.unity3d.com/Manual/upm-ui-giturl.html) _(requires [Git](https://git-scm.com/) installed and added to the PATH)_\n\n1. Open `Edit/Project Settings/Package Manager`.\n2. Click \u003ckbd\u003e+\u003c/kbd\u003e.\n3. Select `Add package from git URL...`.\n4. Paste `com.mygamedevtools.extensions` into the name.\n5. Click `Add`.\n\nUsage\n---\n\nThis package is focused on 3 main areas: Extensions, Tooling, and Attributes. The purpose of these tools, is to improve the overall Unity Editor experience\nwith simple, reliable, and maintainable solutions.\n\n### :large_blue_diamond: Attributes\n\nWe have a total of **3** attributes available:\n\n#### :large_orange_diamond: ReadOnly\n\nThe `[ReadOnly]` attribute prevents changing the field's value in the Unity Inspector\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField, ReadOnly]\n    float myValue = 5.5f;\n}\n```\n\n#### :large_orange_diamond: LabeledArray\n\nThe `[LabeledArray]` attribute allows you to specify names for array elements, instead of the default `Element #n`. You can\neither use a string array or an Enum to provide the names. If the array element count passes the provided names count, the following\nelement names will fall to the default naming\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField, LabeledArray(new string[]{ \"First\", \"Second\", \"Third\" })]\n    float[] myValueArray;\n}\n```\n\n#### :large_orange_diamond: SceneField\n\nThe `[SceneField]` attribute allows you to drag scene assets to fields in the inspector. You can only use this attribute on **int** fields \nsince it will store the scene's build index. It does not have any relation with the scene itself, so if you change the build settings it will\nnot update its value and will reference a different scene. You can add the scene to the build settings via the inspector after dragging the\nscene to the field if it hasn't been yet\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField, SceneField]\n    int mySceneIndex;\n}\n```\n\n### :large_blue_diamond: Tooling\n\nWe have **two** tools available:\n\n#### :large_orange_diamond: Group Game Objects\n\nSimply press \u003ckbd\u003eCtrl\u003c/kbd\u003e + \u003ckbd\u003eG\u003c/kbd\u003e to group the selected game objects. It creates a parent game object in the center of the selected objects.\n\n#### :large_orange_diamond: Scripting Define Symbols Helper\n\nYou can use the `ScriptingDefineSymbolsHelper` to easily add or remove scripting define symbols to your project. For example:\n\n```csharp\nusing MyGameDevTools.Extensions;\nusing UnityEditor;\n\npublic static class CheatsEnabler\n{\n    const string _cheatsDefine = \"ENABLE_CHEATS\";\n\n    [MenuItem(\"Tools/Add Cheats\")]\n    public static void AddCheats()\n    {\n        ScriptingDefineSymbolsHelper.AddScriptingDefineSymbol(_cheatsDefine);\n    }\n\n    [MenuItem(\"Tools/Add Cheats\", validate = true)]\n    public static bool AddCheatsValidate()\n    {\n        return !ScriptingDefineSymbolsHelper.HasScriptingDefineSymbol(_cheatsDefine);\n    }\n\n    [MenuItem(\"Tools/Remove Cheats\")]\n    public static void RemoveCheats()\n    {\n        ScriptingDefineSymbolsHelper.RemoveScriptingDefineSymbol(_cheatsDefine);\n    }\n\n    [MenuItem(\"Tools/Remove Cheats\", validate = true)]\n    public static bool RemoveCheatsValidate()\n    {\n        return ScriptingDefineSymbolsHelper.HasScriptingDefineSymbol(_cheatsDefine);\n    }\n}\n```\n\n### :large_blue_diamond: Extensions\n\nWe have a total of **3** extensions available:\n\n#### :large_orange_diamond: Debug Extensions\n\nAllows debugging collections and jagged arrays.\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    // Can also be a List or any IEnumerable type\n    [SerializeField]\n    int[] myValueArray;\n    \n    int[][] myJaggedArray = new int[5][];\n    \n    void Start()\n    {\n        for (int i = 0; i \u003c myJaggedArray.Length; i++)\n            myJaggedArray[i] = new int[5];\n            \n        DebugExtensions.LogJaggedArray(myJaggedArray);        \n        DebugExtensions.LogCollection(myValueArray);\n    }\n}\n```\n\n#### :large_orange_diamond: Game Object Extensions\n\nA collection of some helpful game object operations\n\n##### :diamond_shape_with_a_dot_inside: Set Children Layer Recursively\n\nSets all game objects in the given transform's hierarchy to the provided layer\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    void Start()\n    {\n        transform.SetChildrenLayerRecursively(LayerMask.NameToLayer(\"MyLayer\"));\n    }\n}\n```\n\n##### :diamond_shape_with_a_dot_inside: Destroy Components\n\nDestroys the given component type instances in a `UnityEngine.GameObject` or its children.\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField]\n    GameObject[] myObjectsToDestroy;\n\n    void Start()\n    {        \n        gameObject.DestroyAllComponentsOfType\u003cBoxCollider\u003e();\n        gameObject.DestroyAllChildrenComponentsOfType\u003cSphereCollider\u003e();\n    }\n}\n```\n\n##### :diamond_shape_with_a_dot_inside: Get Root Game Objects\n\nGets the root game objects of a scene, or optionally all scenes.\n\n```cs\npublic class MyClass : MonoBehaviour\n{\n    void Start()\n    {\n        List\u003cGameObject\u003e allRootObjects = GameObjectExtensions.GetRootGameObjects(true);\n    }\n}\n```\n\n##### :diamond_shape_with_a_dot_inside: Has Layer\n\nChecks if a `LayerMask` contains the given layer index. Useful for physics validations.\n\n```cs\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField]\n    LayerMask _mask;\n\n    void Start()\n    {\n        Debug.Log(_mask.HasLayer(gameObject.layer));\n    }\n}\n```\n\n##### :diamond_shape_with_a_dot_inside: Delay Call\n\nDelays an Action after a given amount of time. You can delay in seconds, frames, or physics (fixed) frames.\n\n```csharp\npublic class MyClass : MonoBehaviour\n{\n    void Start()\n    {\n        Debug.Log(\"Hello there\");\n        // In seconds\n        DelayCall(6, MyAction);\n        // In frames\n        DelayCallInFrames(6, MyAction);\n        // In physics frammes\n        DelayCallInPhysicsFrames(6, MyAction);\n    }\n    \n    void MyAction()\n    {\n        Debug.Log(\"General Kenobi\")\n    }\n}\n```\n\n#### :large_orange_diamond: Object Extensions\n\n##### :diamond_shape_with_a_dot_inside: Destroy Objects\n\nDestroy a given array of `UnityEngine.Object`, which could be GameObjects, Components, MonoBehaviours, and any type that inherits from `UnityEngine.Object`. Keep in mind that the object is destroyed between the end of the current frame and the beginning of the next one.\n\n```cs\npublic class MyClass : MonoBehaviour\n{\n    [SerializeField]\n    Object[] _objectsToDestroy;\n\n    void Start()\n    {\n        ObjectExtensions.DestroyObjects(_objectsToDestroy);\n    }\n}\n```\n\n##### :diamond_shape_with_a_dot_inside: Find Implementation(s) of Type\n\nThis is meant to find `interface` implementations. It works like a `FindObjectOfType`, but for `interface`. You can also use the `TryFindImplementationOfType` to return a bool. Keep in mind that the `interface` implementation will also need to inherit from `MonoBehaviour` to be found since it will be searched within GameObject's components.\n\n```cs\npublic interface IActionable {}\n\npublic class MyAction : MonoBehaviour, IActionable {}\n\npublic class MyClass : MonoBehaviour\n{\n    void Start()\n    {\n        // Common usage\n        IActionable implementation = this.FindImplementationOfType\u003cIActionable\u003e();\n        // Explicit usage\n        IActionable implementation = ObjectExtensions.FindImplementationOfType\u003cIActionable\u003e();\n        // Try usage\n        bool implementationExists = ObjectExtensions.TryFindImplementationOfType\u003cIActionable\u003e(out IActionable implementation);\n\n        // For multiple implementations\n        List\u003cIActionable\u003e implementations = ObjectExtensions.FindImplementationsOfType\u003cIActionable\u003e();\n    }\n}\n```\n\n---\n\nDon't hesitate to create [issues](https://github.com/mygamedevtools/extensions/issues) for suggestions and bugs. Have fun!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmygamedevtools%2Fextensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmygamedevtools%2Fextensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmygamedevtools%2Fextensions/lists"}