#↕️┃editor-extensions

1 messages · Page 26 of 1

misty sierra
#

just realized I should probably ask in the Odin inspector discord... disregard

gloomy chasm
#

Probably better to ask in the Odin Inspector discord server.

misty sierra
#

yea I came to that same realization

#

it's [HideLabel] on the wrapper class definition in case anyones wondering

full cedar
#

Hi, I am trying to detect key inputs so I can create custom binds(unity has very few useful ones).
For example, I wanna create a new script when you press ctrl+alt+s.
Issue is, now matter what I do, best solution I could find is hovering over the scene view to detect key presses with this:

public class EditorBinds : MonoBehaviour
{
    [UnityEditor.Callbacks.DidReloadScripts]
    public static void ScriptsReloaded()
    {
        SceneView.duringSceneGui += DuringSceneGui;
    }

    private static void DuringSceneGui(SceneView sceneView)
    {
        var e = Event.current;

        if (!e.control || !e.alt) return;
        if (e.type != EventType.KeyUp) return;
        if (e.keyCode != KeyCode.S) return;
        Debug.Log(e.keyCode);
    }
}

I tried using Input.GetKey() too but it didn't work either.
I only get S when I am hovering the scene with the first approach.
Is this something that's even possible or am I out of luck?

full cedar
visual stag
full cedar
#

that looks like the thing I needed, will try to implement it a bit later, thanks

full cedar
#

yeap, that worked, thanks a ton!

        [Shortcut("NewNnScript", KeyCode.S, ShortcutModifiers.Control | ShortcutModifiers.Alt)]
        private static void NewScript() =>
            ProjectWindowUtil.CreateScriptAssetFromTemplateFile("Assets/NnUtils/Scripts/Editor/NnScriptTemplate.txt", "NnScript.cs");

stark ether
#

how can i draw custom editor ABOVE my script variables?

real spindle
stark ether
#

like
draw editor stuff
base.inspector gui
draw default inspector?

real spindle
#

base.oninspectorgui will draw the default inspector

stark ether
#

oh

real spindle
#

So yeah draw your custom stuff first, then call that

stark ether
#

thank you

#

@real spindle do you know how to hide script?

#

this one

real spindle
#

If you do that, don't call base.OnInspectorGUI

#

Do you have a property/variable named PlayFabManager?

stark ether
real spindle
#

You were supposed to exclude m_Script

stark ether
#

the one i want to remove

real spindle
#

I think just doing this would work

DrawPropertiesExcluding(serializedObject, new string[] { "m_Script" });
#

If you want to draw everything but the script header/objectfield

real spindle
#

What exactly did you type

stark ether
#
EditorGUILayout.LabelField("Player Info", EditorStyles.boldLabel);
        EditorGUILayout.TextField("PlayFab ID", playFabManager.PlayerID);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"));
        DrawPropertiesExcluding(serializedObject, new string[] { "m_Script" });
real spindle
#

And before that, draw your custom stuff

stark ether
#

ohhhhhhhh

#

sorry my brain is fried rn

#

thankssss

#

it removed

real spindle
stark ether
#

@real spindle do you know how to draw lists by any chance

#

this thing is so confsuing 😭

fleet bison
#

Hello, I am trying to figure out what is being called in a string method in the inspector.

So when you click into the inspector to edit a string what method does unity use to know this string has changed and you have clicked off of the inspector.

I am using OnValidate to update data after you exit a string.

right now I have found that
EditorGUI.EndChangeCheck()
will check when a change ends but this is called every time I update the string I would like something that will be called when I exit the string in the inspector.

Here is what I have for code

        private void OnValidate()
        {
            if (autoUpdate == false) { return; }
            if (previousAssetName != AssetName && nameUpdated == true)
            {
                if (EditorGUI.EndChangeCheck())
                {
                    nameUpdated = false;
                    UpdateName();
                }
            }
        }
south cloak
#

Hello guys, i have a small problem about repainting a property,
i a using a custom editor to draw a property, but the repaint is doing only if I move my mouse.
i have try InternalEditorUtility.RepaintAllViews(); but this is using too much performance (5 fps)...
do you have a solution to repaint my property every 0.5sec, so i keep my fps ?

waxen sandal
#

So Unity 6000 deprecates CanCacheInspectorGUI
[Obsolete("CanCacheInspectorGUI has been deprecated and is no longer used.", false)]
No alternatives mentioned, anyone got any ideas?

waxen sandal
#

That'd be nice if Unity rewrote my existing editors to be retained mode

alpine bolt
#

I'm just the messenger

waxen sandal
#

It's interesting they don't mention it in the release notes either

gloomy chasm
#

That is weird since there are still a lot of IMGUI Property drawers. Maybe they are doing it to 'encourage' people to move to UITK.

alpine bolt
#

For anyone that implements an ObjectField that shows that object's in the inspector, how do you deal with circular references? Setting an object A that shows B that shows A, etc...

object a
    object b
        object a
            object b
                etc...```
alpine bolt
#

In the future I can only see the implementation of a cached ancestry tree for this FieldInfo from the same SerializedObject, following all the custom elements of the same type

gloomy chasm
gloomy chasm
# alpine bolt PropertyDrawer

Hmm, okay actually I know what you can do if you are using UITK. Add a class to it, and then you can just not display the editor

gloomy chasm
# alpine bolt I’m not following

Well, there is a couple of ways to do it. But one way is to in the AttachToPanel event, check if an ancestor has the custom class. If so, then don't show the Inspector for the object field.

north laurel
#

Is it possible to hide some of the Create-Elements I am not using with custom editor code? Feels a bit bloated

tall epoch
#

Anyone know where I can find the replacement for SetIconForObject, it doesnt seem to exist anymore

private static void AssignLabel(GameObject g)
    {
        var tex = EditorGUIUtility.IconContent("sv_label_6").image as Texture2D;
        var editorGUIUtilityType  = typeof(EditorGUIUtility);
        const BindingFlags bindingFlags = BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic;
        var args = new object[] {g, tex};
        editorGUIUtilityType.InvokeMember("SetIconForObject", bindingFlags, null, null, args);
    }
tall epoch
#

nvm found it

gloomy chasm
timid coyote
#

in a class that inherits from TextValueField<string> how can i get the start and end index of a selection?

visual stag
timid coyote
#
public override void SetValueWithoutNotify(string newValue)
        {
            Debug.Log(selectIndex);
            Debug.Log(cursorIndex);
            if (string.IsNullOrEmpty(_oldValue) || string.IsNullOrEmpty(newValue))
            {
                base.SetValueWithoutNotify(newValue);
                return;
            }
            
            int richIndex = GetRichIndex();
            int modifiedLength = _oldValue.Length - newValue.Length;

            if (modifiedLength > 0) _richBuilder.Remove(richIndex, modifiedLength);
            else
            {
                int lastIndex = richIndex + Mathf.Abs(modifiedLength);

                for (int i = richIndex; i >= 0; i--)
                {
                    
                }
               // for (int i = index; i < lastIndex; i++)
                //    _richBuilder.Insert(index, newValue[i]);
            }

            _richTextElement.SetText(_richBuilder.ToString());
            
            _oldValue = newValue;
            base.SetValueWithoutNotify(newValue);
        }```
#

and if i register the mouse down event, i doesnt get trigger when i click on the text box

visual stag
#

I can only imagine that there is no selection at that point in time

timid coyote
#

yea i think, but idk what event should i register to

visual stag
#

You'll have to provide some more info about when this is being called

timid coyote
#

its the built in function, i just override it

late arrow
#

Hello, I'm a bit new to creating custom editors, and this would help me a lot

I have a base abstract class Fruit.
I have children classes, Apple, Banana and Orange, each with different parameters to change.

I want an editor that can select one of the children classes of Banana from a dropdown and use that class's field editor.

For example, I have a List<Fruit> fruits, and in the editor I add a new element. It shows a dropdown, and once I select class Banana, it allows me to change the parameters of that Banana object; when I find it on the code, I can cast that Fruit object to Banana and use its parameters.

How would I do this?

surreal delta
#
field.RegisterValueChangeCallback((callback) => function.Invoke(target, null));

does anyone know why the callback triggers when i move or add components in the inspector?

this is inside a property drawer

alpine bolt
# gloomy chasm Well, there is a couple of ways to do it. But one way is to in the AttachToPanel...

I ended up doing this. I should have thought of it but I was just brain dead

