#↕️┃editor-extensions

1 messages · Page 11 of 1

earnest talon
#

so .name is just the name of the selector itself, .Name() adds the pseudoclasses to the end of the selector

gloomy chasm
#

Ahhh

#

Good to know!

earnest talon
#

I just uh realised that's actually pretty bad too

#

because it overlaps with the name selector constructor for SimpleSelector

#

so I've got to figure that out.

#

just changed it to .USSName() instead

jagged hawk
#

I'll take a look into UIToolkit. As for manually positioning things, it's really just the entire thing that has to be manually positioned as it can be dragged around. GUILayout.Group doesn't appear to be a thing, GUI.Group is though?

jagged hawk
#

I was already using that for the box itself, and from my limited knowledge you cannot nest them, unless there's another thing I can use to apply a background image?

glad pivot
#

is there a way i can add my own type filters to the filter search in the project files?

gloomy chasm
#

I don't really get what you are doing so it is a bit hard to suggest things

glad pivot
# gloomy chasm Nope

is there a way to automatically insert a search term into the search bar instead then?

gloomy chasm
glad pivot
#

i try to avoid it if possible but if its the only option then cronch

jagged hawk
#

Yep, I figured that out just by trying it anyway. I added it to a VerticalScope. How I do the background though is affecting the next bit. Instead of trying to style it out myself, I did an image, and the box has a glow effect when selected which is... just another image. Which means, to account for the glow, there's a fat border and that's pushing my butons away. much sigh

gloomy chasm
gloomy chasm
glad pivot
#

is there any documentation on it?

gloomy chasm
#

lol, no

#

Gotta read the source code

glad pivot
#

figures 😢

#

welp, i guess googling to check if anyone else has done it before

gloomy chasm
#

You can use that to find the last active project browser

#

So not too bad really! Just two quick reflection calls!

glad cliff
#

Sorry man but it does not help at all. I meant exactly that. Collapsing multiple changes into one group make it easy to undo everything at once, but then when you want to redo it it does not work unfortunatelly :/ If I put let's say adding created object to a list and object creation itself into one group, I will undo both, but then redo only creates object but doesn't add it to the list, like it can handle only single operation.

#

Unless there is something I do t understand and I don't know about it...

#

Creating multiple groups mean multiple undo operations, right? If I make a group, add some undo operation, collapse it, then create another group, those will be 2 separate undos? Or making multiple groups in one go is still only one ctrl + z?

gloomy chasm
glad cliff
#

Forgive me pls but this one will be huge XD

#

it is a partial class of a graph view

#

and basically whenever there are some changes i apply them and record them into a single group

#

so lets say deleting one node will destroy one SO associated with it, delete its reference in another SO, deletion will cascade on every edge connected to this node, and with every edge another SO associated with it will be deleted. Overall a lot is going on there

gloomy chasm
glad cliff
#

but when i delete a node, undo it, and then REDO it, then some operations are being ignored or smth... anyway references to this SO are being deleted but SO itself is not

glad pivot
#

i just dealt with something similar just an hour ago. but it was something with how i had written a setter method which ofc was not being called when redo happened. not sure if its something similar you are running into

gloomy chasm
# glad cliff but when i delete a node, undo it, and then REDO it, then some operations are be...

Honestly, there are so many things going on, and the undo system can be a little confusing sometimes. I am going to say it would be best to recreate the very basic setup of the undo system and try different things to learn about it. Like start with just creating objects and undoing and redoing it.

Something that might be going on, it looks like you are deleting assets and undoing the destruction. Unity doesn't like you undoing asset database modification.

Beyond that, I would really recommend reconsidering how you are structuring this. Using SOs like this is really not a great way to go about it.

edgy igloo
#

is there a way to set the sprite of a gameobject seen in the scene view (in editor) based on a bool inside of a script?
for instance lets say the bool was called active and the two sprites were called sprite_active and sprite_inactive

i guess some pseudocode for it would be like

if (active){
    spriteInEditor = sprite_active;
}
else
{
    spriteInEditor = sprite_inactive;
}
gloomy chasm
edgy igloo
#

yeah, although for usage in the editor as it'd make it much easier to setup levels (i have blocks that can be in one of two states on the loading of a level, and it'd be easier to visualise if i can see which state they are in the editor)

jagged hawk
# gloomy chasm I don't really understand what your setup is or what you are seeing. Sorry

I solved it, but it may be ugly. I'll give more context, I'm doing a basic-ish node editor. The visual appearance of the node is handled by two images, one when the node is selected (has an outer glow) and one that isn't. In order for the image to "scale" properly with the glow, there has to be a fat border. This pushes the buttons away by 9px, understandably, so I used additional areas to line the buttons up properly.

So while that works, clean or not, there's one more issue of the missing connection beziers. The connection beziers rely on the rect of the button, but there is no rect anymore. Not sure what to do about that?

This is more or less the entirety of what I have thus far, minus the drawing of the connections: https://gist.github.com/Tencryn/52c2c31eef7b3e97166498c48e788c7c

edgy igloo
#

to give an example
left is scene view currently, right is in-game view
note that only the bottom row of blocks is actually set to the active state, but this isn't visible in the editor

glad cliff
edgy igloo
gloomy chasm
glad cliff
#

HOLY MOLY since when?! 😮 I just switched to new LTS (2021) like a month ago

gloomy chasm
gloomy chasm
gloomy chasm
glad cliff
#

This may be a stupid question but:
another thing I would need that SO allows me to do is having a dedicated inspector for this sort of data container. If it wasn't a SO but pure C# class, can I make an inspector for it? Ofc it would be opened only programmatically then, but that is the goal

#

If I recall, I was trying something like that before but failed, but honestly I dont remember how i tried to do it and what failed in particular

gloomy chasm
glad cliff
#

properties in the inspector window

#

Example:

#

What im working on is a state machine creator. Each edge in a graph view have associated SO to it, and it stores all the information about a transition (just like in a mecanim). When I select the edge i can just simply open inspector for that SO

#

but how would I achieve that with storing all that information about a transition in a C# class?

#

that is not a SO*

edgy igloo
edgy igloo
gloomy chasm
gloomy chasm
glad cliff
#

Just as I thought. So my plan B wasnt that stupid after all XD
Nvm, I will handle it somehow and when the time comes I will make some V2 with a better solution.

#

@gloomy chasm I admire your multithreading man XD

gloomy chasm
edgy igloo
gloomy chasm
glad pivot
gloomy chasm
# glad pivot ok so im not too sure where the file i need to reflect is located. ive been look...

No no, you just get the type. Since the ProjectBrowser is an internal type, we can't get it directly. So to get it, we need to get the assembly that it is in, which is just the Editor assembly. We can get that from any type that we know is in that assembly var editorAssembly = typeof(EditorWindow).Assembly;. Then we get the Project Window type System.Type projectBrowserType = editorAssembly.GetType("UnityEditor.ProjectBrowser");

glad pivot
#

oh yeah, that makes a lot more sense

gloomy chasm
#

After that you just do normal reflection on the type. Like projectBrowserType.GetMethod("SetSearch"); (might need to use the binding flag for nonPublic, I don't remember)

edgy igloo
gloomy chasm
edgy igloo
#

ah that works better
there was a slight delay when i was using OnDrawGizmos()

#

(between toggling the active state and the sprite toggling)

gloomy chasm
#
void OnValidate()
{
#if UNITY_EDITOR
  spriteRenderer = GetComponent<SpriteRenderer>();
    spriteRenderer.sprite = tileActive ? pinkBlockActive : pinkBlockInactive;
  UnityEditor.EditorUtility.SetDirty(spriteRenderer); // We do this so that the sprite will stay set after the scene is changed or the editor is closed.
#endif  
}
edgy igloo
#

i'll likely have to change the condition at some point as i'll be implementing other interactables with their own sprites in future, but that works perfectly now

#

i haven't come across that #if #endif before, is that actually vital to the code working or is it just a preference thing

gloomy chasm
jagged hawk
#

What could cause a Handles.Button to not be interacted with?

Vector3 pos = (rect.center + connector.rect.center) * 0.5f;
if (Handles.Button(pos, Quaternion.identity, 4, 8, Handles.RectangleHandleCap))
{
    Debug.Log("click");
}
glad pivot
# gloomy chasm After that you just do normal reflection on the type. Like `projectBrowserType.G...

i got it. it ended up like this

// Get type
var editorAssembly = typeof(EditorWindow).Assembly;
System.Type projectBrowserType = editorAssembly.GetType("UnityEditor.ProjectBrowser");

// Get window instance
var WindowInstanceInfo = projectBrowserType.GetField("s_LastInteractedProjectBrowser");

// Call method
MethodInfo setSearchInfo = projectBrowserType.GetMethod("SetSearch", new [] {typeof(string)});
setSearchInfo.Invoke(WindowInstanceInfo.GetValue(projectBrowserType), new object[]{"t:TestClass"});
gloomy chasm
earnest talon
#

@gloomy chasm Do you know how to bind values of a UI VisualElement to a C# object (e.g. Textfield value to a string)?

#

There's got to be documentation somewhere but RegisterCallback is uh- not well documented in a way

#

There is binding but that's for Serialized Objects / Serialized Properties.

chrome pendant
earnest talon
#

It's partly here

#

but what in the sam hill

#

it is a really weirdly documented page in the sense that it's clear what we need to do is here but is mixed in with SerializedObject/SerializedProperty

#

so I'm guessing for some reason you must serialize a primitive type and then use that in the bind

#

might just be better off with IMGUI container because this is

#

this is something else

visual stag
#

They are in the process of completely rewriting the binding to support any kind of object

#

currently binding is only really covering serialized properties

earnest talon
#

Ah, thanks

#

Do I just go the IMGUI route then?

#

I'm stuck on Unity Engine 2021.3.6f1 due to university restrictions and I won't have access to that

visual stag
#

you can register change events and do it that way, is there any reason you're not using serialized property though?

earnest talon
#

I'm using GraphView to have nodes with data attached that gets updated based on the values within the extension container.

#

I could try serialize the node itself and have it modify itself from that which sounds not too good of an option

#

I'd personally prefer doing it with UI Elements because of the design benefits

#

How would I register change events

earnest talon
#

Thank you

#

That just really helps with what I'm wanting to do and it's nice to know I just missed something

visual stag
#

it's just a pity it doesn't help with the opposite direction, so unless you're really smart about it you probably have to redraw the whole graph if the serialized representation changes

earnest talon
#

oh that sucks

#

I'm doing it so I can do Unreal-like blueprints for my plugin framework (the graphview window is just a general editor window template I'm creating, which I plan to use to make visually-scriptable plugins with)

#

just the value thing is a bit of a pain now and again

earnest talon
#

I've just started exploring the inner workings of node (esp. custom EdgeConnectorListeners), it's really cool seeing some of how it all works.

rocky crest
#

Using Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); with a custom editor extension. I wish to raycast against a prefab in prefab edit mode, but I do not get any collision with the prefab. It works fine if I drop the prefab into a regular scene. Any thoughts here?

rocky crest
twilit willow
#

i dont know if this is the right place to ask
in vs 2019 there is an option to do ctrl + shift + m to add a function you want it opens a dialog box like this how do i do this in vsc

sinful path
#

Hey everyone,
would you recommend a 50% discount on launch for 1 week or 2 weeks?

glad pivot
#

when i edit a variable in a scriptable object, github dont always detect the change until i press ctrl + s. But on some variables it doesnt detect the change after i do that. I assume the reason is because im not using serializedproperties when changing those certain values as they are being changed from a method. how can i then register a change that should be saved?

#

I am already registering and handling undo's correctly on those variables so i dont know what else i could do

silver phoenix
#

Anyone know of a way to check if the active game view is "Game" or "Simulator"?

glad pivot
#

do you mean the scene and game view?

silver phoenix
#

No, I am using the device simulator. It is like the game view but runs as a mobile device.

#

Window > General > Device Simulator

glad pivot
#

oh, well im not equiped to answer that so someone else would need to

silver phoenix
#

Kind of did a hacky thing, I check the active window type against the game view type. It works

glad pivot
#

i thought that id make a quick tool for generating LUT textures within unity as i didnt find any already. but im having this issue where its only updating the render texture on recompile. even after i press the render button which should just create the file right away. the render method here is only called once i press a button within the window and never any other times. But i am reloading the asset from the assets in OnEnable so i guess that might have something to do with it?

