Skip to content

Commit

Permalink
[GitHub Action] Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Nov 12, 2024
1 parent 01b7bcf commit 40cca16
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 5 deletions.
179 changes: 174 additions & 5 deletions docs/Mod-Creation/Unity-Editor-Usage/RoR2-Editor-Kit-Utilization.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# RoR2 Editor Kit Utilization


[RoR2EditorKit](https://github.com/risk-of-thunder/RoR2EditorKit/tree/main) is a powerful package maintained by the community that contains a robust API and utilities for helping the development of Editor related scripts. Thanks to its 5.0.0 update, RoR2EditorKit's core assembly which contains its API and main functionality does not require RoR2 to be within the editor nor ThunderKit to be installed, as such, it can be used in virtually any scenario to help your development of editor scripts.

This guide will cover common utilizations and tips with working with the API for your editor scripts.
Expand Down Expand Up @@ -49,6 +48,7 @@ RoR2EditorKit comes bundled with a total of 7 inspector subclasses. These are th
The ``Inspector<T>`` is the base class for any and all of RoR2EditorKit's editors, the package uses the word "Inspector" to refer to any ``UnityEditor.Editor`` for distinction purposes.

Features:

* Access to a EditorSettingCollection for the inspector for both Project and Preference settings
* A way to both enable and disable said inspector, enabling and disabling inspectors is one of the key features of RoR2EditorKit. When an inspector is disabled it uses the default inspector.
* Generic callbacks when the inspector is enabled or disabled
Expand All @@ -63,6 +63,7 @@ If youre going to inherit from the Inspector class, you'll need to implement a w
The ``ScriptableObjectInspector<T>`` inherits from ``Inspector<T>`` and its used for creating an Inspector for a Scriptable Object.

Features:

* Implements a toggle for enabling and disabling the inspector, this toggle is placed on the Header of the inspector.

You'll still need to implement your UI manually, or alternatively, inherit from either of the 2 following inspector types.
Expand All @@ -72,6 +73,7 @@ You'll still need to implement your UI manually, or alternatively, inherit from
The ``IMGUIScriptableObjectInspector<T>`` inherits from ``ScriptableObjectInspector<T>`` and its used for creating an Inspector for a ScriptableObject using IMGUI.

Features:

* Handles the creation of an IMGUIContainer which will be used to render your UI

You can implement your IMGUI UI inside the ``DrawIMGUI()`` method.
Expand All @@ -81,6 +83,7 @@ You can implement your IMGUI UI inside the ``DrawIMGUI()`` method.
The ``VisualElementScriptableObjectInspector<T>`` inherits from ``ScriptableObjectInspector<T>`` and its used for creating an Inspector for a ScriptableObject using Visual Elements.

Features:

* Automatically obtains an UXML instance based off the inspector's name, this UXML instance will be used as the actual UI, which then the inspector passes to an abstract method for initialization.
* A method that you can override to validate if a specified path corresponds to your inspector.

Expand All @@ -89,6 +92,7 @@ Features:
The ``ComponentInspector<T>`` inherits from ``Inspector<T>`` and its used for creating an Inspector for a Component or MonoBehaviour.

Features:

* Implements a toggle for enabling and disabling the inspector, this toggle is placed right at the beginning of the component's inspector UI

You'll still need to implement your UI manually, or alternatively, inherit from either of the 2 following inspector types.
Expand All @@ -98,6 +102,7 @@ You'll still need to implement your UI manually, or alternatively, inherit from
The ``IMGUIComponentInspector<T>`` inherits from ``ComponentInspector<T>`` and its used for creating an Inspector for a Component or MonoBehaviour using IMGUI.

Features:

* Handles the creation of an IMGUIContainer which will be used to render your UI

You can implement your IMGUI UI inside the ``DrawIMGUI()`` method.
Expand All @@ -107,6 +112,7 @@ You can implement your IMGUI UI inside the ``DrawIMGUI()`` method.
The ``VisualElementComponentInspector<T>`` inherits from ``ComponentInspector<T>`` and its used for creating an Inspector for a Component or MonoBehaviour using Visual Elements.

Features:

* Automatically obtains an UXML instance based off the inspector's name, this UXML instance will be used as the actual UI, which then the inspector passes to an abstract method for initialization.
* A method that you can override to validate if a specified path corresponds to your inspector.

Expand All @@ -121,6 +127,7 @@ The ``ExtendedPropertyDrawer<T>`` is the base class for any and all of RoR2Edito
The TypeParam <T> can be used to specify what kind of value this PropertyDrawer is Drawing. For example, you can use <SkillDef.Variant> to specify that the Property drawer draws a Variant Skill Def. Or you can use <SomePropertyAttribute> to specify the PropertyDrawer is used for drawing a PropertyAttribute (IE: [Range])

Features:

* Access to a EditorSettingCollection for the PropertyDrawer for both Project and Preference settings
* Easy access to the Data youre drawing by using the ``propertyDrawerData`` property.
* Easy access for creating and setting Editor Settings.
Expand All @@ -130,6 +137,7 @@ Features:
The ``IMGUIPropertyDrawer<T>`` inherits from ``ExtendedPropertyDrawer<T>``and its used for drawing Property Drawers using IMGUI.

Features:

* Utility methods for drawing properties using the non automatic layout GUI system

Due to the nature of IMGUI in PropertyDrawers, you cannot use ``EditorGUILayout`` for drawing IMGUI, you'll need to use ``EditorGUI`` instead.
Expand All @@ -139,17 +147,178 @@ Due to the nature of IMGUI in PropertyDrawers, you cannot use ``EditorGUILayout`
The ``VisualElementPropertyDrawer<T>`` inherits from ``ExtendedPropertyDrawer<T>`` and its used for creating a PropertyDrawer using Visual Elements

Features:

* Automatically obtains an UXML instance based off the PropertyDrawer's name, this UXML instance will be used as the actual UI, which then the PropertyDrawer passes to an abstract method for initialization.
* A method that you can override to validate if a specified path corresponds to your PropertyDrawer.

## RoR2EditorKit's base EditorWindows

### TODO
RoR2EditorKit comes bundled with a total of 5 EditorWindow subclasses. These are the EditorWindow sorted in a hierarchy

### ExtendedEditorWindow

The ``ExtendedEditorWindow`` is the base class for any and all of RoR2EditorKit's Editor Windows.

Features:

* Access to a EditorSettingCollection for the Window for both Project and Preference settings
* Implementation of Serialized Object binding for ease of creation of UI
* Generic callbacks for Serialized Object manipulation
* Custom Open method for assigning the Serialized Object
* Easy access for creating and setting Editor Settings.

If youre going to inherit from the ExtendedEditorWindow class, you'll need to implement your own UI utilizing the ``CreateGUI`` method

### ObjectEditingEditorWindow<T<T>> (T : UnityEngine.Object)

The ``ObjectEditingEditorWindow<T>`` inherits from ``ExtendedEditorWindow<T>`` and it's used for creating an Editor Window for editing a single object.

This type is especially useful for creating a complex UI for editing the specified object and making said editing experience better for the end user

Features:
* Direct access to the editing object by using the ``targetType`` attribute.

#### IMGUIObjectEditingEditorWindow<T<T>> (T : UnityEngine.Object)

The ``IMGUIObjectEditingEditorWindow<T>`` inherits from ``ObjectEditingEditorWindow<T>`` and it's used for creating an Editor Window for editing a single object using IMGUI

Features:

* Allows the creation of the UI using only IMGUI

#### VisualElementObjectEditingEditorWindow<T<T>> (T : UnityEngine.Object)

The ``VisualElementObjectEditingEditorWindow<T>`` inherits from ``ObjectEditingEditorWindow<T>`` and it's used for creating an Editor Window for editing a single object using Visual Elements

Features:

* Automatically obtains an UXML instance based off the EditorWindow's name, this UXML instance will be used as the actual UI, which then the EditorWindow passes to an abstract method for initialization.
* A method that you can override to validate if a specified path corresponds to your EditorWindow.

### EditorWizardWindow

The ``EditorWizardWindow`` inherits from ``ExtendedEditorWindow`` and its used for creating complex wizard setups for aiding the end user in development of assets in a semi-asynchronous fashion utilizing Coroutines.

Unlike ``ObjectEditingEditorWindow``s, an EditorWizardWindow works exclusively with Visual Elements, albeit IMGUI can still be used by using ``IMGUIContainers``

Features:

* A Header, Center and Footer pre-created by RoR2EditorKit that displays the wizard's name, your UI content, and buttons for closing and running the wizard
* A Progress bar that can be used to accurately display the progress of the wizard
* Automatically obtains an UXML instance based off the EditorWizardWindow's name, this UXML instance will be used as the actual UI, which then the EditorWizardWindow passes to an abstract method for initialization.
* Robust implementation of asynchronous code utilizing Coroutines thanks to the ``EditorCoroutines`` package.

Alongside the EditorWizardWindow, RoR2EditorKit comes with the WizardCoroutineHelper, which is used to maintain complex, step-based wizard setups (Coroutine for writing text to a file, then a secondary step that does something with said file)

## The Editor Setting system

### TODO
One of the Key Features of RoR2EditorKit is its robust Settings system, the Editor Setting System allows you to save metadata to specific files that contains settings related to misc Types within the editor. Thanks to a powerful string based serialization system, the Editor Settings system can serialize a multitude of types, such as Strings, integer, chars, colours, animation curves, etc.

![image](https://github.com/user-attachments/assets/4ce52a1c-171c-4465-94e8-89cd8254c2d4)

All of the previously mentioned systems (Inspectors, Editor Windows and PropertyDrawers) have access to the EditorSetting system by either using the properties ``xProjectSettings`` or ``xPreferenceSettings``

By default, RoR2 Editor Kit comes with 2 types of Editor Settings.

| Editor Setting Type | Description |
|--|--|
| Project Settings | Located within your specified project, these settings are bound exclusively within the project itself, and are not shared between project instances. |
| Preference Settings | These settings are bound to your machine, and are used across different instances of RoR2EditorKit, a key example is that inspectors being enabled or disabled are considered a "Preference" setting, this way, user A can have the inspector enabled while user B can have it disabled. |

The Editor Settings system is split in 4 key types.

### EditorSettingCollection

The ``EditorSettingCollection`` is a serializable class which as the name suggests, represents a collection of Editor Settings for a specified Type.
A SettingCollection will always have an owner variable which is obtained from the ``System.Type`` that requested the creation of it, albeit in some scenarios the Type could not exist in the project (IE: Its a preference setting from a type thats not present in the current project)

It contains methods for Obtaining or Creating new settings utilizing ``GetOrCreateSetting``, alongside simply assigning setting values and saving the settings.

Editor Setting Collections are stored in what are called ``IEditorSettingProvider``s.

### IEditorSettingProvider

The ``IEditorSettingProvider`` is an interface that can be implemented in an object to mark it as a provider of Editor Settings. It contains the following members to implement:

* A ``List<EditorSettingCollection>``, which are the actual settings stored by the provider.
* A ``string`` property, which is used to represent the provider with a unique identifier name.
* A ``void SaveSettings()`` method, which is used to save the settings for the provider to disk.

RoR2EditorKit comes bundled with two providers, the Project and Preference settings. These are ScriptableSingletons. for more information on scriptable singletons, refer to [this](https://docs.unity3d.com/2021.3/Documentation/ScriptReference/ScriptableSingleton_1.html) page.

IEditorSettingProviders can be obtained by using the ``EditorSettingManager``

### Editor Setting Manager

The ``EditorSettingManager``is a static class that manages providers and works as a front-end for obtaining ``EditorSettingCollection``s.

## RoR2EditorKit Utilities
It contains methods for getting or creating new instances of EditorSettingCollections for specified ``System.Type`` and can be stored in specified Providers. Providers can be specified by either an Enum to represent the default Providers that come bundled with RoR2EditorKit, or via a string for custom providers.

### TODO
The manager also exposes methods for Resetting and Removing entire editor setting collections, or even resetting entire providers. Careful utilization of these methods must be used as you can easily wipe preference settings by mistake.

### Implementing a custom EditorSettingProvider

This part will cover how to implement your own EditorSettingProvider to the manager. below is an example of one using a ScriptableSingleton.

public sealed class CustomEditorSettings : ScriptableSingleton<CustomEditorSettings >, EditorSettingManager.IEditorSettingProvider
{
[SerializeField]
private List<EditorSettingCollection> _projectSettings = new List<EditorSettingCollection>();

List<EditorSettingCollection> EditorSettingManager.IEditorSettingProvider.editorSettings => _projectSettings;
string EditorSettingManager.IEditorSettingProvider.providerName => nameof(CustomEditorSettings);
public void SaveSettings() => Save(true);

private void Awake()
{
EditorApplication.quitting += EditorApplication_quitting;
}

private void EditorApplication_quitting()
{
Save(true);
}

private void OnDestroy()
{
EditorApplication.quitting -= EditorApplication_quitting;
}

[InitializeOnLoadMethod]
private static void Init()
{
EditorSettingManager.RegisterProvider(instance, () => instance);
}
}

Some things to note:

* The InitializeOnLoad decorated attribute is used for initializing and adding the instance of the ScriptableSingleton to the EditorSettingManager. which is how you can expose your provider to the system.
* For a ScriptableSingleton to work properly in the editor you need to decorate the class with a ``[FilePath]`` attribute, more information about this attribute can be found [here](https://docs.unity3d.com/2021.3/Documentation/ScriptReference/FilePathAttribute.html)

### Implementing an UI for a provider

You can utilize the ``EditorSettingsElement`` to expose a provider's editor settings, this can be achieved by using the following constructor

``new EditorSettingsElement((EditorSettingManager.IEditorSettingProvider)settings));``

Afterwards adding the element to any Visual Element will display the provider's settings in a UI

## RoR2EditorKit Useful Classes

The core library of RoR2EditorKit comes bundled with multiple classes that can aid in the development of editor scripts.

| Class Type | Description |
|--|--|
| AssetDatabaseUtil | Contains utility methods for interacting with the AssetDatabase, such as directly obtaining an asset's guid, directly loading an asset via its GUID, Finding Assets |
| AssetGUID<T> | A struct that is used for encapsulating an Asset via its GUID, useful for keeping constants of assets. these assets can then be loaded using the implicit casting operators. |
| ElementContextMenuHelper | A static class that works as an extension for Visual Elements, it allows you to easily add context menus to any element that are visible via an icon that's added alongside the element. |
| IMGUIUtil | A static class that contains methods for drawing controls using IMGUI in an automatic layout context, it contains methods like drawing a property with a check system, and drawing field based on their type. It also exposes a method for drawing a field for an EditorSetting inside a collection. |
| IOUtils | Contains utility methods for interacting with Paths, such as ensuring directories, obtaining currently selected directories and manipulating paths. |
| R2EKMath | A simple math class used for arithmetic operations, including the ability to round vectors to the nearest grid value rounding vectors and a remap function |
| ReflectionUtils | A static class which contains reflection utilities. |
| SerializableShaderWrapper | A class used for serializing Shader objects as shader name or guid. |
| SerializationMediator | A front-end facade for the Serialization system within RoR2EditorKit, it can be used to match the game's serialization methods for usage on runtime solutions. An optional safety bypass exists as a sub-class which should only be used for Editor related solutions. |
| VisualoElementEditorSettingHelper | A static class that works as an extension for Visual Elements, it allows you to directly connect a VisualElement to an Editor Setting. When the value of the Visual Element changes, the value within the editor setting changes as well. |
| VisualElementTemplateDictionary | A ScriptableSingleton that contains a dictionary of string to Visual Element Tempaltes, you can use this to find a UXML Template by name |
| VisualElementUtil | A static class containing a plethora of extension utilities used for Visual Elements |
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Thunderkit - Using the DOTS framework in Modding

The Data Oriented Technology Stack (otherwise known as the DOTS framework) is a development philososphy and technology tools designed for creating fast performant code by utilizing Data oriented programming. which allows for highly efficient and performant code.

The DOTS framework is built on three key pillars, of which 2 are accessible and one is unknown if it can be used in modding.

| Framework Part | Description | Availability |
|--|--|--|
| ESC - Entity Component System | The ECS is a framework that works on a purely data driven design, where it has Entities that populate scenes, but lack data and behaviour, components which hold the data in an Entity, and Systems, which transform the data of components in a deterministic way | Unknown |
| Burst Compiler | Burst is a compiler that can be used alongside the Job system to create code that improves performance by translating your IL/.Net bytercode into native CPU code using the LLVM compiler. | Available, known method via Unity and ThunderKit |
| C# Jobs | Allows you to create multithreaded code for performance intensive tasks, such as multiple transform modifications, complex mathematic operations and more. Has built in guard rails for development of safe multithreaded code | Available |

This guide will not cover how to use the Burst Compiler or how to Write C# jobs, it'll only cover how to get access to the framework on a ThunderKit context and how to compile your mod

0 comments on commit 40cca16

Please sign in to comment.