public static bool IsCircularReference<TElement>(this TElement element, Object value)
    where TElement : VisualElement, INotifyValueChanged<Object>
{
    bool isCircularReference = false;

    VisualElement parent = element.parent;

    while (parent != null)
    {
        if (parent is TElement parentElement)
        {
            if (parentElement.value == null)
            {
                break;
            }
                    
            if (parentElement.value.Equals(value))
            {
                isCircularReference = true;
                break;
            }
        }

        parent = parent.parent;
    }

    return isCircularReference;
}```
plucky knot
#

Weird question, but is there a way to force unity to focus, force a dialogue to pop-up to tell the user to focus (ShowDialogue requires a focus first), or to fake a focus so my InitializeOnLoadMethod function can start running? I have to do a few restarts for an editor tool and if the editor isn't focused when it restarts, then it won't keep going until you do.

plucky knot
#

Figured it out, EditorApplication.delayCall requires an initial focus, while EditorApplication.update doesn't, so I just that for a frame and just deregister once it starts.

brave valley
#

Does anyone know if there is a callback that I can hook into during the build when a scene is being added to the build? I'd like to run some processing on scenes at build time, but it seems like the only callback I can find occurs before the build starts.

nocturne laurel
#

is there a way to rename the scene name in the hiereachy only? i need multiple instances of this scene, and want them to be named differently each, but i cant get a reference to the ui object representing this scene

ember gate
#

I don't think so.
Simply right-click on your scene in the Hierarchy and click Select Scene Asset. It's going to select the scene in the Assets. Press F2 or right-click and click Rename to rename it.

nocturne laurel
ember gate
#

No, there is no way

nocturne laurel
#

😔

ember gate
#

And I don't see why you would have several scenes named the same way

#

Also, I don't know whether it's possible

nocturne laurel
#

its not several scenes named same way

#

its 1 scene opened multiple times

ember gate
#

There is no way.

nocturne laurel
hollow ore
#

I want to create a prefab asset with sub-assets at once, how can I do that?

gloomy chasm
hollow ore
#

sorry for poor description 😅
I have been getting a bunch of "broken text PPtr record" or something errors when I was trying to create a prefab with sub-assets in script.

I was just trying to do the following:
create a game object, add component, create new material and shader, assign them to the component fields, then save this game object as a prefab and the material and shader as sub-assets

#

now when I made a modification and rolled back somehow I don't get PPtr errors again...

north sphinx
#

Is there any way to serialize unknown class?

#

similiar to PropertyField but without actually having SerializedProperty

#

I need to make custom drawer for [SerializeReference] collection

#

but I can't figure how to make property fields

#

my class does not derive from UnityEngine.Object

gloomy chasm
gloomy chasm
north sphinx
#

Huh?

gloomy chasm
#

Maybe I don't understand, but it sounds like you are just wanting a PropertyDrawer for a POCO

north sphinx
#

I have VisualElement root and System.Object instance. I need to make a serialized property field for it

#

I want to visualize int/float/ushort/string field based on what type is it

hollow ore
gloomy chasm
gloomy chasm
north sphinx
#
[SerializeReference]
        internal IKek[] variables = Array.Empty<IKek>();
#

I want to make a custom drawer for this collection

#

where I simply would serialize each instance separately

#

so I got my custom drawer, I got my instance. I iterate this collection... but what do I do to serialize each of those IKek instances?

#

I don't know which type is it

#

I only know, that Unity can serialize it for sure

#

because they are simply primitives

hollow ore
#

Ugh, IKek is an interface? Good luck with that...

gloomy chasm
#

Okay, so lets clear a couple of things up.

  • They are already serialized. [SerializeReference] tells Unity to serialize the values. So that is already taken care of.
  • The way you normally have custom field drawing for a type in the inspector, is by making a class that inherits from PropertyDrawer.
  • PropertyDrawer cannot draw for Lists or Arrays.
  • This leaves you with three options.
    1. You make a PropertyDrawer (or Editor if a UnityObject) for whatever class contains the IKek[] variables. Iterate over the SerializedProperty and check the type, and draw whatever field is appropriate for that type.
    2. You make a PropertyDrawer for IKek, check the actual type, and draw the field for it.
    3. You make a PropertyDrawer for each type that implements IKek.
#

Option 1, lets you change how the list looks and how the IKek variables are draw specific for that use/object.

#

Option 2 and 3 change how the IKek field is draw in the inspector no matter where it is used.

#

Does that make sense @north sphinx?

north sphinx
gloomy chasm
north sphinx
gloomy chasm
#

Haha

north sphinx
#

but anyway

#

it's not really a solution

#

because I don't know how to actually make a property

#

I have my UnityEngine.Object which contains this IKek[]

#

I'm trying to make a drawer for each of IKek

#

separately

#

but so far I have no idea how

#

foreach (var kek in ikeks) { ??? }

gloomy chasm
#

Where do you have that?

north sphinx
#

in CreateInspectorGUI

#

sorry I meant CreatePropertyGUI

#

confused with Editor

gloomy chasm
#

Wait... that is different

north sphinx
#

well, yeah

gloomy chasm
#

So are you making a PropertyDrawer for a UnityEngine.Object?

north sphinx
#

yes, SO which contains this array

#

but I want it to simply make drawer for each, without showing list view

#

practically as if it was a field

gloomy chasm
#

Ahh, okay that makes more sense now

#

So you want to just show it like a list then?

#

Normal old list, nothing special?

north sphinx
#

I want it to show as if it was drawn as fields

#

public IKek one; public IKek two;

#

this would give me exactly how I want drawer to be

#

but I need this in a collection

#

I can't hardcode it

gloomy chasm
#

So, at the simplest you do

foreach(SerializedProperty kekProp in serializedObject.FindProperty("variables"))
{
    root.Add(new PropertyField(kekProp);
}
north sphinx
#

huh? let me check

gloomy chasm
#

The hard part is the serializedObject.

#

You have to make it yourself

north sphinx
#

seems easy enough

gloomy chasm
#

I can't remember if PropertyDrawer is cached when using with UITK. If it isn't this is easy-ish.

Assuming you have a ObjectField, for your UnityEngine.Object that contains the IKek array. You create a SerializedObject when the value changes, and assign it to a field in the PropertyDrawer, and recreate all of the IKek field elements.

And in DetachPanelEvent you dispose of the SerializedObject

north sphinx
#

bruh, somehow Odin overrides my custom editor drawer

#

so many problems

gloomy chasm
fallen dock
#

Does anyone know why my Colors in the inspector default to black w/ 0 alpha despite doing this [SerializeField] public Color controlColor = Color.white;

#

can you not set default values for colors?

waxen sandal
#

Probably because your thing has laready been serialized?

fallen dock
#

nah tried resetting

#

if thats what u mean

#

actually it might be because its in a serialized class

full oasis
#

Im having an issue with trying to add a bool toggle to a preexisting component using UnityEditor.
I cant find any good source the expand on how to make bool toggle.
Heres a simplified ver of my script

public class SnapTransformComponent : Editor
{
    public bool posX = false;

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        Transform transform = (Transform)target;

        GUILayout.Space(10);
        GUILayout.Label("Position");
        GUILayout.Toggle(posX, "X");
    }
}

The issue is when in the inspector and I click on the bool toggle, it sets it to true and instnatly to false. Nowhere in my script sets the bool to false. I may have written the toggle box incorretly though however, any suggestions?

hollow ore
#

you should be assigning posX = GUILayout.Toggle(posX, "X")

hollow ore
full oasis
#

ah alright, i'll have a look, also thank you, it worked.
I thought the posX after GUILayout.Toggle was the variable it was using.

hollow ore
#

also: is there a reason you are not using the modern UIToolkit?

hollow ore
full oasis
hollow ore
#

it lets you write modern Editor windows and whatever, it's basicallty the tech unity is migrating to

full oasis
#

ah, well I shall look into that

hollow ore
#

yeah, check out the docs, maybe some YT videos about what it really is

#

it's a lot easier to use than the old system

reef hornet
#

Hello there
does anyone know a way to change the background color of a referenced object in the hierarchy?

#

like, when I select one object, and another in the same hierarchy is referenced by it, also change its background color

#

specifically, I figured out how to change the style of a single object in hierarchy, but dont know how to get the rect of the referenced one

summer basin
#

I am actually not sure, whast the best place to ask for. Is there any guide or walkthrough on how to deliver a current projects basesystem as a package for others to be included from lets say git repo? Just wondering if I can just throw all assets in the Runtime folder and copy paste the json package manifest content as dependencies in the package.json?

floral storm
#

Heyho 🙂
In a project i'm working on, they're making use of "scriptable object event channels". I'm sure a lot of you might be familiar with them, since UOP used them and they're mentioned in unity's ebook etc.
What i'm trying to do is to extend the editor in such a way that you can select those event channels, and raise the event with a button. That part is working, but when it comes to draw some fields to pass as the arguments for the selected channel, i'm starting to struggle.
Those arguments that are passed might be primitives, but also some custom EventArgs struct, which in turn could contain several members, including interfaces. What are my options to pick an object that implements said interface?
Here's some shortened code: https://gdl.space/viyotuviyo.cpp
I'm sure there is a less repetitve way of handling this, without all the repetition, but my first attempt to handle it with reflection and so on failed, so that's the current attempt. 🙂 I hope i'll figure something out later on, but for the moment i try to handle the issue with interfaces.

summer basin
gloomy chasm
floral storm
floral storm
dusk portal
gloomy chasm
wheat notch
#

Yo peps, is there an easy to use serializable array?

short tiger
wheat notch
#

They are, i just meant to easily format those.

#

There is an undocumented one. But it's pretty hard to use. :p

short tiger
wheat notch
#

Yes, draw.

short tiger
#

Because if you had a serialized array or List, you could just make a PropertyField for that to draw the default property drawer.

waxen sandal
#

Please elaborate on what you're actually trying to achieve

short tiger
waxen sandal
#

You're asking for a solution while we don't even know what your problem is currently

gloomy chasm
safe sorrel
#

AssetPostprocessor.GetVersion's return value should be increased at least every time I publish an update to a package, correct?

#

I've been increasing it every time I change the script so that Unity will reimport assets properly

floral storm
torpid vale
#

Hello. I've been learning about creating editor extensions and I'm trying to learn how to make a viewport within an inspector but I am having a hard time finding resources. Essentially, what I would like to create is a tool that can create a "solar system" scriptable object. I want the ability to add a sun or multiple suns, planets, moons, celestial bodies. For the parts about creating the scriptable object and populating the data that is no problem, but when it comes to visualizing it in the editor window, I am at a complete loss. Any documentation you guys might recommend or perhaps just proper keywords to search up online as I have not found much so far.

elder wasp
#

Hi! I'm submitting a package and it has content that's under the MIT license (a version of naughty attributes)

#

it got rejected because i dont have the license attached, is that correct? I thought with MIT license it didn't matter?

gloomy chasm
# torpid vale Hello. I've been learning about creating editor extensions and I'm trying to lea...

Basically what you are going to be needing to do is to make a PreviewScene, add a camera to it and whatever objects you want, and then render it to a RenderTexture and draw that. There however is some caveats, like needing to setting the RenderSettings, otherwise it will use the current Scene's settings, and messing with clipping and stuff.

Unity provides a undocumented PreviwRenderUtility class which could do what you need. You can probably google to find some community tutorials and info on how to use it. Looking at the source code for how it is implemented and where it is used might also provide good insight . But there are things online on how to use it, so I would start there.

torpid vale
gloomy chasm
torpid vale
#

Amazing. I really appreciate it. I had no idea what key words to use for my search. As you can imagine, I was getting some pretty bad search results.

gloomy chasm
#

Yeah I just did Unity previewRenderUtility 🙂

torpid vale
#

Simple always works best!

short tiger
flint garnet
#

ui toolkit really good for making Editor script, but for me it's still full of mystery....first: how to get visual element position in screen space?, then second how to get its screen position relative to parent or even root visual element?

alpine bolt
wheat notch
#

Now i know why the string can't serialize.

#

I'm totally setting it with a string type tho, but i guess the content got too arbitrary.

alpine bolt
#

The type probably isn't right

wheat notch
#

I'm not sure if that's physically possible since i would get type errors if i tried that.

#

I was trying to cast some byte data into chars array, then string. Then tried to serialize that. I guess unity didn't like that.

alpine bolt
#

Right now, its all too abstract to be able to help you

wheat notch
#

Neither am i too interested to ask for rn anyways. UnityChanThink

flint garnet
# alpine bolt https://forum.unity.com/threads/how-to-position-visualelement-at-specific-screen...

thanks for reply....i did figure that out, but how about its position in screen space? do you have any information about that??, as example case, i work mainly for editor script today, and i want to display a search window or advanced dropdown on top of the desired visual element, with adjustable position by offset, but get the screen space position of that visual element is so confusing

#

the editor window has position property with it, but visual element is not

gusty mortar
#

Hi ! I am struggling with a PropertyDrawer. It is like like this

  • PropertyDrawer A uses UIToolkit and contains a PropertyField which displays another custom PropertyDrawer B.
  • PropertyDrawer A is used for a class, and I have a list of this class which is properly displayed.
  • PropertyDrawer B is fairly simple and contains a GUILayout.Popup, which is displayed correctly.
    My issue is, when I use the popup and select a value, on selection, the element in the list gets hooked to my cursor as if I was reordering the list. I'm using Unity 2022.2.17. Maybe I'm missing an event consumption at the popup level, but I'm not sure what kind of event I have to catch in the first place...
waxen sandal
#

How od I get UITK to align these toggles properly?

#

Or rather, how do I get the inspector behaviour of aligning all field inputs?

gusty mortar
waxen sandal
#

toggle.AddToClassList("unity-base-field__aligned");
Is what I just added but it doesn't seem to do anything

gusty mortar
#

The doc doesn't give much more info on this unfortunately. I'm trying to find MechWarrior's message on this subject since this question is often asked.

#

Here. This message and the ones following may help

waxen sandal
#

Yeah that's basically what I have

#

It's in a custom editor window by the way

#

Adding unity-inspector-element to the parent seems to have worked

#

But now everything has an extra indent

#

jfc this is a mess

#

Especially since these are default controls...

gusty mortar
#

The element sticks to my mouse for no apparent reason. I tried to see if a drag event was fired, tried to consume current event at the popup level, to no avail

alpine bolt
waxen sandal
#

Yeah that's what you'd think

alpine bolt
# waxen sandal Yeah that's what you'd think
        var defaultFormatEnumField = new EnumField(formatProperty.displayName);
        defaultFormatEnumField.BindProperty(formatProperty);
        defaultFormatEnumField.AddToClassList(UNITY_BASE_FIELD_ALIGNED);
        
        var standaloneFormatEnumField = new EnumField(formatProperty.displayName);
        standaloneFormatEnumField.BindProperty(formatProperty);
        standaloneFormatEnumField.AddToClassList(UNITY_BASE_FIELD_ALIGNED);``` Pretty sure. I've been using UIToolkit for months now
waxen sandal
#

In a editor window or inspector?

alpine bolt
alpine bolt
gusty mortar
alpine bolt
safe sorrel
#

I am writing an AssetPostprocessor that uses a second file to update an imported mesh.

I'm using context.DependsOnSourceAsset(path); to indicate that I depend on this file, and it's mostly working. When I update the second file, the model gets reimported.

However, if the model is imported without that file present, and I then create the second file later, nothing happens.

It doesn't look like DependsOnSourceAsset does anything if the file doesn't exist...which I guess is reasonable

#

but can I do anything about this?

#

so, I need:

  • Unity imports Foo.fbx normally
  • I create Foo.uv
  • Unity reimports Foo.fbx
safe sorrel
safe sorrel
#

Unity was recognizing it had already seen them before and just used the relevant import result

#

I was not incrementing the version of the importer.

safe sorrel
waxen sandal
#

Anyone knows where the internal styles are defined?

waxen sandal
gusty mortar
waxen sandal
gusty mortar
#

Pretty frustrating to be forced to use that kind of workaround 😅

safe sorrel
#

I was having problems with deeply-nested IMGUI elements suddenly winding up with bad horizontal positions

#

looking at the computed styles, it just didn't define styles past a certain level of nesting

waxen sandal
#

Lol

#

It's been what 4 years since uielements, and I still can't believe they're committing to it in such a bad state

terse hazel
#

Hear hear, and ironically enough UI Builder has the worst UX of anything in Unity.

#

Anyway, for my question:

https://docs.unity3d.com/ScriptReference/PrefabUtility.LoadPrefabContents.html

Im trying to load the prefab of the ScriptableObject I double click, but nothing is happening, why would that be?

#if UNITY_EDITOR
[UnityEditor.Callbacks.OnOpenAsset(callbackOrder: 1)]
private static Boolean OnOpenAsset(Int32 id, Int32 line) 
{
    UnityEngine.Object __obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceID: id);

    if(__obj is not Recipe __recipe) return false;
    
    if(__recipe.Prefab == null) return false;

    String __assetPath = UnityEditor.AssetDatabase.GetAssetPath(__recipe.Prefab);
    
    Debug.Log(message: $"Opening Recipe: {__recipe.name} with prefab: {__recipe.Prefab.name} at path: {__assetPath}");
    
    UnityEditor.PrefabUtility.LoadPrefabContents(assetPath: __assetPath);
    return true;
}
#endif
#

Loads a Prefab Asset at a given path into an isolated Scene and returns the root GameObject of the Prefab.
Does this not mean it actually opens the scene in editor like it does when you double click a prefab?

#

If not, then how do I mimic that?

#

Oh, seems I was too hasty here, the third Google result had my answer, this indeed does not do what you'd think, it's all behind the scenes.
You need to use UnityEditor.AssetDataBase.OpenAsset()

#if UNITY_EDITOR
[UnityEditor.Callbacks.OnOpenAsset(callbackOrder: 1)]
private static Boolean OnOpenAsset(Int32 id, Int32 line) 
{
    UnityEngine.Object __obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceID: id);

    if(__obj is not Recipe __recipe) return false;
    
    if(__recipe.Prefab == null) return false;
    
    UnityEditor.AssetDatabase.OpenAsset(target: __recipe.Prefab);
    return true;
}
#endif
terse hazel
#