void Render(bool GeneratePNG)
{
    Graphics.Blit(defaultWhite, renderTexture, ShaderMaterial);
    // * RenderTexture to Texture2D         
    Texture2D tex = new Texture2D(512, 512, TextureFormat.RGB24, false);
    // ReadPixels looks at the active RenderTexture.
    RenderTexture.active = renderTexture;
    tex.ReadPixels(new Rect(0, 0, Resolution, Resolution), 0, 0);
    tex.Apply();

    byte[] bytes = tex.EncodeToPNG();
    string fileName = "";
    if(GeneratePNG)
        fileName = textureName();
    else
        fileName  = "Assets/LUTGenerator/Textures/Default_LUT_Preview.png";

    System.IO.File.WriteAllBytes(fileName, bytes);

    if(!GeneratePNG)
    {
        previewTexture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/LUTGenerator/Textures/Default_LUT_Preview.png");        
        Debug.Log("Preview Render Done");
    }
    else
        Debug.Log("Texture Generated");
}
#

thing is it doesnt update within my assets either until i recompile

glad pivot
#

i tried calling EditorUtility.RequestScriptReload() after rendering, and that does not seem to do it either. so i think it has something to do with validating the asset files

#

or if anyone knows a different way i could render a texture in a editor window with a shader applied that would be perfect

gloomy chasm
#

No need to convert to bytes, you can just save the Texture2D as an asset (unless I am remembering something wrong)

elfin gorge
#

Hi everyone, I'm starting to look into handles with the preview render utility class, I can render the handles correctly to the screen with the following code. However I can't seem to get any interaction from them.
The button I am adding apeares in the center of the cube, however there is no effect or console output when clicking it. I know with defualt scene based handles these functions are meant to sit on OnSceneRender() however I am unaware of whether preview render utility has something like this, or if that would be the reason that the inputs are not being recognised.

There really doesn't seem to be much information on these classes online, and the stuff out their doesn't seem to describe the two of them interacting all that much (I have found a few places online however mainly these are people asking a the handles rendering correctly and not them apearing correctly)

Any help on this would be apreciated.

#
#region Behaviour
// - - -
    private PreviewRenderUtility _previewRenderUtility;
    private Camera _camera;

    private GameObject _renderTarget;
    private Transform _renderTransform;
// - - -
#endregion



protected override void OnInspectorRender()
{
    InitialisePreviewRenderUtility();
    DrawPreviewRenderUtility();

    Button("Debug Button", true, () => Debug.Log("Output"));
}



private void OnDisable()
{
    _previewRenderUtility?.Cleanup();
    if (_renderTarget) DestroyImmediate(_renderTarget);
}

private void InitialisePreviewRenderUtility()
{
    _previewRenderUtility?.Cleanup();
    _previewRenderUtility = new PreviewRenderUtility();

    InitialisePreviewRenderUtilityCamera();
    InitialisePreviewRenderUtilityRenderTarget();
    
    _previewRenderUtility.AddSingleGO(_renderTarget);
}

private void InitialisePreviewRenderUtilityCamera()
{
    _camera = _previewRenderUtility.camera;
    
    _camera.fieldOfView = 60f;
    _camera.farClipPlane = 100f;
    _camera.nearClipPlane = 0.1f;
    
    _camera.cameraType = CameraType.SceneView;
    _camera.clearFlags = CameraClearFlags.Skybox;

    Vector3 position = new Vector3()
    {
        x = Mathf.Sin(Mathf.Deg2Rad * -30) * Mathf.Cos(Mathf.Deg2Rad * 15),
        y = Mathf.Sin(Mathf.Deg2Rad * 15),
        z = Mathf.Cos(Mathf.Deg2Rad * -30) * Mathf.Cos(Mathf.Deg2Rad * 15)
    } * 3f;
    
    Quaternion rotation = Quaternion.LookRotation(Vector3.Normalize(-position));
    
    _camera.transform.SetPositionAndRotation(position, rotation);
}
#
private void InitialisePreviewRenderUtilityRenderTarget()
{
    _renderTarget = GameObject.CreatePrimitive(PrimitiveType.Cube);
    _renderTransform = _renderTarget.transform;
}

private void DrawPreviewRenderUtility()
{
    Rect guiRect = EditorGUILayout.GetControlRect();
    Rect rect = new Rect(10, 10, (guiRect.width + guiRect.x - 20), (200 - 20));

    if (rect.width > 0 && rect.height > 0)
    {
        _previewRenderUtility.BeginPreview(rect, GUIStyle.none);
    
        _previewRenderUtility.Render();
        RenderHandles();
    
        _previewRenderUtility.EndAndDrawPreview(rect);
    }
    
    GUILayout.Space(rect.height);
}

private void RenderHandles()
{
    using(new Handles.DrawingScope())
    {
        Handles.SetCamera(_camera);
        
        Handles.color = Color.green;
        Handles.DrawWireCube(Vector3.zero, Vector3.one);
        
        float size = HandleUtility.GetHandleSize(Vector3.zero);
        
        Handles.color = Color.white;
        if (Handles.Button(Vector3.zero, Quaternion.identity, size * 0.1f, size * 0.05f, Handles.DotHandleCap))
        {
            Debug.Log("Clicked");
            Repaint();
        }
    }
}
wraith crane
#

Is there a way to draw the Enable checkbox of a MB (like in Physics Body) from a custom inspector? (Basically I would like to make the Balancer Authoring script be disabled/enabled from the inspector without the drawback of it not being Updated... But store the enable state in a custom bool variable)

peak bloom
#

any idea why stopImmediatePropagation won't work?

#

it's a parent with single child, clicking the child would trrigger the parent as well even with stopImmediatePropagation
This is a custom foldout with a toggle, so when the toggle clicked, the foldout would get triggered as well

glad pivot
#

this is bizzare. is EditorGUILayout.GradientField(_gradient); supposed to automatically set the gradient by itself? cuz it does. most other cases it would be _gradient = EditorGUILayout.GradientField(_gradient);

dapper path
#

not really sure where to put this but is it possible to increase the scale of the UI in the editor? mine is super tiny

gloomy chasm
gloomy chasm
warm bloom
#

Maybe this is outdated. It's from 2019.

gloomy chasm
gloomy chasm
glad pivot
#

Isee

elfin gorge
plucky hound
#

Hello, I created an empty GameObject (no script, only a transform) that is just supposed to contain 2 other GameObjects, like that:

#

My problem is that when I try to drag it somewhere else, it only selects one part (Head in this example) and what I'd like to do is to select the whole group (Human) with my mouse, but the UI doesn't allow me to drag and drop it to modify the position easily

#

What I've been doing until now is change the position with the transform component inside Human, but that's very tedious with many copies...

pale hull
#

How to get the object value from a PropertyDrawer for the list?

In my class I have

[SerializeReference] public List<string> StingsList = new();

In my custom property drawer I'm trying to get this field value (to add something to the list, for example) like this:

 var stringsList = property.FindPropertyRelative("StingsList").managedReferenceValue;

I'm getting "InvalidOperationException: managedReferenceValue is only available on fields with the [SerializeReference] attribute", but the field has SerializeReference.

short tiger
glad pivot
#

how do i set the start size of a scriptablewizard window? it doesnt seem to work by setting the position rect at awake

#

i just increased the min size instead shruggie

earnest talon
#

For some reason, any attempt to get the width and height of a visual element results in NaN in 2021.3.6f1 (including via VisualElement.style or VisualElement.contentRect or any variation thereof)

#

and resolved style doesn't work either oddly

earnest talon
#

Okay so the UIToolkit Debugger can see the width and height of an element. Clear as day, it can. That means that somehow, some way you can get the Visual Element. I'm not even remotely sure how it's going to NaN under the hood though.

gloomy chasm
earnest talon
#

I found out how thankfully

#

That is really weird behaviour to have in some respects to just after a node is created and added to a graph element.

gloomy chasm
earnest talon
#

yeah, I used style as a last resort test before I found GCE

visual stag
#

but that seems difficult to maintain

earnest talon
#

throwing an exception or using GeometryChangedEvent?

visual stag
#

I mean that something like contentRect is either going to be a value that indicates that it is unset, NaN, or it's gonna throw an exception

earnest talon
#

ah - I used it just as a test and thankfully I don't have to use it. I don't know what Content Rect is useful for specifically

visual stag
#

It's not that specifically, I mean any of the parameters. The only reason GeometryChangedEvent works is because that runs after layout has occurred, and the values have actually been set to something at that point

#

after you add something to the hierarchy it's just in a collection, with the UI dirtied ready to do layout when it's drawn

#

you can even have entire UI structures sitting in memory that have no layout ever occur on them because they're not in a panel, so all their dimensions will be NaN

#

style is the style that has been directly set on the element via C#, and resolvedStyle is whatever the combo of Uss and style is once it's needed to be resolved for layout

earnest talon
#

yeah, those thankfully were explained in the Intellisense documentation

#

I just kept trying things till eventually something worked but I can see why they'd be NaN when they weren't being drawn.

#

I was trying to get the behaviour working afterwards, which probably wasn't working as intended

#

Thankfully I don't think there'll be any other reason to get the information again in the way I was trying to

#

I just needed to center the node on the cursor along the X axis after it was created and drawn so that it could properly appear similar to other blueprinting systems

elfin gorge
#

Hi everyone, sorry to bring this up again but I am still stuck on getting Handles to interact with the mouse within the inspector using the Preview Render Utility.
Right now I have a cube and a button, all I want to do is see if clicking the button will call a debug log. However the Handle.Button doesn't seem to register any inputs.

https://forum.unity.com/threads/previewrenderutility-and-handles.859168/

I have found this thread on the forums, where someone mentions the fix for this being to add the offset from the corner of the window to the left of the preview, to the current events mouse position. However they don't elaborate any further then that. I do not know what they mean by left corder of the preview area / window. And also do not know what adding this offset to the mouse position will do.

So far I have tried doing this code below to:

Rect previewRendererRect = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.MinHeight(200));
Rect editorWindow = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

Event.current.mousePosition += previewRendererRect.min - editorWindow.min;

Whereas the previewRendererRect is the rect used inside

_previewRenderUtility.BeginPreview(previewRect, GUIStyle.none);

However this did absolutely nothing on its own. Am I meant to manually reimplement program interaction logic by doing some sort of ray cast to the editor UI using this mouse position? And if so, how would I actually go about doing this? Elsewise what is the actual correct way of doing this sort of things.

This is my full script: https://pastebin.com/yVD1yuhn.

wheat salmon
#

created a custom mask map creator. If anyone is in need of one DM me.

peak bloom
north sphinx
#

Is there an editor callback for when asset is double clicked?

#

Similiar to how Animator/UIBuilder and similiar stuff works?

peak bloom
#

never personally used it

#

you proly need to see what's in UnityEditor.Callbacks

lethal imp
#

Guys i wanted to make a custom editor that serialize an array of parent class, and the designers could instantiate the child classes inside the editor and this instance will serialize based on the child properties, any tips on how i could achieve that ? Im trying to use [SerializeReference] but it is not working

outer cove
#

what is the element called where you have a slider with the option to also set a low and high value on said slider? Googling has not given any good results

green current
#

Hey folks, I'm trying to build out a custom editor for jump physics and I want to visualize it. Is there any way to set up a mini scene that renders live when showing the editor and has the player character just constantly jumping? Or is there at least a way to manually draw a simple box with a circle moving up and down according to either an animation curve or just manually calculating the position each frame?

outer cove
#

Thanks!

molten sluice
#

Is still posible to use WebView in EditorWindow?

peak bloom
#

pretty sure the webview class still exists, better check that 1st than the linked above

green current
#

dang I'm on windows which isn't supported

#

I'll look for the webview though

#

doesn't seem to exist in the docs

molten sluice
#

Its not exist....

#

I wanted to create a new window and load an iframe there with a color generator, google search..... ChatGPT 😛

plucky hound
#

have a nice day

terse roost
#

Hey, I'm creating a editor using UIElements, which has a grid of ObjectField's. I've created callbacks for when the value changes, but I can't figure out which element was the one that received the event so I can get the proper grid position. Any ideas?

deft leaf
#

Hi. I was wondering, how can I make it so the variables are shown like this? Like, when I create a public bool it just creates one bool, not a grid-like thing like in here

gloomy chasm
terse roost
#

Just need to cast it to VisualElement

lethal imp
#

Guys i created a property drawer for a class on a monobehaviour script and it world perfectly

#

