#↕️┃editor-extensions

1 messages · Page 101 of 1

patent pebble
#

I mean, he can with a custom asset type, but with a default Texture2D asset you can't

#

right?

#

or am I under the wrong assumption

gloomy chasm
patent pebble
#

or are they materials?

#

I've never used Substance

gloomy chasm
patent pebble
#

ah right

#

you can do that with custom asset types

#

but not with the built-in asset types

gloomy chasm
#

You can add any UnityEngine.Object as a subasset of any other asset.

patent pebble
#

last time I checked only ".asset" types support that

gloomy chasm
patent pebble
#

Please note that you should only add assets to '.asset' assets, imported models or texture assets for example will lose their data. from the docs

gloomy chasm
#

The reason you shouldn't is because the UnityEngine.Object (for example Texture2D) is (re)generated when the file is imported. So if you have sub-assets and reimport the texture the Texture2D asset will be recreated and lose it's subasset data.

#

But it is totally possible to do still.

patent pebble
#

oh, my bad then

#

for some reason I was completely convinced that it wasn't possible at all

#

😓

gloomy chasm
#

All good, a good example of it is any time you import a .fbx. It will have things like materials and meshes as sub assets.

patent pebble
#

yep

#

@gloomy chasm but is it then possible to have sub-texture asset within a main texture asset and have Unity still handle it correctly?

#

wouldn't it freak out if you just try to use that texture asset without any custom implementations?

gloomy chasm
pearl drift
#

but you can this

patent pebble
#

hmm I see

#

so you just save the new images with a swapped palette as new sprites then?

pearl drift
#

i still thinking of how i can do this with OnPostprocessTexture

gloomy chasm
pearl drift
#

with custom importer

gloomy chasm
pearl drift
#

i agree that this is not intended

pearl drift
gloomy chasm
patent pebble
#

for this kind of stuff of having multiple versions of a same image I usually just use texture atlases or multiple texture assets with different prefixes or suffixes

#

but I guess your approach could work too

gloomy chasm
#

And even if it was, you can simply do AssetDatabase.IsMainAsset(..)

pearl drift
#

imagine like 40+ sprite frames for just one animated object and multiply it with palette count

patent pebble
#

yeah I see where you come from

#

I'd still probably just handle that at render time instead

pearl drift
#

what you mean?

patent pebble
#

apply the palettes at runtime, either with post-processing or when the textures are rendered

#

my main area of expertise is not graphics, so take this with a grain of salt

pearl drift
#

i want apply palettes at runtime through shader

patent pebble
#

palette swaps are fairly easy to do, specially now with ShaderGraph

#

there's a bunch of tutorials online

pearl drift
#

yes, and all of them has limited color count

#

because guys just shows ReplaceColor node

patent pebble
#

@pearl drift the tricky thing for your implementation will be how to deal with changes in the original texture

#

are you remapping the original pixels based on pixel index or on the original color?

#

*pixel coordinates, not pixel index

pearl drift
#

based on the original color

#

coordinate doesn't matter

patent pebble
#

well I guess if your artists do some changes in the original texture's colors, they can just adjust the palettes accordingly

pearl drift
#

yes, or i can just reimport/rePostProcess it and regenerate palettes

patent pebble
#

I would explore a solution that relies on gray-scale values instead

#

that way you don't have to rely so much on the original colors of the image

pearl drift
#

i think it is the same. The diff is that with "red" solution you just write [0, 255] num into red channel, which will be the index of a color in palette. Grayscale solution just pick [0, 1] and lerp through palette. In all cases you will recolor your source image. In first case it will be black-red and in the second black-white

#

i have seen very smart solution, when guy split index by 3 groups of 2 bits and write them into 2 last bits of each channel, then in shader he reconstruct index from bits and sample palette. The trick is that overriding 2 last bits produces really inconspicuous effect, so your "mapped" image looks exact like source

patent pebble
#

@pearl drift another issue I see with your approach, is that you need to somehow lock the Texture2D asset from having its texture type changed

#

because if you change the type from Sprite to any other, all your palettes will be lost

pearl drift
#

that is another reason to keep palettes separately 🙂

#

good code adventure though

patent pebble
#

yeah that's why I said I'd go a different route

#

Honestly, I would just make a scriptable object store all the palette data and keep a reference to the original texture

#

or something along those lines

pearl drift
#

the 1st i've said was "can we pls just use tints?" and my artist have looked to me with such face i just was unable to refuse

pearl drift
patent pebble
#

yes as long as you keep the data outside of the texture asset, it doesn't matter if the designer messes up the texture type in the inspector and the sprite sub-assets are lost as long as your tool can just re-generate them

#

but at that point I'd skip that and just have the palette tool and then feed those palettes into a shader to swap them as needed

#

seems better than having a bunch of different textures in the same asset

#

you'd have a lot less bloat in size

#

and more flexibility

pearl drift
#

all generates and works well, except it weird grey stripes on final render. I even can't figure where they came from

icy merlin
pearl drift
#

@icy merlin this is strange, because none of textures has filtering, i mean it is point (no filter). Also picking R (or G or B) channel from my grayscale texture will give us 0..1. Here i have 4 different colors and palette texture 4x1. So giving for UV [0, 0.25) will produce 1st color, [0.25, 0.5) -> 2nd color, [0.5, 0.75) -> 3rd color and finally [0.75, 1) -> 4th color. So i think there i no issue with interpolating index.

icy merlin
#

I haven't used ShaderGraph extensively; are you sure that passing nothing in for the sampler will definitely use the sampler set on the texture, not a generic default sampler?

#

(That would certainly be reasonable behaviour to expect, I just don't know if it's what it does or not.)

pearl drift
#

the problem was about TextureFormat

final stag
#

man am i in love with uielements

#

tried to go back to imgui because of an old project and the idea of rebuilding the entire UI in UIElements is haunting me

hasty rover
#

The good news is you cant since ui toolkit isnt on feature parity with the working ui

night siren
#

would it be possible to make a sort of TSubclassOf from UE4 that works on ScriptableObjects? i'd like to use a child class in my ScriptableObject, but it seems like that is not possible 😄

gloomy chasm
night siren
#

i have a scriptableitem class that has a var with type AffixEffect, that isn't a scriptableobject itself, but it has a subclass AffixEffect_Stat which has more vars that i'd like to use instead of the base AffixEffect class

#

sorry if that doesnt make any sense

#

i googled around and people said that unitys serialization doesnt support it, but i just wanted to know if there was a way to make a TSubclassOf<T> from UE4 😄

gloomy chasm
gloomy chasm
night siren
#

CObjectScriptable is just a subclass of ScriptableObject that has some extra stuff

gloomy chasm
night siren
gloomy chasm
#

What does it inherit from?

night siren
gloomy chasm
#

Okay, I see. So can you tell me again what you are wanting?

night siren
#

where it says Affix Effect

#

i want to use the subclass

#

CAffixEffect_Stat

#

so that i can change the values that are to be generated 😄

#

and also other subclasses at some point

gloomy chasm
#

Ah, you need to use the attribute [SerializeReference] in order to have polymorphic serialization on a field.

night siren
#

now its just empty haha 😄

gloomy chasm
# night siren now its just empty haha 😄

That is because it is null 😉
You will either need to make a custom property drawer so you can chose the type, or get an extension from github that adds a drawer for it.

night siren
#

ah right, is there an extension that automatically can draw those, or would i have to write one? 😄

night siren
#

thank you so much man, seriously

#

@gloomy chasm it just works, holy shit. thanks!!

visual jay
#

Hi, for some reason I cannot find a package that I can find in another project, why?

#

These are 2 windows from 2 projects of mine

icy merlin
#

By default it won't show you Preview packages that aren't installed; you have to opt-in to it in settings.

gloomy chasm
visual jay
stone grove
#

is this for unity editor window help

#

i have a problem with it

gloomy chasm
stone grove
#

ok

whole steppe
#

how do i make an inspector button "stay down" once it's clicked once?

#

here's the script i'm using :

private void DrawViewSelectionButtons(SubViewToggle[] subViewToggles)
{
    EditorGUILayout.BeginHorizontal();
    if (DrawingHelper.DrawNarrowButton("X-Axis"))
    {
    }
    if (DrawingHelper.DrawNarrowButton("Y-Axis"))
    {
    }
    if (DrawingHelper.DrawNarrowButton("Z-Axis"))
    {
    }
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    if (DrawingHelper.DrawNarrowButton("Select All"))
    {
        for (int i = 0; i < subViewToggles.Length; i++)
            subViewToggles[i].check = true;
    }
    if (DrawingHelper.DrawNarrowButton("Clear All"))
    {
        for (int i = 0; i < subViewToggles.Length; i++)
            subViewToggles[i].check = false;
    }
    EditorGUILayout.EndHorizontal();
}
#

I want to be able to push down the "X-Axis", "Y-Axis" AND / or Z-Axis buttons & have them stay pushed down once clicked. Then if clicked again, they pop back up. More than 1 of these can be pushed down at once.

wild edge
icy merlin
# whole steppe how do i make an inspector button "stay down" once it's clicked once?