Apparently this is even better?
Not sure what the exact differences are though.

UnityEditor.SceneManagement.PrefabStageUtility.OpenPrefab(prefabAssetPath: UnityEditor.AssetDatabase.GetAssetPath(__recipe.Prefab));
alpine bolt
#

I currently have something like

.unity-inspector-main-container
  | 
  --- ... (some hierarchy levels)
          |
          --- .unity-inspector-element
                |
                --- ... (some hierarchy levels)
                        |
                        --- CustomField.unity-base-field__aligned
                              |
                              --- Label```
waxen sandal
#

I can show you tomorrow

idle tree
#

I've been trying to write an editable text field in a unity Editor window and like, nothing I do lets me edit it. I cant find a single reason why I can't edit this field, there's nothing special about it. I assume something I dont know or dont understand is preventing it.


        // Initialize the edited damage string if not already set
        if (string.IsNullOrEmpty(guiAttackData.EditedDamageString))
        {
            guiAttackData.EditedDamageString = guiAttackData.TotalDamagesString;
        }

        // Display the text field for editing damage
        Rect textFieldRect = GUILayoutUtility.GetRect(200, EditorGUIUtility.singleLineHeight);
        guiAttackData.EditedDamageString = EditorGUI.TextField(textFieldRect, "Total Damage:", guiAttackData.EditedDamageString);```
#

Is there any obvious reason there why I cannot edit the EditorGUI.TextField? when I click in it and select the text, but I cannot edit the text. Hitting keyboard keys do nothing

#

All the other fields let me edit them just fine, but something's special about THAT stacks of fields that prevents it

#

Here's the full stack that leads to the field being drawn:

#

spent about 4 evenings on this now, the fields just arent editable no matter what I do

#

not editable either 🫠

#

something haunted has to be going on, this field isnt editable no matter how simple I make it

#
    private void ChatboxInputField()
    {
        textFieldInput = GUILayout.TextField(textFieldInput, GUILayout.ExpandWidth(true));
        if (Event.current.type == EventType.KeyDown)
        {
            SubmitInputField(textFieldInput);
            Event.current.Use();
        }
        if (GUILayout.Button("Submit", GUILayout.Width(100)))
        {
            SubmitInputField(textFieldInput);
        }
    }```
#

THIS was the problem, I finally found it 🫠

#

somehow this was eating all subsequent inputs

#

if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return)
this made it stop consuming all inputs but I dont really understand why

safe sorrel
waxen sandal
#

I had to add extra padding to the dropdownfield though since htat wasn't indenting correctly

safe sorrel
#

bit of a question about writing my own asset importer.

I am going to be reading a binary file and extracting many records from it. For each record, I want to let the user configure how to handle that record.

How should I do this? I guess I could make a List<RecordInfo>, but ideally the user shouldn't be able to manually create or remove entries from this list

#

Perhaps I need to make a custom editor.

visual stag
safe sorrel
#

Do I need to mark something dirty after updating the list, or would that only be relevant if I was modifying the importer’s settings and needed it to import again?

reef hornet
#

Hello there
does anyone know how to check in a custom editor when someone has finished editing a property?
Like, when I have a list of ints and want to sort them
but when I try to do it in OnInspectorGUI, the sorting happens on each new character input

safe sorrel
#

rather than updating its serialized data as part of the import

#

so that makes sense, yeah

gloomy chasm
white wind
#

anybody knows how to get selected assets in tree view of project window?

alpine bolt
#

A note: you can get folders. Folders' assets are of type DefaultAsset (folders don't have a types)

white wind
alpine bolt
#

Oh yeah. Forgot to mention that. My bad

white wind
#

np

native geode
#

I had feature in my inspector so that part of it glows when hovered.
It was very unresponsive (basically updated when inpector gets redrawn which was about every second)
Dont want to update my inspector all the time but when being hovered, i think it is okay
This code solved my problem which was not visible at first but started to appear now

if(checkRect.Contains(Event.current.mousePosition)) {
    EditorUtility.SetDirty(target);
}

Now when hovering over inspector, cursor keeps switching to loading icon and back
Searched far and wide over internet and can't figure out how to make this happen

To note, this code is executed on object inheriting ": Editor"

gloomy chasm
native geode
#

and never saw that

gloomy chasm
#

Great, glad I could help 😄

still ferry
#

Is there a way to modify the class header inspector? I know there is OnHeaderGUI() but there is no information about it. Everything I tried didn't worked so far 😄

hollow ore
#

looks like they both achieve the same thing, only in two different ways with some other constraints (e.g. one only available in classes derived from MonoBehavior, another available anywhere as a static function)

hollow ore
#

ah, editor window ≠ inspector header, it might not be what you are looking for...

still ferry
#

yeah excatly, but i figured it out! Messing with inspector toolbar isn't worth it - that's the conclusion 😆

whole steppe
#

I'm having a weird one. My scene view only ever updates/renders if I'm moving/looking/scrolling or if I'm in play mode. Was messing around with editor scripts and render pipeline asset/camera stuff and not sure which broke it. I've since deleted the editor script but could there be a chance the internals haven't updated? Do I need to recompile Unity somehow?
Anyone know how I can figure out how to fix this?

#

Seems like its localised to a single scene and still happens even if I remove everything in the scene. What??

fresh lintel
#

@whole steppe is Always Refresh on?

whole steppe
fresh lintel
hollow ore
#

huh, interesting, I wonder does it do the same thing as EditorApplication.QueuePlayerLoopUpdate();?

#

as that's what I was using for editor tool, as the updates were happening in a very slow rate, mostly when moving mose, moving camera etc, similarly to Cloudy's case

naive valve
#

Hi! So I'm trying to write an editor tool that processes some levels, and I encountered unusual thing.

How do I assign a prefab to a script programatically?

Basically I have a component CoolScript that contains List<GameObject> myPrefabs; and which does totally awesome stuff with them, and so far I've been filling that list manually. In older version of my scenes I have just instantiated the objects directly in the scene. However, with the magic of EditorUtility.GetPrefabParent() I can get the prefab from the instantiated objects.

So, once I've found that prefab, I want to feed it into the CoolScript.myPrefabs, alas it is Object and not GameObject (as the prefab is not instantiated, but lies waiting in my assets). Considering you can drag and drop prefab in inspector onto a GameObject field, it follows that I should be do it programatically, but I can't figure out how.

gloomy chasm
naive valve
#

casting it gives me null

#

and I have no idea why

gloomy chasm
#

Uhh Debug.Log(thePRefabYouFound); it

#

It is possible you are not getting anything at all.

naive valve
#

oh god never mind, I'm such a doofus

#

the list wasn't allocated

#

sigh

#

I've been looking at this code for like an hour now

#

everything was being casted correctly xD

gloomy chasm
#

Haha, been there

gusty mortar
#

Hi ! Is it possible to replace the popup that a DropdownField show ? Like if I wanted add a searchfield.

deft plover
#

Hello everyone! I wanted to ask for a suggestion about how to proceed on an editor implementation. I want to show a custom property drawer for a field, which is an array of scriptable objects. The editor for this component is currently a custom editor in UI toolkit.

I tried creating a custom component with BaseField<MyScriptableObject[]> as base, and use it in the UXML by binding it to the field I want to show, but I guess BaseField does not work with this type (I never get any SetValueWithoutNotify calls, whereas it works if I switch to, say, a BaseField<string> and bind it to a string field). In that regard, I wonder where it's written the types of fields it work with.

I also looked at how ListView is implemented, which surprisingly enough only inherits BindableElement but does not implement INotifyValueChanged (but I admit I still have to get the reason why we have two interfaces for this, so there must be a reason there); in any case the implementation looks pretty complicated and quite tailored for the specifics of ListView, so I don't know if this would be the correct route.

I guess I'm missing something pretty basic, but before I go further I wanted to get some suggestions about the simplest way to go.

native geode
#
[MenuItem("GameObject/Microlight/SpriteRenderer Health Bar")]
private static void AddSpriteRendererHealthBar() {
    // Get prefab
    GameObject go = MicroEditor_AssetUtility.GetPrefab("SpriteRendererMicroBar");
    if(go == null) return;

    go = Instantiate(go);   // Instantiate
    go.name = "HealthBar";   // Change name
    if(Selection.activeGameObject != null) {   // Make child if some object is selected
        go.transform.SetParent(Selection.activeGameObject.transform);
    }
}
[MenuItem("GameObject/Microlight/UI Image Health Bar")]
private static void AddImageHealthBar() {
    // Get prefab
    GameObject go = MicroEditor_AssetUtility.GetPrefab("UIImageMicroBar");
    if(go == null) return;

    go = Instantiate(go);   // Instantiate
    go.name = "HealthBar";   // Change name
    if(Selection.activeGameObject != null) {   // Make child if some object is selected
        go.transform.SetParent(Selection.activeGameObject.transform, false);
    }
}

I have this code that allows me to spawn 2 prefabs from the folder. This code works.
My question is, how to make this dynamic? So that is searches for all of the prefabs inside the folder and generate menu item for the each of those.

Ideally, I dont know exact folder (if user moves folder from "Assets/Plugins" to for example "Assets/OtherStuff")

low wharf
#

hey yall, it's my first time making a custom inspector for a script and I think I made some sort of rookie mistake here.
While all fields drawn are editable, only the Y Rotation Limit fields and Y Position Limit fields retain their values. Everything else resets to 0 when clicking off or hitting enter after inputting some value. As far as I can tell, all 6 of these are identical so I don't know what's causing it. (Don't mind how X Rotation Limit has different display, i was fiddling with a better organized field)

https://gdl.space/eyerufayow.cs

gloomy chasm
#

Though really it would be much better to use SerializedProperty and SerializedObject for getting and setting the values, as that supports undo/redo automatically, along with allowing prefab overrides

deft plover
alpine bolt
#
            _listView.RegisterCallbackOnce<GeometryChangedEvent>(_ =>
            {
                _listView.Rebuild();
            });``` is this the way we successfully draw a `ListView` for the first time? After `AttachToPanelEvent`
gloomy chasm
alpine bolt
#

I wonder what are the conditions to build it before

gloomy chasm
#