but when i use it on a struct inside a dictonary it send me error because of the EditorGuiLayout, só i used the editor gui but the elements did not scale properly

#

I wanted to make the same layout i had without the dictonary

#

Is it because im trying to use the dictonary editor at the same time i use the property drawer?

ornate oriole
#
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
    SerializedProperty iter = new SerializedObject(property.objectReferenceValue).GetIterator();
    float height = EditorGUI.GetPropertyHeight(property, label);
    while (iter.NextVisible(true))
        height += EditorGUI.GetPropertyHeight(iter) + EditorGUIUtility.standardVerticalSpacing;
    return height;
}

I'm trying to make a CustomPropertyDrawer and I've been searching on how to set the height... the only thing I could find is this, but it gives me some errors (type is not a supported pptr value, object at index 0 is null).
I'm using this within a class which derives from PropertyDrawer and make all my other CustomPropertyDrawers derive from this, so I want to make it as universal as possible.
Any ideas how to make this work?

ornate oriole
#

Nwm, I can just set the height within OnGui with height = lastRect.y - position.y + lastRect.height and return it in GetPropertyHeight

The only thing I don't understand is when I have an array and every element in the array has the height of the last element instead of having their own height...

#

Any ideas why this happens and how to fix this?

gloomy chasm
#

Also also, EditorGUI.GetPropertyHeight returns the height of the property including any child properties. So if memory serves, you can just do return EditorGUI.GetPropertyHeight(property);

ornate oriole
#

Idk, it broke when I changed it to return EditorGUI.GetPropertyHeight(property);

#

I'll try the first one

ornate oriole
#
public class PropertyDrawerCustomDefault : PropertyDrawer
{
    protected float _height;
        
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        SerializedProperty copy = property.Copy();
        SerializedProperty end = copy.GetEndProperty();
        _height = EditorGUI.GetPropertyHeight(copy);
        while (copy.NextVisible(true) && copy != end)
            _height += EditorGUI.GetPropertyHeight(copy);
        return _height;
    }
}

That's how I did it

gloomy chasm
ornate oriole
#

ooh, ok

gloomy chasm
#

It is EqualsContents that you want

ornate oriole
#
public class PropertyDrawerCustomDefault : PropertyDrawer
{
    protected float _height;
        
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        SerializedProperty copy = property.Copy();
        SerializedProperty end = copy.GetEndProperty();
        _height = EditorGUI.GetPropertyHeight(copy);
        while (copy.NextVisible(true) && SerializedProperty.EqualContents(copy, end))
            _height += EditorGUI.GetPropertyHeight(copy);
        return _height;
    }
}

That's how it is now

#

but now It's cursed

#

Both are the same and should have the same size, yet have very weird heights

#

Custom Property Drawers will make me go insane

gloomy chasm
#

Ahh, @ornate oriole try just returning EditorGUI.GetPropertyHeight(property, true);

ornate oriole
gloomy chasm
#

Also, careful about cashing the height like that. PropertyDrawer instances are reused between different properties of the same type.

gloomy chasm
ornate oriole
ornate oriole
#

As it looks from my perspective, the PropertyDrawer is just constantly resetting the height of properties of the same type to the height of property in encountered last (basically loops through and does stuff like: allPropertiesOfThisType.height = encounteredProperty.height and at the end of the loop it sets the height to the height of the last one in the array). Except for properties which are declared separately:

public SomePropertyWithCustomDrawer imOk;
public SomePropertyWithCustomDrawer[] imAllTheSame;
#

For now I'll just try some other nasty thing instead.

gloomy chasm
#

The way it works is that when Unity goes to draw a property, it checks to see if there is a property drawer for that type. If there is, it will create a single instance of that property drawer.
Then for every property of the type that it encounters, it simply gets the instance of the drawer and passes the the property to the GetPropertyHeight and OnGUI methods.

ornate oriole
#

I see, I understand the concept here, but the thing that still confuses me is the height it sets to these properties.
With a single property the height is correct.
With an array of properties there is only one height (equal to the height of the last element in array)
The single property is unaffected by the heights in the array, so there seems to be a problem with the properties being in an array only

#

Right now it's declared like this:

[Serializable] struct AttackSet { public Attack[] someAttackArray; }
public Attack someSeparateAttack;
public AttackSets[] someAttackSets;

Seems like in my case the Attack[] array breaks, so I'll try to do this instead:

[Serializable] struct NastyContainer { public Attack attack; }
[Serializable] struct AttackSet { public NastyContainer[] someAttackArray; }
public Attack someSeparateAttack;
public AttackSets[] someAttackSets;

Which would basically 'separate' the attacks (not make a direct array of attacks)
If that works then I'll be happy enough.

gloomy chasm
ornate oriole
#

Sure, I'll chuck it into a pastebin

gloomy chasm
ornate oriole
#

You can ignore the _height += stuff, I set the height directly at the end of the scripts

#

just didn't delete it yet

#

And it might be a mess since I've been experimenting and didn't clean it just yet 🙏
But it should be readable enough

#

Also, what's the order of execution of these methods, especially in an array?
Does it first go through each OnGUI method and then it draws the whole array? If that is the case then it would make sense why the height was the same everywhere

#

oh my f** god

#

@gloomy chasm It's ok, I think I solved the problem

gloomy chasm
ornate oriole
ornate oriole
# gloomy chasm Oh what was it?

I don't really know (probably due to the order of the method execution so my _height was being reset several times and only after that the height was being set)
I just chugged my problem into ChatGPT and it surprisingly gave me a correct solution

gloomy chasm
ornate oriole
#

additional field in base class:

protected Dictionary<int, float> _heightDictionary = new Dictionary<int, float>();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
    _heightDictionary.TryGetValue(property.propertyPath.GetHashCode(), out float height);
    return height;
}

within OnGUI:

_heightDictionary[property.propertyPath.GetHashCode()] = _height;
#

basically making a dictionary and read the height later from it, instead from the _height field directly

#

it's kind of a workaround since I need to play around with it in the OnGUI but it works so I'm happy

gloomy chasm
#

Do NOT cache the height, at all, no, bad

ornate oriole
#

oh.

gloomy chasm
#

GetPropertyHeight is called before OnGUI. Also things like EditorGUI.GetPropertyHeight call the GetPropertyHeight of the property drawer

ornate oriole
#

Ooh, I see..
But I checked it out and it seems to be working for now without any issues
How exactly can it break?

gloomy chasm
#

Firstly, if anything else ever calls EditorGUI.GetPropertyHeight and a property using this method is present. It will give incorrect results.

ornate oriole
#

Even if it calls GetPropertyHeight first, the height returned from the dictionary will just have the default value of 0, then OnGUI gets called and updates the dictionary, and whenever another GetPropertyHeight gets called it already has the height there

Idk how exactly does the instantiation of the custom PropertyDrawer instance works, when it's deleted, how exactly and how often does it update the inspector, but for now it looks good, idk, maybe it has to be a specific scenario when it actually does break, or I'm lucky that it didn't break just yet

gloomy chasm
#

Again, just don't cache the height. Why are you caching it?

ornate oriole
#

Like I get the main idea that it could break, but for now I just don't see where and when exactly it could break, what would have to happen to make it break

#

Both the solutions with iteration and simple EditorGUI.GetPropertyHeight(property) didn't work and the height was nowhere close to what it was supposed to be for some reason

#

oh wait, I'll check something

#

Yeah, I checked it once again with EditorGUI.GetPropertyHeight(property, true) since I had EditorGUI.GetPropertyHeight(property, label) earlier, but it still doesn't work

pale hull
#

Hi. Is there a way to redraw only some fields with property drawers and leave the others the same?
I can find fields with FindPropertyRelative and redraw them, and I can draw default fields with PropertyField.
But how I draw default all except fields I specify (and redraw), without actually drawing all of them (so if a new field would be added I won't need to update custom drawer)

green current
pale hull
green current
pale hull
# green current Hmmm I'm pretty new to the editor stuff, but I'm messing around with it a bit. I...

I have a list of class instances, which I create through editor to configure stuff.
I think I find a solution (for my problem at least).

 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var lines = 1;
            EditorGUI.BeginProperty(position, label, property);
            foreach (var field in property.managedReferenceValue.GetType().GetFields())
            {
                var fieldType = field.FieldType;
                if ("type I don't want to redraw")
                {
                    var rectType = new Rect(position.min.x,
                        position.min.y + lines++ * EditorGUIUtility.singleLineHeight,
                        position.size.x, EditorGUIUtility.singleLineHeight);
                    EditorGUI.PropertyField(rectType, property.FindPropertyRelative(field.Name)); //draw default
                }
            }
// custom redraw for needed elements5
            EditorGUI.EndProperty();
        }
green current
#

Ahhh I see

#

That makes sense then

visual stag
pale hull
north sphinx
#

When I create game object in edit time. How can I make it so scene becomes dirty and does not instantly saves assets?

#

I create object like this

            var go = new GameObject(type.Name, type);
            go.transform.SetParent(transform);
#

and for some reason scene is instantly saved

visual stag
north sphinx
#

so hold on

#
            var go = new GameObject(type.Name, type);
            Undo.RegisterCreatedObjectUndo(go, "Instantiated node");
            go.transform.SetParent(transform);
#

is this how it's meant to be?

#

what about modification of serialized data?

            Undo.RegisterCompleteObjectUndo(this, "Added connection");
            connections.Add(connection);
#

and destroying of game objects

#

DestroyImmediate(node.gameObject);

visual stag
north sphinx
#

I tried this, but no luck

        private void Awake()
        {
            Undo.undoRedoPerformed += OnUndo;
        }

        private void OnDestroy()
        {
            Undo.undoRedoPerformed -= OnUndo;
        }
visual stag
hidden oak
#

Anyone knows if its possible to create an animation preview VisualElement with UIToolkit? I'm building an editor and would like the following behaviour:

  • User selects and animation with an object picker
  • The selected animations preview is displayed in a visual element next to the object picker
  • The user can scroll the animation and see the time for a given frame.

Basically, can I create an instance of the preview window (bottom of inspector) and place it in my custom editor?

#

This window. It's displayed when selecting an animation (fbx) in the inspector

#

I've managed to get the animation window to show in various ways with GetWindow<AnimationWindow> but I dont need the whole window, just the preview module.

north sphinx
#

I register in EditorWindow class

visual stag
north sphinx
#

what would be appropriate callback then?

visual stag
#

OnEnable iirc? Just test it's called and registered

north sphinx
#

yep, that was it

#

damn

#

this is much more complex

#

I found out I store elements in a list as well

#

which makes deletion through Undo leak

#

Is there a way to register some callback along with Undo?

#

Or maybe register undo as action alltogether?

#

or I guess I better not rely on lists...

unreal hedge
#

i'm trying to add c# extention to my VS code editor but it doesn't exist

#

all youtube tutorials show it having a green logo and a verification from microsoft

#

does it not exist anymore ?

green current
earnest talon
#

@gloomy chasm I've been getting more and more used to using UIToolkit now - I'm able to do a majority of what I could in IMGUI and then some (e.g. extra stylized functionality).

gloomy chasm
earnest talon
#

Yeah

#

I've also fixed a lot of issues with my USSOM

gloomy chasm
earnest talon
#

and I'll be releasing the exportsheet & exportselector attributes soon

#

USSOM is the only reason I'm able to do this reliably

gloomy chasm
#

They grow up so fast 🥹

earnest talon
#

I'm essentially creating and exporting the sheet whilst storing const/static variables in the class that the sheet and the object uses.

#

is it always great? no

#

but the reason I do it is mostly for color variables

#

that way I can just tweak on the go

gloomy chasm
#

You know uss supports variables right?

earnest talon
#

yeah and var() is missing from USSOM rn

#

but I'm using C# so I need the variables in C#

#

meaning I can use the same variables for C# and have them translate in USSOM. (C255 allows me to create UnityEngine.Color objects with RGB-255 values)

gloomy chasm
# earnest talon

Kind of defeating the point of USS still.... I take back half of what I said!

earnest talon
#

well

#

I can use USS properly

#

and I know how to

#

I just have those in case I want to do quick changes

#

so I just scroll up to a script instead of opening a style sheet and making a change

gloomy chasm
earnest talon
#

it depends on what I'm doing

#

there are things I can do in USSOM that would require some extra step(s) in USS

#

such as using UnityEngine.Color objects for values

gloomy chasm
earnest talon
#