You need to store the button state yourself for each one, and display the button differently depending on whether or not they're true. This StackOverflow question has a bunch of examples: https://gamedev.stackexchange.com/questions/98920/how-do-i-create-a-toggle-button-in-unity-inspector

whole steppe
#

i dont want to use checkbox buttons. I want to use regular buttons.

#

@icy merlin @wild edge

icy merlin
#

You can display the active/inactive status however you like, it doesn't need to be a checkbox. But you still need to store the state and display the button differently depending on it.

whole steppe
#

ok

pearl drift
#

How you guys deal with rect counting when implement custom gui? I'm trying to place EditorGUI.DrawPreviewTexture, and i can't stop looking for some GetCurrentOffset or something like this. Maybe i can somehow get size of current BeginHorizontal or something?

pearl drift
#

@gloomy chasm What is control?

gloomy chasm
pearl drift
#

the rect of the whole thing?

#

i mean i want to place my DrawPreviewTexture() right after last UI element. Unity's editor tools building is the most messed up thing i've seen

clever sun
#

Does anyone know if the Pixel Crushers assets "Dialogue System For Unity" and "Quest Machine" work with Unity’s newer UI Toolkit? I am having trouble parsing all of the UI tool names (1st and 3rd party) for compatibility haha. Thanks!

pearl drift
simple bloom
#

Is there a way I can show an inspector for an object as if it were one of its child classes?

To explain, I have an abstract class SubactionBase, and tons of things that extend it. Some of these classes have serializable public fields. I have a List<SubactionBase> on a script. I have an editor script that adds specific implementations of SubactionBase to the list. How would I go about displaying the inspector for the actual class of that instead of the nothing I get trying to serialize an abstract class? I am expecting to have to do a bunch of if (subaction is ____) in OnInspectorGUI, but is there a way I can just draw the property of that class once I have it cast to what it actually is?

icy merlin
simple bloom
icy merlin
#

In theory I think it should just work in the regular inspector if it has that attribute? I haven't used that path recently myself, though.

#

(And assuming all the relevant classes have [Serializable] attributes.)

#

Basically the hard part is usually getting the list of derived classes to serialize correctly; once that's working the editor gui (hopefully) sorts itself out.

simple bloom
#

I think that might be where I'm tripped up because it doesn't seem to be showing anything

icy merlin
simple bloom
#

Okay, so, hierarchy is this:
The script TestFighter is a MonoBehaviour, it has a public List<FighterState>
FighterState is a plain C# object that is marked Serializable. It contains several List<SubactionBase> as described above, as well as a few serializable fields like StateName.
SubactionBase is [System.Serializable], as are all of it's implementations

In the inspector, I can see the list of FighterStates, but when I add any, they're just empty elements.

simple bloom
#

Wait, I think I see something

#

My list of FighterState isn't [SerializeReference]'d? Maybe that's it?

#

No, that wasn't it

#

I still don't even see the basic string fields and whatnot

#

WAIT. GOT IT.
FighterState itself had an abstract class that wasn't serializable

#

@icy merlin you wonderful wonderful person

icy merlin
#

Yeah, that would probably break it. Sounds like it's all good now!

simple bloom
#

Ahahahah it works! Now I'll go through that blog post and see what I have to do to make the rest of this list look pretty. First step, figure out a way to get Element N to be replaced by the class name. Now that I'm solidly in the realm of "stuff I can reasonably google" I'll see what I can do

supple willow
patent pebble
#

is there a way to get a notification when an internal EditorWindow is closed?

#

I need to run some logic when a ColorPicker window is closed

pearl drift
#

@patent pebble i think it is simpler to compare current and previous color value

patent pebble
#

I just need to get a notification when the ColorPicker window closes so I can set focus to a different control

pearl drift
patent pebble
#

yeah I figured I can just check what window is focused with EditorWindow.focusedWindow

#

I'd prefer if there was a OnClose callback or something that I can subscribe to, would be more readable

whole steppe
#

how do i use

if (DrawingHelper.DrawNarrowButton("X-Rotation")) { rotationAxisSelected = 0; }

as

GUILayout.Toggle ( enableToggle, "Toggle Me", buttonStyle );

?

patent pebble
#

Does anybody know if there's a way to add a button in the bottom bar of the editor?

#

I'm going to make some tools to report some details and warnings about the project and the bottom bar is a perfect location for a visual status icon/button

#

but I have no clue how to add stuff down there, nor where to look in the source code 😅

onyx harness
#

Go injection

#

Look for AppStatusBar, AppToolbar, those types

#

or just open the Visual Debugger

whole steppe
#

someone can help?

#

how do i use

if (DrawingHelper.DrawNarrowButton("X-Rotation")) { rotationAxisSelected = 0; }

as

GUILayout.Toggle ( enableToggle, "Toggle Me", buttonStyle );
#

only posting it 1 more time

patent pebble
#

@onyx harness aaah right right, thanks for the reminder! I always forget about the IMGUI Debugger 🙏

shadow violet
whole steppe
#

no, i want to have a button act like a toggle....

#

@shadow violet

patent pebble
#

@whole steppe use a toggle with the style of a button

#
someBool = GUILayout.Toggle(someBool, "Toggle with button style", GUI.skin.button);```
shadow violet
#

^ Then in addition to that, throw a if-statement for whatever you set your toggle for, below the toggle whenever you need it, if(someBool){ ... }

patent pebble
#

@whole steppe when doing this sort of thing it's usually more helpful to think "I want this control to LOOK like this other control"

#

because you are not changing logic, just the way they are rendered, i.e.: changing their GUIStyle

#

most IMGUI controls have overloads that use styles

#

a "control" in this case is the term used for any IMGUI thing (buttons, labels, toggles, etc)

whole steppe
#

i just want the button to be held down until i click on it a 2nd time. @patent pebble

patent pebble
#

yes

#

that's how toggles work

whole steppe
#

ok

#

@patent pebble : & I want the logic to work with the button. When it's down,
rotationAxisSelected = 0;, AND / OR rotationAxisSelected = 1 AND / OR
rotationAxisSelected = 2;
& you can have more than 1 set value at once

patent pebble
#

@whole steppe do you want only 1 button, or do you have multiple buttons?

whole steppe
#

@patent pebble : I have multiple buttons. "X-Rotation", "Y-Rotation" & "Z-Rotation"

patent pebble
#

@whole steppe can all of those buttons be turned on at the same time? or are they mutually exclusive?

#

if they are mutually exclusive you can use GUILayout.Toolbar, if they are independent you can just use toggles with button styles

whole steppe
#

@patent pebble : They can be turned on at the same time.

patent pebble
#

use toggles as we told you on previous messages

#

and handle the logic inside a bool check

whole steppe
#

that's what i'm doing.....

EditorGUILayout.BeginHorizontal();

// if (DrawingHelper.DrawNarrowButton("X-Rotation")) { rotationAxisSelected = 0; }
// if (DrawingHelper.DrawNarrowButton("Y-Rotation")) { rotationAxisSelected = 1; }
// if (DrawingHelper.DrawNarrowButton("Z-Rotation")) { rotationAxisSelected = 2; }

if ( GUILayout.Toggle ( enableToggle, "X-Rotation", buttonStyle ) ) { rotationAxisSelected = 0; }
if ( GUILayout.Toggle ( enableToggle, "Y-Rotation", buttonStyle ) ) { rotationAxisSelected = 1; }
if ( GUILayout.Toggle ( enableToggle, "Z-Rotation", buttonStyle ) ) { rotationAxisSelected = 2; }

EditorGUILayout.EndHorizontal();
#

@patent pebble

patent pebble
#

you need to cache the toggle's bool

#

and you need to use a separate bool value for each toggle

whole steppe
#

how would YOU do it with this code?

#

@patent pebble

patent pebble
#

i told you on the code snippet I shared

someBool = GUILayout.Toggle(someBool, "Toggle with button style", GUI.skin.button);```
#

then do an if with the someBool

#

and the rotationAxisSelected logic inside

whole steppe
#

ok

patent pebble
#
if (someBool)
{
    // Do thing
}
whole steppe
#

ok

patent pebble
#

but by the look of your code, I would guess you only want to select one axis at any given time

#

in which case, use GUILayout.Toolbar

whole steppe
#

nope, because i want to be able to rotate an object on 2 or more axes at the same time @patent pebble

patent pebble
#

ah, then yeah, toggles

whole steppe
#

ok

#

@patent pebble : How would I cache "enableToggle" ?

patent pebble
whole steppe
#

yes, but that doesn't really tell me anything as i'm using private bool enableToggle = false; at the top of my script

#

@patent pebble

patent pebble
#

then you are caching the result of the toggle in that bool

whole steppe
#

so im already doing it? for some reason when i click the button, it doesn't stay down even though im caching it already.

#

@patent pebble

patent pebble
#

share the code then

whole steppe
#

ok

patent pebble
#

i literally copypasted you multiple times how the toggle is supposed to be used, you can also check the documentation

#

I'm sorry but I just can't keep copypasting the same thing over and over if you refuse to use the information we give you 🤷

whole steppe
#

@patent pebble :

public class StudioEditor : Editor {

    private GUIStyle buttonStyle;
    private bool enableToggle = false;

