All Projects → GieziJo → ScriptableObjectVariant

GieziJo / ScriptableObjectVariant

Licence: MIT license
Unity Odin editor helper which permits to set a "SOVariant" attribute to a ScriptableObject and override, or not, certain fields (similar to prefab variants but for scriptable objects).

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to ScriptableObjectVariant

Devtools Playground
Standalone Devtools for prototyping & debugging
Stars: ✭ 190 (+533.33%)
Mutual labels:  inspector
MultiGame
MultiGame is a tool for rapid development in Unity
Stars: ✭ 16 (-46.67%)
Mutual labels:  inspector
v8-inspector-api
A simple node module to access V8 inspector + some tools to export and read the data.
Stars: ✭ 43 (+43.33%)
Mutual labels:  inspector
ScriptableObjectDropdown
Dropdown for ScriptableObjects
Stars: ✭ 40 (+33.33%)
Mutual labels:  scriptableobject
mp4analyser
mp4 file analyser written in Python
Stars: ✭ 50 (+66.67%)
Mutual labels:  inspector
intuit-spring-cloud-config-inspector
Inspection of Spring Cloud Config properties made easy using React
Stars: ✭ 18 (-40%)
Mutual labels:  inspector
Inspector
🕵️ An angular library that lets you inspect and change Angular component properties
Stars: ✭ 169 (+463.33%)
Mutual labels:  inspector
prosemirror-dev-toolkit
Injectable developer tools for ProseMirror rich-text editors implemented in Svelte and TypeScript.
Stars: ✭ 44 (+46.67%)
Mutual labels:  inspector
mdebug
基于React开发的新一代web调试工具,支持React组件调试,类似于Chrome Devtools。A Lightweight, Easy To Extend Web Debugging Tool Build With React
Stars: ✭ 237 (+690%)
Mutual labels:  inspector
httplab
The interactive web server
Stars: ✭ 3,856 (+12753.33%)
Mutual labels:  inspector
license-ls
Get a list of licenses used by a projects dependencies
Stars: ✭ 17 (-43.33%)
Mutual labels:  inspector
build-inspector
Inspect your builds to look for changes in filesystem, network traffic and running processes.
Stars: ✭ 12 (-60%)
Mutual labels:  inspector
BowieCode
Personal Code/Snippet Library for Unity 3D
Stars: ✭ 23 (-23.33%)
Mutual labels:  inspector
Portal
A clojure tool to navigate through your data.
Stars: ✭ 239 (+696.67%)
Mutual labels:  inspector
dom-inspector
Dom inspect like chrome dev tools.
Stars: ✭ 124 (+313.33%)
Mutual labels:  inspector
Marionette.inspector
🔍 Marionette Inspector - Explore your App
Stars: ✭ 170 (+466.67%)
Mutual labels:  inspector
IceKori
A simple Unity-Inspector friendly visual programming language on Unity.
Stars: ✭ 46 (+53.33%)
Mutual labels:  odin-inspector
InspectorClient
Inspector client
Stars: ✭ 13 (-56.67%)
Mutual labels:  inspector
inspector-laravel
Connect your Laravel application to Inspector.
Stars: ✭ 164 (+446.67%)
Mutual labels:  inspector
ConfigAssets
Simple & Lightweight solution for managing configuration assets in Unity projects
Stars: ✭ 26 (-13.33%)
Mutual labels:  scriptableobject

Releases openupm License: MIT twitter

Scriptable Object Variant for Unity (Scriptable Object Data Overrider)

Description

Adds a field to any scriptable object tagged with the [SOVariant] attribute that lets you select an original SO (parent) and override selected fields in the child object.

When changing values in the original, values are automagically propagated to the children.

Usage

Add the tag [SOVariant] before the class header of any ScriptableObject class you want to be overridable, i.e. to be able to create a variant of.

Example:

using Giezi.Tools;

[SOVariant]
[CreateAssetMenu(fileName = "TestScriptable", menuName = "Create new TestScriptable")]
public class TestScriptable : ScriptableObject
{
    [SerializeField] private float myFloat = 3L;
    [SerializeField] private GameObject myGameObject;
    [SerializeField] private int myInt;
    [SerializeField] private TestScriptable myTestScriptable;
}