I'm passing in a Unity Engine color value directly to the USS Object Model and it translates the value for me into rgb/rgba USS functions.

gloomy chasm
#

You can do element.style.backgroundColor = Color.white;

earnest talon
#

you can

#

but I want my values in USS files.

gloomy chasm
#

No, why would you need to have the values both in uss and C#

earnest talon
#

having them in C# (as the const/static variables) is so I can quickly change them for the USS exporter and have it appear when I load up unity.

#

having them in USS is the primary thing

gloomy chasm
#

So.... you have them in C# to basically 'fix a problem' that you created for your self...

earnest talon
#

I found out a few days ago

#

and just have it on the things to do

visual stag
#

I also don't really understand the need for the C# version of USS, is it just because you like having strict compilation?

earnest talon
#

not even that

#

I just didn't want to write native USS

#

so I could have everything in C# and work from one language alone.

#

but in the end, I learnt USS, some UXML and a lot of web-dev related stuff in the process

#

don't regret it though - I got a lot more out of it than I expected and learnt a lot more in the process

gloomy chasm
earnest talon
#

the USS style sheets being generated are important for the styles of the editor window

#

it's just a tool I made for preference of C#, nothing more and nothing less.

gloomy chasm
earnest talon
#

because I could do that

#

but there's less educational value in it for me.

#

I don't learn if I just use everything that came from the factory (there are exceptions and what not)

#

I do it not because I think my way's better

#

I just do it because I want a challenge and I want to learn.

gloomy chasm
#

Fair enough, cool that you learned a bunch! But also, having the colors in the code still defeats the point of USS, also, no light theme support 😢

earnest talon
#

I'll add in stuff for light theme, for sure.

#

genuinely out of pure interest for what that would entail technically.

earnest talon
#

it's not even a permanent solution, I just have them there so I don't have to scroll to the bottom of the script

#

the only reason XML is there is because I've built in a habit of doing XML on anything and everything I create now.

gloomy chasm
#

There might be a better way now to do it within the UXML, idk.

earnest talon
#

probably yeah

#

I need to explore UXML more

#

also I will add too

#

the only reason I'm doing BP is to do a visual scripter for IMGUI using UITK

#

out of just the genuine interests of

#

A) USS

#

B) Visual Scripting Logic and how you'd roughly create a visual scripting system for any game engine

#

C) How to execute a visual script

gloomy chasm
#

Wait wait, so you are writing a tool in UITK to write code for IMGUI? 😂

earnest talon
#

It'll already be not as performant unlike just native IMGUI or UITK

earnest talon
#

and what I'm doing is

#

I'm making two tools at once.

#

a basic UE-Like graph toolkit

#

and then the Plugin creator on top of that as a separate class inheriting from it

#

it's funny in many ways and it's just a case of "can it be done, if so how cursed?"

gloomy chasm
earnest talon
#

yeah

#

I think some people will be under the assumption I don't know or care how bad this is (or could be) both from technical, logical and performance reasons.

gloomy chasm
#

Ehh, honestly, as long as you know what and why you are doing. It is all good!

earnest talon
#

true

#

I am fully aware of what I'm doing and why it's bad at least

#

had to research that beforehand.

gloomy chasm
#

All good then!

earnest talon
#

but I still wanted to do it because it's fun to learn both practically and theoretically

#

still the rabbit-hole of imgui-vs-rmgui will never cease to end

#

in terms of overall, it's case-dependent

#

in terms of unity, UITK (RMGUI) is preferred over IMGUI - except in the case of very simple controls

gloomy chasm
#

Indeed, I do stuff like that all of the time! Dove deep in to the internal View system to make sidebars! Just to see if I could.
Made a way to search bound IMGUI fields in any editor window. That one was cursed!

earnest talon
#

noice

#

plus the stuff we learn is transferrable to actual solutions for actual problems (overall, not saying that yours isn't an actual problem dw - just mine)

gloomy chasm
#

Ehh, sometimes less so than others xD

earnest talon
#

yep

#

USSOM i learnt more of the technical constraints of language translation / exporting, UI Design and the web-dev languages.

#

is it a better system than what Unity has, no.

#

I'd be dumb to think that. It's just a curio of sorts from curiosity and persistence.

#

I wonder if you've had any sort of tool project like that yourself, Mech

gloomy chasm
earnest talon
#

yeah

gloomy chasm
#

No, interest or motivation for me mostly comes from a use-case. If there is no use-case I have little interest/motivation to work on something

earnest talon
#

that's fair. I'm only lucky to have the chance to do these less-practical projects because I'm a student still

visual stag
#

Just as long as you don't get too attached to those projects and realise that without a usecase you are procrastinating, that's totally fine

visual stag
#

This is not what this channel is for, but you need to properly configure the !ide you use

grave hingeBOT
#
💡 IDE Configuration

If your IDE is not autocompleting code
or underlining errors, please configure it:

Visual Studio (Installed via Unity Hub)
Visual Studio (Installed manually)

VS Code*
JetBrains Rider
Other/None

*VS Code's debugger plugin is unsupported.
We recommend using VS or Rider instead.

visual stag
#

If errors are underlined in red, it's working

peak bloom
#

is UItk's pixel size calculated based on screen aspect ratio already or not?

#

e.g vis.style.width = new Length(200);

#

I'm doing this manually currently myScreenRatio * 200 or should I not care about it? also this is for editor extension

pine reef
#

how do you make rider syntax highlight unity packages?

#

by default it looks like this

visual stag
jagged hawk
#

When dealing with a custom property drawer that's inside a list, when I interact with an enum popup field, it thinks I want to reorder the list. What would be causing that?

green current
jagged hawk
#

I wouldn't use my code as a foundation for your learning, I'm guessing everything myself lol

green current
#

Everything is an opportunity for learning

#

Hmmm what is the role of BeginProperty?

#

Isn't the field itself representative of the property?

#

Also, if I understand correctly I believe EditirGUI.PropertyField tries to automatically figure out what to do. Maybe they're related?

jagged hawk
#

Yeah, it figures out what the property field is. I think the idea behind BeginProperty is if you want to group property fields, but I honestly have no idea on that. All I know is, what I have, causes major visual issues lol

gloomy chasm
jagged hawk
#

This is just an item in a list that shows different fields depending on the type selected. How do I stop selecting an enum triggering the drag of the list item? It messes up everything.

jagged hawk
#

Lowkey losing my cool, cannot find the answer anywhere and I'm unable to progress. Selecting an enum shouldn't initiate drag, furthermore, dragging list elements shouldn't cause them to forget everything.

It really seems like a unity bug when something like this happens all because of selecting an enum field

low radish
#

Hi, I am trying to switch mesh of my walls, it works but when I select multiple walls and press the update walls button it only changes one wall

#

`[CustomEditor(typeof(WallSwitcher)), CanEditMultipleObjects]
[ExecuteInEditMode]
public class WallSwitchEditor : Editor
{
WallSwitcher wall;

private void Awake()
{
    wall = (WallSwitcher)target;
}

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();

    if (GUILayout.Button("Update Walls"))
    {
        wall.SwitchWallMesh();
    }

    if (GUI.changed)
    {
        EditorUtility.SetDirty(wall);
    }
}

}`

gloomy chasm
gloomy chasm
low radish
#

ohh got it THANK YOU!

jagged hawk
#

@gloomy chasm I simplified it more, it doesn't look as buggy due to less height mess but it is still the case where I click on the enum, and it's trying to drag despite not holding down click. Dragging, with the default behaviour and no custom stuff, is buggy in itself where elements will hide behind other elements so that's expected, it's just... I need it to not drag when I'm selecting a type.

This is the entire code:

public enum ConditionType { Variable, Quest };

public class ConditionalObject : ScriptableObject
{
    public ConditionGroup[] conditionGroups;

    [System.Serializable]
    public class ConditionGroup
    {
        public ConditionType type;
    }

    [CustomPropertyDrawer(typeof(ConditionalNodeObject.ConditionGroup))]
    public class ConditionGroupDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(position, label, property);

            Rect typeRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
            EditorGUI.PropertyField(typeRect, property.FindPropertyRelative("type"));

            EditorGUI.EndProperty();
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            return EditorGUIUtility.singleLineHeight;
        }
    }
}
visual stag
#

I don't think it's relevant in property drawers afaik

jagged hawk
#

shrug_animated I have tried removing it, makes zero difference to the end result in my experience

gloomy chasm
jagged hawk
#

2022.2.14f1, tried it in 2023.1.0b11 with the same result. The issue does not occur with 2021.3.22f1, unrelated stuffs have issues but the property drawer works flawlessly
Update: Doesn't occur with 2022.1.24f1 and 2023.2.0a9 so I guess either it was fixed unintentionally for the latter, or intentionally but wasnt applied to 2022.2 or 2023.1. I did submit a bug report just in case detailing this.

zinc spoke
#

does anyone know any way of getting path to "Unity Editor" and not the "Project"
I need this to generate a .gitconfig file with a path to "Editor\Data\Tools\UnityYAMLMerge.exe"

green current
green current
#

Ah. I would assume you can just use the full path

#

Are you unsure of where it's located in your file system?

zinc spoke
#

no no no I know where it is and i have setup my github to use it

#

[mergetool "unityyamlmerge"]
trustExitCode = false
keepBackup = false
# Replace path with path to your Unity version!
cmd = 'E:/Unity Editors/2021.3.16f1/Editor/Data/Tools/UnityYAMLMerge.exe' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

#

problem being this path is absolute

#

so every person on my team that wants to use my repo needs to change the path

#

I was thinking about making an editor script that changes the path automatically

green current
#

Ohhhh and you want to know how to reference it through PATH so you can just say "unitymerge.exe" or whatever it is, yes?

#

Or at least to avoid having to specify things like version number?

zinc spoke
#

what I am thinking about is having a static editor class that changes the ".gitconfig" file that is in the root of my repo and unity project with "InitializeOnLoadMethod" attribute

#

that is simple C# stuff

#

problem is one of the things that I need to set in the file is the path to the Unity Editor tool

#

"UnityEditor.AssetDatabase" and other classes like that seem to only be able to get info for the current project

#

and not the actual Editor itself

#

@green current

green current
#

So are you trying to set it up so that every unity project works this way? Every project on your system? Or just this one project?

zinc spoke
#

my project is on gogs (self hosted git) and I want everyone who downloads the project to have the stuff set up for them automatically

green current
#

Ahhh

#

Hmmm I'm not sure.

north sphinx
#

So... I have custom window that relies on selected game object in scene.
When I start PlayMode that object instance seems to be destroyed and my custom window breaks.
So the question is how can I get new instance of that object in playmode?

I tried hooking into EditorApplication.playModeStateChanged and reading Selection.activeObject from here. But it seems like it's still pointing to dead reference

#

thus I get errors about accessing destroyed gameObject property on monob

twin dawn
fading snow
#

How would I make a custom button show underneath the "Add Component" button? Image for reference, I want it to be like the "Generate Component" button

gloomy chasm
gloomy chasm
gloomy chasm
errant shale
#
  • I struggle to find any article on how to make clickable scene areas. For example, the tilemap grid that allows you to place tiles in it, without either gizmos or selectable objects on them. Is there any article, manual etc. on how to achieve anything similar to this?
gloomy chasm
errant shale
#
  • Idk whether it's handles or not tbh. Should i go with my specific context maybe to make it clearer?
spice turtle
#

Is it possible to edit tilemaps somehow in a scriptable object? Trying to make templates I can paste onto my tile map

ebon helm
#

I'm creating a object field with EditorGUILayout.ObjectField(). How can I determine which object field is currently focused in the inspector so I can draw additional gui depending on that selection

hoary grove
#

How can I check if a Prefab is currently open in the Prefab editor view?

peak bloom
#

@gloomy chasm how can we use DropDownMenu on runtime (uitk)? and sorry for the ping 😃

#

I'm looking for an easy way to make nested menus like in DropDownMenu

peak bloom
#

it is, but how can I use it? I'm using it with ToolbarMenu all this time, but don't know how to use it WITHOUT toolbarmenu due to it editor only

#

also dropdownmenu is not visualElement so can't just use it as is, by that I mean we can't just add it as a child of visualelement

gloomy chasm
#

Taking a look at the source code. All it is is literally just a list basically. Looks like EnumField uses GenericDropdownMenu. Doesn't even use DropDownMenu.

gloomy chasm
peak bloom
#

Aight, looking into it now 👍 .. thanks!

#

it uses DropDownMenu