    public override void OnInspectorGUI() {        EditorGUILayout.BeginHorizontal ( );
        bool xRot = GUILayout.Toggle ( enableToggle, "X-Rotation", GUI.skin.button );
        EditorGUILayout.EndHorizontal ( );
    }

}
gloomy chasm
whole steppe
#

how would i set it, @gloomy chasm ?

gloomy chasm
whole steppe
#

I do do that already, @gloomy chasm :

bool xRot = GUILayout.Toggle ( enableToggle, "X-Rotation", GUI.skin.button );
gloomy chasm
patent pebble
#

@gloomy chasm hey iirc you mentioned you are quite experienced with the whole View, GUIView, HostView, etc thing, and I was wondering what would be a good approach to insert stuff into existing Views

#

I've been digging for a couple hours and so far I've only figured I can use the position of an existing View, create my own View and then draw whatever I need to insert there

#

I'm trying to add stuff to the top toolbar and the bottom toolbar of the Editor

gloomy chasm
#

What version of Unity?

patent pebble
#

2020.3.3 and upwards

#

Im trying to add buttons there

#

but in the top Toolbar they would mess up with the auto layout of unity

gloomy chasm
#

In later versions the AppStatusBar is UITK as well. But for 2020.3 idk if you can do much without using something like Harmony.

patent pebble
#

@gloomy chasm hmmm, I'm trying to stick with LTS versions for now

#

I'll check out UITK

#

I guess for now, I will try to just overdraw on top, and for cases where the main window is too small and the layout gets shrunk in, I can just draw on top of the small "packages in use" yellow dropdown

#

and on the bottom on top of the generating light info area

#

(whenever it's not generating lighting settings)

gloomy chasm
#

That is for adding visual elements to the toolbar.

patent pebble
#

@gloomy chasm oh, that's pretty neat!

#

I wonder if something like that is possible just with IMGUI, there's a ton of methods and properties on the Toolbar class that I haven't tested yet

gloomy chasm
#

Just come to the dark(UITK) side! You cannot resist forever!

patent pebble
#

i may actually have to finally learn UITK 🙃

pearl drift
#

I'm struggling with color field. I need to place dynamic count of color fileds in a row (horizontally) but i can't figure out why those fields not adapt to window width whatever GUILayoutOption i pass and i get this editor view, where you can see just one and a little part of color field but there are 14 more in right lands

patent pebble
#

@pearl drift share code

pearl drift
#

@patent pebble ```csharp
EditorGUILayout.BeginHorizontal();

        for(int i = 0; i < palette.Count; i++)
        {
            palette[i] = EditorGUILayout.ColorField
            (
                new GUIContent(string.Empty),
                palette[i],
                false,
                false,
                false,
                GUILayout.MaxWidth(_paletteElementSize),
                GUILayout.ExpandWidth(true)
            );
            GUILayout.FlexibleSpace();
        }

        EditorGUILayout.EndHorizontal();
I think there is some default color field width, because GUILayout.MaxWidth() + GUILayout.ExpandWidth(true) helps
patent pebble
#

@pearl drift you can just do GUILayoutUtility.GetRect and then edit the values as you want

pearl drift
#

Perfectly i want some logic to move elements to next line if window's width capacity was reached. Must be easy as just call Begin and End horizontal on over width

patent pebble
#

I can share the logic for the rows columns

#

also, for your thing you may want to use the internal Color field without the picker

#

looks cleaner

#
private void DoColorField(Rect rect, SerializedProperty colorProp)
{
    int id = EditorGUIUtility.GetControlID(FocusType.Passive);
    object[] args = new object[] { rect, id, colorProp.colorValue, false, false, false };
    colorProp.colorValue = (Color)EditorGUIProxy.DoColorField(args);
}

private static partial class EditorGUIProxy
{
    public static System.Reflection.MethodInfo m = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.EditorGUI").GetMethod("DoColorField", (System.Reflection.BindingFlags)60/*Instance|Static|Public|NonPublic*/);
    public static object DoColorField(params object[] args)
    {
        return m.Invoke(null, args);
    }
}
pearl drift
pearl drift
patent pebble
#

because SerializedProperties are the best way to deal with Editor data

#
private void CalculateGridDimensions()
{
    int elementCount = Data.currentTexturesSearched.Count;

    float usableWidth = Structure.GridViewRect.width - Structure.gridViewMargin.x * 2 - Structure.scrollbarWidth + Structure.gridElementSpacing;

    int maxColumns = Mathf.FloorToInt(usableWidth / (Data.GridElementSize + Structure.gridElementSpacing));
    Data.rows = Mathf.CeilToInt((float)elementCount / (float)maxColumns);

    if (elementCount < maxColumns)
    {
        Data.columns = elementCount;
    }
    else
    {
        Data.columns = maxColumns;
    }
}```
#

here's the code to calculate a grid

#

it's a bit out of context

#

but you get the idea, instead of assigning to the Data.rows / Data.columns you can return a Vector2 or something

patent pebble
#

for the "usableWidth" you pass the total width of the area you are drawing in, usually the inspector or editorwindow width - some margin values

#

and for the maxColumns you just divide the usableWidth by the width of an element

#

this is assuming all your elements have the same width

pearl drift
#

yep, this is clear 🙂

patent pebble
pearl drift
#

What with UI Toolkit? Can we do same things with it more easily

patent pebble
#

i'd assume the logic itself would be pretty similar

gloomy chasm
patent pebble
#

@gloomy chasm IMGUI is a pain in the ass to do some basic things

#

like grids or radio buttons

gloomy chasm
patent pebble
#

yeah, scrolling, freeflowing and variable grid sizes

#

gets a lil janky

gloomy chasm
#

Radio buttons, you mean like where only one can be toggled on at a time?

gloomy chasm
patent pebble
patent pebble
#

doing a grid with scrolling in both axis, zoom in/out, free flow, different element sizes and drag and drop features

#

first time I did it it took me a while

gloomy chasm
#

Ah, yeah. I think it ended up taking me a day or so to do? But I was also making a more 'generic' base so I could have a 'grid view' control and a 'list view' control.

patent pebble
#

but I don't do a lot of stuff with grids, so there's no rush for me

drowsy marten
#

are there plans to be able to serialize custom classes on base class variables?

#

or is the only way rn is to use scriptable objects/monobehavior?

icy merlin
drowsy marten
#

thank you, very veyr much

#

im about to lose my mind

icy merlin
#

It's not a complete solution on its own (you may need custom editor code depending on what you want to do) but it should handle the serialisation part.

drowsy marten
#

i already have the editor

#

the only problem is it reverting to the base class

drowsy marten
#

it worked!

#

just had to undo my changes and add "SerializeReference"

terse hazel
#

Are PropertyDrawers using UI Elements currently broken?

I have this quick test, but it shows No GUI Implemented

PropertyDrawer TestTypeDrawer.cs

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;

using UnityEngine;
using UnityEngine.UIElements;

[CustomPropertyDrawer(type: typeof(TestType), useForChildren: true)]
public sealed class TestTypeDrawer : PropertyDrawer
{
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        Debug.Log("Active");
        
        VisualElement container = new();

        FloatField floatField = new(label: "Fancy Label");
        floatField.RegisterCallback<ChangeEvent<float>>(callback: evt =>
        {
            Debug.Log(evt.newValue);
        });

        container.Add(floatField);
        
        return container;
    }
}
#endif

Type TestType.cs

using System;
using UnityEngine;

[Serializable]
public struct TestType
{
    [SerializeField]
    private Int32 i;

    public TestType(Int32 i)
    {
        this.i = i;
    }
}

Usage Usage.cs

using UnityEngine;