Could try calling Refresh(), and Rebuild() (don't remember the order) though it shouldn't be needed.

alpine bolt
gloomy chasm
#

If you really did, then it is a bug.

alpine bolt
#

The specific case is I first create and add the ListView in the default ctor, then on the parameter ctor (that comes after default ctor) it builds the list and should populate it

alpine bolt
# gloomy chasm show?
        public TwoDimensionalDirectionClipNamesField()
        {
            styleSheets.Add(SpriteAnimationClipperStyleSheets.TwoDimensionalDirectionClipNamesField);
            Add(_listView);
        }

        public void BindProperty(SerializedProperty property)
        {
            var activeDirectionsName = nameof(SpriteAnimationClipperData.activeDirections);
            var activeDirectionsProperty = property.FindPropertyRelative(activeDirectionsName);
            
            var clipNamesName = nameof(SpriteAnimationClipperData.ClipNames).GetBackingFieldName();
            var clipNamesProperty = property.FindPropertyRelative(clipNamesName);
            
            _listView.bindItem = BindElement;
            
            _listView.itemIndexChanged += ItemIndexChanged;
            
            var newActiveDirections = GetActiveDirections(activeDirectionsProperty);
            _listView.itemsSource = newActiveDirections;
            
            _listView.RegisterCallbackOnce<GeometryChangedEvent>(_ =>
            {
                _listView.Rebuild();
            });
(...)```
#

The BindProperty is called in a cascade of BindProperty methods that start in a constructor of a VisualElement

gloomy chasm
alpine bolt
#

To keep it simple, I usually inherit exclusively from VisualElement

gloomy chasm
#

Hmm, I don't see you assigning a MakeItem callback

alpine bolt
whole steppe
#

can i make this propertydrawer only display the field as the type? Rather that the name of gameobject + type?

waxen sandal
#

Probably not with using the default objectfield

north laurel
#

any tips?

gloomy chasm
# north laurel any tips?

I would probably make the the top section with the "Refresh", "Auto Save" etc. in to a Toolbar and use the Toolbar equivalent for the controls, like ToolbarButton instead of Button

whole steppe
#

ugh, what am i doing wrong here

#

inheriting from U.Object just gives me just a pointer field

#

is it even possible to write a custominspector for a serailzed poco?

gloomy chasm
whole steppe
#

oh gosh u right lol, im entirely in the wrong direction UnityChanOops

gloomy chasm
#

Editor -> how a UnityEngine.Object looks in the inspector.
PropertyDrawer -> How a class field is drawn in the inspector.

atomic sable
#

The inspector can serialize and display uints. How do I display them in a property drawer? There doesn't seem to be a EditorGUI.UIntField() method.

#

Right now I'm just using a long field. Is doing this and clamping it at 0 that the correct way?

atomic sable
#

Also, I seem to be unable to get the serialized property I need through FindPropertyRelative?

Code for debug log:


        var iter = new SerializedObject(property.objectReferenceValue).GetIterator();

        iter.NextVisible(true);
        do
        {
            Debug.Log($"{iter}: {iter.name} - {iter.propertyType}");
        } while (iter.NextVisible(false));

Code for getting property:

SerializedProperty stats = property.FindPropertyRelative("<BaseStats>k__BackingField");

SerializedProperty name = stats.FindPropertyRelative("<WeaponName>k__BackingField"); // line 41
#

In fact, I copied <BaseStats>k__BackingField straight from the debug log and it didnt work.

#

this is in a property drawer script in the OnGUI method. I'm pretty sure I'm suppose to use property.FindPropertyRelative here. Maybe there's just something easy I'm missing?

waxen sandal
#

Try printing path

alpine bolt
# atomic sable Also, I seem to be unable to get the serialized property I need through `FindPro...

To make sure an name is right I recommend getting the field name reference directly from the class instead of using typed strings, like so:

var someFieldName = nameof(SomeClass.SomeField) or SomeClass.Private_SomeField_Name;
//if its backed
var someFieldBackedName = $"<{someFieldName}>k__BackingField";
var someFieldProperty = property.FindPropertyRelative(someField or SomeFieldBackedName);```
alpine bolt
grave hingeBOT
silent cargo
atomic sable
stark geyser
#

!warn 859849705214967808 Don't spam commands on the server.

grave hingeBOT
#

dynoSuccess yaboihammad has been warned.

atomic sable
#

I think FindPropertyRelative is just bugged? If I convert BaseStats to a serialized object and use FindProperty instead of FondPropertyRelative it works.

waxen sandal
#

It's not each unity object is a separate serializedobject

atomic sable
#

im not sure what you mean by that statement

#

If I serialize BaseStats by doing new SerializeObject(stats.ObjectReferenceValue) and then do FindProperty which finds the backing fields, shouldn’t stats.FindPropetyRelative find the backing fields?

alpine bolt
atomic sable
#

Quote from the docs:

When the SerializedProperty references a compound type, such as a struct, class or array, then this method can be used to lookup a child property by name.

#

The property is a class, so it sounds like it should work

gloomy chasm
atomic sable
#

And the serialized property returned by FindPropertyRelative doesn’t have any further paths for other serialized properties that can be found with another FindPropertyRelative?

gloomy chasm
atomic sable
#

Well i can comprehend the idea of references, i just think its a bit weird FindPropertyRelative doesn’t work with it

brisk pilot
elder wasp
#

Is there any way to autmatically import the changelog from unity asset store into my own asset as a text file?

#

Also, I know that with UnityEditor.PackageManager.UI.Window.Open("name of the asset") i can open the package manager with an asset selected. Is there any way to also be on the samples tab?

pseudo jasper
#

Is there a way to get the folder where a script is located from a static function? If I have an instance of a scriptable object I can use eg AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)), but I'm looking for a method that doesn't require that I have an instance

red fossil
#

Hello! I don't know if I'm asking in the right place, but I have some problems when I try to build a unity 2023.2.18f1 project, I get all kinds of errors. Pls help

timid coyote
#

i dont understand why my buttons arent aligning with the rest of the fields.
RichTextStyleButton is derived from Button and has this uss

:root
{
    flex-grow: 1;
    
    border-radius: 0;
    margin: 0;
}```

```cs
 internal sealed class RichTextStyleField : VisualElement
{
private void Initialize()
        {
            this
                .AddStyleSheet()
                .AddClass(BaseField<bool>.ussClassName;);

            _label = new Label("Style")
                .AddClass(BaseField<bool>.labelUssClassName);

            // same thing for _singleButtonsRoot
            _multipleButtonsRoot = new VisualElement()
                .AddClass("buttons-root");

            _boltButton = new RichTextStyleButton("B", FontStyles.Bold);
            _italicButton = new RichTextStyleButton("I", FontStyles.Italic);
            _underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
            _strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);
}

 private void Compose()
        {
            _multipleButtonsRoot
                .AddChild(_boltButton)
                .AddChild(_italicButton)
                .AddChild(_underlineButton)
                .AddChild(_strikethroughButton);

            _singleButtonsRoot
                .AddChild(_lowercaseButton)
                .AddChild(_uppercaseButton)
                .AddChild(_smallcapsButton);

            this
                .AddChild(_label)
                .AddChild(_multipleButtonsRoot)
                .AddChild(_singleButtonsRoot);
        }
}```
and the uss 
```css
.buttons-root
{
    flex-grow: 1;
    flex-direction: row;
    
    overflow: hidden;
    border-radius: 7px;
}```
red fossil
gloomy chasm
gloomy chasm
timid coyote
#

i tried

#

putting all the buttons in a visualelement and then ass the class, but nothing

gloomy chasm
#

Probably have to add unity-input-field__label as well to the label

timid coyote
#

i tried that too

#

i think i was testing combinations when i wrote that message because i have it rn

gloomy chasm
#

You mean it is working or it is already there?

timid coyote
#
 private void Initialize()
        {
            this
                .AddStyleSheet()
                .AddFieldClass();

            _label = new Label("Style")
                .AddLabelClass();

            _multipleButtonsRoot = new VisualElement()
                .AddClass("buttons-root");
            
            _boltButton = new RichTextStyleButton("B", FontStyles.Bold);
            _italicButton = new RichTextStyleButton("I", FontStyles.Italic);
            _underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
            _strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);

            _singleButtonsRoot = new VisualElement()
                .AddClass("buttons-root");
            
            _lowercaseButton = new RichTextStyleButton("ab", FontStyles.LowerCase);
            _uppercaseButton = new RichTextStyleButton("AB", FontStyles.UpperCase);
            _smallcapsButton = new RichTextStyleButton("SC", FontStyles.SmallCaps);
        }```it is there and its still not aligned
gloomy chasm
#

I don't see it there?

timid coyote
#
public static T AddLabelClass<T>(this T target) where T : VisualElement
        {
            string labelClass = BaseField<bool>.labelUssClassName;
            return target.AddClass(labelClass);
        }```
#

this function adds it

gloomy chasm
#

Ahh, so lets do this, add the ussClassName to the root, add the alignedLabelUssClassName to the root, add the labelUssClassName to the label.

timid coyote
#
private void Initialize()
        {
            this
                .AddStyleSheet()
                .AddFieldClass()
                .AddAlignedFieldClass();

            _label = new Label("Style")
                .AddLabelClass();

            _multipleButtonsRoot = new VisualElement()
                .AddClass("buttons-root");
            
            _boltButton = new RichTextStyleButton("B", FontStyles.Bold);
            _italicButton = new RichTextStyleButton("I", FontStyles.Italic);
            _underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
            _strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);

            _singleButtonsRoot = new VisualElement()
                .AddClass("buttons-root");
            
            _lowercaseButton = new RichTextStyleButton("ab", FontStyles.LowerCase);
            _uppercaseButton = new RichTextStyleButton("AB", FontStyles.UpperCase);
            _smallcapsButton = new RichTextStyleButton("SC", FontStyles.SmallCaps);
        }```
#
public static T AddFieldClass<T>(this T target) where T : VisualElement
        {
            string fieldClass = BaseField<bool>.ussClassName;
            return target.AddClass(fieldClass);
        }```
gloomy chasm
#

Not sure, I would open up the UITK debugger and look at a base input field (like that Text fiedl right above it) and copy over classes until you get it. Also possible that the right side is forcing itself to be too big, but I don't think so.

timid coyote
#

ill do that, thanks 😄

oak grotto
#

Hey, I wonder how to get not connected ports in editor.

#

I'm getting all connection by doing var connections = (GraphView)view.edges.ToList()

#

its from UnityEditor.Experimental.GraphView;

#

and it only returns connected ports

#

okay, i've found a way

public List<Port> GetUnconnectedPorts(GraphView graphView)
{
    List<Port> unconnectedPorts = new List<Port>();

    foreach (var node in graphView.nodes.ToList())
    {
        if (node is Node myNode)
        {
            foreach (var port in myNode.inputContainer.Children().OfType<Port>())
            {
                if (!IsPortConnected(port))
                {
                    unconnectedPorts.Add(port);
                }
            }

            foreach (var port in myNode.outputContainer.Children().OfType<Port>())
            {
                if (!IsPortConnected(port))
                {
                    unconnectedPorts.Add(port);
                }
            }
        }
    }

    return unconnectedPorts;
}

private bool IsPortConnected(Port port)
{
    return port.connections.Any();
}
thin rampart
#

Hi all, I'm having a lot of trouble understanding unity Serialization and how to do custom inspector and property drawer. Given the example below, how can I make the "test" field of my scriptable object display not a PropertyField, but the actual Inspector Element of the object ? (So in this case it would expose the name field of the SERIALChannel class).

    [Serializable]
    public abstract class COMChannel : UnityEngine.Object
    {
        [SerializeField]
        public bool isOpen;
    }

    [Serializable]
    public class SERIALChannel : COMChannel
    {
        [SerializeField]
        public string name = "hello";
    }
    
    [CustomPropertyDrawer(typeof(COMChannel), true)]
    public class COMChannelDrawer : PropertyDrawer
    {
        private VisualElement root;
        public override VisualElement CreatePropertyGUI(SerializedProperty property)
        {
            root = new VisualElement();
            Debug.Log(property.displayName); //Does output test, which is the name of the field
            //generate the error : InvalidOperationException: managedReferenceValue is only available on fields with the [SerializeReference] attribute. But... the field DOES have the [SerializeReference] attribute...
            Debug.Log(property.managedReferenceValue);
            return root;
        }
    }

    [CreateAssetMenu(fileName = "E6Settings", menuName = "New E6Settings")]
    [Serializable]
    public class E6Settings : ScriptableObject
    {
        [SerializeReference] // Or [SerializeField] ? I don't know.
        public COMChannel test = new SERIALChannel();
    }
gloomy chasm
thin rampart
#

@gloomy chasm Yes indeed I was about to post that I found the solution. I'll post how I did it, but mostly my issue was coming from that inheritance

gloomy chasm
#

Yeah the only runtime types you can inherit from is MonoBeavhiour and ScriptableObject. Can't inherit from like Component, or Mesh or Texture2D or any others.

thin rampart
#

It was as simple as that :

    [Serializable]
    public class COMChannel
    {
        [SerializeField]
        public bool isOpen;
    }

    [CustomPropertyDrawer(typeof(COMChannel), true)]
    public class COMChannelDrawer : PropertyDrawer
    {
        private VisualElement root;
        public override VisualElement CreatePropertyGUI(SerializedProperty property)
        {
            root = new VisualElement();
            root.Add(new PropertyField(property));
            return root;
        }
    }

I even managed to add a dropdown that allow me to switch between different subType of the COMChannel and everything works fine :

property.managedReferenceValue = Activator.CreateInstance(availableChannelTypes[changeToChannelType]);
            property.serializedObject.ApplyModifiedProperties();
            property.serializedObject.Update();

It did took me a while tho to understand I had to manipulate the managedReferenceValue... not a lot of information about that.

gloomy chasm
thin rampart
#

I'll check that, I'm relying on reflection to do so for the moment and it seems to be working fine.

#

Thanks for the help !

gloomy chasm
simple wasp
#

hi, i'm trying to get the inspector to show different UI based on different values but i cant get it working, i want the fields to disappear /appear based on action type

[CustomPropertyDrawer(typeof(ActionInfo))]
public class ActionInfoDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        Debug.Log("Drawing ActionInfo");

        SerializedProperty actionTypeProperty = property.FindPropertyRelative("actionType");

        // Draw the actionType dropdown
        EditorGUI.PropertyField(position, actionTypeProperty);
        position.y += EditorGUIUtility.singleLineHeight;

        // Customize the GUI based on the action type
        switch (actionTypeProperty.enumValueIndex)
        {
            case (int)ActionInfo.ActionType.UnitTarget:
                // Show options for UnitTarget
                EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
                position.y += EditorGUIUtility.singleLineHeight;
                EditorGUI.PropertyField(position, property.FindPropertyRelative("baseRange"), GUIContent.none);
                break;
            case (int)ActionInfo.ActionType.GridTarget:
                // Show options for GridTarget
                EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
                position.y += EditorGUIUtility.singleLineHeight;
                EditorGUI.PropertyField(position, property.FindPropertyRelative("aoeRange"), GUIContent.none);
                break;
            // Add more cases as needed
        }
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        // Return the height needed for the number of properties you are displaying
        return EditorGUIUtility.singleLineHeight * 3;
    }
}