gloomy chasm
#

At least somewhat

peak bloom
peak bloom
#

in my case moving a visualelement will make vertices count jump to 120k... what an insane bug

gloomy chasm
earnest talon
#

any of you know how to use Experimental.GraphView.Resizer?

earnest talon
#

It doesn't seem there's any documentation on Resizer - just it's members?

#

looks like you aren't even supposed to use it - just found that adding a resizableelement works and modify that with UnityStyleSheets instead

earnest talon
#

doing some hacky behaviour (for better or worse) allowed me to forcibly do group resizing with Resizable element without it breaking everything.

sour oracle
#

What are your guys' opinion on having custom editors in separate files vs having them in the same file as the component they are attaching to?

Same file bloats the project and can sometimes make it hard to find the custom editor, which is prevented by placing it in the same file but then you have to add a bunch of pre-processor directives..

safe sorrel
#

someone asked about polymorphic SerializeReference in another chat and was directed to bring it up here

#

there are several tools that can help with this

lethal imp
#

Guys i used a property drawer on a collection and when i change an element all the others elements keeps the same modification, is there a way to fix this ?

earnest talon
#

Your project won't compile if you do.

#

you'll be splicing run-time code with editor-only code and it'll cause numerous errors in the console

#

learnt the hard way last year, just before my first team's project cause I did that mistake with my first plugin :)

sour oracle
#

That's what the pre-processor directives are for ;)

earnest talon
#

you have to keep them in separate scripts

earnest talon
#

keep them separate anyway

sour oracle
#
#if UNITY_EDITOR
    [CustomEditor(typeof(ShrinkingPlayableAreaManager))]
    public class ShrinkingPlayableAreaManagerEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            var manager = (ShrinkingPlayableAreaManager)target;

            if (GUILayout.Button("Initialize"))
            {
                manager.Initialize();
            }
        }
    }
#endif
}
earnest talon
#

Main reason is legibility

#

other reason is so you can modify both easily without having to scroll forever based on scale

sour oracle
#

That's true

earnest talon
#

also if you do IMGUI you should really get used to structuring your editors too

#

so many people complained about it in the circles I knew

#

turns out they just do one or two scripts

#

not proper panel/context-based structures

safe sorrel
#

can you elaborate?

earnest talon
#

The way I do IMGUI editors is

#

you have the initial opening panel that contains the editor window creation and opening process, with the main OnGUI call

#

then you have "Panels" which have their own structures, all with one exactly the same "PanelName.Draw()"

safe sorrel
#

ahh, okay, I see

earnest talon
#

that way you're splitting context apart and you're making it easier to edit the sections you're working on

safe sorrel
#

oh yeah, I wound up doing exactly that for one game

#

because I realized I couldn't get the different panels to play nice with each other if they weren't all drawn in one big go

earnest talon
#

you don't do it in all one big go really

#

you only draw the panel you need

#

and you track the state of the overall editor

sour oracle
#

I am not making very fancy editors though as you can see x) It's just a button which calls a function that would normally be triggered by an event

earnest talon
#

which is a pain to test bugs with sometimes if you're constantly changing the scripts because of editor window refreshing

earnest talon
#

all you really need to do is create a folder called Editor in the location of the main script

#

and create a new script in that

#

that way it doesn't compile nor will have any chance to.

sour oracle
#

Editor folders littered everywhere

earnest talon
#

that's why I generally just stick to one main one in the assets personally

#

and have sub folders in that for each plugin I'm working on

#

more specifically

#

it's Editor/Plugins/pluginNameHere

#

that way I keep the editors in one place and everyone on my team projects knows "oh okay this is neopolitan's work, best not mess with it"

#

so even if they mess up the main object classes, they can't mess up the editors anywhere near as easily without my approval first

#

there'll always be others who prefer it another way

#

or would tell you to do UIToolkit

#

preprocessor directives is a solution to the problem but even if it shouldn't compile, I wouldn't take that chance.

#

Unity pretty much tells us that anything in a folder labelled Editor isn't being packaged with the main game files

sour oracle
#

Gotcha

earnest talon
#

I wish you luck though

safe sorrel
#

i mixed that up with IMGUI

#

even though it is an immediate-mode GUI

#

just not that immediate-mode GUI

earnest talon
#

iMGUI is

#

it's all IMGUI

#

OnInspectorGUI does take IMGUI

knotty pebble
#

Hey, specific help here with custom editors. How can I access the drawing method for drawing these fields in this array? Basically I want to hide one of the fields when the enum is set to something specific. Where should I create a custom editor?

gloomy chasm
knotty pebble
#

Alright I'll research property drawers thanks :)

knotty pebble
#

Oh this actually works this is so cool, SerializedProperty.enumValueIndex is really useful for checking what the enum is

#

thank so much!

#

actually one thing, this is looking pretty scuffed, I just made the rect for the other variable have lower y position, but it's not changing the bounds of the array, how to fix?

#

less confusing, it looks like this with 1 element

still pecan
#

Hello. What is the proper way to update something during edit mode

#

currently I use ondrawgizmos for updating everything

opaque seal
still pecan
opaque seal
#

EditorApplication.update will always fire. It is not bound to any interaction, maybe you are confusing it with OnSceneGUI?

still pecan
knotty pebble
#

does anyone know why the element doesn't change height to match the fields? (making a property drawer)

opaque seal
elfin gorge
#

Hi everyone, I was wondering how do we get the exact rect of the inspector / custom editor class? I've seen online for EditorWindows people can use "position" however I can't seem to find anything that difinativly gives me exactly the editors bounds all the time.
The best I have found is doing this:

Rect editorRect = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

However this does give me what I assume is the correct bounds, it also for some reason gives me a rect of (0, 0, 1, 1), alternating between a correct and incorrect value.
Is there a better way to do this?

#

I also was wondering as a second question whether or not IMGUI would be useable with assets for the asset store, I am trying to rewrite the editor for some scriptable objects so that they are more userfriendly and I keep coming across people using IMGUI instead of just the base inspector. Right now I don't know another about IMGUI to be able to tell if its worth looking into as a solution to all my issues with this, however I figure it would be worth knowing at the start if I can even package this with the asset (both functionally and legally since its someone else's code).

opaque seal
elfin gorge
#

Brilliant thank you, with the event.repaint does OnInspectorGUI get called from other events? If so if I am trying to do somethign that will register button clicks do I need to make sure to only check handles on an EventType of mouse down? or does that not matter?

opaque seal
#

OnInspectorGUI is called consecutively with multiple event types AFAIK. So yes, for special kinds of operations where you want to listen to mouse clicks you can use EventType.MouseDown in that method. However, finding out which elements were clicked is far more sophisticated. This article might help you out to gain a deeper understanding of what is happening in the IMGUI draw methods: https://blog.unity.com/technology/going-deep-with-imgui-and-editor-customization

#

(Of course for simple button interaction you can use GUILayout.Button and be done with it immediately, but I guess you are after more complex stuff :D)

elfin gorge
#

I'm wanting to look into handles right now, and have gotten it to the point where I am rendering them ontop of a PreviewRenderUtility, though I can't get any interaction from them. So currently trying to debug that at the moment, Dx

#

The only thing online I have found said that I'd need to add an offset ot the mouses position based on the whole inspectors rects lower left edge, to the previews rects left edge. Not sure if that would work but thats why I was asking about the rect xD

#

Thank you though ^-^

scarlet hedge
#

idk where to ask this but my rigidbodys information isnt showing up

#

i remember it used to tell u the velocity and stuff

elfin gorge
#

If you want to see the extra info you need to set you inspector to Debug mode

#

You can do that at do that by pressing the 3 dots at the top, next to the padlock of the inspector

scarlet hedge
#

that doesnt show me the velocity

#

idk what made it disappear i was able to see it a couple of days ago

#

i can see it on another project

#

wait i think its got to do with the editor version

elfin gorge
#

Ah, hmm. Maybe then. I didn't know there was a difference between versions. Is upgrading fine for you?

#

If not you can always write as script that just outputs the velocity as a field.

scarlet hedge
#

its downgrading actually

#

i use the 2022 version but it wasnt showing up so i tried 2020 and it worked

solemn pond
#

So im trying to write my custom editor script.
but when using EditorGUILayout.BeginFoldoutHeaderGroup() im not getting any arrow to the left of it in the inspector.

public override void OnInspectorGUI()
    {
        serializedObject.Update();

        physicalFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(physicalFoldout, "Physical Properties", EditorStyles.boldLabel);
        if (physicalFoldout)
        {
            hitBoxRadiusProp.floatValue = EditorGUILayout.Slider("Hitbox radius", hitBoxRadiusProp.floatValue, 1f, 20f);
            attackRangeProp.floatValue = EditorGUILayout.Slider("Attack range", attackRangeProp.floatValue, 1f, 20f);
        }
        EditorGUILayout.EndFoldoutHeaderGroup();

        statsFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(statsFoldout, "Stats", EditorStyles.boldLabel);
        if(statsFoldout)
        {
            factionProp.enumValueIndex =  (int)(Unit.Faction)EditorGUILayout.EnumPopup("Faction", (Unit.Faction)factionProp.enumValueIndex);
            roleProp.enumValueIndex =  (int)(Unit.Role)EditorGUILayout.EnumPopup("Role", (Unit.Role)roleProp.enumValueIndex);
            EditorGUILayout.PropertyField(maxHitPointsProp);
            EditorGUILayout.PropertyField(attackDamageProp);
            attackSpeedProp.floatValue = EditorGUILayout.Slider("Attack Speed", attackSpeedProp.floatValue, 1f, 10f);
            threatMultiplierProp.floatValue = EditorGUILayout.Slider("Threat Multiplier", threatMultiplierProp.floatValue, 1f, 10f);

        }
        EditorGUILayout.EndFoldoutHeaderGroup();

        EditorGUILayout.PropertyField(spellBookProp);

    }
#

message was too long, so i had to remove the first foldoutgroup, but theres no change to the code

#

also, my sliders dont seem to work during runtime

waxen sandal
#

It's because you overrode the style

#

Sliders should work though I think

covert palm
#