public class Usage : MonoBehaviour
{
    [SerializeField] private TestType testType;
}
```EDIT: Fixed fault in example code.
#

The debug messages are never logged.

#

If I remove the property drawer it works just fine.

icy merlin
#

I haven't used UIElements, but shouldn't you do something with the floatField? Like, add it to the container?

vapid prism
terse hazel
terse hazel
vapid prism
terse hazel
#

Yeah, that's what I did now.
However, that might break third-party dependencies. They might be doing the same things and that could be troublesome.

vapid prism
terse hazel
#

Unfortunately my fears were not unfounded.
The inspector breaks when importing Odin.

vapid prism
#

Does Odin make their editors support UI Toolkit Property Drawers? Might work when they've wrapped it.

terse hazel
#

Nor does it change when I change the execution order, but that would likely still break things.

vapid prism
#

Welp that sucks a bit. The latest Unity 2022 Alpha supposedly now supports UI Toolkit Property Drawers out of the box though, so maybe by 2023 Toolkit is viable for such a thing?

terse hazel
#

We'll have to wait and see. UI Elements certainly has a lot of promise - so I'm looking forward to it.
Bit of a shame it wasn't done when the new editor UI was introduced.

terse hazel
summer creek
#

Hey, I'm using VSCode with C# extension to edit Unity scripts, but for some reason there's no autocomplete for whatever I'm trying to write

#

on linux btw

pearl drift
#

is there a way to avoid space between elements?

#

or get width of this spaces

visual stag
#

If this is IMGUI, create a modifed GUIStyle

pearl drift
#

no, this is custom editor window

visual stag
#

IMGUI or UIToolkit.

pearl drift
#

oh, not UIToolkit, then it is IMGUI

#

but i see no method to pass GUIStyle to color field

visual stag
#

Then your other option is to position them manually with EditorGUI instead of EditorGUILayout

patent pebble
#

i was making an extension method to get the array from a SerializedProperty

public static T[] GetSerializedPropertyArray<T>(this SerializedProperty property)
{
    if (property == null || property.arraySize == 0)
    {
        return null;
    }

    if (property.isArray == false)
    {
        throw new ArgumentException($"{property.name} is not an array property");
    }
...
#

but it seems to fail with any kind of multidimensional, or nested collection

#
[SerializeField] string[,] _test;
#

My Unity serialization knowledge is rusty

#

is this not allowed?

visual stag
#

string[,] is not serializable

#

you can just look in the debug inspector and see if it's there

#

if it's not, it's not serialized

patent pebble
#

@visual stag aaah right right. I should've checked if it was displayed on the inspector
I was doing this for an EditorWindow tool so the thought didn't cross my mind

#

thx for the answer

gloomy chasm
patent pebble
#

does the new [SerializeReference] change anything regarding collections and serialization?

#

Generic Lists and array fields decorated with [SerializeReference] apply the attribute to the elements of the list/array not the list/array instance itself. only found this on the docs

gloomy chasm
gloomy chasm
patent pebble
#

@gloomy chasm i see, thx again 🙏

forest lava
#

anyone know any good sword mechanics

#

wrong chat

glacial plank
#

Anyone know how to get the values of a List<Type> using serializedProperty?

waxen sandal
#

arraySize/getarrayelementatindex

#

or something like that

glacial plank
#

Yeah, that gives you a property reference to the element, but how do you modify the element value

waxen sandal
#

Depends on the type of your list

#

Or is it system.type

glacial plank
#

Yeah System.Type

waxen sandal
#

System.Type is not serializable by default

glacial plank
#

Hm okay, so I was going off the advice from the web that it's better to use serializedProperties instead of directly modifying the values yourself...

When I directly modify them and then call EditorUtility.SetDirty(target) the object doesn't seem to save

#

Any way to go that route instead?

waxen sandal
#

That advice is correct

#

But your type won't save

#

You'll have to write something to serialize it yourself

glacial plank
#

So you're saying the scriptableObject itself will refuse to save non-serializable fields?

waxen sandal
#

Not the scriptableobject, but the serialization system that saves fields to files on your disk

#

There's a bunch of open source serializable types

glacial plank
waxen sandal
#

Yes

glacial plank
#

Okay, good to know. Thanks

fickle quarry
#

I am creating assets and wondered if I can manage all my assets in 1 project. I want to have 1 main folder with the company name, with 1 subfolder per asset. To upload the asset I have to select the company folder, without being able to select the subfolders.
Does this mean I have to use 1 project per asset? I would like to manage it all in a similar way because the assets can support each other.

rocky jasper
#

How do you tell the inspector to display a variable like this?

#

I'd like to have a range setting with a min/max

fickle quarry
rocky jasper
fickle quarry
#

Owhh understood it wrong

gloomy chasm
rocky jasper
shadow violet
#

Any idea what causes e.DrawHeader(); to do... This? And any way to fix it? O.o

Component[] components = Selection.activeGameObject.GetComponents<Component>();
for (int i = 1; i < components.Length; i++)
{
Editor e = Editor.CreateEditor(Selection.objects[0]);
e.DrawHeader(); //withtout this, everything works fine but I want to also include a header, is there another way?
Editor editor = Editor.CreateEditor(components[i]);
EditorGUILayout.InspectorTitlebar(true, components[i], true); //this just displays the header "Transform", "Box Collider", "Mesh Filter", etc
editor.OnInspectorGUI(); //this is supposed to display the serialized variables of "components[i]", which works but why DrawHeader cause it to get squished regardless of the width of my custom editor window?
}

Is there some other line I need to "end" or "close" the draw call or something? Why would it cause everything to get squished like that?

#

(sorry image didnt get attached in my last message o.o)

visual stag
#

Presumably something is changing EditorGUIUtility.labelWidth and not setting it back

shadow violet
#

Hmm, interesting, for the time-being I basically just tried to replicate the header manually (downside is I cant get the static dropdown and icon change menu but I guess thats not terrible), that GUIUtility code might give me a place for research though, so thanks for that

shadow violet
simple bloom
#

Is there a way I can draw a property only if a list is expanded? I have a List of a serialized class and I want to add in a special add button to the list, but I only want it visible while that list is expanded. I know I could make a custom class that extends List and do a property drawer, but is there another way to do this without making a new class?

#

Okay, I tried the "make a class that extends list" solution and it doesn't work. It doesn't seem to display the list properly.

patent pebble
#

it depends a lot on the situation

#

if you want a button only on the top of the list or if you want it on every element of the list

#

you can use a custom attribute to add buttons to variables, there's a bunch of them online

#

and I think NaughtyAttributes also does, but I don't know if they are only method buttons or not

placid hamlet
#

Fellow editor extenders

#

I am confuse

#

I have a bunch of ScriptableObjects with custom inspectors, and for some reason only one of them keeps its values when I close down the project

#

The mysterious vanishing data is in a List and is represented using a ReorderableList

#

The code in question:

{
    FieldInfo[] fields = typeof(PlayerData).GetFields();

    foreach (FieldInfo field in fields)
    {
        SerializedProperty serializedProperty = serializedObject.FindProperty(field.Name);

        if (serializedProperty.isArray)
        {
            ReorderableList reorderableList = new ReorderableList(serializedObject, serializedProperty, true, true, true, true);

            reorderableList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, serializedProperty.displayName);
            reorderableList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => EditorGUI.PropertyField(rect, serializedProperty.GetArrayElementAtIndex(index), GUIContent.none);
            reorderableList.onAddCallback = (ReorderableList reorderableList) => serializedProperty.ArrayAdd(toAdd => toAdd.isExpanded = true);

            reorderableLists.Add(reorderableList);
        }
        else
        {
            serializedProperties.Add(serializedProperty);
        }
    }
}

public override void OnInspectorGUI()
{
    foreach (SerializedProperty serializedProperty in serializedProperties)
        EditorGUILayout.PropertyField(serializedProperty);

    EditorGUILayout.Space();

    foreach (ReorderableList reorderableList in reorderableLists)
    {
        reorderableList.DoLayoutList();
        EditorGUILayout.Space();
    }

    if (serializedObject.ApplyModifiedProperties())
        AssetDatabase.SaveAssets();
}

private List<ReorderableList> reorderableLists { get; } = new List<ReorderableList>();
private List<SerializedProperty> serializedProperties { get; } = new List<SerializedProperty>();```
#

Ah, looks like I solved it

waxen sandal
#

Define refresh

#

That can be like a 100 different things

pure siren
#

Why does Don't Save actually save?

#

Am I missing something?

#

Dumbest thing I've seen in a while

vapid prism
#

So it's Save modifications, discard changes, and do nothing on Save/don't/cancel?

pure siren
#

Note: Currently a window with three buttons is shown. Save and /Don't Save/ both cause the Scene(s) to be written. Cancel leaves the Scene(s) untouched

#

From the Docs ^^

#

Like who would ever want that?

patent pebble
#

@pure siren are you sure the "Don't save" option actually saves the scenes?

#

last time I used it, only the 1st option saved scenes

#

I'm pretty sure the Save and Don't save both return true, but only the first one will save the scenes

icy merlin
#

If that's the case then the documentation is wrong, which would be bad too.

patent pebble
#

you use 'Save' or 'Don't Save' to continue and do whatever you do (usually open a new scene or something like that)

#

and you use Cancel to just cancel the thing you would do

#

at least that's how I remember it

icy merlin
#

I agree that the return value behaviour makes sense, though it should be more clearly documented.

patent pebble
#

docs seem to be updated in the recent versions

#

but not on the current LTS doc versions

#

If the user selects Save, the Editor saves the modified Scenes. If the user selects Don't Save, the Editor does nothing. However, both Save and _Don't Save__ indicate that the user is okay to proceed with the current operation (closing the Scenes). Therefore both these choices return true to indicate that the operation can continue.

#

@pure siren there's your answer

#

they should update the current versions of the docs 😓

#

I've left feedback on that docs page. But i have no clue how long they take to fix this sort of thing

pure siren
#

It still doesn't allow you to check if Save or Don't Save was clicked. Although I don't really see a use case for that, it could be implemented manually with DisplayDialogComplex.

patent pebble
#

@pure siren i believe there's events that notify you when a scene is saved

#

so you can just use those to check if Save or Don't Save was clicked

viscid bear
#

Is there a way to add a function to EditorGUILayout.Foldout like we can do with button.onClick.AddListener? I want to execute function whenever user clicks on the foldout or label.

shadow violet
# viscid bear Is there a way to add a function to EditorGUILayout.Foldout like we can do with ...

AFAIK you cant extend the Foldout directly, though because it returns a bool, you could setup your own event with a "last state" of the returned bool, for example:

System.Action OnSomeEvent;
bool isFoldoutExpanded;
bool lastFoldoutState;

//Somewhere in OnGUI()
isFoldoutExpanded = GUILayout.Foldout(isFoldoutExpanded, ...);
if (lastFoldoutState != isFoldoutExpanded) {lastFoldoutState = isFolderExpanded; OnSomeEvent?.Invoke();}