Create Scriptable Object Variant from context menu

Context Menu

In Unity, you can right click any scriptable object tagged SOVariant to create a variant of this object (Create > Create SO Variant). The new object will have the selected object as parent.

Advanced usage in Editor Script

A helper script has been implemented (SOVariantHelper.cs) which allows you to changed parents, override states and values from within other editor scripts.

Set a new parent:

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
ScriptableObject parent = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/parent.asset");
        
SOVariantHelper<ScriptableObject>.SetParent(target, parent);

Set a field overridable:

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
        
SOVariantHelper<ScriptableObject>.ChangeFieldOverrideState(target, "MyFloat", true);

Set a new value of a field (automatically propagates to children):

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
        
SOVariantHelper<ScriptableObject>.ChangeFieldValue(target, "MyFloat", 45f);

Set a filed to be overridden and set new value (automatically propagates to children):

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
        
SOVariantHelper<ScriptableObject>.SetFieldOverrideAndSetValue(target, "MyFloat", 45f);

Set a parent and set new overridden value (automatically propagates to children):

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
ScriptableObject parent = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/parent.asset");
    
SOVariantHelper<ScriptableObject>.SetParentOverrideValue(target, parent, "MyFloat", 45f);

Set a parent and set new overridden values (automatically propagates to children):

ScriptableObject target = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/child.asset");
ScriptableObject parent = AssetDatabase.LoadAssetAtPath<ScriptableObject>("Assets/Tests/parent.asset");
    
SOVariantHelper<ScriptableObject>.SetParentOverrideValues(target, parent, new Dictionary<string, object>(){{"MyFloat", 45f},{"MyInt", 12}});

Implementation

The visual interface is implemented in Odin's OdinPropertyProcessor. The data with the parent and the overriden fields is kept serialized inside the asset's metadata, set in unity with AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(targetObject)).userData.

Installation

Requires Odin to be installed before adding the package

Using Unity's package manager

Add the line

"ch.giezi.tools.scriptableobjectvariant": "https://github.com/GieziJo/ScriptableObjectVariant.git#master"

to the file Packages/manifest.json under dependencies, or in the Package Manager add the link https://github.com/GieziJo/ScriptableObjectVariant.git#master under + -> "Add package from git URL....

Using OpenUPM

The package is available on OpenUPM. OpenUPM packages can be installed in different ways:

  • via OpenUPM CLI: openupm add ch.giezi.tools.scriptableobjectvariant
  • by downloading the .unitypackage and adding it to your project with Assets > Import Package > Custom Package....

the package will be added as a scoped registry, which you can inspect under Project Settings > Package Manager > OpenUPM.

Alternative

Download and copy all files inside your project.

Known issues and tweaks to be made

List of known issues

Efficiency

The attribute [SOVariant] only acts as tagger, which is then looked for in SOVariantAttributeProcessor:OdinPropertyProcessor -> ProcessMemberProperties, where the first line reads:

if(!Property.Attributes.Select(attribute => attribute.GetType()).Contains(typeof(SOVariantAttribute)))
    return;

The problem with this is that SOVariantAttributeProcessor is thus set to be called for every ScriptableObject:

public class SOVariantAttributeProcessor<T> : OdinPropertyProcessor<T> where T : ScriptableObject

There is probably a way to directly call SOVariantAttributeProcessor from the attribute, but I haven't found how.

Selecting the parent object

The selected parent should be of the exact same class as the overriden item (otherwise fields might be missing) and should not be the child itself. This check is currently done when setting the parent as:

if (parent.GetType() != target.GetType())
{
   Debug.Log("Only equal types can be selected as parent");
   return;
}

if (AssetDatabase.GetAssetPath(parent) == AssetDatabase.GetAssetPath(target))
{
   Debug.Log("You can't select the same object as parent");
   return;
}

It would be alot better to directly filter the possible candidates when selecting in the object, but adding the AssetSelector attribute with a filter, or building a custom ValueDropdown both did not work, not sure why.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].