[CreateAssetMenu]
public class ActionInfo : ScriptableObject
{
    public string actionDescription = "Action Description";
    public int baseRange = 0;
    public int baseDmgAmount = 0;
    public enum ActionType
    {
        UnitTarget,
        GridTarget
    }
    public ActionType actionType;
    public int aoeRange =  0;```
gloomy chasm
simple wasp
# gloomy chasm `PropertyDrawer` is for saying how a serialized field (property) is drawn in the...

hmm i dont get it, i updated to this but still not showing something

[CustomPropertyDrawer(typeof(ActionInfo))]
public class ActionInfoDrawer : Editor 
{
    protected void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        Debug.Log("Drawing ActionInfo");

        SerializedProperty actionTypeProperty = property.FindPropertyRelative("actionType");

        // Draw the actionType dropdown
        EditorGUI.PropertyField(position, actionTypeProperty);
        position.y += EditorGUIUtility.singleLineHeight;

        // Customize the GUI based on the action type
        switch (actionTypeProperty.enumValueIndex)
        {
            case (int)ActionInfo.ActionType.UnitTarget:
                // Show options for UnitTarget
                EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
                position.y += EditorGUIUtility.singleLineHeight;
                EditorGUI.PropertyField(position, property.FindPropertyRelative("baseRange"), GUIContent.none);
                break;
            case (int)ActionInfo.ActionType.GridTarget:
                // Show options for GridTarget
                EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
                position.y += EditorGUIUtility.singleLineHeight;
                EditorGUI.PropertyField(position, property.FindPropertyRelative("aoeRange"), GUIContent.none);
                break;
            // Add more cases as needed
        }
    }
}

[CreateAssetMenu]
public class ActionInfo : ScriptableObject
{
    public string actionDescription = "Action Description";
    public int baseRange = 0;
    public int baseDmgAmount = 0;
    public enum ActionType
    {
        UnitTarget,
        GridTarget
    }
    public ActionType actionType;
    public int aoeRange =  0;
}
gloomy chasm
#

Though as a note, I recommend using UIToolkit instead of IMGUI as it is much easier to style, and just generally easier to use. (Also what Unity is moving to)

barren moat
#

How can I add a context menu to a folder in project?

#

This is what I've tried:

    const string BatchMenu = "CONTEXT/Object/Scripts/Batch Enable Nullable";

    [MenuItem(BatchMenu)]
    static void BatchEnableNullable(MenuCommand command) {
      var path = AssetDatabase.GetAssetPath(command.context);
#

I know folders are of type DefaultAsset but I tried Object because that feels like the most general type.

visual stag
#

(and you would make a validate version that greyed it out if it wasn't a folder, not ideal I know)

barren moat
#

That's what I had working now

#

The are problems with the vertical split project view though. Right clicking the left pane doesn't select the folder

#

(I'll try it myself after lunch)

visual stag
#

Oh god I tried to use the debugger for this and things are not happy

visual stag
# barren moat Can you access the context object if you do that?

Yes, but it won't work anyway. This approach seems to:

const string BatchMenu = "Assets/Scripts/Batch Enable Nullable";

[MenuItem(BatchMenu)]
private static void BatchEnableNullable(MenuCommand command)
{
    string path = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]);
}

[MenuItem(BatchMenu, isValidateFunction: true)]
private static bool BatchEnableNullableValidate(MenuCommand command)
{
    string[] guids = Selection.assetGUIDs;
    if (guids.Length != 1)
        return false;
    string path = AssetDatabase.GUIDToAssetPath(guids[0]);
    return Directory.Exists(path);
}
barren moat
#

Yeah, unfortunately that just disables option on the left of the project view

#

Because it's not part of the selection

visual stag
barren moat
#

Okay it's slightly different to what I tried, I'll take a look

#

Thanks @visual stag. I'll let you know how it goes after lunch

barren moat
#

it's possible that activeObject differs when a folder is selected

#

@visual stag well that works a treat, not sure what was going on before.

#

Thank you! <3

#

Pretty annoyed that i have to do this, I enabled nullable refs in the csproj and then found out that the VS editor extension generates an old style of csproj that doesn't support that specific option.

#

So now I'm making a tool that prefixes files with #nullable enable en masse hahah

#

So annoying

#

We have three programmers each using a different IDE

visual stag
barren moat
#

Vscode 4 life

#

Debuggers are overrated

waxen sandal
#

🔨

rocky cipher
safe sorrel
#

I'm writing an Overlay. I want it to show a button if the currently selected object has a specific component on it.

#

the point is to be able to hide everything except objects referenced by that component

#

wait, this is going to be a UIToolkit question

#

I will ask it there in a bit

waxen sandal
#

Ther's a uitk channel?

ashen wyvern
#

is there a way to analyze the project and throw some sort of error if there is an asset reference comming from a "forbidden" folder?
Context: I have a "dev" folder where each dev has their own experimental stuff. Nothing outside the dev folder should reference the dev folder. Can I somehow do something so the editor gets really mad if something references this evil folder? 🤔

waxen sandal
#

Yes, fastest would probably be to use something like grep to find all GUIDs and then try check whether they're in the dev folder or not

gloomy chasm
# safe sorrel I will ask it there in a bit

This sounds like an editor Overlay question. I don't fully get your question, but I am pretty sure this is the right place for it. Overlay has stuff for showing an overlay based on selection and stuff.

waxen sandal
#

Or you can walk the tree with SerializedObjects/SerializedProperties but that's slooooow

safe sorrel
gloomy chasm
#

They said they were had something else/better in the works... but... 🤷‍♂️

#

It is basically just checked every x ms to see if visible is true or false hah

safe sorrel
#

related problem: the Overlay I'm writing searches for all objects of a certain type to do work on

#

I want to limit this to just the current prefab stage if one is open

#

Should I just grab the root object from the PrefabStage and use GetComponentsInChildren?

gloomy chasm
#

Hmm... this sounds a bit funky like this isn't the intended way to do it. Maybe it is, but can you share a bit of context to what you are doing? There might be an easier way.

gloomy chasm
safe sorrel
#

imagine you have three different groups of objects in a prefab, and you want to be able to show just one of the three groups at a time

#

the problem is that FindObjectsByType is searching all of the open scenes

#

on the bright side, SceneVisibilityManager.instance.ShowAll(); does only affect the currently active prefab stage

#

so that's convenient

gloomy chasm
#

Ahh, so yo want to show all available groups in the overlay.

safe sorrel
#

Well, that'd be a nice stretch goal!

#

I'm not sure how I'd do that.

#

with IMGUI it's obvious, since you're drawing the entire GUI every frame

#

I have minimal UITK experience

gloomy chasm
#

Are the groups defined just in a component then?

safe sorrel
#

Each group is a component that references other renderers, lights, and a few other specific things

#

So yeah, that's the gist

#

I don't want to actually turn things on and off, so I'm showing and hiding the game objects those referenced components are on instead

#

(which is close enough)

gloomy chasm
#

What I normally do for this sort of thing is setup a singleton with a list (or even a static works) and would have my group component have [ExecuteAlways] and in OnEanble and OnDisable add/remove the group to that list.

#

Then you can just check that list instead of having to do big potentially expensive searches

safe sorrel
#

I'm okay with doing a search each time

#

(and that might make the problem worse!)

#

restricting myself to the current prefab stage, that is

gloomy chasm
#

Yeah but then you can have a event for each time a group is added/removed and easily update your UITK elements. So adding a group component would 'automatically' update the UI

safe sorrel
#

ah, I see

#

Actually, I could split the difference

gloomy chasm
#

And you can do PrefabStageUtility.GetCurrentStage()?.IsPartOfPRefabContents(group.gameObject) to see if it is in the stage

safe sorrel
#

and just make the group fire an event when created or destroyed, even though I don't keep a list

safe sorrel
#

So in that case, a singleton list would be workable

safe sorrel
#

the latter is what I'd do with UGUI

gloomy chasm
safe sorrel
#

Okay, so roughly what I was imagining

#

I’m just unfamiliar with the “rules” for UITK. Gotta play around with it a bit

#

So far I’ve only used it in very basic property drawers, where the layout never changes after creating it

gloomy chasm
#

Ahh yeah, totally get it, feel free to @ me with any questions. 😄

safe sorrel
#

Maybe I’ll go nuts and replace my old IMGUI debug menu with UITK

#

Immediate mode is just so convenient, though..

#

I ran into a wall with scroll views, though. Can’t get them to grow up until a maximum size and then start scrolling

gloomy chasm
#

Hmm, need to set them to style.flexGrow = 1?

safe sorrel
#

(In IMGUI, I mean!)

gloomy chasm
#

Ahh

#

Yeah the scroll views in IMGUI can be a little finicky to setup sometimes

safe sorrel
#

ah, isn't there a static even that fires after a reload?

gloomy chasm
safe sorrel
#

ooh, okay, so I'd use RegisterCallback on the root visual element

#

That makes sense.

gloomy chasm
#

Yeah exactly

safe sorrel
#

great, thanks (:

#

Do you know if Unity is constructing a new MyOverlayClass every time it shows the overlay? I see that CreatePanelContent is an instance method..

#

if so, I presume I can store some references to my visual elements in fields

#

(i will tryitandsee !)

gloomy chasm
safe sorrel
#

it looks like it's re-using the same object

#

that's still fine, really

#

unless it can somehow display the same overlay multiple times

gloomy chasm
#

It can't

#

(I mean, you can probably fanagle it to if you wanted it to...)

safe sorrel
#

i did see you can make any editor window support overlays...

#

time to join the Bad Idea Club

gloomy chasm
#

Actually, you know when you hide an overaly, it is actually still there haha.

safe sorrel
#

speaking of, it'll be nice to convert some of these editor windows into overlays

#

well, at least this one

#

it's literally just a toggle

gloomy chasm
safe sorrel
#

maybe a custom graph editing window

gloomy chasm
#

Yeah, all I can think of so far is graph/node windows

#

Ah I know, a custom editor window, where each component is an overlay hahaha

safe sorrel
#

custom game view where it's rendered entirely by overlays

gloomy chasm
#

Hahaha

safe sorrel
#

Okay, it looks like it creates a new object for each place the overlay is shown

#

(i'm logging the hash code of the Overlay in response to AttachToPanelEvent)

#

interestingly, it's logging twice every time I click on the overlay

#

well that's a bit weird, actually...

#

it's logging once for each instance of the overlay that's open

gloomy chasm
#

Welcome to UIToolkit 🙂

safe sorrel
#

i'm surprised it's firing every single time I click on the overlay

gloomy chasm
#

It is because it starts to drag it out

safe sorrel
#

ah, that's why it was randomly firing once or twice

#

clicking on the label caused one pair of detach-attach events

#

clicking on the title causes two pairs

#

it's not actually related to how many overlays are open

gloomy chasm
#

Basically it deletes whatever the overlay is currently, and then makes a new one for whatever the overlay's 'free form' look is

safe sorrel
#

bonus gotcha: you can't ask if a game object is in a prefab during Awake or OnEnable!

I am now using EditorApplication.delayCall to wait a bit before updating the overlay

#

(and using a bool flag so I don't try to update it 30 times in a row)

#

Looks like it's behaving itself now

gloomy chasm
#

So, I have a IMGUIContainer that draws a list of asset previews. When the mouse hovers over an item for x time I want to draw a custom 'live' preview.

I have two (really one) issues though, the preview doesn't show smoothly due to the lack of repaint events, and it doesn't show in the correct amount of time since it lacks update events.

#

Suggestions on the best way around this/trigger repaint events for a IMGUIContainer?

#

And ideally, it wouldn't just constantly be repainting because that would be a bad idea for performance

waxen sandal
#

Can't you just do some custom repaint behaviour that starts on enter and keeps going until you exit?

karmic night
#

You might be able to play with editor coroutines for both the hover for x time and to run repaint quickly for the previews to show smoothly. But there’s probably no getting away from constantly repainting if you want the previews to stay smooth.

shadow violet
#

Is there a way I can use AssetDatabase.LoadAssetAtPath with a string as the type? Or somehow save a type with JSON? This seems to return null:

typeName = "UnityEngine.GameObject";
var obj = AssetDatabase.LoadAssetAtPath(assetPath, System.Type.GetType(typeName));
Debug.Log(obj, obj);

But this works fine:

var obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.GameObject));
Debug.Log(obj, obj);

What im trying to do, is make a way I can store a reference to a prefab in my project through a JSON file, essentially store the path to the asset, and when I need to, load that path, but LoadAssetAtPath requires me to also know the type, so I need a way to store that type as well, or is there maybe another way I can approach this whole thing?

gloomy chasm
unreal light
#

i just noticed unity 6 has an actual Type tree view?

#

at least it seems like it has it in ui builder

#

does someone know how this is setup? i'd like to use it for a SerializableSystemType to well, serialize system types

gloomy chasm
shadow violet
# gloomy chasm You can use `AssetDatabase.LoadMainAssetAtPath` instead unless you need to load ...

I was thinking of LoadMainAssetAtPath but to my understanding, it is not intended to load things like meshes a part of a fbx, which is one thing I may need to do with some assets - I am also trying to use both the GUID and path, where the code will first try a path, if it fails to find an asset at the path itll try the GUID, for cases where an asset might be re-imported or pulled from a git, then even though the asset is the same and nothing about its size or anything changed, Unity might assign it a different GUID, so in those cases, im hoping the path will be enough (assuming the name of the asset doesnt change)

shadow violet
barren moat
deft plover
plush spade
#

Can someone explain to me why these disturbances are happening?
Is it related to style?

Why does the list view that does not cause problems when the graph view is added to the rootVisual element cause problems when it is put in a foldout in the extension view in the node?

Working Case

        private static void TestCase1()
        {
            _instance.rootVisualElement.Add(TestCaseListView());
        }

Problem Case

        private static void TestCase2()
        {
            var node = new Node();
            var contentSpace = new VisualElement();
            contentSpace.name = "Content Space";

            contentSpace.style.width = 200;
            contentSpace.style.height = 100;
            contentSpace.style.backgroundColor = Color.white;
            contentSpace.style.flexGrow = 1;
            contentSpace.style.flexShrink = 1;
            node.extensionContainer.Add(contentSpace);


            var foldout = new Foldout();
            foldout.style.flexGrow = 1;
            foldout.style.backgroundColor = Color.grey;

            contentSpace.Add(foldout);
            foldout.Add(TestCaseListView());

            node.RefreshExpandedState();
            GPView.Instance.AddElement(node);
        }
#

And also here is list view creation same as api doc

        private static ListView TestCaseListView()
        {
            const int itemCount = 10;
            var items = new List<string>(itemCount);
            for (int i = 1; i <= itemCount; i++)
                items.Add(i.ToString());

            Func<VisualElement> makeItem = () => new Label();


            Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = items[i];

            const int itemHeight = 16;

            var listView = new ListView(items, itemHeight, makeItem, bindItem);

            listView.selectionType = SelectionType.Multiple;

            listView.itemsChosen += objects => Debug.Log(objects);
            listView.selectionChanged += objects => Debug.Log(objects);



            listView.style.height = 200;
            listView.style.width = 100;
            listView.reorderable = true;
            listView.reorderMode = ListViewReorderMode.Animated;
            listView.style.flexGrow = 1.0f;
            listView.style.flexShrink = 1.0f;
            return listView;
        }
naive charm
#

Can someone help me with this editor script? I'm trying to just refresh some properties of a "LegConstraintRig" script I have every time the transform handle is moved in the Scene view, and the position seems to be updating when I move it (as seen with the Debug.Log statement), but EditorGUI.EndChangeCheck() always seems to return false so RefreshProperties() never gets called.
I'm basing the script off of this docs page : https://docs.unity3d.com/ScriptReference/Handles.PositionHandle.html
I can't seem to find any difference

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(LegConstraintRig))]
public class RiggingEditor : Editor
{
    void OnSceneGUI()
    {
        LegConstraintRig rig = (LegConstraintRig)target;

        EditorGUI.BeginChangeCheck();

        Vector3 newPosition = Handles.PositionHandle(rig.transform.position, rig.transform.rotation);

        Debug.Log($"newPosition: {newPosition}");

        if (EditorGUI.EndChangeCheck())
        {
            Debug.Log($"Property changed");
            Undo.RecordObject(rig.transform, "Move Transform");
            rig.transform.position = newPosition;
            rig.RefreshProperties();
        }
    }
}
fiery canopy
#

Quick question, Am I allowed to create a custom editor for a struct or does it only work with MonoBehaviors/Components?

#

I ask because I tried doing what I want with a PropertyDrawer, but that seems to not give me much flexibility when it comes to running extra functions.

gloomy chasm
fiery canopy
#

dang kind of figured that was the case.

gloomy chasm
#

You should be able to do 'anything' with a ProeprtyDrawer though that you can with an Editor

#

What are you trying to do which you were having a hard time with?

fiery canopy
#

Yeah but I have this issue where the data I have doesn't populate until after my scenes load and so my editor tool doesn't update until after it click on a object and then it populates the data when the inspector is drawn.

#

So I have a custom TimelineClip taht needs a serializedProperty that my PropertyDrawer updates. And it doesn't update until after the PropertyDrawer has finished being drawn.

#

So I have to click on each timelnie clip to have the data be propagated.

#

Which I don't want to do everytime a scene is loaded.

gloomy chasm
#

That sounds like you are assigning data in the draw it self, which you shouldn't be do at all.

#

For PropertyDrawers or Editors.

fiery canopy
#

Well no what I was trying to do was set a SerializedProperty from said PropertyDrawer when it was loaded but forgot that isn't a thing that can be done since you have to have the Drawer in loaded in the inspector for its drawing function to be called.

So I instead have to populate the data I want when the scene loads instead of when the PropertyDrawer is told it needs to draw something.

#

And that seems to work out for me.

#
private static void OnPlayModeChanged(PlayModeStateChange obj)
        {
            EditorCoroutineUtility.StartCoroutineOwnerless(
                SetDataRoutine());

            EditorCoroutineUtility.StartCoroutineOwnerless(
                SetObjectRoutine());
        }

        private static void OnSceneOpened(Scene scene, OpenSceneMode mode)
        {
            SceneName = scene.name;
            Debug.Log(SceneName);

            EditorCoroutineUtility.StartCoroutineOwnerless(
                SetDataRoutine());

            EditorCoroutineUtility.StartCoroutineOwnerless(
                SetObjectRoutine());
        }

Basically putting the code I want in here fixes my problem

atomic sable
outer kraken
#

small question, is EditorApplication.hierarchyWindowItemOnGUI cleaned up on Domain Reload by Unity or do i need to remove my Listener(s) manually when that's happening?

If i need to do it manually, what is the proper way to do so?
Is, for example, EditorApplication.quitting called before a Domain Reload? (Nope, it isn't, just tried it out)

I have no idea where i should hook into for unsubscribing (if that's even necessary) ~.~

soft plinth
#

Whether you need to unsubscribe or not, you can verify by yourself... Try adding a Debug.Log and see if it gets sent multiple times after code is recompiled.

outer kraken
#

Oh damn, didn't know these exist! Thank you very much, seems to be exactly what i need 😄

acoustic dragon
#

Hey, I'm trying to create an atlas v2 through script. Basically what I'm doing is:

var atlas = new SpriteAtlas();
atlas.Add(spritesArray);
AssetDatabase.CreateAsset(atlas, "Assets/SomeName.spriteatlasv2");

But doing so causes a native error to appear saying that this extension is not supported. Removing v2 from extension lets me create atlas, but it's a v1 one. I've searched everywhere, but couldn't find a way to create v2 atlas through code, any ideas?

snow pebble
#

is it possible to interact with scene window with an editor window tool ? or is that only possible with editor scripts relating to monobehaviours and scriptable objects

#

eg clicking in the scene to get a world position

waxen sandal
#

Is that what you're looking for?

#

You can just subscribe to that

snow pebble
#

i think so ? ill try it

#

kinda wish unity would explain that better in the docs some where

snow pebble
#

is it possible to bind to a field in the EditorWindow itself?

public class CreatorTool : EditorWindow{
    [SerializeField]
    string _error; //bind label to this
...
}

i tried putting _error as the binding path but i think that only works if the editor relates to an actual object

waxen sandal
#
            SerializedProperty environmentId     = _self.FindProperty("targetEnvironment");
            DropdownField      environmentSelect = new DropdownField();
            environmentSelect.BindProperty(environmentId);```
_self is new `SerializedObject(this)` in an editor window
snow pebble
#

ah so like this:


        var errProp = new SerializedObject(this).FindProperty("_error");
        _errorLabel.BindProperty(errProp);
        _errorLabel.RegisterValueChangedCallback((evt) =>
        {
            var target = evt.target as Label;
            target.style.display = evt.newValue == "" ? DisplayStyle.None : DisplayStyle.Flex;
        });
waxen sandal
#

You still have to dispose the serializedobject on window destroy

snow pebble
#

oh its not garbage collected?

waxen sandal
#

If something implemetns a dispose method, you're supposed to call it

snow pebble
#
    ~SerializedObject()
    {
        Dispose();
    }
``` seems they call it for you when garbage collects it
waxen sandal
#

Looks like it's caled when it's GC'd but it's still good practice

safe sorrel
#

It gets called, eventually

#

I...did not realize that you need to dispose SerializedObject though, haha

#

good to know

unreal light
#

i'm having a weird behaviour with a custom visual element i'm making to control a property drawer.

Basically its for a custom serialization solution for classes not derived from Object, it basically accepts a System.Type in one of its properties, and depending wether or not the fed Type is null or not, it should either Hide a HelpBox and Enable a container, or do the oposite (show the help box and disable the container)

#

the issue i'm having is that... it seems like the UI is not updating itself correctly? https://i.gyazo.com/f7e5d0cd797d4c41e60f00e9c08391c5.gif

Its weird because i have checked the code with a debugger and the behaviour i'm looking for at attachment (check if the type to serialize is null or not, and affect the ui accordingly) is running, but nothing happens in the inspector itself until i update it

#

here's the code itself

#

SetDisplay is an extension method i made that just sets the display style to flex or none depending on the bool value, rest is vanilla uitoolkit

#

using unity 6 btw

#

ok now i'm even more confused

Decided to set the typeBeingSerialized on CreateInspectorGUI and it works now (??)

gloomy chasm
gloomy chasm
unreal light
#

oh

#

derp

#

give me a sec

#

there it is

#

keep in mind that my issue was happening because i wasnt setting the typeBeingSerialized on CreateInspectorGUI, which... confuses me

#

since i am setting it on the UpdatEFieldCollection method, which gets called as the PropertyField gets bound afaik

gloomy chasm
#

Ahh that is where the confusion is, the RegisterValueChange callback does not get raised when the visual element is first created

#

You could avoid this partially I think my making SerializedFieldCollectionElement inherit from Bindable and write it like the base control are.

unreal light
gloomy chasm
#

The only time the typeBeingSerialized is set, is from the UpdateFieldCollection method which is only called in the RegisterValueChangeCallbackwhich dos not run on startup

unreal light
#

i beg to differ

#

you can see in the video that the method does get called

#

which is why i'm confused on this behaviour

gloomy chasm
#

Hmm.. PropertyField might behave differently then... but that is weird....

unreal light
#

definetly

#

i'll try what you suggested with the bindable bit

#

is there an event for when a serialized object is bound to an element?

gloomy chasm
unreal light
#

ahh

#

ok i got it

#

thx

plucky knot
#

Is there a simple process if I have a standard cs project, but want to also support a unity package version? I'd use a dll, but those can't get defines to strip code after compiling. Or would I essentially have to maintain a unity specific repo just with the package format + a duplicated file structure of the main repo? 🤔 (figured this was fine here as it is package related)

gloomy chasm
#

Not sure if that would fit your needs.

ebon delta
#

Is it possible to add a custom play button here? I would like to make my own next to the original one that makes my character spawn from the editor camera positon

ebon delta
#

cool thanks 😄

gusty mortar
#

Hi ! Could somebody exlain to me how OnValidate is triggered when modifying a field ? Since it's not triggered when I set my object dirty with EditorUtility.SetDirty(), I assume it happens at another level

gusty mortar
#

Yeah I read that already. I wanted to know how a change in a field is different from a dirty serialized object in the eye of OnValidate

gloomy chasm
#

Dirty just tells Unity that the object does in fact need to be saved, whenever Unity next saves.

#

While something like setting the value with SerializedObject/SerializedProperty, updates the serialized data.

gusty mortar
#

OK. So it doesn't have anything to do with the change detection. Thanks 🙂

gloomy chasm
#

Yeah, exacty. 🙂

reef hornet
#

hello there
is it possible to add a custom icon/text to the bottom/top bar of the unity editor?

gloomy chasm
gloomy chasm
#

It is also possible for the bottom bar in the same manner that the linked extension does it for the top bar. So you can take a look at the code and the unity source code and add support for the bottom bar as well.

thin rampart
#

Hey all, would it be possible to bind a TextField to the currently selected Asset filename ? I'm developing a Custom Editor Windows, and for a specific type of asset, when it is selected I would like to be able to see and edit the name of that Asset. And I was wondering if I could use binding for that. If not I guess I'll have to write all the logic in a ValueChange callback but that's only one-way, if the asset name is changed from elsewhere it won't be reflected in my custom editor windows...

gloomy chasm
#

And rebind to the new SerializedObject of course

thin rampart
#

That sound reasonable. I'll give it a shot ! Thanks

gloomy chasm
#

Sure thing!

thin rampart
#

@gloomy chasm So I did something like this (sorry for the long variable name...). But it seems I can't retrieve the name property on the gameObject, it return null. (My asset is a Prefab)

        private void OnSelectedCompositionChange(Composition newSelection)
        {
            Debug.Log($"Changed selection to {newSelection.gameObject.name}");

            // Dispose the old selection serializedObject and serialize the new Selection
            if(serializedSelectedCompositionGameObject != null )
                serializedSelectedCompositionGameObject.Dispose();
            serializedSelectedCompositionGameObject = new SerializedObject(newSelection.gameObject);

            Debug.Log(serializedSelectedCompositionGameObject.FindProperty("name")); // Can't find the name property...

            // Bind the serialized object name to the text field
            if (compositionNameField != null)
                compositionNameField.BindProperty(serializedSelectedCompositionGameObject.FindProperty("name"));
            serializedSelectedCompositionGameObject.ApplyModifiedProperties();
            serializedSelectedCompositionGameObject.Update();
        }
thin rampart
#

Haaa, how do you find a list of property like that in the doc ? I think I've encouter this kind of issue a lot of time. Is it because it is private so a "m_" is automatically added ?

gloomy chasm
thin rampart
gloomy chasm
thin rampart
#

For info, it doesn't rename the Asset prefab. I still have to use AssetDatabase.RenameAsset method in the ValueChange callback. I was a bit too quick earlier ^^.

plucky knot
#

Although then you can't add via git url anymore... which seems fine?

crystal isle
#

hey yall, maybe a beginner question here, but is there a way to listen to a value changing in the inspector and call a function to change to a different variable in the object?

surreal delta
#

but if you need it to be more specific you can either do a custom inspector script get the property you want to check if it changed, listen to the change event and modify the property you want

thin rampart
#

Hey all, I've a quite particular question. When editing prefab in the isolation context you can set a scene as a environment scene. But, the GameObject inside that environment scene do not visually update. To make it simple in the scene I've a cube with a Script attached to it that move the cube around, the script is set to be ExecuteAlways and the update function does get trigger while I'm in the Prefab Editing context (Checked with a Debug.log). But my Cube isn't moving... if I quit the prefab context it start moving again. Is it a bug, something I didn't understood or simply not possible ?

#

Nevermind, it had to do with my scene being opened in the Hierachy and in the Prefab context at the same time. I guess that "duplication" is causing this probleme and quite a lot of other problem...

modest pumice
#

anyone knows why i am getting an erorr on this ?

flat surge
#

How do you guys auto-update your builds? Or at least have the Unity editor auto-download the newest Unity version so your project are ready to use it?

Also, how do you auto-update radeon drivers?

topaz bone
#

Why would i want to download each editor version evry time new one just come out thou?

gloomy chasm
gloomy chasm
whole steppe
#

where can I put a something that I only want to happen when the dev/me click a GO with a customeditor?

#

onGUI is constant while the editor is open, I want only when it opens

barren moat
#

Check out game-ci for a suite of scripts for building

#

We ended up using our own machine though because GitHub actions run out of memory quickly

#

But you can still use them as a reference

#

I think you can grab unity hub from chocolatey too... Sorry just going from memory

#

There is definitely a way to grab it with curl or similar

#

Then you can give it the right arguments to download the editor you need. You can pull that from the project unity version file

mellow elk
#

Hello guys, I'm beginner with no experience in editor scripting.
Any recommendation of where you I start? Thank you in advance.

barren moat
#

Then Google how to achieve that goal

mellow elk
barren moat
mellow elk
#

No, I’m genuinely beginner to this topic. I appreciate yourhelps and advices

short tiger
mellow elk
mellow elk
short tiger
#

The type of editor scripting that can be useful depends on the game you're making and the problems you need to solve to get there.

barren moat
flat surge
hollow ore
#

Help, how to update the inspector when the serialized object changes?
For example assume I need something like Diagnostics[] to show in inspector when somehting is not OK with the component, e.g. it's referencing other objects and when they don't meet some criteria it should show in the inspector a helpbox saying "object X, Y, Z don't meet certain criteria"

hollow ore
#

uitk

gloomy chasm
hollow ore
#

and just bind it?

gloomy chasm
#

Yup

hollow ore
#

but to write custom controls for each diagnostic, or can I generate helpboxes "on the fly" by transforming the Diagnostic somehow?

gloomy chasm
#

I guess I should be clear, is Diagnostics[] in a SerializedObject (or stored in a UnityEngine.Object) or is it in some non-serializable class?

hollow ore
#

If I can bind to an array Diagnostics[] (where it's defined as struct Diagnostic { Severity severity; string message; }) and tell uitk: "here, for each of them create a single help box"

#

it is annotated with [Serializable] and is just stored there in the component

#

because honestly I didn't know of a better way to do that

gloomy chasm
thin rampart
#

Hey, I can't find in the Doc a proper way to update a DropdownField choices list when the user open the dropdown. I tried this :

dropdownField.RegisterCallback<ClickEvent, DropdownField>((evt, dropdown) => {
  dropdown.choices = composition.motionLayersName; 
  dropdown.MarkDirtyRepaint();
}, dropdownField);

But the Dropdown popup is shown before the change to the choice is made, so I've to click it a second time to actually see the change...
Any idea ?

gloomy chasm
#

You could try doing it on the PointerDown event (can't remember if you would want trickle down or no trickle down)

thin rampart
#

@gloomy chasm As an example, I would like my dropdown list to reflect the list of GameObject in the hierarchy. But this can change at any time so i've to update at some point the choice dynamically. I could have some event to listen for a change in that hierarchy and update the dropdown there, but In my actual use case it's a bit more tricky so it's much easier if I recompute the choice list when the dropdown get's opened.

i'll try the PointerDown event

#

Perfect that worked ! Thanks

barren moat
flat surge
#

I don't like having to check everytime if theres an update

waxen sandal
#

Sounds like a bad idea

#

But you do you

topaz bone
#

it might be worth to mention why its not greates idea... each version require a disk sapce from you. unless u want to also recycle old one... but generally the is no point to go for every minor update... just do it once you see there is feature or bug fix you need

gloomy chasm
#

More importantly every update no matter how small has a chance of introducing new bugs or breaking things. So it is a good idea to stay on a single version for the majority of your project. When you are on a LTS it is safer to update for the LTS bug fixes, but it still comes with risk.

#

That is the main reason why it is not recommended to update versions automatically.

waxen sandal
#

Not a small chance lol

#

Also you'll be desyncing the version you're working in and the one you're building

#

Any bugs you notice might not be present in the other

gloomy chasm
waxen sandal
#

Oh

gusty mortar
#

Hi ! Is there a way to listen for shortcuts in UIToolkit ? I tried listening to keyboard event on my inspector, but it is bypassed by default shorcuts apparently (i suppose it's a matter of focus)

gusty mortar
barren moat
#

Most unity updates break our project and need manual repair. Upgrading Unity is a big deal that I usually leave until I absolutely need to update. Especially if you're using a non-LTS version.

#

I usually timebox two hours for the update and the whole team needs to merge in their branches first, then if I can't get the update done in that time (due to various plugins and whatnot breaking) we reconsider why we're doing it. I'd advise staying with the latest LTS version for as long as possible and only upgrading if you have an engine bug or there is an absolute must-have feature.

#

You don't need to check every time there's an update, you just don't update.

flat surge
#

I'm worried if we ignore updates, we'll have a bigger problem down the road

barren moat
flat surge
#

Thanks for the advice though!

#

Down the road, I can see myself gravitating to your methodology

barren moat
#

Me too lol

visual stag
#

Meanwhile when working on personal projects I'm always on the most cutting edge version. Though I'll keep the previous version around to roll back if something is busted

#

I think it definitely depends on the size of the team and what experiences the project has had with upgrades

tough cairn
#

can end change check be used in this manner ?

        var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( assets[0] );

        UnityEditor.EditorGUI.BeginChangeCheck();

        RF.SetActive( true );
        RF.passMaterial.SetFloat("_Fade", 1.0f );

        if( UnityEditor.EditorGUI.EndChangeCheck() )
        {
            UnityEditor.AssetDatabase.SaveAssets();
        }
#

ehh... nvm i see where my logic falls flat

#

hmmm it still doesn't work

#

here is what i got so far :

[RuntimeInitializeOnLoadMethod]
static void Save()
{
    var assets = UnityEditor.AssetDatabase.FindAssets("FullScreenRenderFeature");

    var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( assets[ 0 ] );

    RF.SetActive(true);
    RF.passMaterial.SetFloat("_Fade", 1.0f);

    var guid = UnityEditor.AssetDatabase.GUIDFromAssetPath(assets[0]);

    UnityEditor.AssetDatabase.SaveAssetIfDirty(guid);
}
#
[UnityEditor.InitializeOnLoad]
public class Hook : UnityEditor.Build.IPreprocessBuildWithReport
{
    static Hook() => hook(); // On Launch 

    public int callbackOrder => 0;

    public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) => hook(); // On Build 

    static void hook()
    {
        var guids = UnityEditor.AssetDatabase.FindAssets("FullScreenRenderFeature");

        if (guids.Length < 1) { Debug.LogError("not found"); return; }

        var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);

        var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( path );

        // Save Render feature
        RF.SetActive(true);
        UnityEditor.AssetDatabase.SaveAssetIfDirty(new UnityEditor.GUID( guids[0] ));

        // Save material 
        RF.passMaterial.SetFloat("_Fade", 1.0f);
        var m_guid = UnityEditor.AssetDatabase.GUIDFromAssetPath(UnityEditor.AssetDatabase.GetAssetPath(RF.passMaterial));
        UnityEditor.AssetDatabase.SaveAssetIfDirty(m_guid);

        // Force save 
        UnityEditor.AssetDatabase.SaveAssets();
    }
}

this worked

pale pollen
#

hi guys

#

i am working with scriptableobject

#

an i wanna set icon for scriptableobject's instance

#

tried using SetIconforObject, but it doesnt work as aspect

still ferry
#

Hey, did anyone encounter problem when making editor for generic class in unity 6.0? It doesnt work for me like it used to..

    public abstract class TestGeneric<T> : MonoBehaviour
    {
        public T value;
    }

    public class TestGenericInt : TestGeneric<int>
    {
        
    }

    [CustomEditor(typeof(TestGeneric<>), true)]
    public class TestGenericEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            
            EditorGUILayout.LabelField("Testing field", EditorStyles.boldLabel);
            DrawDefaultInspector();
            
            serializedObject.ApplyModifiedProperties();
        }
    }
#

If I make empty class e.g TestGenericBase it will work, but I'm not the biggest fun of empty class just for the sake of editor :/

hollow ore
#

How do I prevent change callbacks being triggered on a property fields in custom editor when the inspector is opened?

#

When I select an object with a script that has custom inspector and setup a callback in the CreateInspectorGUI like below, the message is logged whenever I select the object and inspector opens

propertyField.RegisterValueChangeCallback(_ => Debug.Log($"property field '{propertyField}' changed"));
gloomy chasm
hollow ore
#

Oh no :(
Can you propose an alternative solution in that case?
I have custom inspector base class that collects certain annotated properties from the component, and depending on the type of annotation notifies the component of the changed value.
For example I have a "Variant" property that is annotated such that when it's value is changed in the inspector it updates the component data, and the component emits C# event that other components currently on the scene are subscribed to.
The problem is that reacting to the event in the component triggers some calculations, so I want to avoid doing them each time I select another object and new inspector is opened.

#

I use it to generate shader asset files, and some property fields perform a simple uniform update on the material, while some other properties change the shader soruce code itself, and I just can't afford to regenerate the shader each time I simply change selection

#

for example here I have a prefab that generates a raymarching shader from the scene hierarchy:

#

and changing the Variant in the Sdf Torus Controller in the inspector is intended to regenerate the whole shader with alternative function for the torus

#

while some other properties like Main Radius don't regenerate the shader, they just update the uniforms

#

My idea is to just... write a custom inspector for each kind of component and live without property fields

gloomy chasm
hollow ore
#

Can you point me to the right docs? I am a novice when it comes to UITK

#

specifically to the Bind event because I can't find it

gloomy chasm
#

Oh... right... it is an internal event... 😬

#

You can use the TrackSerializedProperty extension method I guess instead of the ValueChange event

#

Or the TrackSerializedObjectValue extension method for I think when any value on a SerializedObject changes.

hollow ore
#

yup, thank you very much, this is enough for now

snow pebble
#

how do you keep the values of editor tool settings ? it keeps resetting every time i close the editor window or recompile my code

#

its incredibly annoying

hollow ore
#

in my case my inspectors are just "views" of the data that is stored and serialized in components

snow pebble
#

mine isn't. for example i set a grid size for placing things, this is just solely for the editor tool

#

every time i close it and reopen its back to 0

hollow ore
#

so I bind to serialized properties of components to get updates when data changes and register handlers to update the component data when controls change

snow pebble
#

thats fine if the data relates to objects

hollow ore
#

hmm, I am not sure in this case, I am still learning editor tools. I had the privilage of designing my tool around prefabs, custom inspectors and components, so the data is just there, stored on game objects directly.

#

is this some kind of "preset"?

snow pebble
#

yeah its easy enough when the data relates to game data

#

its just a placement tool for level editing i want to place things snapped to grid sizes

hollow ore
#

or should it be a persistent tool setting

snow pebble
#

i have a bunch of other settings too id like to keep persistent

#

my only other option is tie to a scriptable object

hollow ore
#

maybe PlayerPrefs?

snow pebble
#

but then why bother have an editor window when i might aswell make it a part of the scriptable object editor

#

these are the settings i want to persist when i close the editor tool

hollow ore
#

I haven't used PlayerPrefs myself, but this sounds like something that could help you in that case

snow pebble
#

hm maybe

snow pebble
#

oh interesting

#

thanks

plucky knot
#

It's a persistent SO, so just make a SerializedObject from it and should be the same from there to get the bindings. But I rarely ever use bindings, so I can't confirm much about that side.

snow pebble
#
           slider.BindProperty(_instance.FindProperty("_bounds"));```

it works \o/
snow pebble
#

ok i dont understand gui styles i put this as my style:

style = new GUIStyle()
{
    normal = new GUIStyleState() { textColor = Color.white, background = Texture2D.blackTexture },
    fontSize = 15,
    alignment = TextAnchor.MiddleCenter,
    stretchWidth = true,
    stretchHeight = true,
    fixedWidth = 100,
};

yet no background comes up behind the font

#

i just have font white but i thought the background would show

#

this is how it looks which is fine until its over an object that is white

#

then its unreadable so was trying to put a black texture behind it

visual stag
#

I'd just draw a DrawRect manually before it

snow pebble
#

textColor works fine

visual stag
#

I don't know if every control uses all of GUIStyle. I forget, haven't done IMGUI stuff in years

snow pebble
#

thats fair though ui toolkit doesnt yet support world space tracking

#

so i dont have much choice

visual stag
#

I generally also don't build GUIStyles from nothing, and use the constructor that takes another GUIStyle

#

EditorStyles already has so many good starting points

snow pebble
#

arent those for inspector elements

#

im using Handles.DrawLabel()

visual stag
#

They're GUIStyles, you can use them for whatever

#

*If an API takes a GUIStyle

snow pebble
#

well i did try EditorStyles.label but the font is super faint and hard to see if infront of bright objects

#

if there was a white cube in that scene it be unreadable lol

visual stag
#

My internet has dropped, my point is that you don't need to use the empty constructor, you can pass in another GUIStyle to duplicate it and only modify one part of it

#

Doesn't help the issue, just gives me peace of mind I've set everything up at a basic level 😄

snow pebble
#

yeah i wonder .normal isn't the default state of the label

visual stag
#

Perhaps not

snow pebble
#

they have .normal and .onNormal

#

bit confusing

#

really hope they prioritise some scene visual elements for ui toolkit -_-

visual stag
#

Ah, I see why my API was using DrawRect, it's because I support a background color as well as a foreground

#

it would be silly to make lots of GUIStyles 😄

snow pebble
#

it seems this did the trick:

            var style = EditorStyles.helpBox;
            style.normal.textColor = Color.black;
            style.normal.background = EditorGUIUtility.whiteTexture;
visual stag
#

Could also be that imagePosition is set to TextOnly somehow

snow pebble
#

using white texture from utility works but not black texture static reference

#

ill just stick to white with black font as long as its working im happy 😄

visual stag
#

Gets a small Texture with all black pixels.

Unity sets all pixels of this Texture to transparent black (0,0,0,0).

#

well, there's your problem

snow pebble
#

ah the alpha

#

thats a pain 😄

snow pebble
#

does serialized objects not work with finding properties that are lists?

#

i keep getting null when it should find it

waxen sandal
#

Context?

snow pebble
#

ive since re-written editor so no longer relevant but it was a list in an scriptable object with serialized field but find property didn't work on the serialised object of that scriptable object

#

it worked for fields that were floats though

#

¯_(ツ)_/¯

waxen sandal
#

I mean we understood that much, but you gave no context on the structure of your data nor how you were doing FindProperty (i.e. what path were you using on whcih member etc)

tough cairn
#

anyone knows how to emit events to ui-toolkit ?

tough cairn
#

ye i seen that channel , had a quick peek - its just under "artist tools" and no one is answering any code related questions

visual stag
#

You can script everything in Unity, the groups only help you find channels

still ferry
#

Is the only way to use custom generic editor window to use some abstract base class? Can't we just use something like this? (it doesnt work of course, but maybe I missed something)