Then if you need to if(isFoldoutExpanded) {DisplayGUIStuff();}

waxen sandal
#

The correct way is using the Event.current field and check the type etc... But that can get quite complicated so if you need something simple then the above works

regal crest
#

hi, i wonder if there is a straightforward way to make Foldout Headers. Like i would like a header to foldout all variables inside of it.

#

i can use foldout to find Transform, or specific properties, but how do i tell him to foldout all headers?

patent pebble
#

Does anybody know how to check if the Inspector window is currently showing the vertical scrollbar?

#

I'm making a custom editor for some scriptable objects and I need to know so I can adapt my rects accordingly

real ivy
#

Hi all
Just wondering how can i check if the selected is an fbx asset?
Selection.activeGameObject.name.EndsWith(".fbx") this doesn't work it seems

#

O i can use AssetDatabase.GetAssetPath

radiant swallow
#

I'm attempting to make a custom editor window for my dialog. I'm having two nagging issues I cannot seem to figure out. First, when editing text in the text area, the undo is not recording at all. Second, when I make a change in script and it reloads, I lose all my drawn Beziers until I add a new node. Any help would be greatly appreciated. https://paste.ofcode.org/yt6D5pRDkSWquzri66eXNv

waxen sandal
patent pebble
waxen sandal
#

Ugh, I must be misremembering the name

#

sec

visual stag
#

Losing data over script reloads is also a lack of serialization

radiant swallow
#

That is why I stopped serialization on most of the values. private SO_Dialog selectedDialog; private GUIStyle nodeStyle; [NonSerialized] private DialogNode draggingNode; [NonSerialized] private Vector2 dragOffset; [NonSerialized] private DialogNode queuedNodeParent; [NonSerialized] private DialogNode queuedRemoveNode; [NonSerialized] private DialogNode queuedNodeToConnect;

#

should I also be specifically telling it to serialize something?

patent pebble
#

but I can't get the value from the m_scrollPosition

#

inspector.GetType().GetField("m_ScrollPosition").GetValue(inspector)
I can't get that, i don't know if it doesn't exist anymore in the InspectorWindow class or what

waxen sandal
#

Another easy way is to use guilayout to get a rect with max width

patent pebble
#

I can't believe it was that simple 😶

#

I have been struggling with this issue for months, and every time I just gave up and made all my tools preemptively add a buffer margin to account for scrollbars

visual stag
patent pebble
#

@waxen sandal thanks a lot 🙏 do you know if getting a rect with 0 height can cause problems for the layout system?

Rect testRect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 0);
#

I remember having situations where my entire Unity exploded when getting zero-height elements in ReorderableLists

waxen sandal
#

I haven't had issues with that

#

But it might add a few pixels of padding if you use more guilayout

patent pebble
#

@waxen sandal I see, I'll keep an eye for that. Many thanks

summer creek
#

Why am I getting this in my output

[fail]: OmniSharp.MSBuild.ProjectManager
        Attempted to update project that is not loaded: /home/araraura/Unity/Projects/test/Assembly-CSharp.csproj
[warn]: OmniSharp.Roslyn.CSharp.Services.Navigation.FindUsagesService
        No document found. File: /home/araraura/Unity/Projects/test/Assets/test.cs.

I'm trying to use unity on linux through vscode and I've installed everything the arch wiki told me to, and still
if anyone knows then please ping me

summer creek
#

Also I have another issue where Rider doesn't appear in external tools

worthy dust
summer creek
weak void
#

Hi! I have a question regarding a custom inspector editor. I'm trying to draw the contents of a list where each entry should be on a new line. I'm using EditorGUILayout.BeginHorizontal and EditorGUILayout.EndHorizontal around each entry, but they still all draw on the same row. I'm not super familiar yet with all the gui layouts yet

waxen sandal
#

You probably want some BeginVertical

weak void
#

Replacing the horizontal with vertical draws each element below each other

#

Just to confirm, each number should be on a new line. I wasn't really clear about that 😄

waxen sandal
#

Don't replace

#

Add it around your loop

weak void
#

That works and I just realized why.. Thanks!

ornate lantern
#

Is there a way to make a MenuItem async? I want to open all scenes and take a screenshot of each one for a thumbnail for a level selector. This only screenshots the last scene as it's not asynchronous.

onyx harness
#

You might want to use coroutine

waxen sandal
#

async/await probably works as well

worthy dust
#

@summer creek where ever you installed rider, just manually point unity to rider's executable

summer creek
#

yea i installed it through the AUR so i didn’t know where it was

wind heart
#

Does anyone have any tips, or an editor extenstion, to help with placing objects in a scene? For example, I want to place a reflection probe in the scene on the ground in front of where I'm currently standing in the scene view. But if I create a new reflection probe in the heirarchy it appears at 0,0,0 and finding it and dragging it to my current scene location is a chore. Often I will create the object as a child of something nearby and then drag it out, but that too is problematic when I have hundreds of placed objects in my scene, so then I have to open two hierarchy windows and lock one of them to the probes section, which is also a pain. Why can't I simply right click in the scene, and get a context menu, with add item, and maybe a toggle to select "under cursor" with it doing a raycast into the scene that can collide with terrains, or "at my location"? This would save literally thousands of hours and I don't understand why Unity doesn't have this as a built in feature for scene construction.

#

I can't even drag the object I created into the scene view to have it placed where the mouse is...

#

Well that does work with prefabs... Maybe if I create a prefab of a reflection probe? The idea is ridiculous but...
Well that seems to have worked, though I can't seem to slide the probe around on the terrain keeping it at the terrain height by holding shift, which I thought worked with other objects...
Ah, I see, it's shift and ctrl to do that. It's called surface snapping:
https://docs.unity3d.com/Manual/PositioningGameObjects.html

waxen sandal
#

I've craeted scripts in the past to move objects in front of the camera

#

Or to raycast into the scene and instantiate an object at the hit point

icy merlin
meager sigil
#

Is there a way to change this via a script ?

#

Basically to check quick multiple resolutions to see if everything UI related behaves correctly

waxen sandal
#

Reflection can do it iirc

wind heart
icy merlin
meager sigil
#

@heady shadow @icy merlin You are great, thanks for the pointers.

patent pebble
#

Is there a way to force Unity to refresh the priority order on the menu items on the top bar?

#

usually I have to comment out the [MenuItem(...)] attribute in the script, recompile, uncomment and recompile

#

only that seems to update the order of the menu items

#

there has to be a better way to do this, anyone has info on this?

waxen sandal
#

Not aware of anything

#

Unfortunately

patent pebble
#

restarting Unity seems to work too, but it gets annoying with heavy projects

waxen sandal
#

The whole menu item thing is a big mess

patent pebble
#

yup

#

maybe it's possible with reflection to update the value, it has to be cached somewhere

#

but I have no idea where to begin looking

waxen sandal
#

Not sure but I vaguely remember trying to look into it and not finding anything before

patent pebble
#

the weird thing is that sometimes they refresh just fine, but other times they don't 😅

#

found these two classes on the source MenuService, MenuItemScriptCommand

#

i'm hoping some of the methods there can be used to solve this

icy merlin
#

In the past I've found Unity to be quite aggressive in caching things based on attribute data; scripts would often continue running in edit mode for a while after I removed their [ExecuteInEditMode] attributes, for example.
What Unity does or does not reload on script recompilation has always been extremely confusing to me.

fickle quarry
#

I followed the Unity Guide for making the project, but wonder:

If my asset isn't that big, and a tool, would it be better to put the asset in a Plugin folder in the root or still the name of my company?

https://www.youtube.com/watch?v=Sp7vUE3Hmtw

gloomy chasm
fickle quarry
#

Good to know, thanks!

patent pebble
#

what's the correct way of copying a SerializedProperty?

#

i have PropertyA and PropertyB

#

they are both arrays

#

I want to copy the values from A to B

#

do i need to iterate over every element individually and copy it? Or is there a simple way of just copying the entire array?

gloomy chasm
#

serializedObject.CopyPropertyValue(..) or something like that

patent pebble
#

but from what I've seen that's used to copy 1-to-1 representations of serializedpropertys between 2 different SerializedObjects

#

I'm not sure tho

gloomy chasm
#

Are the properties you want to copy at different paths?

patent pebble
#

they seem to be using it to copy values from one SerializedObject to another SerializedObject

gloomy chasm
#

If CopyFromSerializedProperty doesn't work for you, I think you need to be more specific in what you are doing exactly.

patent pebble
#

I'll share some context on my situation

gloomy chasm
patent pebble
gloomy chasm
#

Yeah, thinking about it, it uses the path.

#

So if the path is different it will not work.

patent pebble
#

I have a wrapper class that has an array, and a container class that has multiple wrappers

[Serializable]
public class Wrapper
{
    [SerializeField] private Color[] _array;
}

public class Container : ScriptableObject
{
    [SerializeField] private Wrapper _originalWrapper;
    [SerializeField] private Wrapper[] _modifiedWrappers;
}
#

in my particular case, I want to make copies of the _originalWrapper and paste them in the _modifiedWrappers array

#