I have a question regarding the updating of a property drawer. I have a group box and want to update the contents of it based on a bool. I have a callback on the toggle, which seems to be getting called. The issue I have is with how to redo the the contents.

    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        var root = new VisualElement();
        var label = new Label(property.name);
        root.Add(label);
        DrawGroupBox();
        root.Add(new Label("after box"));

        return root;
        
        void DrawGroupBox()
        {
            //_groupBox.Clear();
            var constantBoolProp = property.FindPropertyRelative("useConstant");
            var constantBoolField = new PropertyField(constantBoolProp);
            constantBoolField.RegisterCallback<ChangeEvent<bool>>(evt => DrawGroupBox());
            _groupBox.Add(constantBoolField);
            if (constantBoolProp.boolValue)
            {
                var constantVal = new PropertyField(property.FindPropertyRelative("constantValue"));
                _groupBox.Add(constantVal);
            }
            else
            {
                _groupBox.Add(new PropertyField(property.FindPropertyRelative("variable")));
            }
            root.Add(_groupBox);
        }
    }```
The following is happening: the commented groupBox.Clear(), if I uncomment it, it never shows anything. Not quite sure why if I add stuff after the clear.  
If commented, it *does* show, but still doesn't update properly. if the bool goes from false to true, it seems to do something, but not the correct thing: now shows the groupbox after the second label ("after box"). if it goes from true to false, nothing seems to be happening
I'm sure it's something basic I'm missing here
#

Ah one of the issues was a mistake on my part, the root.add(groupbox) shouldn't be inside the method. Now it just doesn't do anything, although the event gets called 100%

covert palm
#

Nvm I switched to hiding it by changing the style.display

tight pine
#

Hey ppl, I have a PropertyDrawer for a tag list (array of strings) but I want the UI to allow the user to insert the tags as comma separated values and save/parse when they FocusOut of the text area. I've made functions to convert the csv to array and the other way around and they work perfectly. But I need to keep the state of the text areas and the current focus control name.
If I keep them on the PropertyDrawer as class variables it works exactly as I want for one object, but of course, Unity reuses the instance of the drawer for all other objects.
I don't want to store the values of the text area or the control name on my actual object.
What could I do?

#

I even thought of creating a dictionary and use the hash of the object as a key to store the values for all objects.... but seems silly.....

#

or maybe not...

gloomy chasm
tight pine
#

yep

#

I tried the Dictionaries.... they work perfectly... it still feels a bit wrong for some reason.

#

What do you think @gloomy chasm?

gloomy chasm
tight pine
#

huuu What is a delay field??

#

(googling)

tight pine
#

hoooooooooooooo

#

darn!!!! I didn't know these existed

gloomy chasm
# tight pine hoooooooooooooo

And if that wasn't a thing. All you do is have a string field, before drawing the TextField, you would check if it is null, if so you set it to be the property string value. You give the TextField this string field. Then on Enter or lost focus, you set the property string value to the string field, and set the string field to null.

tight pine
#

Thank you so much @gloomy chasm

gloomy chasm
tight pine
#

Let me know if I ever have a chance of hiring you 😉

tepid roost
#

has anyone been able to drive the "Font Asset Creation Tool" all from scripting

gloomy chasm
tepid roost
#

as long as it works that is fine

#

more or less wanting to rebuild font atlases based on custom character sets derived from the loc system

#

helps keep atlas size down for asian languages since a lot of glyps are often not used

gloomy chasm
#

Now, this is just from residual memory, so idk how helpful it will be. But I feel I remember you had to use the FontImporter, and maybe even have to get a pointer to the c++ object to access some of the fields that are not even exposed to C#.

#

But I would start by looking at the source for the FontImporter

tepid roost
#

yeah it looks fairly exposed since TMP stuff is all just in a package and a asmdef

#

gross the part that does the work is not even its own function

#

its just inline with the other ongui stuff

#

though looks like i can easily get it to popup the window and edit all the fields to be correct

#

who donst live a good thousand line long function that mixes ui drawing code with functionality

#

atleast got it auto populating all the fields of it as needed

gloomy chasm
tepid roost
#

like i think i am one of the few people that does not mind imgui, but i also never put in piles of logic to do the work just in the condition for drawing a button

gloomy chasm
ocean hatch
#

I have a serializeable class that has a MyBaseClass property, and this base class have two child classes (all serializeable). In a custom editor script I'm attempting to use PropertyField or ObjectField to get this property to display correctly, but I get the error: type is not a supported pptr value
Anyone know what I'm doing wrong?

short tiger
ocean hatch
short tiger
#

You can nest them, but it doesn't affect serialization.

ocean hatch
short tiger
#

Then you need SerializeReference and a custom editor to choose the type.

#

SerializeReference lets you define a field of a base type and assign derived types to it.

atomic sable
#

What do you mean inspector attributes?

covert palm
#

when setting an object field to "None", it still shows the last selected object until the inspector refreshes. Do I need a callback and refresh it manually?

atomic sable
#

You want to override what draws for the Range attribute?

atomic sable
#

Sounds like you’ll have to parse the file then if(attribute) draw a slider

#

I don’t know enough about that kind of stuff though so i may be wrong

atomic sable
#

Ohh. EditorGUILayour.Slider or EditorGUI.Slider

#

There’s a bunch of different methods

earnest talon
#

I think one of them

#

is you might have to use reflection to create attributes that add inspector elements like that

#

I use a translator to Common Intermediate Language for C# that allows me to tell when methods are called on startup that are internal-use only.

earnest talon
#

one thing I'm finding issue with right now is data persistence with UI Elements

#

I've gotten IMGUI technically working with UIE blueprinting but it's not supposed to work and I can already tell it won't work later down the line with global variables and port-to-port pass through.

#

for one frame, the Execute function in the first node successfully gets the "true" value from the boolean port

#

but after that, it won't update the condition because the data held in the port is null.

#

how would I keep the state of each port/visual element persistent for IMGUI without it resetting after one read? (it won't visually reset because the condition in the main execute port doesn't reset if the object value in the data port is null)

earnest talon
#

I did manage to find a work around for that for now, by "resolving" the port's value based on whether or not it has a connection as the first step during a node's execution. If it doesn't then it'll stick to whatever's there (based on the entry field), if it does - it'll get the value.

#

and it worked at least

gloomy chasm
earnest talon
#

well I need to have a bool output port link to a bool input port and pass the data through (and similar for any data type output to input)

#

I found a way to do it though

gloomy chasm
earnest talon
#

I just need the bool value to be transferred or to work with a global variable.

#

Each node only runs through an Execute() function

#

no pass-in params, resolves the values and operates off of them.

gloomy chasm
#

What I mean is, UITK should not be handling the transfer. That should all be done on your model/viewmodel

earnest talon
#

ah, I thought the model was part of UITK because it was UITK-based.

gloomy chasm
#

Oh no no no

#

UITK is view only

earnest talon
#

so that's just the layout and visual aids

#

you supply all transfer, etc.

gloomy chasm
#

Yeah exactly

earnest talon
#

the only weird persistence issue I have is

#

if an input port has a field assigned to it, although that field is assigned to the Execute() func will never be able to read it more than once

#

and it'll read as null for every subsequent read, unless it has a connection to another port

#

the way I get around that is just never resetting the value of the node's condition (in case of the branch node) and having it operate on the last known value - it updates whenever that value changes but reading the input port's value again* will be null every subsequent read

#

mb though @ thinking the model was part of the UITK

gloomy chasm
#

Idk what your setup is @earnest talon . Only thinking about it briefly, but the way I would approach a BP like visual scripting thing is like this.
Have a base node with an void Execute() method, and two lists of a custom NodeProperty class, one for inputs and one for outputs. More on that later.
For things like branch nodes, for loop nodes, etc. You inherit from the base node, and implement the logic in the Execute. Adding things to the two lists as needed.
For other types of nodes, you use reflection to get the methods, and invoke them in the Execute method, you populate the two lists from the params of the methodinfo.

About NodeProperty, that would also be a base class with two-ish implementations. One for manual setup where it stores the value, and one for reflection where it gets/sets the value.
The base class would contain things like linked nodes/properties, maybe parent node, etc.

For UITK, you can basically just have a single node class. For each node in the graph, you would create a UITK node. You populate the ports by getting the values of the two lists. And thats it.

#

Again this is only thinking about it for a couple of minutes, so there are probably things I didn't think of or better ways to do it. But, that is the basic idea.

earnest talon
#

the only difference being the properties and reflection

#

the only things extra I'm tracking are the execute ports*

#

that way execute goes to the next method afterward, if there is a connection to the port.

#

I've been doing some testing with what I've gotten so far and i knew it would be inefficient compared to IMGUI done raw

#

but I'm surprised at how efficient IMGUI already was aside from the visual scripting gimmick thing I'm doing

#
RAW IMGUI LOW  -  126 ticks / 12,600 nanoseconds / 0.0126 miliseconds
RAW IMGUI HIGH -  1927 ticks / 192,700 nanoseconds / 0.1927 miliseconds

VIS IMGUI LOW  -  3896 ticks / 389,600 nanoseconds / 0.3896 miliseconds
VIS IMGUI HIGH -  10249 ticks / 1,024,900 nanoseconds / 1.0249 miliseconds```
#

those are just the low/high values I found in a brief window

#

the lowest so far has been 67 on RAW IMGUI

#

3896 still on VIS IMGUI

#

a lot of that processing power is probably going towards resolving the port connections

#

out of curiosity, how much overhead should a visual scripting system generate on top of the raw methods?

#

I need something as a baseline to at least aim for efficiency-wise.

gloomy chasm
earnest talon
#

for the overall OnGUI method itself

#

meaning resolving each port connection per node

#

and executing it

gloomy chasm
#

Oh right, this is a IMGUI creator thing

earnest talon
#

getting info from ports

#

setting info to ports

#

and yea

#

a lot of the overhead is generated from the per-node port connection iterations.

gloomy chasm
#

What are you iterating?

#

You should be able to just do direct connections

earnest talon
#

the ports themselves have data passed in and out of them

#

oh wait

#

that's not execute

#

the first one isn't really necessary, I can remove that

visual stag
#

is there a reason that is not just if (p is Dataport port)?

earnest talon
#

oh I didn't know about that

#

thank you

#

those two changes immediately took the overhead down

#