 [CustomEditor(typeof(TestGeneric<>), true)]
    public class TestGenericEditor : Editor
    {
        private TestGeneric<BaseType> testGeneric;

        protected override void OnEnable()
        {
            base.OnEnable();

            testGeneric = (TestGeneric<BaseType>)target;
            // code
        }
       
        public override void OnInspectorGUI()
        {
            // code
        }
    }
snow pebble
#

am i misunderstanding how tracking property values work? i want my button to hide when a value is true so i have:


var btn = root.Q<Button>("edit-button");
btn.TrackPropertyValue(settings.FindProperty("_editMode"), (prop) =>
{
    //this should get called since the value changed to true
    Debug.Log(settings.FindProperty("_editMode").boolValue);
    btn.visible = !prop.boolValue;
    btn.SetEnabled(btn.visible);
});
btn.clicked += () =>
{
    //set to edit mode
    settings.FindProperty("_editMode").boolValue = true;
    settings.ApplyModifiedPropertiesWithoutUndo();
    settings.Update();
};

for some reason the TrackPropertyValue never gets called when it should since i changed the value to true in the click

night totem
#

Hi guys

#

How to make the text not duplicate?

gloomy chasm
#

Also, calling Update after Apply does nothing

night totem
#

help guys

gloomy chasm
night totem
gloomy chasm
night totem
#

I took out the transparency and now I can't see the name.

gloomy chasm
#

Isn't that what you want..?

night totem
gloomy chasm
#

That is what you want, right?

night totem
#

I have to choose colors to see the text.

#

That's why I made it translucent.

gloomy chasm
#

Right... that is how colors work. If you have light text on a light background, the light text is going to be hard to see

night totem
#

Also I noticed if I start playmod or exit unity it all goes away how do I save it?

gloomy chasm
#

Well, two things, first Unity can't serialize dictionaries. And Unity also can't serialize static fields. So you would need to make it a list (or serialize it to a list) so it can be saved, and store it in a class derived from ScriptableSingleton

#

However, you have other issues. What happens when you change scenes, or close and reopen Unity? The instance ids may be different. And you will also need to manage when gameObjects are deleted in the editor so you can remove them from the dictionary

night totem
#

can you elaborate?

gloomy chasm
#

Oh what part?

night totem
#

conservation

gloomy chasm
#

Pardon?

night totem
#

color preservation

gloomy chasm
# night totem color preservation

The long and short of it is that I would recommend one of these options:

  • 'store' the color in the name of the game object, like UI __#8634eb. And then parse the naming by finding the __# and anything before that is the actual name and anything after that is the color.
    • Downside is that it would show in the title field in the inspector when the object is selected.
  • Add a component to the object to store the color.
    • You can make it invisible using hideFlags (google).
    • Downside is you have to manage adding/removing the component as the user sets/clears the color.
    • If the asset/plugin is removed, you will have "Missing Script" warnings.
  • Have a component that you add to the scene that stores the references and the colors.
    • Downside is it can get tricky if multiple scenes are loaded at once, and you have to manage adding/removing the objects from the list on the component
night totem
#

Is there an easy script that does all this?

night totem
#

I thought I could do something similar, but without the extra elements.

burnt dove
#

When opening an scene by code, how can I avoid this popup? Basically, if the scene can't be opened I would like to skip it rather than get this popup.

gloomy chasm
gloomy chasm
# night totem can I see it?

Just google like Unity hierarchy header or unity hierarchy enhanced and you can also add github to the end of the search to find stuff on github. Or on the asset store just search for hierarchy. There are a bunch, like 25+

dusty drift
#

People I did a UI like that using UI toolkit and filling the table at runtime using a cs script. Now I would like to be able to rename the nodes... do you know how can I achieve that by code?

severe lance
#

All of these it's warning about should be part of the hierachy, so no clue why it's saying it's not registered

severe lance
#

I guess the problem is that it doesnt take into account of object created after storing the state

#

im not sure if that's a problem though?

real spindle
severe lance
#

Yeah, I hit a stackoverflow if I register like 10k trees

#

the terrain tool does undo operations fine if I populate it from that instead

#

but I need to populate stuff that isn't supported by the tree tool

#

I guess technically you can't interact with the terrain trees so there's a lot of information that doesn't need to be undo from them and basically just undos the state

#

which is kinda what I want too as I don't care about reference bindings, so if I can just suppress that warning from spamming 10k times that would be great

topaz bone
#

Any tips on how to properly draw a property field for [SerializeReference]<Interface> field? I just want only accept monobehaviour components that implement this interface. Preferably generic solution for interfaces but I can settle on creating property drawer for each interface my self.
Just wanna know if there is any thing I could look in to or read about it. And preferably using ui toolkit rather than MGUI

short tiger
pseudo aspen
#

Hello, does anyone knows if it's possible to define scripting symbols that activate only when running specific (or at least any) Unity PlayMode tests? I.e is there a way to have #if PLAYTEST_1 and activate it only when running the first test? If not, is there at least something like #if UNITY_PLAYTEST?

sinful mountain
#

hi , can anyone help solve this issue

rotund lava
#

Hi all, bit of an odd issue I've run into
I'm creating a PropertyDrawer that shows an extra field when one of the Enum values is selected
Hiding and showing this Vector2 field according to the Enum works fine, however I cannot edit the values of the Vector2 field
Any ideas?

#

The field is being created as below:
EditorGUI.PropertyField(customOffsetPos, property.FindPropertyRelative("customCursorOffset"));

rotund lava
#

Figured it out, I forgot to submit an increased GetPropertyHeight() value for when the additional field was shown

ashen wyvern
#

is there some sort of type, attribute, drawer or black magic so that if I have [SerializeField] GameObject thingy I can specify if that thingy is supposed to be something from the scene or a prefab asset? 🤔

real spindle
burnt sail
#

hi - can someone help me with test setup lifecycles? I have a set of EditorMode tests that run together, and a few fail, if I run them again they work and it makes me thing maybe the [Setup] method isn't called once per test, but once per set of tests, or the state handoff between tests is not what i think

#

If i select and run five tests, does Setup get called five times or once?

#

ah actually i think our issue is StartCoroutine() being called at some point in our code under test

burnt sail
#

that was a problem, as is the fact i didn't realise that behind these tests is some scene getting objcets spawned, so if [Setup] creates two objects, next tese there's two more, now total 4

#

yay okay, so now i'm back ot jsut the startcoroutine() getting call in teh code under test breaking the tests

barren moat
#

How can I unset a property on a material variant?

#

I can see Material.SetColor but not UnsetColor or UnsetProperty etc

#

oh nvm it's RevertPropertyOverride!

barren moat
#

How can I modify this field on an existing model via code?

visual stag
barren moat
hollow ore
#

How to make my SerializableObjects from my embedded package be detected by Unity?

#

I added a scriptable object asset to my package's Editor directory, but when I tried selecting it in a component, the dropdown didn't suggest it

#

I found "hideInEditor": false, that I could add to package.json, but SOs are still not recognized

atomic sable
#

Should I always use GetPropertyHeight in property drawers when drawing properties?

#

Or is using singleLineHeight + standardVerticalSpacing ok practice?

gloomy chasm
atomic sable
gloomy chasm
#

I think 2021 as well but not too sure

atomic sable
#

I tried making an editor once but gave up because I couldn’t figure out how to reference the actual doc i made in the UI toolkit without a hardcoded path

gloomy chasm
#

Yeah... that is cause you gotta use a hardcoded path. One way (which I use) is to get the current folder dynamically, and use that as the starting point so that it is safe if a user moves the folder.

An alternative is if you make a VisualTreeAsset or StyleSheet (or any other UnityEngine.Object) a serializable field, you can assign a default value to it in the inspector when you click on the script. I tend to not like it as much since it is hard to tell from code where the value is coming from.

atomic sable
# gloomy chasm Yeah... that is cause you gotta use a hardcoded path. One way (which I use) is t...

See that’s why i kinda stay away from it unless for editor windows. I use the default serialized fields when I make an editor window, but they don’t exist for editors and property drawers. To get around this in the past I’ve used a scriptable object class that has the editor/property drawer class declared inside of it so i can use its default references that way, but i dont think my job would like that level of jank…

#

@gloomy chasm do you use AssetDatabase.GetAssetPath for getting it dynamically?

gloomy chasm
# atomic sable <@131292153300123648> do you use AssetDatabase.GetAssetPath for getting it dynam...

Yeah, what I do is have this class in the root Editor folder, and then have a wrapper utility class with methods like LoadVisualAsset(string documentName) that uses the GetFolderPath() method from this class, and then adds the path to wherever I store all of the UI files (uxml, uss, png, etc.)

internal class EditorAssetsFolderLocator : ScriptableObject
    {
        /// <summary>
        /// Reterns the project reletive path to the "Editor" folder in the assets folder.
        /// </summary>
        public static string GetFolderPath()
        {
            var locator = CreateInstance<EditorAssetsFolderLocator>();
            var script = MonoScript.FromScriptableObject(locator);

            string path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(script));
            if (Path.DirectorySeparatorChar != '/')
                path = path.Replace(Path.DirectorySeparatorChar, '/');

            DestroyImmediate(locator);
            return path;
        }
    }
atomic sable
#

Hmm im pretty sure AssetDatabase.GetAssetPath would break in a package tho

gloomy chasm
#

Nope 😄

#

Works just fine

atomic sable
#

even ones added through a repo?

gloomy chasm
#

You mean github repo?

atomic sable
#

Not github but yea basically

#

I dont remember specifically what problem but i’ve had issues with it before with some stuff not working correctly

gloomy chasm
#

Hmm.. pretty sure (like 98%)

atomic sable
#

hmm okay. I’ll ask a senior dev about it, thanks!

pale sequoia
#

I'm working on a small tool that uses Physics to place stuff in a level in the editor.
Currently I'm in a bit of a bind so maybe this is just a rubber 🦆 moment. I want to make it so that you select stuff in the level, press "Add" and everything with a Rigidbody gets noted down using my SimulatedBody struct to note the Rigidbody, the position before simulation and the rotation before simulation so that I can reset both if you don't like how things ended up.
The problem for me is figuring out when noting down the original position and rotation is a good idea.
Do you select stuff in the level, press "add" and then press Simulate?
And if so, how would I handle deletion of objects, adding objects, etc...a lot of work right?
Do you just select bodies in the level you wish to simulate and then press Simulate?
What if you accidentally lose the selection for whatever reason? How do I handle the potentially misaligned storage of pre-simulation stage?

ashen wyvern
#

is there something like IProcessSceneWithReport but for prefabs? 🤔