looping through the color array and assigning individually every element works fine, but it's ugly and has a lot of boilerplate code

#

so I was wondering if I can just straight up copy the entire property

gloomy chasm
#

I see, I don't think that there is a built-in way to do it. You could write an extension method that does it though.

patent pebble
#

so I guess I'll go the same route and make one for setting arrays

gloomy chasm
#

I would switch on the target property's type, and if it is a basic type, then copy it, otherwise iterate through both of the properties recursively calling the method.

gloomy chasm
patent pebble
#

found this online

#

seems to work for any property

gloomy chasm
patent pebble
gloomy chasm
patent pebble
visual stag
#

2022.1.0a15

Serialization: Added: SerializedProperty.boxedValue property.
Serialization: Added more examples to the reference for dealing with Arrays with SerializedProperty.
Serialization: SerializedProperty.boxedValue property supports reading and writing entire Structs.

gloomy chasm
#

I also wonder why it is just structs and not classes considering that on the serialization side they are both treated as value types.

visual stag
#

I am on my phone, so no. But I presume object

#

Seeing as, ya know, it's boxed

gloomy chasm
#

Yeah, I would assume that it would be object, just curious ya know.

onyx harness
#

it is object

gloomy chasm
#

Alrighty, thanks.

onyx harness
gloomy chasm
#

On interesting, that could actually be quite handy.

#

Why is the Integer just a break?

onyx harness
#

enum as well

#

because of that :

gloomy chasm
#

Ah, got it.

visual stag
#

Huh, so how does the struct part work

gloomy chasm
#

Looks like it is just a object field called structValue

visual stag
#

Oh, I see

onyx harness
visual stag
#

Certainly still unclear whether that would work on a class

#

I also wonder when the CsReference updates

#

seeing as we are behind again

onyx harness
#

Won't change anything, GetStructValueInternal is external

visual stag
#

I know, I'm just speaking generally

gloomy chasm
#

I would assume it doesn't work for classes since the method name specifies struct.

#

Though again, I wonder why.

visual stag
onyx harness
#

Yeah

visual stag
#

everything mentions "properties" and that's not talking C#

gloomy chasm
visual stag
#

Will have to wait until someone tests it 😄

gloomy chasm
#

I won't be able to test it until this evening, but if no one else has by then I will and will let you know. 🙂

visual stag
#

now I might have to include boxedValue 😓

#

I've already forgotten that other addition to serialization that happened last release (maybe I'm hallucinating)

onyx harness
#

I feel really outdated in Unity now

gloomy chasm
visual stag
#

I might have just been thinking of that weird UIToolkit property drawer mention

gloomy chasm
visual stag
#

I'm glad they're putting packages under headers now.
I also note in this release that they've dealt with the overhead of just having the Visual Scripting package in your project

#

So for those that didn't just remove it as the first step, rejoice

gloomy chasm
visual stag
#

I mean this

gloomy chasm
visual stag
#

Previous release got a bug with this much code fixed:

using UnityEngine;

public class Container : MonoBehaviour
{
  public Object[] Data;
}```
Next release I report this one with this much code:
```cs
using UnityEngine;

public class Container : MonoBehaviour
{
  public string[] Data;
}```
#

just feels stupid

#

(and while reporting that one, I find another one)

gloomy chasm
visual stag
gloomy chasm
#

That's so broken, that should be a high priority bug... right... right??

visual stag
#

You would think so

gloomy chasm
#

I never even saw that it was in preview, was it ever a public preview? I will have to check it out!

visual stag
#

No preview

gloomy chasm
#

I would have thought that they would have tbh.

visual stag
#

The needle guys pick up on these packages a little earlier than the notes do so if you do want to find stuff early I'd recommend their server https://discord.gg/8ubk9xqE

gloomy chasm
#

Cool, thanks.

#

Ah yes, because this is helpful. I now know exactly what changed...

onyx harness
#

Hahaha

tough cairn
#

will changes to a scriptable object will persist in Build ?

#

( when u reopen the app , would it have the same data as the last play session )

split bridge
visual stag
split bridge
opaque viper
#

is odin editor any use?

waxen sandal
#

If you want low effort, decent editors sure

#

But you'll have to spend time learning it

icy merlin
#

If you already own it (e.g. from Humble Bundle) then it can be quite a timesaver. Whether it's worth the money if you don't is more dubious.

urban spruce
#

guys why my editor is not have unity intalisions?

opaque viper
#

sorry but i dobt understand your english

opaque viper
radiant swallow
#

When I run undo on this code it brings the file back but how do I make undo include all the operations in this function? I.E. When I control+Z the file comes back but the list is still missing the node ect. ```
public void RemoveNode(SO_DialogNode queuedNode)
{
foreach (SO_DialogNode node in nodes)
{
node.RemoveChild(queuedNode.name);
}
nodes.Remove(queuedNode);
CreateLookup();
Undo.DestroyObjectImmediate(queuedNode);
}

gloomy chasm
gloomy chasm
# radiant swallow Thank you.

You most likely want to Undo.IncrementGroup()(Or similar name) at the end so that if you remove multiple nodes one right after another they will be separate operations.

gritty forge
#

Anyone know if there's a way to get the editor to respect visual studios "exclude from project" setting on source files? I've been digging a bit but can't seem to find anything about it.. not sure I want to roll my own editor extension yet

#

I have some source files that I want access to as I refactor, but don't want compiled (since obviously the refactor is breaking those files as well)

#
  <ItemGroup>
    <Compile Include="Assets\Archived\Scripts\ARCHIVED_GameManager.cs" />
    ... x 10,000 ...

Essentially getting unity to read/use this Compile group in the Assembly-CSharp.csproj file..

icy merlin
gritty forge
#

Ah, interesting. I could try just making an .Archived folder under scripts

#

success!

#

That is .. lovely. Thanks @icy merlin. So, if you want to have a script (that's not mass-commented out) you can just create an .Archived folder (note the dot) and then exclude the items in Visual Studio. VS won't compile them and unity won't import them (and hence, won't write them to the .csproj file) and voila, you can keep that old nasty smelly code around and copy and paste it to your shiny new codebase however you please

urban spruce
opaque viper
gloomy chasm
#

@onyx harness So as I do every couple of weeks/months I went back try and make a window/system for editing the menus from the editor. I stopped last time because the 2020.3 and 2021.1 menu system was so different it didn't seem worth it. But I decided to take another crack at it for only the latest 2021.2.
2021.1 has the nice Menu.AddExistingMenuItem(..) method, so I try to use it and find that they removed it in 2021.2, and as far as I can tell there is no replacement for it...
The whole ModeService internals have been rewritten again too which is where it was being used! What is a guy to do!

#

Why can't they just keep their internals stable, I'm trying to use them here! 😛

onyx harness
#

Lol, it's a running gag among Unity dev I guess :D

onyx harness
#

@gloomy chasm But why dont you use AddMenuItem?

gloomy chasm
onyx harness
#

To be honest, I dont even know what does AddExisting

gloomy chasm
onyx harness
#

Better use Add & Remove then

#

I see they added a menuChanged hehe

gloomy chasm
onyx harness
gloomy chasm
gloomy chasm
onyx harness
#

Why would they

#

What does it do

gloomy chasm
# onyx harness What does it do

In I think 2020.1 they added a more limited version of the editor called "safe mode" for when you open a Unity project when there are compile errors. ModeService handles that, but is capable of having any number of modes.

onyx harness
#

Oh I see

gloomy chasm
#

And as far as why? Idk, why did they rewrite it from 2021.1 to 2021.2?

brisk mango
#

I am trying to make a custom property drawer for IPAddress and I have this code just to test but nothing shows up in the editor when i have a field of the IPAddress type.

[CustomPropertyDrawer(typeof(IPAddress))]
public class IPAddressDrawer : PropertyDrawer {
    public override VisualElement CreatePropertyGUI(SerializedProperty property) {
        var container = new VisualElement();
            
        container.Add(new Label("Test"));

        return container;
    }
}```

It's in an editor window, if i change it to a struct i made just to test it works properly, System.Net.IPAddress is serializable and it is used properly in both cases, do you know why this isn't drawing anything?
#

or could you point me to an already completed implementation of an ip address property drawer

#

im also very new to editor extensions so it could be something very stupid

onyx harness
#

Not sure, but probably the Serializable is not the same between native C# & Unity

#

Does it show up normally if you dn't even use a PropertyDrawer?

brisk mango
#

no, nothing shows if i dont use a property drawer, but i figure thats because unity doesnt know how to handle an IPAddress

#

i just checked and its just System.Serializable

#

should be the same, putting that on a struct makes it work in unity

onyx harness
#

Struct made by you

brisk mango
#

yes

onyx harness
#

As a little tip, if you put anything in a normal way in a public field, and it doesn't show up in the Inspector

#

It just mean it is not serializable

#

(In the Unity way)

brisk mango
#

but isnt the purpose of PropertyDrawers to make something serializable in the unity way?

onyx harness
#

Nope, I understand it can be confusing at first

#

PropertyDrawer does not make things serializable

#

It allows to draw on something serializable

brisk mango
#

is there a way to make something unity serializable? maybe using extension methods or something

onyx harness
#

Hum... rewriting an IPAddress...

#

Let me give it a try

brisk mango
#

i suppose... could i subclass it?

onyx harness
#

if you can

brisk mango
#

I'll just make a struct for an ip address, then write a drawer that makes it look like an ip address

onyx harness
#

Yes

brisk mango
#

how would I limit the integers?

onyx harness
#

Much easier

#

Limit?

#

You mean get a range of 0-255?

brisk mango
#

yeah

onyx harness
#

IntSlider

#

I mean, this is for IMGUI stuff

#

For UI stuff, I don't know

brisk mango
#

oh and should i use imgui or uielements

onyx harness
#

The future is in UIToolkit

brisk mango
#

uielements seems closer to other gui systems ive used

onyx harness
#

I'm a bit old & outdated

brisk mango
#

uitoolkit?

onyx harness
#

UI Toolkit is the new name of UI Element

#

Yes, I know, this is confusing

#

just a new name

#

Unity loves that, confuse people

brisk mango
#

unity is just a big rolling ball of features that are constantly either deprecated or in preview

#

i swear

onyx harness
#

Welcome 🙂

brisk mango
#

so now i have this

public override VisualElement CreatePropertyGUI(SerializedProperty property) {
    var container = new VisualElement();
            
    container.Add(new Label("Test"));

    return container;
}```