(removing direction is not direction.input, as that's only called if the node is an input node & if p is dataport port)

#

9736 was the highest recorded for Vis IMGUI but that was the very first frame which was odd itself

#

but it's now at

#
RAW IMGUI HIGH        -  1729 ticks / 172900 nanoseconds / 0.1729 miliseconds
RAW IMGUI FIRST-FRAME -  122 ticks / 12200 nanoseconds / 0.0122 miliseconds

VIS IMGUI LOW         -  114 ticks / 11400 nanoseconds / 0.0114 miliseconds
VIS IMGUI HIGH        -  1617 ticks / 161700 nanoseconds / 0.1617 miliseconds
VIS IMGUI FIRST-FRAME -  9736 ticks / 973600 nanoseconds / 0.9736 miliseconds
#

still a fair lot worse overhead

#

but a lot less than it was

#

it's averaging around 200-900 ticks / 20000 ns -> 90000 ns / 0.02 ms -> 0.09ms

#

imgui's averaging around 80-1600 ticks - which is weird

#

they're pretty much neck and neck though (when all options are ticked/highlighted) but I'll need to test it on more systems

#

I'll have to snoop around and see what other issues I've got

covert palm
#

I'm trying to make a property field that's linked to value inside a scriptable object, is that possible?
This is what I have and it's currently not working

        var variableRef = new SerializedObject(variable.objectReferenceValue); // references scriptable object
        var variableRefProp = variableRef.FindPropertyOrFail("value");
        Debug.Log(variableRefProp.floatValue); // shows correct value
        var variableFieldValue = new PropertyField(variableRefProp, "Value"); // doesn't work/show```
plucky knot
covert palm
#

Oh thanks, now it works perfectly 👍

glad pivot
#

i must be missing something. _Chance.floatValue = EditorGUI.Slider(chance_Rect, new GUIContent("Chance"), _Chance.floatValue, 0, 100); does not let me change the actual value of the slider. anyone knows why?

glad pivot
#

could it be an issue that im trying to make a propertydrawer for a struct and that is causing it to not be editable?

gloomy chasm
glad pivot
gloomy chasm
glad pivot
#

yeah im aware my naming isnt great, just trying to get it to work clown_dead

gloomy chasm
#
EditorGUI.Slider(chancePosition, _Chance, 0, 100, "Chance");
glad pivot
#

that didnt really change anything

gloomy chasm
#

Also, is the issue that it simply won't slide at all? Also, are you looking at it in a custom inspector? If so, make a new component that just has a single field of LootPoolRarity so you can check there with knowledge that there is no chance of anything else affecting the value

glad pivot
#

yeah, i cant grab the slider or open the window to select an object for the field. im looking at it in the inspector through another script like this

public class LootPool_ScriptableObject : ScriptableObject 
{
    public LootPoolRarity Rarities;
}
gloomy chasm
glad pivot
#

no it does not, should it?

gloomy chasm
#

I was just checking if you might have other code that is affecting it.

#

ooh

#

I know

#

ya gotta override the GetPropertyHeight method

glad pivot
#

right, that is true, i completely forgot that was a thing

gloomy chasm
#

it defaults to just a single line height. So that is why the first field works and can receive input, but non of the others can.

glad pivot
grave elk
#

hey i want to work on a project with a friend, and basically share the files between our computers. Saw that unity collaborators was depricated. and the new version you gotta pay for, which are not my intentions. Github is not possible either since the files ar eover 100mb. Anyone ideas on other free(!!!) solutions?

wild edge
safe sorrel
#

we worked it out (it was a missing .gitignore (also, this was the wrong chat))

glad cliff
#

I want to display all child properties of of my object reference in editor, but despite there should be one int and one string, there is nothing.

// Create a VisualElement for each behaviour
        for (int i = 0; i < _behavioursProperty.arraySize; i++)
        {
            var behaviour = new SerializedObject(_behavioursProperty.GetArrayElementAtIndex(i).objectReferenceValue);
            var childProperty = behaviour.GetIterator();
            var behaviourElement = new VisualElement();
            while (childProperty.NextVisible(true))
            {
                var p = new PropertyField(childProperty);
                behaviourElement.Add(p);
            }
            root.Add(behaviourElement);
        }
#

_behaviours is a list of abstract type, maybe that is the problem idk... I have done this already with IMGUI and it being abstract wasnt an issue, but maybe this new UI doesnt like polimorphism as much? Anyone knows something about this?

visual stag
#

You need to call Bind to get property fields to build in UIToolkit

#

It's called by default in some scenarios, but if you're using your own SerializedObject I think that's not going to be the case

glad cliff
#

oh really? I thought it is used only to... well... Bind a property, not display it

#

ill check that!

#

oh wait... but this way I dont know how to get paths for these properties...

#

I dont know them in advance.
_behaviours holds an abstract type not without a reason

visual stag
glad cliff
#

RIGHT! I totally forgot it is an option... Im still very new to UI Toolkit. Thanks, that solved the problem

glad cliff
#
            var foldCont = new PropertyField(childProperty);
            foldSpace.Add(foldCont);
            foldCont.BindProperty(childProperty);
            var x = foldSpace.Q(className: "unity-object-field-display");
            Debug.Log(x);

Now i have something I cant find explanation for. Instead off adding whole property visual element I want only to add this object display nested somewhere inside, but no matter what way I try to access it, its always null.

#

I tried everything that came to my mind, but its always null. I tried even add this property element and then query its parent to get to this object display, but the same happens

visual stag
#

Bind does not build things immediately, it's complicated

#

you would have to register events to try to detect when it's created

glad cliff
#

ohhhhhh great... it is so unintuitive XD

glad cliff
#

omg that ui toolkit drives me crazy XD
now uss is messing with me

#
.transition{
    margin-top: 30px;
}
.transition > .unity-object-field__selector{
    display: none;
}
.transition > Image{
    display: none;
}
.transition > .unity-base-field__input{
    border-width: 0px;
    background-color: var(--unity-colors-window-background);
}

.transition are property fields, and this top one works, but everything below it does not

#

i cant modify anything nested in this visual element -,-

viral gulch
#

Hi everyone... I'm trying to create and store a ScriptableObject with some bools and floats when my custom editor detects that there is no available configuration file. For that I wrote this constructor, and added the attributes required to the class:

        static ConfigEditor()
        {
            int count = AdvancedBuildSettings.GetSettingsFiles(out List<string> results);

            if (count == 0) {
                Debug.LogWarning("ADVANCEDBUILDSETTINGS: Did not find a configuration, adding a new one for you in the Assets/ folder...");                
/* Line 21 */   AssetDatabase.CreateAsset(CreateInstance<Config>(), "Assets/AdvancedBuildConfig.asset");
                AssetDatabase.SaveAssets();
            } else if (count > 1) {
                Debug.LogWarning("ADVANCEDBUILDSETTINGS: Multiple Configurations found, this can lead to unexpected behaviour. Please remove them. A list follows:");
                foreach(string result in results) {
                    Debug.LogWarning("ADVANCEDBUILDSETTINGS: " + result);
                }
            }   
        }

When I now create a .unitypackage and drag it into another project I get this error, but the file above (hardcoded for testing) gets created. After restarting the Editor, the asset is usable just fine.

Unable to import newly created asset : Assets/AdvancedBuildConfig.asset
UnityEngine.StackTraceUtility:ExtractStackTrace ()
ConfigEditor:.cctor () (at ConfigEditor.cs:21)
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes (System.Type[])

UnityEngine.UnityException: Creating asset at path Assets/AdvancedBuildConfig.asset failed.
  at (wrapper managed-to-native) UnityEditor.AssetDatabase.CreateAsset(UnityEngine.Object,string)
  at ConfigEditor..cctor () [0x0001f] in ConfigEditor.cs:21 
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes (System.Type[]) (at /home/bokken/build/output/unity/unity/Editor/Mono/EditorAssemblies.cs:149)

I have no clue what I'm missing here, and tried a couple of different approaches.

gloomy chasm
viral gulch
#

Well, it's filled with information about the build configuration that's required in the next step, so I'm kinda stuck with that. I was hoping to get some portability into different projects with it (set up once, use often), and save myself tinkering with jsons.

#

But thanks for the feedback, maybe I'll go through a setup screen of sorts.

gloomy chasm
#

Are the settings only used in the editor? If so and you only need one. Then you could use a ScriptableSingleton.

viral gulch
#

It basically stores the original build information here, allowing you to configure different settings for different Host OS and Build Targets. (i.e. When on Windows Host, build IL2CPP for Windows Targets, when on Linux Host regenereate .sln file and build IL2CPP).
It allows you to configure a set of build options for different buildservers, basically. But I have to "reset" to the original ones after building in batchmode locally.

#

It's really targeted towards CI Pipelines with Gitlab and sorts.

gloomy chasm
#

Oh, yeah then a ScriptableSingleton should work great for you!

viral gulch
#

thanks, I'll check the docs 😉

#

I'm more of the backend guy, so I don't do a lot with editor and scriptables 😉

gloomy chasm
gloomy chasm
viral gulch
#

well, that made quick work of it. thanks for helping out.

viral gulch
#

Okay, did have to revert back to not using singletons, as there actually is a valid use case for storing multiple configurations. Aside from that: This little tool just out 5 of our unity projects through our gitlab pipelines, and instead of them being mono builds, they are all il2cpp builds for win/mac/linux respectively, and also pipe their data into sonarqube from build server instead of the developers server. All while the devs can continue to use the mono target while developing if they so choose to.

#

Now to polish and put it in the asset store for the probably 5 people in the world that need this 😉

glad cliff
#

I have a problem for which i found also a thread on a forum, but unfortunatelly without an answer, tho it is I would say a very basic problem...
https://forum.unity.com/threads/repaint-a-whole-inpector-windows.740576/
Overall its about repainting editor window for inspected element in a custom editor while using UI toolkit. Repaint() just doesnt work, and MarkDirtyRepaint() also doesnt fit into this scenerio :/

gloomy chasm
glad cliff
#

then it is logical to assume that I dont

#

the problem is when I add or remove behaviour from my SO

gloomy chasm
#

So you add a behaviour, and..? What do you expect to happen and what does happen and where?

glad cliff
#
var dropdownMenu = new GenericDropdownMenu();
        var types = System.AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .Where(x => typeof(FSMCBehaviour).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface);

        foreach (var type in types)
        {
            dropdownMenu.AddItem(type.Name, false, () => AddBehaviourOfType(type));
        }

        var addButton = new Button(()=>dropdownMenu.DropDown(root.worldBound, root, true)) { text = "Add Behaviour" };
        root.Add(addButton);
#
private void AddBehaviourOfType(System.Type type)
    {
        var behaviour = ScriptableObject.CreateInstance(type) as FSMCBehaviour;
        behaviour.hideFlags = HideFlags.HideInHierarchy;

        AssetDatabase.AddObjectToAsset(behaviour, serializedObject.targetObject);
        AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(behaviour));

        _behavioursProperty.arraySize++;
        _behavioursProperty.GetArrayElementAtIndex(_behavioursProperty.arraySize - 1).objectReferenceValue = behaviour;

        serializedObject.ApplyModifiedProperties();
    }
#

instance of some SO is created and added to a list of behaviours

#

but every behaviour is simply a foldout with some additional logic and then iterating through all of its properties, which are binded to SO fields

#

but SO (behaviour) itslef isnt binded to anything

gloomy chasm
#

Ahh, but then you don't see it in the inspector for your FSMC State, correct? I assume you are manually creating each of the elements for the behaviours in the OnCreateInspector method.

glad cliff
#

correct

#

i finally found some workaround. Basically i dont put everything in root visual element, but i make aother container in it, and then put everything in it. When I need to repaint inspector I just call root.Clear() and populate with newly generated container. It makes the job done, but let's say that you can see in the editor that Clear() was called XD

peak bloom
#

repaint sorta useless in uitk

gloomy chasm
# glad cliff correct

Right-o, that is expected. What you need to do is to create a element that inherits from BindableElement, and bind it to the list. When the value changes, you can then add/remove the behaviour elements

peak bloom
#

you can force it to reconstruct the whole hierarchy

        private void TryForceRefresh(VisualElement container)
        {
            container.schedule.Execute(() =>
            {
                var fakeOldRect = Rect.zero;
                var fakeNewRect = container.layout;

                using var evt = GeometryChangedEvent.GetPooled(fakeOldRect, fakeNewRect);
                evt.target = container;
                container.SendEvent(evt);
            });
        }
glad cliff
gloomy chasm
peak bloom
#

agreed, avoid it if you can 😂

glad cliff
gloomy chasm
glad cliff
gloomy chasm
glad cliff
#

those arrows are not native to edges in graph view

gloomy chasm
#

Yeah, I know.

#

Doesn't change anything about using Repaint in UITk

#

(Not that you should never use it. Just the vast majority of the time it is the wrong answer)

glad cliff
#

well in this case the geometry changes everytime edge moves, so this arrow needs to be re-rendered every time user drags the edge

gloomy chasm
#

How are you drawing the arrow?

glad cliff
#

ofc, repainting like every frame would be stupid for sure XD
but yeah, there are cases when UIT related stuff need to be repainted from time to time

#

here it is

gloomy chasm
glad cliff
#

it is a very awful flashback tbh couse I remember that for a long time i was trying to achieve it without MeshGen as google was meesing with me haaaard XD

#

for hours I googlde stuff like "generating mesh in unity editor" but I never came across MeshGen while searching until someone here on Unity discord told me about it... my blood was boiling man

gloomy chasm
#

Haha, well glad you got it figured out!

errant shale
#
  • Can someone share a link of custom tools (not windows nor inspectors) guide articles/series? All i find out there is related to anything but the in-scene custom editor thing except unity documentation, which is not really helpful for me
gloomy chasm
errant shale
#
  • What lets you modify game objects in the scene directly by dragging, clicking on them etc.. I believe that "custom tool" is an official term for this, isn't it?
errant shale
#
  • Yes, i did. I based my test tool off that, and now i'm lost. Reading anything else in the docs but this example passes through my kettle brain without making any effect, and any non-official article tells me about windows and inspectors, but not tools
gloomy chasm
errant shale
#
  • There are much more problems other than this, but hopefully i'll find a solution myself eventually. I really don't like to bother people much 😄
gloomy chasm
errant shale
#
  • I'm familiar with the concept, and i already tried using scaling slider handle for the resizing purpose. However not only it's inconvenient to use, it acts unpredictably, so seems like it's not an option here. As for the grid, currently it's just a bunch of draw line calls. But this is just a visualisation without any interaction in it for sure, and googling it didn't give anything even slightly related to the topic.
gloomy chasm
errant shale
#
  • Will look into it, thank you
glad cliff
#

If grid isn't huuuuge, nor is created or modified at runtime, i would consider writing something that will actually instantiate a game object for each cell, then if you want some generic inspector for a grid cell then it is simple as making a MonoBehaviour for such cell and writing a basic custom inspector for it.
In case that grid is huge or individual cells will be created at runtime, instantiating game objects will be performance heavy, so then I assume you gonna need a lot of math for it. You could make then a single game object containing information about the grid, but still you will need some cords to track 3D space occupied by each cells, and then do a raycast from mouse position with some math (which I even dont want to try think about) to determine if ray intersects with a cell, as there is no game object with physical geometry so you cant just receive raycast hit.

#

I dont know the context so it is still hard to say. If this grid is gameplay related and not only some data visualizer or smth, then definitely a game object for each cell would be a way to go

#

For expanding and contracting a grid i believe it would be as easy as creating 4 empty game objects in a scene which transforms are forced to be on a single plane, and then some script to dynamically adjust grids metrics based on positions of these 4 game objects. Simply dragging one of these game objects will result in expanding/contracting a whole grid.

gloomy chasm
# glad cliff If grid isn't huuuuge, nor is created or modified at runtime, i would consider w...

I would really never recommend using GOs as handles/gizmos. That has so many side-effects. Saving with the scene (or making sure they don't as the case may be), dirtying the scene (in this case making sure they don't), bad performance for resizing the grid quickly, bad performance when switching out of the tool, bad performance for... anything really. And you have to manage the lifetime of the GameObjects

As an aside about the raycasting thing. The Handles class has a number of methods for getting a sceneview raycasy from a point. And you can use the Plane class to get the intersection point on a cell 🙂

glad cliff
#

The more you know! Never made a scene-based tools so havent used this classes at all, but i believe the premise is not far off

gloomy chasm
# glad cliff For expanding and contracting a grid i believe it would be as easy as creating 4...

Yeah, you could do that, or you could just do this to get 4 handles instead.
No need to fuss with GOs or anything

List<Vector3> positions = new ();
private void OnSceneGUI()
{
  for(int i = 0; i < positions.Count; i++)
  {
    positions[i] = Handles.PositionHandle(positions[i], Quaterion.identity);
    positions[i] = new Vector3(positions[i].x, 0, positions[i].z); // Contstrain to 0 on the y.
  }
}
glad cliff
#