and it's showing up as this in the editor
#

Do I need to enable ui toolkit somewhere?

onyx harness
#

show me the complete class

gloomy chasm
onyx harness
#

You can't do UI from a PD? O_O

brisk mango
#

this is such a mess

#

ok thank you

#

ill just use imgui ig

gloomy chasm
brisk mango
#

is there no way to switch it?

#

ok ok fine, imgui it is

#

hate this for me tbh

#

there goes 30 mins lmao

gloomy chasm
#

There is-ish. You can enter internal mode to switch to it. Or you can create a custom editor for all MonoBehaviours (There are several online that do this already)

brisk mango
gloomy chasm
brisk mango
#

custom editor i guess

#

whichever is less hacky actually

gloomy chasm
brisk mango
#

doesn't seem to be plug and play...

#

ill just use imgui

#

this is too much

gloomy chasm
brisk mango
#

wait

#

now its working

#

ok

#

ill take it

onyx harness
#

I think in your case, I would just use a string, make PD on it to customize it the way you want. And then IG I convert it to IPAddress

brisk mango
#

can you use pds for validation?

onyx harness
#

Yes

brisk mango
#

...would you happen to have resources or something to point me towards for that?

onyx harness
#

In a PD you draw everything yourself, therefore using IMGUI for validation is quite straight

brisk mango
#

ok, ty

#

ty both

onyx harness
#

var newValue = TextField()
If (editor detects a change)
{
// validate
}

#

nothing fancy in there

gloomy chasm
#

For UITK you would

field.RegisterValueChange(evt => {
  if (evt.newValue /*valudation*/)
  {
    // whatever...
  }
};
brisk mango
#

ty both again!

brisk mango
gloomy chasm
brisk mango
gloomy chasm
hushed oar
#

So I'm doing some hacky serialization of ScriptableObjects. I create instances during edit mode and serialize them. After seralization, the instance IDs are 0 in the serialized file. Is there any gimmick with ScriptableObject instances created from code during edit mode that I should be aware of? I assume the garbage collector for some reason disposes of the instances since they don't exist in any files?

waxen sandal
#

You probably need to craete them as files

#

Non file backed SOs are only really supported (iirc) if they're on a component in a scene

#

If that GO becomes a prefab it breaks

gloomy chasm
#

It is a long shot, but does anyone happen to know of a way to prevent a window (custom or non custom) from updating its layout?

#

What I want to do is to animate an editor window to look like it is expanding out (0 width > final width).

hushed oar
celest galleon
#

is there an easy way to display attributes based on a selected enum or similar in the inspector? i only kinda recently learned about the whole serialization thing.
i have prefabs that have different "actions" such as "attack" or "heal", both of which will have different attributes and i don't want to list attack stuff if the action is a heal for example.

onyx harness
#

By attribute, you mean field?

celest galleon
#

more or less

onyx harness
celest galleon
#

thassa lotta lines

onyx harness
#

There is no native showif attribute in Unity

celest galleon
#

would be cool... thanks tho, it's a good reference

onyx harness
#

You use it like this:

public bool blabla;
[ShowIf(nameof(blabla), Op.Equals, true)]
public string foo;
celest galleon
onyx harness
#

Yep

celest galleon
#

dope, okay

onyx harness
#

ShowIfDrawer.cs in Editor

#

ShowIfAttribute.cs not in Editor

celest galleon
#

goddit

#

do i need to be using anything? i can't get it to show

onyx harness
#

does it compile?

#

I guess yeah, ShowIfAttribute is from NGTools namespace

#

you need it

#

or put it in your namespace

celest galleon
#

right, makes sense

#

i might need some clarification on the usage, despite the example provided.
i have my own enum which is either "Attack" or "Heal". How do I show something using this if i have one or the other selected?

onyx harness
#

The 3rd argument

#

instead of true, you put Attack or Heal

#

Read the attribute humanly

#

Show if "blabla" is {Equals} to {true}

celest galleon
#

right. im just getting an exception, but i think that's cause of the first argument im using.

#
    public ActionType actionType;
    [NGTools.ShowIf("actiontype?", NGTools.Op.Equals, ActionType.Attack)]
    public AttackCharged attackCharged;
    public int saveDC;
    public bool needsRecharge;
#

im not sure what to put into the first field cause i can't use actionType in it

onyx harness
#

what is "?"

celest galleon
#

just a placeholder

onyx harness
#

But it is supposed to be the exact name of the field

celest galleon
#

nameof(actionType)?

onyx harness
#

Yes

#

or "actionType"

celest galleon
#

actionType doesn't work, cause it's not a string, or something. tostring doesn't do anything

#

nameof gives me an index out of range exception.

onyx harness
#

What is the error that you are seeing?

#

oh

#

let me try it

#

Works fine on my end

celest galleon
#

hrm. i'll try to restart unity. it's not working with a regular bool either using the same example

onyx harness
#

What version of unity are you using?

celest galleon
#

2021.2.3f1

#

restarting didn't help nah

onyx harness
#

Ran it on 2021.3.0f1 and it works flawlessly

#

I guess you must have plugins

celest galleon
#

the only plugins i have is DOTween

onyx harness
#

Well show me the logs

celest galleon
#

might sound dumb but which logs?

onyx harness
#

The errors

#

The exceptions

celest galleon
#

right, thought you might mean a different thing

onyx harness
#

Sorry, but I need the real log

#

not just the head message

celest galleon
#

figured

onyx harness
#

I know what is a OOR exception 🙂

celest galleon
#

lmao my bad

onyx harness
#

lol, this exception comes from Unity

#

Are you using arrays?

celest galleon
#

the class itself is used as an array, since a card can have a variable number of actions

onyx harness
#

Totally possible that ShowIf won't work for nested stuff

#

It works correctly for rooted fields

#

but for array in class, in field, in whatever, a PropertyDrawer is gonna have a hard time to correctly display

celest galleon
#

bleh

onyx harness
#

also, keeping that kind of information is not a good habit if you seek for help

#

Just remember that

celest galleon
#

i didn't figure it was that important

onyx harness
#

Like the callstack, I see 🙂

celest galleon
#

i did ask for clarification on that

#

iunno im just a dum dum i g

onyx harness
#

It's fine it's fine, but remember, to less we have to ask you back, the faster you're gonna get your solution 🙂

gloomy chasm
#

Is there an editor window style that is a combination of the normal style and the popup style, meaning that it is the normal window but with the editor, aka the popup style but with a border and shadow?

onyx harness
#

I think I don't get it

#

What's the issue of the popup one?

gloomy chasm
#

First is popup second is normal.

onyx harness
#

Hum... 2019.4 I have this popup, and it seems I see a shadow

gloomy chasm
#

That is an aux window or maybe utility.

#

I mean winow.ShowPopup()

#

window.ShowDropdown(..) is the style I want. But it closes on losing focus which is not what I want.

onyx harness
#

You can always draw a border yourself if that's the biggest issue

gloomy chasm
#

I need to work for other windows than my own unfortunately.

hasty axle
#

Can someone tell why it's giving me an error?

visual stag
#

install the developer pack it's asking you to install?

hasty axle
#

This one?

hasty axle
#

Developer or runtime?

visual stag
hasty axle
#

Ok

#

After I download it, do I need to relaunch vs code?

visual stag
#

I would assume so

hasty axle
#

Okay

barren moat
#

Does anyone know why I'd get this error when trying to attach an MB from an editor assembly to an object? In my test project I could create an object tagged "EditorOnly" and it just worked.

#

Is this something new in 2021 maybe?

#

I tested in 2020

#

Yeah, this is straight up broken in 2021 it seems

visual stag
#

Why should you be able to attach a script from an editor assembly?

#

I personally don't remember that ever being a thing

visual stag
barren moat
visual stag
#

Yes

barren moat
#

It worked for me in 2020.3.18 I think. I might need to double check now

#

But I'm pretty sure it just attached

#

Maybe I'm confused

slim zinc
#

The script must derive from mono behaviour. I'm pretty sure you got the wrong script

barren moat
#

It's a MonoBehaviour in an editor assembly

slim zinc
#

I don't know your project. But just move it out of the editor assembly and test

visual stag
#

pretty sure you've never been able to do this, and need to use the editor preprocessor

barren moat
#

Hm, okay. I must have done something wrong in testing then

#

Not clear how the editor preprocessor could help though.

#

If I'm not permitted to add the script at all

visual stag
#

You add the editor preprocessor while it's in a runtime assembly, so it's stripped from the build

barren moat
#

The scene is not intended to be included in a build so it's okay

slim zinc
#

Script and/or assembly

visual stag
#

Not that I know of, but you can exclude the script

slim zinc
barren moat
#

Which brings me back to the beginning

#

I've never used the preprocessor before but it sounds like it could achieve what I want

slim zinc
#

You just put #if UNITY_EDITOR at the top of your script and #endif at the bottom

visual stag
#

The real hack is to add the assembly definition to a platform you never build for

#

then it's runtime but practically editor-only 😄

#

and hope it doesn't freak out when you make a build

slim zinc
#

Meh, sounds hacky, what if you at some point do want to build for that platform?

barren moat
visual stag
#

Choose one you never will?

slim zinc
barren moat
#

Not really.

slim zinc
#

It will

barren moat
#

It's a scene of example usages of a library that is distributed with the package. Users end up with the example assembly in their builds.

#

That will exclude specific code from compilation.

#

I want to exclude a DLL from being included in a build.

slim zinc
#

You were talking about scripts though

visual stag
#

Examples are usually distributed in .unitypackages in packages, I imagine for that reason

barren moat
#

You're right @visual stag perhaps I hadn't applied the asmdef definition or something because it's not working now. mb

barren moat
#

I just did some googling to see if there was a solution, I guess I misinterpreted that thread.

barren moat
#

"scripts" == C# files

visual stag
slim zinc
barren moat
#

Oh that's nice. So they'll be treated as separate assemblies that are optionally imported? @visual stag

#

I could play with that, it sounds good.

barren moat
visual stag
#

They're not imported at all (appending a folder with ~ will exclude it from being imported), and when you click the sample in the package manager it'll throw the referenced subfolder into the Assets directory

barren moat
#

Yeah, that's great. This could well be the answer. Thanks @visual stag

slim zinc
barren moat
#

@visual stag FYI I tried moving the asmdef into the "samples" folder and it's still automatically included in the build even when not imported. Was a good thought though!

visual stag
#

Samples~?

barren moat
#

I can try renaming it, I wasn't sure what the ~ meant there

visual stag
barren moat
#

It's being picked up by the package manager as is

visual stag
#

During the import process, Unity ignores the following files and folders in the Assets folder (or a sub-folder within it):
Files and folders which end with ‘~’.

barren moat
#

Oh nice!

#

Ah, cool. Yes that works but it also hides it from the development project which is not ideal. Perhaps we can achieve something with a symlink from the main project.

slim zinc
barren moat
#

FYI the symlink is working perfectly so far!

#

I just link from Assets/Samples to Assets/ThePackage/Samples~

#

And unity only sees the files under Samples instead of Samples~ (which it ignores)

#

👌

#

A git hook with a rename might work too, but this feels more elegant

west drum
#

Does anyone know how to make a Dropdown field using UIElements, on version 2020.3?

gloomy chasm
west drum
#

@gloomy chasm I thought that is only available from 2021.1

west drum
#

Thanks, ill take a look

idle tree
#
    private static void HandleHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
    {
        //HandleBackground(instanceID, selectionRect);

        Color fontColor = Color.red;

        Object obj = EditorUtility.InstanceIDToObject(instanceID);
        if (obj != null)
        {
            var prefabType = PrefabUtility.GetPrefabInstanceStatus(obj);
            if (prefabType == PrefabInstanceStatus.Connected)
            {
                if (Selection.instanceIDs.Contains(instanceID))
                {
                    fontColor = Color.white;
                }

                Rect offsetRect = new Rect(selectionRect.position + offset, selectionRect.size);
                EditorGUI.LabelField(offsetRect, obj.name, new GUIStyle()
                {
                    normal = new GUIStyleState() { textColor = fontColor },
                    //fontStyle = FontStyle.Bold
                }
                );
            }
        }
    }```

I am attempting to edit someone else's code to highlight certain game objects in my hierarchy.
The above code works to change the font color of all Instanced Prefabs to red.
I would like to change it to be able to change any prefab that contains specific components to specific colors.
#

current functionality visualized

#

I can't seem to figure out how to detect if the thing is the thing I want it to be, I tried this but it returned null:

#
GameObject prefabtype2 = PrefabUtility.GetNearestPrefabInstanceRoot(obj);
if (prefabtype2.TryGetComponent(out MrManPlayerCharacter mrMan))
{
 // code here
}```
#

prefab.utiltiy has a ton of methods but I cant seem to find one that returns what I need to be able to test if thing is/contains thing that Im looking for

#

I can get this far, but when I try to do anything with prefabtype2, the console gets spammed with hundreds of errors per frame

idle tree
#

I got it to work, scrtch all the above

#
    private static Vector2 offset = new Vector2(18f, 0);

    static CustomHierarchy()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HandleHierarchyWindowItemOnGUI;
    }

    private static void HandleHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
    {
        //HandleBackground(instanceID, selectionRect);

        Color fontColor = Color.red;

        Object obj = EditorUtility.InstanceIDToObject(instanceID);

        if (obj != null)
        {
            GameObject prefabtype2 = PrefabUtility.GetNearestPrefabInstanceRoot(obj);
            //Debug.Log(prefabtype2);
            if (prefabtype2 != null)
            {
                if (prefabtype2.TryGetComponent(out MrManPlayerCharacter mrMan))
                {
                    ColorThisElement(Color.yellow, instanceID, selectionRect, obj);
                }
            }
        }
    }
#

has this effect

gloomy chasm
#

I've been working on a sidebar like VS, Rider, UE5 etc.
I'm pretty with how it is going.
I feel pretty clever for the resizing because the window is a popup window I added a UITK element to the window that you drag to resize (only in the 'wide' direction of the window)

naive loom
#

Anyone has/know good tutorial on how to simulate update in editor,

pure siren
#

Is it possible to detect keypresses in an editor window class when the window is closed?

#

Or is it possible to have an editor class that persists the whole time the editor is open?

#

I basically want to store a reference to a GameObject in the scene and either toggle its active state or visible state on a keypress

gloomy chasm
pure siren
gloomy chasm
#

You would need to get that reference each scene change anyway right?

pure siren
#

Rather than just opening a window

gloomy chasm
pure siren
#

Thanks as always 🙂

queen violet
#

I have a monobehaviour with a list of a Serializable object, and that object also has a list of serializable objects, even If set the root monobehaviour dirty, the changes to the sub objects fields aren't saved in my editor script. Any special thing to do for this case ?

gloomy chasm
queen violet
#

You can imagine monobehaviour class A, has a list of class B (serializable), B has a list of class C (serializable).

  1. I double for loop through both lists and assign a vector3 field on class C.
  2. EditorUtility.SetDirty(object A)
#

I know there are ways to use the serialization wrappers for unity objects etc, can't find docs on how to propertly save custom classes marked as Serializable - when they are child objects or in lists.

gloomy chasm
#

No, that sounds like it would work. Again if you want show the code I could tell you better.

queen violet
#

It should work even if I set the values using raw c# and not the special serialized wrappers? SerializedObject / SerializedProperty - but those can't be used since thy require Unity objects.

gloomy chasm
gloomy chasm
queen violet
#

Yea, but the field i'm after is on a non unity object. I must be missing something simple. Will keep digging.

#

Thanks for the help.

gloomy chasm
queen violet
shadow violet
#

This might not be editor-specific, but I have a editor script that logs pretty much whenever you do anything (like delete a file, move an asset, rename a object in the hierarchy, etc), is it bad to send a System.IO.WriteAllText(...) to every time anything is done, or should I maybe "queue" a bunch of messages then write the whole queue at once? Im just wondering if I move like 20 files at once, thats 20 "save" calls to a text file ina short time, is that "bad" to constantly write like that or is it better to do it periodically/as infrequent as possible?

gritty forge
# shadow violet This might not be editor-specific, but I have a editor script that logs pretty m...

20 would be insignificant, but you probably ought to do it a better/different way - perhaps by keeping the file handle, opening it, writing as events come in, disposing it as your application closes, and periodically flushing it (every five minutes? one minute? whatever you feel is appropriate). Alternatively, not making 20 save calls, but instead making a "saveOperations(list<operation>)" kind of interface or usage pattern.

shadow violet
gritty forge
shadow violet
#

Ah I see, ill try that out - thanks for the guidance :)

tough cairn
#

seems like unity console window adds it

#

what i did was : Start() { Debug.Log( Application.consoleLogPath ); }

#

u can subscribe to the event and add the time manually tho :

Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type ) 
{
    _myTextField.text += condition;
};
#

also the console has this if that's what u were asking for

tough cairn
#

then use logMessageReceived and add your own

weary birch
#

Hi.
How do I add a list like this in a custom inspector?