never touched hanles in my life before so didnt know they dont need any physical attachement in a scene XD

gloomy chasm
#

Haha, yeah, it is pretty neat!

glad pivot
#

yesterday i was just looking if anyone had made a property drawer for making quick buttons to trigger methods for debugging. i did find this (https://github.com/madsbangh/EasyButtons/tree/master) but my VS code didnt want to recognize the namespace so it worked in engine but vs code was complainging and i dont know how to fix that. anyone that could help with that?

glad pivot
#

or knows another package that just works straight away?

errant shale
#
  • So, it's that grid thing again. In the docs on tool context there's a comment saying that it can be used for custom selecting logic. Which is actually what i want. Rn the grid still remains a bunch of lines, and the only way to select it is through the hierarchy which is annoying. But as usual, the internet is completely silent about this custom selection logic. Here's what i'm talking about
#
  • And also it's mentioned that tool context is used to " implement specialized versions of the built-in transform tools", which includes the rect tool. And the thing is, i badly want to be able to resize my grid with this kind of tool, i.e. drag any point at the border. As always, i founf no articles on this. Does somebody here have any, or at the very least could point me in the right direction? I would be very grateful
gloomy chasm
#

(I mean it has its own implementation for the transform tools when editing a spline. Not the rect too specifically)

errant shale
#
  • Will check that out. Is it a built-in package, or must i search it up on github/asset store?
gloomy chasm
jagged hawk
#

Is there something special I'm missing? I want this box to have a background color of #3C3C3C but instead it's displaying as #2A2A2A. What's causing that?

This is inside my EditorWindow, and I can confirm it should be #3C3C3C with ColorUtility.ToHtmlStringRGB:

    void OnGUI() {
        GUI.backgroundColor = new Color(0.235f, 0.235f, 0.235f, 1f);
        GUI.Box(new Rect(0, 0, position.width, 32), GUIContent.none);
        GUI.backgroundColor = Color.white;
    }
gloomy chasm
daring temple
#

Please help guys i am trying to use CreatePropertyGUI to create custom attributes with VisualElements and I know unity 2022.2 and later CreatePropertyGUI should work and earlier than that it should just say "NO GUI Implemeneted" because the older unity version still use the imGUI system... That's what you would expect at least, however i am having the inverse affect where i have tried a CreatePropertyGUI in unity 2022.2.4 and even 2023 and it still says "NO GUI Implemented" but OnGUI still works fine. The image shows the code and the output and this is in unity 2023, where VisualElements should definitely work

plush island
#

Is there a way to nest an inspector for a ScriptableObject inside of a ReorderableList or ListView for a custom inspector?

gloomy chasm
glad pivot
daring temple
whole steppe
#

I can't get intellisense to work on vs 2022

#

And External Script Editor just lists the exe for visual studio (devenv) rather than the actual Visual Studio version

grave hingeBOT
#
Visual Studio guide

If your IDE is not underlining errors in red or autocompleting code,
please configure it using the link below:

Visual Studio (Installed via Unity Hub)
Visual Studio (Installed manually)

visual stag
whole steppe
analog laurel
#

If I use

public class SpriteCustom {
  public string key;
  public Texture2D texture;

  public SpriteCustom(string key, Texture2D texture) {
    this.key = key;
    this.texture = texture;
  }
}
  
public List<SpriteCustom> customs = new List<SpriteCustom>();```
I get a decent enough inspector editor for what I need to do
#

However, if I try to add a custom list like so:

public class SpriteCustomTest<T> : List<T> where T : SpriteCustom {}

public SpriteCustomList<SpriteCustom> customs = new SpriteCustomList<SpriteCustom>();```
it is no longer compatible with the inspector.

Is there a way to get the same compatibility without writing a whole custom process?
safe sorrel
#

I want to make a property drawer that draws all of the properties in a row. I have lots of structs that contain two fields, where the second one is a number, so I figure I can just write this thing once

#

my first thought was to write a drawer that just iterates over all of the properties. However, in a list, this malfunctions:

#

(this is after calling Reset on the property at the end)

#

as you can see, it's running through all of the properties in the entire list...

#
        while (property.Next(false))
        {
            // ...
        }
#

if I don't Reset, then it throws an error after drawing all of the properties in a single row

#

the motivation is to avoid having to know the exact name of the two properties to be drawn

#

I think I'm fundamentally misunderstanding how to use the serialized property

#

I switched to passing true for that "enter children" argument, and now...

#

the number on the right appears to be the ID of the SO on the left; changing it turns the reference into a Missing

#

I switched to calling Next(true) once, then calling Next(false) repeatedly, and that appears to be working right

#

curiously, this also meant that the last list in the inspector had its last entry go missing, along with an error complaining that the operation was not possible when moved past all properties

#

just the last list, though. I guess that's because the whole thing gets serialized into one long sequence?

#

calling Reset() makes it happy again. But, again...definitely unclear on the specifics here 🙃

gloomy chasm
safe sorrel
#

Got it!

#

like an end iterator

#

so when I do property.Next(true);, that steps into the struct and gives me the ScriptableObject on the left in that image

#

and then if I did it a second time, it was wandering into the ScriptableObject reference, I guess.

gloomy chasm
safe sorrel
#

Right.

#

Just some internal part of the reference, I guess

#

since changing those numbers was changing the references

gloomy chasm
#

Yeah, you can use property.NextVisible(true) to not get the internal serialized fields

#

Fields with the [HideInInspector] attribute will also be skipped with NextVisible(..)

safe sorrel
#

gotcha

#

ack, mucked it up again

#
        int count = 2;
        var prop = property.Copy();
        prop.Next(true);
        while (count > 0)
        {
            var child = new PropertyField(property, "");
            child.style.flexBasis = first ? 0 : 100;
            child.style.flexGrow = first ? 1 : 0;
            elem.Add(child);
            first = false;
            --count;
            prop.NextVisible(true);
        }
#

perhaps .Copy also rewinds the property?

#

"Returns a copy of the SerializedProperty iterator in its current state." suggests it doesn't, though...

#

it behaves correctly if I just do var prop = property;

#

(and then Reset at the end)

tough cairn
#

anyone knows how to convert anon object to json ? i tried the following

var data = new { roomLink = roomLink, roomName = roomName, secret = secret };
Debug.Log( data );
// output : { roomLink = localhost:8338, roomName = new room name, secret = password35 }
        
var json = JsonUtility.ToJson( data );
Debug.Log("JSON = " + json.ToString() );
// output : JSON = {}

Debug.Log("JSON = " + UnityEditor.EditorJsonUtility.ToJson( json ).ToString() );
// output : JSON = {}
gloomy chasm
tough cairn
#

anonymous object new { key = value , key2= value2 }

gloomy chasm
#

All the same unity serialization rules apply when using JasonUtility

#

Would need to use Newtonsoft.json

tough cairn
#

heh, no other way ?

gloomy chasm
#

You might be able to serialize an array of system.object... maybe...?

#

I don't think so though

tough cairn
#

hmmm

#

sounds like an idea

#

but its not part of the editor dll's lol

gloomy chasm
#

What are you trying to do?

tough cairn
#

JsonUtility.ToJson( new { key = value } )

#

without declaring a class or a struct

gloomy chasm
#

Why are you trying to do that I mean. I am getting the feeling it is not something you should not be doing 😛

tough cairn
#

lol probably not

#

but it should be possible lol

#

i mean it logs out the first line pretty well

#

then the json logs are empty :<

gloomy chasm
#

Why are you trying to serialize something random to json... I feel like there is a lot better way probably...

tough cairn
#

i mean i can just declare a class and fill in the values ... but it would be much more convenient to send post data with inline anonymous object

#

instead of creating 100's of these classes

#
public static void Post( string uri, string json, Action<Result> callback ) {
    var req = UnityWebRequest.Post( uri , json, "application/json" );
    req.SetRequestHeader("Content-Type", "application/json");
    ...
gloomy chasm
#

Why would you create 100's of the classes...?

tough cairn
#

making a rest api , and i need to quickly test bunch of json file structures

#

also the inputs / outputs are not always consistent - sometimes keys will be missing for what the api should return

rough tangle
#

Hey guys !

Are we able to somehow make TextAreas within the editor window scroll-able?

I'm running into the issues where the text is becoming so much that I can't see my buttons at the bottom haha

#

I've been able to make the entire window scroll-able, but that's not quite what Im after

tough cairn
#
using ( var scope = GUILayout.ScrollViewScope( scroll , /* optional */ GUILayout.Height( 100 ) ) ) 
{ 
    // .. your text area gui here 

    scroll = scope.scrollPosition
}```
rough tangle
#

I'll give it a shot! Thanks @tough cairn

#

I assume scroll is a vector 2?

tough cairn
#

yes

rough tangle
#

Sweet! Thank you 😄

tough cairn
#

yw

rough tangle
#

Hey @tough cairn I seem to be getting an error using the ViewScope;

#

Not sure if there is something I'm missing, but it doens't like being invoked as a method

tough cairn
#

notice how i wrapped it inside a "using"

#

if u don't want to use this wrapper u can use these methods instead :

scroll = GUILayout.BeginScrollView( scroll  );

// .. your text area gui here 

GUILayout.EndScrollView();
rough tangle
#

Oeh! Okay that seems to work

#

Sorry new to this 🙂

Noted down for future!

tough cairn
# gloomy chasm Why would you create 100's of the classes...?
public static string AnonObjToJSON(object input)
{
    //dynamic result = new ExpandoObject();
    //var dict = ( IDictionary<string, object> ) result ;
    var dict = new Dictionary<string, object>();
    foreach (PropertyInfo propertyInfo in input.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
        dict[propertyInfo.Name] = propertyInfo.GetValue(input, null);
    var output = "";
    foreach (var kv in dict) output += $"{kv.Key}:" + ( kv.Value is string ? $"\"{kv.Value}\"" : kv.Value ) + ",";
    return "{" + output + "}";
}
#

hehe

#

i might use it recursively for more complex stuff , for now seems to do the trick

rough tangle
#

Hey @tough cairn

One last question in regards to formatting

#

Do you know if we can use hyperlinks or any kind of other rich text like we normally would with TMP?

tough cairn
rough tangle
#

Can this be applied to labels as well? 🤓

#

Looks like iot

#

😄

#

Woooo! Man you're a top tier lad

#

It works!

gloomy chasm
tough cairn
tough cairn
gloomy chasm
tough cairn
#

yeah

finite hamlet
#

I'm trying to update multiple packages from a script

#

but it seems sometimes the process gets interrupted after one package

#

maybe the package installation causes a appdomain reload, cancelling my async routine?

#

I also noticed if you don't wait until one package has installed, any subsequent requests get just ignored

safe sorrel
#

I know that you couldn't multi-select packages to install/remove all at once until recently

#

maybe there's a relation there

finite hamlet
#

maybe I could modify Packages/manifest.json and use Resolve instead?

#

or Packages/packages-lock.json

#

public static PackageManager.Requests.AddAndRemoveRequest AddAndRemove(string[] packagesToAdd, string[] packagesToRemove);

#

oh

waxen sandal
#

Oh yeah, we just edited the text file

manic pilot
#

Not sure if this is the right place to ask, but I'm working on tooling (hand pose relative to object)

Ideally this would be configured by opening a "fake" prefab scene and doing the configuration in isolation. However, this component can be added to any object, including non-prefab ones, so AssetDatabase.OpenAsset(whateverObjectToConfigure); won't work. Any suggestions, or even ideas as to where to look further?

crude forge
#

working on tooling in an EditorWindow... trying to make a selectable list of images that can be clicked on (and selected) or drag-and-dropped into the scene. right now I got to the stage of having a scrollview pane with the images, but not sure how to tackle the next two parts of this

errant shale
#
  • Is it possible to show a helpbox from within a property drawer without implementing a custom editor just for this purpose?
charred inlet
#

I'm looking for a way to "gray out" or remove menu items from the "Create Asset" menu. The [MenuItem] attribute has a validation feature, but [CreateAssetMenu] does not. I want to show or enable my menu item inside the Create menu only when a prefab is selected. Some of Unity's menu items do that (eg "Prefab Variant" or "Create Template from Scene") but I could not find a code example for this. Anyone got an idea to make this work?

#

context: right-click in the Project view, not in the scene hierarchy

gloomy chasm
gloomy chasm
gloomy chasm
errant shale