#↕️┃editor-extensions
1 messages · Page 20 of 1
You can create a custom inspector or property drawer and draw a custom ReorderableList which lists you override all the behavior
There’s a callback for adding a new element
Can I just change the behaviour for lists ? Like I already have a custom for the class I did no want to create other for the array serialization too
Or there is no option ?
I don’t think so. Best bet would be to make a custom property drawer for all lists
But with this I will also need to make changes to the custom serializable dictionary
And every other form of data structure
I mean yea if you have your own custom data type like a serializable dictionary you’d have to implement it yourself for that, but for regular arrays/lists you’d only have to do it once for the base collection type I think.
Yeah but like this default copy the previous think, just fuck all the serialize reference feature
I made it into EditorGUILayout.LabelFields instead.
Now they are all moved over to the extreme left of my screen
Where I don't want them to be.
So how would I control their positioning?
It also didn't actually give me scrollbars 😅
That is because they are being positioned in the “root” layout which is a vertical container the size of your screen. If you want them to live within a certain text, you need to Begin/EndArea which will specify a new rect for the layout to live within
But so is that different from the BeginScrollView I have?
scrollViewPosition = EditorGUILayout.BeginScrollView(scrollViewPosition, GUILayout.Width(consoleWindowRect.xMax), GUILayout.Height(consoleText.Count() * consoleFontSize));
foreach (string line in consoleText)
{
EditorGUILayout.LabelField(line);
counter += 1;
}
EditorGUILayout.EndScrollView();
The whole idea is that you nest layout containers. So within the Area you create a Scroll View and within the scroll view you draw your labels
Sure, I understand the concept. I don't understand how Unity wants me to do it is the thing hah.
Do I make a Begin/End that encapsulates the ScrollView calls?
Do you know if I have acess to the + button call on lists
Do I make a Begin/End nested within the scrollview?
Example (idk if I’m formatting it correctly on mobile, sorry)
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
// List of strings to display
string[] stringList = new string[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
// Scroll position variable for the scroll view
Vector2 scrollPosition = Vector2.zero;
void OnGUI()
{
// Create an area scope to define where elements will be placed
GUILayout.BeginArea(new Rect(10, 10, 300, 400));
// Add a label to indicate what the following UI elements are for
GUILayout.Label("String List:");
// Create a scroll view to make the list scrollable
scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(280), GUILayout.Height(350));
// Create a vertical layout scope to organize the list elements vertically
GUILayout.BeginVertical();
foreach (string item in stringList)
{
// Display each string as a label
GUILayout.Label(item);
}
// End the vertical layout scope
GUILayout.EndVertical();
// End the scroll view
GUILayout.EndScrollView();
// End the area scope
GUILayout.EndArea();
}
}
So I needed several begin/ends
Jeez. Well thanks @wispy delta I'll try that.
And now you use GuiLayout instead I see 😅
You need to draw the list yourself with the ReorderableList type. The docs should show how but I can help if you get stuck
Use EditorGUILayout if it’s in an inspector or editor window
It is an Editor window, yes.
There’s only a couple exceptions like GUILayout.Button bc there is no editor version of that function 🤷♂️
EditorGUILayout doesn't have BeginArea
Ah okay then that’s an exception as well haha
Rule of thumb is to use the editor version if it exists and fallback to the runtime versioning if not
I think I'm close to the finishing line.
Although there are a couple of things
1: The scrollbars are not visible but I can scroll...
2: ...to a degree? I have 40 labels, but it stops at 28.
Ah nevermind, it got all 40
But
I still can't see the actual scrollbars.
Can you paste your full script again
private void OnGUI()
{
lineTex = new Texture2D(1, 1);
leftPanelRect = new Rect(new(0, 0), new(leftPanelHorizontalSpace, position.size.y));
consoleWindowRect = new Rect(new(leftPanelHorizontalSpace + 2f, 0), new(position.size.x, position.size.y - 2f));
GUI.color = grey;
GUI.DrawTexture(leftPanelRect, lineTex);
GUI.color = darkGrey;
GUI.DrawTexture(consoleWindowRect, lineTex);
GUI.color = Color.white;
int counter = 0;
GUILayout.BeginArea(consoleWindowRect);
scrollViewPosition = EditorGUILayout.BeginScrollView(scrollViewPosition);
EditorGUILayout.BeginVertical();
foreach (string line in consoleText)
{
EditorGUILayout.LabelField(line);
counter += 1;
}
EditorGUILayout.EndVertical();
EditorGUILayout.EndScrollView();
GUILayout.EndArea();
}
What is the position field?
position field?
The one you use when constructing the console rect
That is a field inherent to EditorWindows. It's their position in Screenspace.
ok I see. Wasn’t sure in what context this OnGUI script was being called
In EditorWindows all the time
Even setting "alwaysShowHorizontal" and "alwaysShowVertical" to true still doesn't show the scrollbars
Oh I solved it
It's a buffer issue. There isn't enough room.
Ah okay word. Yea it looked right to me
Problem is, I want the window to be expandable "forever" whether it's docked or not.
But I can't quite figure out what the logic is for that.
Here the window is docked. But as you can see on the right side, the bar extends beyond the frame.
Here the window is undocked, but you can see that the horizontal scrollbar extends off into infinity and the vertical is still not visible.
This line is responsible.
consoleWindowRect = new Rect(new(leftPanelHorizontalSpace + 2f, 0), new(position.size.x - 4f, position.size.y - 4f));
Ok, so in the end there is no workaround for serialized reference duplication, on the editor ? Unless a build for every case I need it
You can’t make a [CustomPropertyDrawer(typeof(List<>)), true]? Sorry I’m on mobile and can’t check
What is this use for children that is setting to true
Are you setting the width of the Area rect correctly? That should be the width of the window, the scroll view should let its contents grow indefinitely
I read it but i can’t understand it
Might not be necessary, but you said you wanted it to work for all Lists, so I figure including derived classes would satisfy that
I am unsure. The Rect that I calculate goes here GUILayout.BeginArea(consoleWindowRect); to ensure that the scrollview only grows within that rect.
Hmm. I’m grabbing lunch now but I’ll check back in a bit and give it a closer look
position.size.y - 4f gives a slight buffer right above the frame of the bottom of the windows max length.
So that seems to be correct.
But the width is...not working the same for some reason.
Hm i used but the duplication still happen, I guess unity just copy paste the serialize object with everything in it, including the serialize reference
Is there any callback that is, on this object creation so when unity duplicate I can set it to null ?
Okay, turns out that the padding I was needed was equal to the padding I had "added" when I created the rect 🤦♂️
That is so silly.
leftPanelRect = new Rect(new(0, 0), new(leftPanelHorizontalSpace, position.size.y));
consoleWindowRect = new Rect(new(leftPanelHorizontalSpace + 2f, 0), new(position.width - leftPanelHorizontalSpace, position.height));
Watch how I subtract leftPanelHorizontalSpace from the position.width
Now to figure out why the horizontal scrollbar doesn't actually conform to the overflow
Ah okay. Just need to add Width to the Labels
Although some type of overflow system would be nicer 🤔
Yes it’s the addition callback I was referring to. I don’t see any docs for the class (thanks Unity 🙄) but I think it’s list.onAddCallback
I’m think it would look something like. Not at a computer so idk what the exact implementation is
private void OnAdd(ReorderableList list)
{
if (Attribute.IsDefined(fieldInfo.FieldType.GetElementType(), typeof(SerializeReference)))
{
// If [SerializeReference] is used, then add a new element using your own logic
return;
}
// add a duplicate
}
}
I might be off-base here, but does the BeginVerticalLayout function have an overload for GUILayoutOptions? If so, maybe you need to add the arg GUILayout.ExpandWidth(true)
Well the real issue is that I want word wrapping in the label/text areas.
but that doesn't seem to be an option
For that you just need to make a GUIStyle, enable word wrap, and pass it as an arg to the LabelField method
You can do something like
var logEntryStyle = new GUIStyle(EditorStyles.labelField){
word wrap = true // idk what the field name is
};
Unity did not like that
UnityException: set_wordWrap is not allowed to be called from a ScriptableObject constructor (or instance field initializer), call it in OnEnable instead. Called from ScriptableObject 'HostEmulatorWindow'.
See "Script Serialization" page in the Unity Manual for further details.
HostEmulatorWindow..ctor () (at Assets/Editor/HostEmulator/HostEmulatorWindow.cs:19)
Is that because I cached the style?
private readonly GUIStyle consoleStyle = new GUIStyle() { wordWrap = true };
Yes
Yea putting it there means it gets created from the ctor
Ugh, how annoying. Can't organize anything, Unity will fight you 🥲
do it from OnEnable or in OnGUI you can use null coalescing op to only create it if it’s null
style ??= new GUIStyle(…
consoleStyle ??= new GUIStyle() { wordWrap = true };
Look at how I did it in my first example
I passed EditorStyles.labelField which means the new style is a copy of the label style. If you don’t pass a style to copy it will be a default style
Now I guess the question is, if I want text I can copy from this console window I'm constructing
Would I need to use a bunch of text areas?
Because you can't mark a label
I think there’s a SelectableLabel?? 🤔
But does a label like that also support wordwrap?
The style is independent from the function
Doesn’t matter if it’s LabelField or SelectableLable
Or at least it should t
I had an ephiphany
Why not just mash all text together and put in one TextArea
🤦♂️
private void DrawConsoleWindow()
{
int counter = 0;
StringBuilder sb = new();
consoleStyle ??= new GUIStyle(EditorStyles.textArea) { wordWrap = true };
GUILayout.BeginArea(consoleWindowRect);
scrollViewPosition = EditorGUILayout.BeginScrollView(scrollViewPosition, alwaysShowHorizontal: true, alwaysShowVertical: true, GUILayout.ExpandWidth(true));
EditorGUILayout.BeginVertical();
foreach (string line in consoleText)
{
sb.Append(line);
counter += 1;
if (counter < consoleText.Count)
{
sb.Append("\n");
}
}
EditorGUILayout.TextArea(sb.ToString(), consoleStyle);
EditorGUILayout.EndVertical();
EditorGUILayout.EndScrollView();
GUILayout.EndArea();
}
Idk if that’s the move tbh. Text areas are meant to be editable by the user. You could disable it but might still be weird. And idk if it can be culled optimally. I think it will run slowly for lots of text whereas individual (selectable)labels won’t be drawn if they’re “offscreen”
Any reason not to use selectable label?
I just wanted a text area that could be selected so you can copy the text from there that you'd want 🥲
Like a normal console window
And SelectableLabel doesn’t work?
I mean I can make many labels
But the issue is that you'd have to select every line individually.
Which would be quite tiresome if you needed to copy multiple lines
What is the context for the text? Like what type of info are you trying to display
It logs traffic between a host and client.
So you want to be able to select the text of more than one log at a time? I didn’t think you could do that in the builtin console, but if you do want to do that you might need to use text area - or just use a selectable label and concatenate the strings
No like the command line
Not Unity's console
Just like a command line window, you can copy any number of lines
I gotcha. Yea then I I think a disabled TextArea, like you said, is what you’d need to do.
How do I disable being able to edit but can still copy-paste?
Or sorry, not copy paste
but just copy the text in it
For a lot of text do you know off the top of your head which would be faster? I figured text area might be but wasn’t sure
Yea I wasn’t sure if SelectableLabel wasn’t meant for large amounts of text, but if it doesn’t chug for your needs +1 to selectable label.
TextArea ux = select/type
SelectableLabel ux = select
I have made a simple system for culling. I can set an int in my script to a number and the Queue I am using will start dequeueing entries until the size of the queue is the size of the max size I set. This should mean that the log should never overflow to the point of slowing down rendering in cases where the TextArea might grow too big.
That might mess with the scroll bar no? Unless you’re okay with not showing older entries
Well, it's a tradeoff
Since you mentioned TextArea can't cull
If the TextArea grows to the maxmium number of lines I set it to, then the scrollbar will never change size from that point on anyway.
Oh that’s not what I was saying - I just wasn’t sure how either handled culling
Sorry for confusion. I would just let it show the whole contents and if perf becomes a problem revisit it. You could paginate it or find a more complex solution
This is what happens if I use SelectableLabel instead btw
It shrinks vertically for some reason
I can still scroll in that little box so I can see that all the text is present
But the container itself is just very squished
So it’s not word wrapping and the selectable label has its own inner scroll view?
Might need to pass GUILayout.ExpandWidth and/or Height
ExpandHeight makes it take up the parent containers height, however it does not have any scrolling past what the parent container has.
I think at this point I'll be satisfied with just having the TextArea
Already spent too much time on what is admittedbly a very small UX thing in this tool 🥲
Thanks for the help though
Np. If you do wanna continue down the ux rabbit hole, I think you can fix it by doing consoleStyle.CalcSize(new GUIContent(sb.ToString());
Which calculates the unconstrained size of the text content for the given style
and then set the size of the selectable label to the calculated size using GUILayout.Width/Height
When you decide to use reflection and recursion to deeply compare two ProjectBrowser objects 🙃
How can I add to the Tile Palette brush settings on a custom brush? I want to put some text or images that hint at usage of the brush in red area. (it would need to be referenced too often to just be in documentation)
I'm guessing it has to do with TilePaletteBrushInspectorElement and/or TilePaletteBrushInspector but I don't know how to add to or edit that (besides adding variables in the brush class)
yo! i couldn't find out what this window was called so I couldnt google it correctly. I wanted to know if there was a way I can add my own categories here. Something similar along the lines of [CreateAssetMenu] kinda thing
hmm, is it possible that if i put Editor folder in Plugin folder it does not get ignored when i build cuz i am getting exceptions, or maybe cuz it is under assembly ?
asmdef yep
Editor folders in asmdefs are ignored, you should create an asmdef for the editor folder that is only included in editor time
ok will try that
I'm trying to make a dropdown but I can't quite make it work. When I click my button, nothing happens.
// The relevant code that calls the OpenTypeDropdownMenu
...
if (EditorGUILayout.DropdownButton(new(Enum.GetName(typeof(DataType), layout.Type)), FocusType.Keyboard))
{
OpenTypeDropdownMenu(layout.Type, index);
}
...
private void OpenTypeDropdownMenu(DataType checkedType, int entryIndex)
{
DataType[] values = (DataType[])Enum.GetValues(typeof(DataType));
List<string> names = Enum.GetNames(typeof(DataType)).ToList();
int checkedIndex = names.IndexOf(Enum.GetName(typeof(DataType), checkedType));
int picked = EditorGUILayout.Popup(checkedIndex, names.ToArray());
if (values[picked] == checkedType) return;
else
{
dataEntries[entryIndex].Type = values[picked];
switch (values[picked])
{
case DataType.Void: dataEntries[entryIndex].Value = ""; break;
case DataType.Bool: dataEntries[entryIndex].Value = "false"; break;
case DataType.Int: dataEntries[entryIndex].Value = "0"; break;
case DataType.Float: dataEntries[entryIndex].Value = "0.0"; break;
case DataType.Long: dataEntries[entryIndex].Value = "0"; break;
case DataType.String: dataEntries[entryIndex].Value = ""; break;
case DataType.Vector2: dataEntries[entryIndex].Value = "0.0,0.0"; break;
case DataType.Vector3: dataEntries[entryIndex].Value = "0.0,0.0,0.0"; break;
case DataType.Color: dataEntries[entryIndex].Value = "1.0,1.0,1.0,1.0"; break;
case DataType.Quaternion: dataEntries[entryIndex].Value = "0.0,0.0,0.0,1.0"; break;
}
}
}```
EditorGUILayout.Popup is an immediate-mode selection field, it requires it be called continously so it can be drawn and recieve events
So do I just need to track a boolean for that then?
Or can I do it some other way?
I tried with GenericDropdownMenu but I couldn't make it work because it kept asking me for a VisualElement root
if you want to draw a blocking dropdown, use a GenericMenu
Where it says "String" I want a dropdown to appear with other types.
GenericDropdownMenu is for UI Toolkit, which you could also use, but it's a different UI system and would require you port your editor UI generally
Yeah okay. Didn't want to port at least. I was just trying to get a dropdown which seems like a hard ask 😅
Just use GenericMenu as I mentioned
Okay. Will try that.
Though, if this whole thing is just an EnumPopup, use that instead of this "dropdown button" concept
Is that a separate class?
As long as I can do something once the type is picked then it's probably fine
Seems there is a problem with using the EnumPopup or I'm using it wrong.
I have multiple entries that each might have different types
However when I use the EnumPopup as in the example, it changes the type of all the types currently in my entries list at the same time.
The problem is likely to do with your code
contextMenuTypePicked = (DataType)EditorGUILayout.EnumPopup("", contextMenuTypePicked);
if (EditorGUILayout.DropdownButton(new(Enum.GetName(typeof(DataType), layout.Type)), FocusType.Keyboard))
{
OpenTypeDropdownMenu(layout.Type, index);
}
I use it like so.
And the menu does appear as expected
however it changes the type of every entry in my list
This is just default. But if I change the Void to an Int for example.
It changes both
your code isn't showing how this loop works
private void DrawDataEntries()
{
for (int index = 0;index<dataEntries.Count; index++)
{
DataEntryLayout layout = dataEntries[index];
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Type");
contextMenuTypePicked = (DataType)EditorGUILayout.EnumPopup("", contextMenuTypePicked);
if (EditorGUILayout.DropdownButton(new(Enum.GetName(typeof(DataType), layout.Type)), FocusType.Keyboard))
{
OpenTypeDropdownMenu(layout.Type, index);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Key");
layout.Key = GUILayout.TextField(layout.Key);
GUILayout.EndHorizontal();
switch (layout.Type)
{
case DataType.Void: continue;
case DataType.Bool:
GUILayout.BeginHorizontal();
if (bool.TryParse(layout.Value, out bool result))
{
layout.Value = $"{GUILayout.Toggle(result, "")}";
}
else
{
layout.Value = $"{result}";
GUILayout.Toggle(result, "");
}
GUILayout.EndHorizontal();
break;
case DataType.String:
GUILayout.BeginHorizontal();
GUILayout.Label("Msg");
layout.Value = GUILayout.TextField(layout.Value);
GUILayout.EndHorizontal();
break;
}
if (GUILayout.Button("-"))
{
for (int layoutIndex = dataEntries.Count - 1; layoutIndex > -1; layoutIndex--)
{
if (dataEntries[layoutIndex] == layout)
{
dataEntries.RemoveAt(layoutIndex);
break;
}
}
}
EditorGUILayout.Separator();
EditorGUILayout.EndVertical();
}
}
The code was exactly 5 characters too long ugh. Had to remove some spaces.
I don't understand, contextMenuTypePicked is not in this scope, so of course it will affect every instance of the loop, it's not even declared in the loop
It's declared outside of it, just like the example...
But the example isn't doing what you're doing; it's an example
Well yes. That is why I'm asking for help. To rectify the issue.
Do I need to use an enum value per entry instead?
Yes, presumably layout.Type in your case
thanks a bunch!
Hi, how do I make the editor show me a message when i try to build? I usually forget to update the version numbers and such for my game-
Use a custom edtior instead of the build function or automate the process
I'm working on an editor tool to help me make levels for my game and I'm wondering is there a way to make it so when you Instantiate an object in the editor prevent the new object from being selected by the Selection.activeobject variable?
I would expect that they are not ? You could always save the Selection.activeobject value and reinitialize it after you instantiate the object.
Yeah that seemed to work, but I had to do it in a weird way because the instantiation of the new object would make the selection instantly take focus away from the object I wanted selected.
But since the object I wanted selected needs to be run in a certain case I just checked if the Selection.activeobject was equal to the gameobject I wanted selected and if it wasn't just set it.
I have an asset that I use to store some data that I create with AssetDatabase.CreateAsset. I want to save a list of some other data in the same asset file, so I'm using AssetDatabase.AddObjectToAsset for each list element.
When I want to load them back I'm doing AssetDatabase.LoadAllAssetRepresentationsAtPath and then casting the results to the other data type, but I get an InvalidCastException. Are these the wrong functions or is it something else?
Seem to me that you try to cast the wrong asset. Inspect the type of the object to see what you are actually loading.
I wanna do a custom editor for a custom tile palette, then i would like to show the texture and then select tiles of the palette with the mouse and then modify specific attributes of selected tiles. How can i do a canvas on the window where i can interact with the mouse?
baseTriggerGroup = EditorGUILayout.BeginFoldoutHeaderGroup(baseTriggerGroup, "Base Trigger");
if (baseTriggerGroup)
{
EditorGUILayout.PropertyField(_showInPlayMode);
EditorGUILayout.PropertyField(_triggerOnce);
EditorGUILayout.PropertyField(_triggerMask);
EditorGUILayout.PropertyField(_isProp);
EditorGUILayout.PropertyField(_dependentOn);
EditorGUILayout.PropertyField(_remoteTrigger);
EditorGUILayout.PropertyField(_deactivatedBy);
}
EditorGUILayout.EndFoldoutHeaderGroup();
I have this code to create a foldout group. However _deactivatedBy is a List<> is creating an error in the inspector. I understand the problem but I wonder how I can still bring a list, which is also some kind of foldout, into a custom editor foldout? What's the way to do it then?
Is it a bug that this Closing event doesn't trigger on this errror but Opening does?
PrefabStage.prefabStageOpened += OnPrefabOpen;
PrefabStage.prefabStageClosing += OnPrefabClose;
Any idea how to get AssetPreview.GetAssetPreview() to work with hdrp decal projectors that are prefabs ?
Does anyone know if there's a way to obtain the context of a log if not specified in case Im making my own ILogHandler?
Can't you just use normal buttons? Like GUI.Button/GUILayout.Button with the tile's texture as the content (if you are using IMGUI).
Idk what would be faster. Maybe UIToolkit but I'm not familiar with that
Uhm other questiln in unity custom editor it is possible put a lot of elements o a panel that can be scrolled ? Because if i do osmal idea i will need to put all those buttons in the inspector
thank you
so this example from Unity UI Builder, and when we click those button in red circle....unity open the relative file scripts in text editor....my question is HOW?
OpenAsset
I'm looking to create a direction gizmo that I can manipulate in the sceneview. Kinda like some of the gizmos in the vfx graph. Any ready made thing I can yoink. Plowing through the gizmo code for the vfx graph is kinda tough
I have the code. The class itself is private I cant do MyCoolGizmo:VFXGizmo
You can duplicate the package or simply recreate the class
sure but I dont want to do that just for a silly gizmo
Then deal with it... You have two solution, if you do not want to use them it is your choice. The class being private make sense, in my opinion to be honest. It has not been made to be use in other context.
I'm in the process of making a Perception component that has a list of Senses (Serializable objects). Each Sense has a confidence evaluator (also a Serializable object). This evaluator has a custom PropertyDrawer that uses a ReorderableList so that I can include custom functionality on the AddDropdownCallback. However, when I add an item to an evaluator in a Sense, it is also added to all other Senses. Is there a way to stop this so that each sense can have a unique evaluator?
You have to be careful about caching data in a PropertyDrawer. It's reused by default.
If this is the case, then how can I use a ReorderableList with a GenericMenu? To my understanding, the ReorderableList needs something cached in order to know what to draw; and the GenericMenu needs something cached in order to know where to add items.
You can disable caching by overriding CanCacheInspectorGUI. Or you can cache your data in a static Dictionary<SerializedProperty, TValue>.
Is it possible to force the inspector to repaint from a PropertyDrawer?
I catch an exception in my GetPropertyHeight method, which is resolved once I manually manipulate the Inspector or return to the object after selecting a different object in the Hierarchy.
how do you listen for changes to serialized properties ?
is that possible?
serializedObject.FindProperty("_scale").OnChange += something like this but it doesnt have such an option
uitk binding does something like this iirc
yeh but dont want a ui element involved
I mean you can look at how they do it
i dont see any example of where unity do it
Is there anyway to customize the style of EditorGUI Slider? Specifically I want to draw an IntSlider in my editor window and I want it looks like a ruler with scales
and question 2: anyway to split the editor window into 2 pages side by side?
what unity classes / functions / methods do I need to look into to make something like this
This is how the menu of a scriptableObject looks, but I want to recreate something similar as a Custom Editor for a script I have
Reorderablelist
I'm creating a "context menu tree" of options via EditorGUILayout.Popup() (by specifying child options with the slash.) This works fine except the context menu looks like it's a straight Windows control - totally different appearance than the rest of the IMGUI controls (such as the dropdown created by EditorGUILayout.EnumFlagsField().) Does Unity have something with similar functionality that utilizes the normal IMGUI visuals?
Not the exact thing you asked for but just letting you know that this exists https://docs.unity3d.com/ScriptReference/IMGUI.Controls.AdvancedDropdown.html
Neat customizable dropdown with a search. Not sure if it supports selecting items, though. You know, the checkmark
Similiar to what shadergraph has. Or the add component -menu
I had seen that but haven't yet played with it. Will give it a closer look.
Probably a style. You can look into https://github.com/DefaultLP/UnityEditorStyles
How can I customize this Script Icon? I'd like to add my custom icons so it's visually more separatable
Simply select the script in the project folder
In the top left of the inspector you should see a button to change the icon
From there select one of the default icons or anything that you want!
ah thanks easier than expected
Can you maybe give me a last hint how to disable the Gizmo Icon rendering by default? Cause I intentionally just want the icons to be visible in the GameObject's component view and not necessarily in the scene itself since it's quite spammy
I have 2 arrays of the same length. I want to render them where both arrays appear combined for each corresponding item. So like a box group with one field and then another field. Is there an easy way to do this without creating another array with the data paired up?
I tried using a property drawer but it seems to apply the attribute on each element rather than the array field itself.
Sorry for thr late reply, I was sleeping 🥱
You can go under the gizmos drop-down on the scene view tab
And there you can either change the size of all 3d icons
Or if you scroll down you should be able to disable giz os for only that script
Creating an editor for the component is your best bet if you don't want to create one type that has both arrays
Any idea what's wrong here? i breakpoint SetLabels call, it does happen, but no labels are added to prefab
public class Kek : AssetPostprocessor
{
private void OnPostprocessPrefab(GameObject g)
{
var isGhost = g.TryGetComponent(out GhostAuthoring _);
var labels = AssetDatabase.GetLabels(g);
const string ghostLabel = "GhostPrefab";
if (!labels.Contains(ghostLabel))
{
if (isGhost)
{
var newLabels = new string[labels.Length + 1];
for (int i = 0; i < labels.Length; i++)
{
newLabels[i] = labels[i];
}
newLabels[^1] = ghostLabel;
AssetDatabase.SetLabels(g, newLabels);
}
}
else
{
if (!isGhost)
{
var list = labels.ToList();
list.Remove(ghostLabel);
AssetDatabase.SetLabels(g, list.ToArray());
}
}
}
}
How do you instantiate a custom IMGUI control, e.g. https://docs.unity3d.com/Manual/TreeViewAPI.html ?
That's one of the examples at which I'm looking. It instantiates an entire window, though. How do you create such a control in identical fashion to something like GUILayout.Button()?
Unrelated question...I get the super basic "EditorGUILayout is intended for the editor" and "GUILayout" is intended for the game...but not why there's both a GUILayout.Toggle and EditorGUILayout.Toggle but only a GUILayout.Button and not an EditorGUILayout.Button. Can anyone clarify?
@waxen sandal ...actually, to be clear...I'm doing all of the serialized setup noted in the text you posted. My issue is that I'm in the middle of something else's OnGUI() and need to be able to inject the tree list into that - e.g. after a few buttons, toggles, etc.. Should I just call its OnGUI() from within that other OnGUI as is being done in your text? I've tried that - not seeing the list and it's breaking some other functionality. Would help narrow the issue down if I knew that yes, in fact, calling the tree list's OnGUI() from another thing's OnGUI() is the recommended way of rendering such things.
The tree view needs to maintain state and thus it has to be kept somewhere outside of OnGUI
Where you call OnGUI on it doesn't matter all that much
I have done that - works in similar fashion to the text you noted above.
@waxen sandal ...found the problem - control flickering to life. Thanks.
What was it?
I'm integrating all of this into an XNode graph. The problem was that while new nodes were getting their serialized data structure initialized the old ones were not.
Ah that would explain
What's the recommended method of positionally integrating a custom control like this into an existing layout of controls? That is...TreeView's OnGUI() requires a Rect, which is absolute and completely overrides any current IMGUI control positioning. So, it just plows over any Buttons, etc. that I've already rendered. I'm assuming - but haven't yet found - that there's some sort of IMGUI control position - the location where the next control would be placed - that I could read and use to seed the Rect fed to the TreeView, and then manually update (e.g. IMGUI.Position.X+=TreeView.Height) so that the controls I place after the TreeView were rendered below it. Is there a better way?
Thanks again.
I'm calling GetControlRect(). Seems to always pass back (0,0,1,1) so not sure exactly how it's supposed to function. By default passing that Rect into the custom TreeVIew does place it correctly but it's only a single line high. So, I set the height of the Rect returned from GetControlRect() to EditorGUIUtility.singleLineHeight*3.0f and, as expected, the TreeList is now three lines tall. So, that's all good. The only issue is that the next control rendered in the OnGUI() function now overlaps the TreeList - shows up one line below the start point. So, I am getting the custom control positioned right but the proper amount of space isn't being skipped. Any ideas?
Ah ok yes I was aware of that. I thought of something more default configured since I don't want to spam the scene of users of my asset right away 😄
Uhh I think that is probably something about XNode causing that
Ok, so on the assumption that my problem might be with XNode I'm now aiming to just inject the custom TreeList into a normal component. So, I created a TestComponent that inherits from GameObject that contains the custom TreeList, and then an associated PropertyDrawer for that TestComponent. The PropertyDrawer overrides the CreatePropertyGUI() function, instantiates a root "VisualElement" container, instantiates a PropertyField for each variable, and then adds those to the root container. All of that is working fine. How, though, would I add a custom control like the TreeList to the PropertyDrawer? The variables are straightforward - declared in the component and no further initialization needed. The TreeView and TreeViewState need to be instantiated, though, and the TreeViewState passed as a parameter to the TreeView. How would that be done in this paradigm?
PropertyDrawers generally shouldn't keep state that's not on the target
There might be a UITK treeview though that works for you
But I'm not super well aware of that
@waxen sandal ...I got the TreeList working with XNode via combining EditorGUILayout.GetControlRect() with GUILayoutUtility.GetRect(). Seems too weird to be the recommended way of doing this.
Hi! I have some problem about UIBuilder with Editor. For example, if I have a TextField in my UXML, but I don’t want to directly assign it to a type in MonoBehaviour, but rather process it internally in the editor class first, turning it into other data before passing it to MonoBehaviour, does that mean I can’t use Bind? Or can I bind to the fields of the Editor class? Or Do I have to write such complex silly hard code like root.Q("ElementName").Q("ElementName").Q("ElementName").text to get the value of TextField?
Does anyone know how to get the second line of text like there is here?
Whaat unity using an api that they don't expose? that's crazy
LOL
I was going to see if I can search for "Waiting for Unity's code to finish executing" to see if it was on the C# side by some chance...
Maybe a waste of time
Figures, nothing 😦
I'd reckon it's on editorutility somewhere
But wouldn't surprise me if it's native only
There's DisplayDialogComplex somewhere in EditorUtility
Maybe that
Lots of interesting methods, but looks like it is native only 😦
I think I remember reading a forum post from a Unity developer explaining the logic behind which callstack gets shown there. I think there must be an attribute or a method that can be used to register a callstack to be used here, sort of like ProfilerMarker, but I don't remember reading about one.
I could imagine that. Truly no idea where I would find it though.
Inspect it via GetExecutingAssembly, it often returns garbage tho
Found this, looks like aras first implemented this. Still reading through the replies.
https://forum.unity.com/threads/lots-of-busy-hold-on-etc.833644/#post-5512300
@gloomy chasm This seems to be the last mention of it in this thread, unfortunately:
https://forum.unity.com/threads/lots-of-busy-hold-on-etc.833644/page-2#post-5644144
Yeah, I was on page 7 and not really seeing anything. Guess they never ended up adding it to the C# side 😦
Thanks for looking! 😄
Sure. MartinTilo, who is the UI dev for profiling tools, appears to be still active on the forum, with a post today. He might reply to a thread or a PM.
I should probably not just quote reply to this thread though huh?
Eh, this thread is mainly about something else though, people thinking that the new dialog is causing their slow downs.
But I'd definitely link to his last post about it in the new thread, maybe even ping him directly.
Well here it is if ya wanna watch it or anything https://forum.unity.com/threads/how-to-show-progressbar-window-with-second-line-of-context-like-the-busy-progress-bar.1512770/
Is there a way to change the LOD screen percentage of the fbx file without manually editing the .meta file?
when i hit my ui button for my custom editor which is for a scriptable object the code creates a bunch of assets for the scriptable object. at the end of the code i put this:
Selection.activeObject = target as TestObj;
yet i still lose focus in the inspector for my scriptable object which is very annoying. why is this? and how do i fix it?
maybe the asset hasn't imported yet?
in which case you can prolly force a refresh with AssetDatabase.Refresh() or whatever it's called
and then change activeObject afterwards
also I have a question - does unity's undo system support saving/loading states directly?
more specifically, I have a chain of (a varying number of) undoable user actions, and I want to be able to jump back to a specific point in the history of that object
hmm maybe I can use the https://docs.unity3d.com/ScriptReference/Undo.RevertAllInCurrentGroup.html thingies
yeah I think that's what I want 
You can't undo a specific object, only the top operation in the stack unfortunately.
You can group multiple undo operations together and undo/redo all of them at once. Which is what the linked method does.
Isnt it possible to bind a property field to a ScriptableSingleton?
public class TextsList : ScriptableSingleton<TextsList>
{
[SerializeField] public List<string> Texts = new();
public void SaveData()
{
Save(true);
}
}
public class TextsEditorWindow : EditorWindow
{
private void CreateGUI()
{
var root = rootVisualElement;
var list = new PropertyField();
var serializedObject = new SerializedObject(TextsList.instance);
list.BindProperty(serializedObject.FindProperty("Texts"));
root.Add(list);
Button button = new Button(() => TextsList.instance.SaveData()) { text = "Save" };
root.Add(button);
}
}
Cause I get a list that cant be edited
You need to call Bind(serializedObject) on the root as well
var serializedObject = new SerializedObject(TextsList.instance);
root.Bind(serializedObject);
it changes nothing :/
yeah that's what I need
Ahh okay I misunderstood then. Yeah that method is what you want exactly then.
such use case for ScriptableSingleton is not documented at all so I was forced to use a hammer, no bindings, just setting up values manually
public class TextsEditorWindow : EditorWindow
{
private void CreateGUI()
{
var root = rootVisualElement;
List<string> textList = TextsList.instance.Texts;
var list = new ListView(textList)
{
showFoldoutHeader = true,
showAddRemoveFooter = true,
showBorder = true,
showBoundCollectionSize = true,
reorderable = true,
reorderMode = ListViewReorderMode.Animated
};
list.makeItem = () => new TextField();
list.bindItem = (el, i) =>
{
(el as TextField).SetValueWithoutNotify(textList[i]);
(el as TextField).RegisterCallback<ChangeEvent<string>>(e => textList[i] = e.newValue);
};
root.Add(list);
Button button = new Button(() => { TextsList.instance.SaveData(); }) { text = "Save" };
root.Add(button);
}
}
Something is not working for me, I would like to make the IfCode array appear only when "if" is entered in the CodeLine
using UnityEngine;
[CreateAssetMenu(fileName = "New EnemyAI", menuName = "Mod Tool/Enemy/New AI")]
public class AIScriptableObject : ScriptableObject
{
public string AI_Name;
[SerializeField] public Classes[] VoidFixedUpdate;
[System.Serializable]
public class Classes
{
public string CodeLine;
public Classes[] IfCode;
}
}
[CustomEditor(typeof(AIScriptableObject))]
public class AIScriptableObjectEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
AIScriptableObject aiScriptableObject = (AIScriptableObject)target;
for (int i = 0; i < aiScriptableObject.VoidFixedUpdate.Length; i++)
{
SerializedProperty codeLineProperty = serializedObject.FindProperty("VoidFixedUpdate").GetArrayElementAtIndex(i).FindPropertyRelative("CodeLine");
SerializedProperty ifCodeProperty = serializedObject.FindProperty("VoidFixedUpdate").GetArrayElementAtIndex(i).FindPropertyRelative("IfCode");
EditorGUILayout.PropertyField(codeLineProperty, new GUIContent("CodeLine"));
if (codeLineProperty.stringValue == "if")
{
EditorGUILayout.PropertyField(ifCodeProperty, true);
}
else
{
ifCodeProperty.ClearArray();
}
}
serializedObject.ApplyModifiedProperties();
}
}```
ScriptableSingleton seems worse than using a normal, singleton ScriptableObject. The latter auto-saves, whereas ScriptableSingleton forces me to call Save() when changes are made
Why does ScriptableSingleton require Save and use InternalEditorUtility.LoadSerializedFileAndForget and InternalEditorUtility.SaveToSerializedFileAndForget?
Seems more difficult
A plain ScriptableObject doesn't auto save unless you dirty it or use SerializedObject to modify it.
To persist between sessions, a ScriptableObject must be in the assets folder. This causes AssetDatabase updates, requires a hard path to retrive the asset, and cannot be saved to user settings or preferences.
oh ok, that makes more sense
I was also thinking, a ScriptableSingleton that does not persist -- you just want a singleton in memory -- is really easy, I now see the benefit
Yeah, if you want it just during the session it is not needed. But really, I find it nicer and cleaner to use still
Persisting state across domain reloads is super-helpful
I used to rely on an EditorWindow to do that, IIRC
Yeah it really is nice!
There is also SessionState if you just need some simple data
I saw some people exposing some references to the editor in their EditorWindow script so they could assign a VisualTreeAsset for example upon which editor window is built. Before that I didnt know you can expose public variables to editor scripts and I cant find anything documented about it to learn more. I see my public variables for script extending EditorWindow but not for Editor or anything other related to editor only scripts. How does it work, are there any resources about it?
Mostly im interested on what classes can have default references set in inspector. It is a cool idea to assign lets say VisualTreeAsset or a Stylesheet as a default reference for editor window, so it doesnt need to search for it (which is pain to make it relative), but it cant be done for lets say a class extending PopupWindow or Editor :/
The class must inherit from UnityEngine.Object, and only serialized fields in it that inherit from UnityEngine.Object will be exposed
public class MyEditor : Editor
{
// This can be assigned because `ScriptableObject` inherits from `UnityEngine.Object`.
[SerializeField] private ScriptableObject _myObject;
}
can i change the display from none to flex of a visual element when i hover over the :root ?
just register pointer over event
Anybody know how I can create a custom scene draw mode that renders based on some data the objects in the scene have. For example Render all object with a certain component green and those without red. Just like the Contributors / Receivers debug mode works. It seems custom debug modes work only with global shader properties. So the question is how to put the per instance data there, if they even support per instance data. I cant seem to find the source for the build in shader anywhere
does it have to be built in shader based? any would do, just use untextured standard with color
a way to hack around the per instance data can be, i havent tested, adding code that gets called when object is being rendered
then you can set global shader var color before rendering each object based on whatever you need
just tested, wont work
If I would guess, the only possible way I seem to find to change the SceneView rendering is: https://docs.unity3d.com/ScriptReference/SceneView.SetSceneViewShaderReplace.html which would be like, if I am right, https://docs.unity3d.com/Manual/SL-ShaderReplacement.html
The actual other Debug Mode seem to be hardcoded: https://docs.unity3d.com/ScriptReference/SceneView-cameraMode.html
That is, if you use the built in renderpipeline. Scriptable Rendering Pipeline are open source and could be modified if needed. (If there is no actual way to achieve what you want)
(And yes, you can use per instance data that are already present in the original material such as color or texture)
As far as I can tell the scene view debug modes have nothing to do with the srp. I couldn’t even get a hlsl or shader graph to render anything. Only the CG version worked. And when you said you can use per instance data… I was asking how?
You can replace the shader that is being render for every object of the scene by using the function I listed. And, as I stated, you can then use the data in the original materials to feed your shader.
how exactly are you proposing to use said data in original materials ?
besides the data I'm interested in visualizing is not on the material it's on the Renderer
From my experience, you would have to draw the scene whenever you implement a custom ScriptableRendererPipeline. Whenever you start a project with no rendering pipeline, the scene is absolutly dark.
https://catlikecoding.com/unity/tutorials/custom-srp/custom-render-pipeline/
I'm using HDRP not a custom render pipeline
Then, I'm afraid it might be something else you want to do.
I was making a point that you could copy HDRP and modified it how you want.
no I want to recreate the Contributors/Receivers debug mode but for Static/Non Static shadow casters
and I'm telling you HDRP does not render the scene view debug modes
And I'm telling you that you have to render the scene yourself whatever RenderPipeline you use.
So, somewhere in HDRP, it most do that.
Which means, that you could modified that bit of code to do whatever you want.
This is what you are refering to. Arent you sure that it does not use data that is being feed to the shader ?
I'm not at all sure how it is implemented, the furthest I got was a call to the c++ internals
Sorry, I had to go. I wanted to say that if you use URP, you can simply use a RenderFeature. I'm not sure if there is an equivalent here for HDRP. Maybe you could try to add a Custom Post Processing Effect.
Also, my point still stand that you could modified HDRP to your needs if you truly want. https://github.com/needle-mirror/com.unity.render-pipelines.high-definition
I want to create a custom scene debug mode, not change things at runtime
Forget about it
Quickest turn around
You fail to understand that the render pipeline is used to draw the scene aka, in the editor not runtime.
Is there a way to get all prefabs in AssetDatabase that specifically have specific mono behaviour on root game object?
Nope, not unless you use the new Search (QuickSearch). I think you also need to toggle on that feature in the index manager
I need it from code
basically need to avoid creating game object
I need as much performance as possible
and for some reason labels don't work
at least, setting them from code
I don't follow. Can you explain what you are wanting to do?
I need to get all prefabs with X mono at root
I do it frequently
so I need it to be as performant as possible
and avoid accessing prefabs that don't have it
I do it via
AssetDatabase.FindAssets
Right... so you use the Search API. After building the index (slow, but one time) it can find it
haha yeah it 100% has a API I use it for my asset on the asset store 😉
it runs on background instance of Unity editor even. Literally. But that's not relevant to topic too much
What API is that?
is it fast even?
Yuup, very. Faster than the AssetDatabase.Find, as it is actually indexed and multithreaded
No async only. Why doesn't that work?
because I run in a very special context
which is already a background task of Unity
async is no use there
I think you can still run it, no?
if I can't get result synchronoisly, then it's no use
if it blocks main thread for a while- it's fine
once again, this is background task
Idk what you mean when you say "background task" in this case
literally another instance of Unity editor running in parallel to main one
Huh
Not sure why you couldn't suspect the task why it waits for the results?
Regardless, your only other options is to use AssetDatabase.Find and load and unload, checking for the component, or read the asset files to check for them
because task is not mine and I don't have a control over it, as it's partially part of c++ side
yeah, sadly
I want to use labels so bad
oooh
I want to add them automatically in post import
but they just don't get added here
AssetDatabase.SetLabels(g, labels);
does nothing
They for sure should...
You can use SearchService synchronously it looks like after all https://docs.unity3d.com/2021.1/Documentation/ScriptReference/Search.SearchFlags.Synchronous.html
here I reported code
oooooh
I'm stuped
I think I need to pass game object
not monobeh

Wonder what'll be faster then
Huh?
AssetDatabase with labels vs search api
I want to add labels during post import
so basically the lag is spread over time in a way you don't notice
and then AssetDatabase uses c++ side filtering
and avoid creating garbage game objects
which is likely the biggest contributor to speed of my code
nope
that's not it
labels just don't want
-_-
public class Kek : AssetPostprocessor
{
private void OnPostprocessPrefab(GameObject g)
{
var isGhost = g.TryGetComponent(out GhostAuthoring _);
var labels = AssetDatabase.GetLabels(g);
const string ghostLabel = "GhostPrefab";
if (!labels.Contains(ghostLabel))
{
if (isGhost)
{
var newLabels = new string[labels.Length + 1];
for (int i = 0; i < labels.Length; i++)
{
newLabels[i] = labels[i];
}
newLabels[^1] = ghostLabel;
AssetDatabase.SetLabels(g.gameObject, newLabels);
}
}
else
{
if (!isGhost)
{
var list = labels.ToList();
list.Remove(ghostLabel);
AssetDatabase.SetLabels(g.gameObject, list.ToArray());
}
}
}
}
SetLabels get called 100%
newLabels contains 1 element with GhostPrefab 100%
yet no label
how do I make centered button with UITK
with IMGUI I can just insert FlexibleSpace before and after button but I can't find anything for uitk
anyone knows where is the "Jump To State" code in the CsReference ?
( context menu item only visible when in play mode )
try crossfade?
thats fine
I use playmaker to play states and this is the action :
it plays the state direcly
even when there are no connections
normalized time:
great!
does this work?
/* CenteredButton.uss */
container {
flex-direction: column;
align-items: center;
justify-content: center;
}
yes, ty
Hi there 👋
I'm fairly new to the custom editor system and I'm trying to figure out something:
Why should I use serializedObject.FindProperty for each property I want, rather than just do _myScript = serializedObject.targetObject and then access all of my public properties from it ? Is it just so we can access to private serializedProperties ?
Because for now I'm using both but it does not feel right.
So with SerializedProperties, you can access private serialized fields and a bunch of things like Undo are automatically handled for you
Ok thanks, and could you tell me how I can edit my properties without doing _myScript.health = 10 ?
I'm looking for example, or even documentation but I didn't find anything
Is this a custom editor or propertydrawer?
CustomEditor
Annnd I had to ask you to finally land on this https://docs.unity3d.com/ScriptReference/SerializedObject.html
So I just have to serializedObject.FindProperty("health").floatValue = 10; and then serializedObject.ApplyModifiedProperties();
Ok thank you and sorry for my inability to look for the right doc ^^'
EditorApplication.update is keeps running of the plastic scm making unity 2022 editor unusable at all. does anyone has the same issue?
Your sentence makes no sense
Anyone got a clue why m_navmeshOrigin is null
surface is not null, m_navmeshSurface is not null
Hey guys! I have a project with prefabs and codes and I wanna turn it into a package so I can import it to another project. Just like packages from the asset store. How is that possible?
thank you!
Is there a callback for if assets are importing or something? I got a really niche issue. I havea package that has a Overlay that opens by default. It loads UXML. The issue is that when you first add a package, all the scripts are loaded first, before the assets are imported. So the overlay will try to load the UXML before it has imported.
Yeah I was thinking about trying that, though might not happen soon enough. Will be worth a try even if it is a bit of a junky setup
I'm working on a GUI where the scrollview updates (and is updated by) values when they are changed. I can't seem to find out how to 'get' the scrollview off of the reordered list, nor how to give it a callback when the scrollview's horizontal bar is clicked on
any clue on how to do both of these things?
legacy GUI?
public override void OnGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label)
{
// DRAW lave with extra " leftWidth "
// ...
if (Event.current.type == EventType.Repaint)
{
leftWidth = position.width - current_x;
}
}
Am i using the right event here ? or is it just the fact that the draw x position is getting recurrently modified in the loop ?
not sure , but i think i seen something like this in the CsReference where the UnityEditor.EditorGUI.PrefixLabel been implemented
OnGuI gets executed multiple times , one of which is run with a EventType.Layout event
Yeah I know that but if you're just doing something basic like drawing text/buttons/input fields using the normal APIs you do't have to mess with them
trying to figure out how much space is left over after the GUI layout have been run
so i can offset the label with the left over width
this will return the dimensions for the current GUI width
yes
this will only be known after the gui on the right side from the first label has been computed
just wondering if there is a way to capture data post layout event
hence why i tried force the set leftWidth only at repaint stage
should be possible somehow ... GUILayout.FlexibleSpace is a thing after all
ah well its not too important , ill just leave empty white space at the right hand side
I have no idea what is going on. I can't add a field of my FooBar class as a drawn property via the FooBarPropertyDrawer.
Here is the Drawer
[CustomPropertyDrawer(typeof(FooBar))]
public class FooBarDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
var rect = new Rect(position.x, position.y, 30, position.height);
EditorGUI.PropertyField(rect, property.FindPropertyRelative("test"), GUIContent.none);
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
public class FooBar : MonoBehaviour
{
[SerializeField] private string test = "123";
}
And here the usage of the class as property
public class ResourcerScanner : MonoBehaviour
{
[SerializeField] private RenderTexture renderTexture;
[SerializeField] private int resWidth = 1920;
[SerializeField] private int resHeight = 1080;
public FooBar foobar;
}
I receive the error NullReferenceException: : SerializedProperty is null (as seen in the screenshot).
Can someone explain me what I am doing wrong?
have you put [Serializable] on FooBar?
I did not since it's inheriting from MonoBehaviour I thought it's implied.
I now added it but the error still persists
oh right, i didn't notice that somehow
i'm guessing property.FindPropertyRelative("test") in that code returns null? 🤔
i have a property drawer with a custom delete button (calls property.DeleteCommand if said button is pressed).
This drawer then is used for my elements inside my listview, but after deleting a property im meant to rebuild the listview and im kinda confused as to how to achieve this since the button lies inside the property drawer and the SerializedPropertyChangedEvent isnt working (its invoked constantly & rebuilding causing recursion)
i wanted to use onItemsAdded / removed but those only work if i add and remove elements from the listview and not from adding to the item source (and usually my add logics are done inside classes instead of the editor for my use case)
any suggestions?
you are using a custom property drawer for mono behaviour, its not a property, its a serialized object
its a bit more complex than outright doing it like that and i had headahes with something similar a couple days ago
To tl;dr make a custom editor for your mono behaviour (instead of a property drawer) and draw the editor inside your other class
Ohhh ok thanks man! I wouldn't have figured it out on my own
I have a UnityEvent property in my inspector for my component.
I need to access the Type and Method being referenced in the property.
Any idea how I can access it? I only managed to get the method name but to use reflection properly I need the Type, Namespace and Method name
there's static helper for that
var methodInfo = unityEvent.GetValidMethodInfo(MyMethod);
Yeah I found that one - but that's not enough. I need to find the Type info as well which is unfortunately isolated in the UnityEvent instance.
then do it via GetInvocationList
foreach (Delegate delegate in unityEvent.GetInvocationList())
{
MethodInfo methodInfo = delegate.Method;
string methodName = methodInfo.Name;
//Do the rest with the methodInfo
}
note it would behave slightly differently if you're subscribing to it annonymously/via lambda
I give it a try. Thanks so far 🤝
[SerializeField] private UnityEvent<string, string> onResult;
private void Start()
{
onResult.GetInvocationList();
AddResourcerScannerFront();
}
GetInvocationList() is not available for me. What Unity version are you using?
wdym? you're using it there, no?
Nah it's not resolvable
proly I was brainfarted here, @waxen sandal or @gloomy chasm can we do GenInvocationList on UnityEvent? pretty sure we can
Nah UnityEvent isn't a delegate
You can probably find it through serializedproperties
well there you go @unborn wagon see @waxen sandal answer
just this (see the example) 😄
https://docs.unity3d.com/ScriptReference/Events.UnityEventBase.GetPersistentListenerState.html
Also the UnityEventTools class
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor;
public class InspectorView : VisualElement
{
public new class UxmlFactory : UxmlFactory<InspectorView, UxmlTraits> { };
Editor editor;
public InspectorView()
{
}
internal void UpdateSelection(NodeVisual node)
{
Clear();
UnityEngine.Object.DestroyImmediate(editor);
editor = Editor.CreateEditor(node.data);
IMGUIContainer container = new IMGUIContainer(() =>
{
if (editor.target)
{
editor.OnInspectorGUI();
}
});
Add(container);
}
}
i have an inspector window in an editor window i have but it refuses to use custom editors does anyone know why
Hi there 👋
I have a strange behaviour in my CustomEditor.
In OnSceneGUI I do a Physics.OverlapBox and it detects all colliders that are inside 👍
But if my GameObject is a CharacterController, it does not detect it anymore :/
It detects it as soon as I start editing one of the CharacterController properties or if I manually simulate Physics (which I don't want to since Rigidbodies will be impacted)
Do you know why it behaves like that and how I can fix it ?
This is just a guess, but try calling Physics.SyncTransforms first
I had hopes, but no :/
It's really frustrating, all other colliders are working correctly
And in Play Mode I don't have the issue at all
Yeah CharController can be weird
Have you tried modifying some values of the CC from the script?
If modifying it in the inspector works, that might work too
I can't, I'm working on a tool that displays a List of Colliders inside an area.
I don't know in advance what kind of Components will be present
I fear that changing some values, even during one frame, breaks something user's side
Custom Editor in Custom Editor Window Inspector Not working
Custom Editor in Custom Editor Window Inspector Not working
Can a custom editor not be applied to a base type with a child that is a generic, or to the generic type directly, without either inheriting UnityEngine.Object? Seeing examples of custom editors for generic bases but they are monos, so just curious if that restriction is actually a restriction or just an edge case that sometimes works.
Here is what I did in case other stumbles onto that:
// in OnSceneGUI()
var ccs = GameObject.FindObjectsOfType<CharacterController>();
foreach (var cc in ccs)
{
cc.slopeLimit = cc.slopeLimit;
}
With this I change pretty much nothing and CharacterController is finally detected
if a Unity dev is passing by, a little explanation would be highly appreciated 🙂
Ah that's what I was looking for 👍
iirc same thing happens at runtime if the mesh under cc is updated/reimported
my guess it has to do with the fact that cc works on precomputed data baked into triangles
something fails to rebake it or something similar
Is there any callback that runs when removing a component from an object in the editor?
Pretty sure there is no straight forward OnComponentRemove function. There is three solution that can think of:
- Use CustomEditor with OnDisable with the
target == null. - Use ExecuteInEditMode.
- Use a manager that periodically looks for if a component has been removed. In other words, there is a script somewhere that check the difference between the component that it knows of and the component that is actually there.
SO the problem with 1. and 2. is they only seem to work on scene objects. Not on prefabs
I'm using a variety of #3 - basically my custom editor window
and will probably do a pass on build or something
Is it a component being added on a prefab particulary ?
Yes
The whole concept of what I'm building involves adding a component to a prefab to get it to do something special
I'm usually doing scene pass, sometimes prefab pass as well before building.
Notably for the platform variation
What do those mean? I'm new to build preprocessing
Not something unusal
is there more I should look at?
Basically I just want a ScriptableObject to contain a reference to every prefab with this particular component in the project.
A concrete example would be that some platforms do not support reflective floor. So, on those platform I swap the floor at build time.
Have you try to use Addressable ?
That seem like a use case for that.
I don't want to use Addressables, as I'm building an editor tool for other people to use
hoping to avoid adding dependencies
But I'm actually curious how addressables would make this work better?
To avoid loading all these prefabs in memory?
You could address your prefabs in a fashion that would helps you find them back.
Ah see that would require extra work and configuration for my users
The goal here is dead simplicity
you add the component, and it works
And yes, addressable is a most for smaller platform to reduce the memory usage.
However, I really doubt that you would be memory intensive
I will take another pass later at reducing memory usage. Most use cases for this will involve only a few such prefabs being marked per project
Why do you need to have access to those prefab ?
I've seen something simular in the Netcode for GameObject API.
There is two way of doing it, manually dragging them in a list or adding them whenever you want.
This is a necessary to remove the hicup of memory allocation
(You wouldnt want to load every asset necessary when you first load the network library)
I'm trying to go with a low maintenance approach:
- Add to the list in OnValidate() for the component
- Recheck/repopulate the list in a build preprocessor
- Perhaps recheck/repopulate on https://docs.unity3d.com/ScriptReference/EditorApplication-playModeStateChanged.html as well
The first use case I'm going for is for small games with less than 10 of these things
I'm not that worried about the memory impact for now
though I will see how bad this can get because I could see this causing a lot of angst in the editor for large projects
Anyway I'm guessing there's no real way to get an On Removed callback for a prefab component
so I think I have what I need. I'm just curious about build preprocessors
and what you meant by "scene pass" and "prefab pass"
Never used it this one specifically
I used the audio and texture to force specifics settings on the importation previously.
Ah interesting
so it will run once per prefab in the project? That might be helpful...
From my experience, you can easily do a "scene pass" with https://docs.unity3d.com/ScriptReference/Build.IProcessSceneWithReport.html
Although I wonder if it wouldn't be faster/simpler just to do one big AssetDatabase.FindAssets to find them all and build the list at once.
The prefab needs to be worked whenever you build the bundles. (Given that you use AssetBundle)
Ok these are cool though, so thank you
Also, note that the IProcessSceneWithReport does trigger in the Editor when you play it as well.
Really useful
AssetBundles are an interesting use case
I think I will tackle that at a later point but these give me ideas for how to handle them
Going to start with a proof of concept for simple projects without bundles/addressables etc
Addressable is a wrapper on the assetbundle. But, yeah, as a consume of a 3rd party I would prefer if you were to use AssetBundle directly instead of the Addressable
In hierarchy, Upper MicroAudio object is blue because it is connected with prefab
Bottom one is not becasue i created it with editor code, how can i link it with prefab from folder, i have the guid
This is the code for creating it in editor with right click menu
So my question is how to basically make bottom MicroAudio object blue
https://docs.unity3d.com/ScriptReference/PrefabUtility.html
Maybe you could look at: ConvertToPrefabInstance and InstantiatePrefab.
Hmm those are public static yet dont work for me, can find them in docs tho
Just changed this line and it works
Thanks for help, didnt know prefab utility was a thing
I'm experiencing some verry weird behaviour. Under a specific setup the initialization of the MonoBehaviour is Awake, OnEnable, OnDisable, OnEnable, Start. Changes done to the MonoBehaviour in Awake are reverted between the second an OnDisable, OnEnable.
Setup:
- The MonoBehaviour includes a [ExecuteAlways] or [ExecuteInEditMode]
- Duplicating a Prefab (containing this MonoBehaviour) with Ctrl+D, Ctrl+C + Ctrl+V or context menu).
- The prefab is parented to another gamobject.
It can be replicated with the attached script.
I already posted on the forums about it https://forum.unity.com/threads/class-with-executealways-initializes-with-awake-onenable-ondisable-onenable-start-for-parented.1515419/, https://discussions.unity.com/t/class-with-executealways-initializes-with-awake-onenable-ondisable-onenable-start-for-parented-prefabs-in-editor-mode/311315.
Anyone here know what is going on?
I'm experiencing some verry weird
Anyone can help me to my post from yesterday?
if not ill have to post on unity forums and wait 2 weeks again sigh*
this one
can't you just set flag and reset it after rebuilding 
I know it's hacky but entire unity UI is completely hacky, especially if you're on older version of unity
I want to make custom inspector for my serializable class that contains Dictionary with at most 6 key-value pairs, should I use Editor or PropertyDrawer?
So the PropertyDrawer has a button to remove itself from a list?
Well, Dictionaries are not serializable. But basically Editor is for anything that inherits from UnityEngine.Object (like MonoBehaviour does), and PropertyDrawer is for normal C# classes.
Yea basically (i have a check that filters out the button if its not an array member from its path)
the reason im trying the above is just to force a rebuild cause my layout cant keep up and needs forced rebuilding
Yeah you are not meant to use PropertyDrawers like that
how do you set the flag though <__<
is there a way to inject a custom delete button on a property drawer then?
cause thats what im going for
and i understand there is a way but its so freaking ugly
(basically using a hard reference of the casted target variable)
which defeats the entire point of serialized properties...
Just set the makeItem callback along with the bindItem callback on the ListView
And add the button there
You cant ^^
i already spoke with unity directly on that
serialized properties do not support custom views (when bound)
unity told me to directly make a hard reference if i want to do that
Makea hard reference?
im not sure if thats the term but basically getting the variable through something like (MyType)target.myVariableList*
Oooh, why would you do that the heck
Cause thats what they officially told me
my first attempt to begin with was to make a bindItem / makeItem solution with BindProperty
but that crashed my editor
cause "its not supported"
What version are you on?
2021.3 LTS
Ahh, hmm. Do you have a forum link to the conversation you had with Unity, or was it else where?
yea sec
actually the conversation is half like that i wonder where the hell is the other part
im searching for where i discussed hard references (if it was in discord or somewhere else)
but the core point is that i am using hard reference methods to handle editor logic inside some classes i have so i wanted to have access to those as well so i guess thats where it also stemmed from
Anyway i will sidetrack way to much if i begin over analyzing the topic
i just wanted to see whats my alternative to this problem
at this point I just gave up and realized that unity internals are terribly designed so I just go with w/e solution is working even if it's extremely ugly
because most of the time I have to go through reflection to unity internals and there isn't many things uglier than that anyway
This is on 2022.3 and works just fine. Give it a go if you want https://gdl.space/abibohurun.cs
Doesnt work on 2021.3 thats what matters for my project :/
which is weird if it works for you on 2022.3
wth changed
The code I just linked specifically doesn't work on 2021.3? Or do you just mean in general?
Idk for me it leads to some weird GUI artifacts / buggy warnings (check the forum page) and also sometimes it would say "layout is struggling to keep up"
So the code I just linked specifically doesn't work? I am asking because it can be quirky and so if it is not set up specifically a certain way, it will not work.
I am very familiar with the ListView code. Unity's implementation has been fully rewritten about 3 times since it was first added. I have reimplemented my self once to get performance and features I needed. Iirc, one of those rewrites was 2021 > 2022
ill check out once i got time cause im kinda spend tbh
im at it the entire day
ill let you know by pinging you
Oof, understadnable. Been there haha
Any idea why when I open a project in Unity 2023.1.16f1 it hangs on loading the project? Only for one project, as I tried with others and it works. And if I open copies of the project that get blocked, they don't open either. I need urgent help
need help
I have a serializable class, Progression, that stores all of my save data. I can serialize it to JSON and deserialize it back into an instance of the Progression class.
I want to make editor window that can load a save file, let me edit the object, and then write it back to disk.
I'm stuck on how I'd do this, though. I can produce a Progression instance, but...how can I display that in the editor window? It's not a serialized property, so I can't use a PropertyField.
Serialize it into the window
And create a serializedobject from the window (this)
Ah, that makes sense.
the editor window is a unity object, after all
I'm a little fuzzy on what to do if I directly modify the field instead of going through the serialized object
void OnGUI()
{
if (GUILayout.Button("Load"))
{
progression = Serializer.Deserialize<Progression>("save");
}
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(progression)));
serializedObject.ApplyModifiedProperties();
}
do I need to do something to make Unity understand that I've modified the field?
Call Update
Got it 👍
Anyone know where I can find a description of these categories? In particular what is "Essentials" and how does that differ from "Other"?
This is from the Asset Store Tools validator window.
best bet is to look at what unity puts in those, i guess
This helps thanks
Hi there 👋
I'm working on a CustomEditor and when I RegisterValueChangedCallback on a Toggle, the callback is called each time I Select / Unselect my component, even though toggle value has not changed.
Here a snippet:
public override VisualElement CreateInspectorGUI()
{
_visualElement = new VisualElement();
_visualElement = visualTreeAsset.Instantiate();
_visualElement.Q<Toggle>("copyMasterAnimation").RegisterValueChangedCallback(OnCopyAnimationToggle);
return _visualElement;
}
My guess is _visualElement has not finished its Binding process when I register the callbacks and when Binding is done it triggers the Change Event.
So my question is:
How can I ensure Binding is done before registering my Callbacks ?
For now I'm registering my Callbacks in _visualElement.schedule.Execute() and it's working but I'm not sure this is the right way of doing things.
Is there some workaround for dictionaries? Can I just make EditorGUI.IntField and when that changes, I just add that value to dictionary?
Generally people just write a serializable dictionary. If it cannot be serialized, the values will not be saved.
I wrote one my self if ya wanna use it, can even just rip it out and slap it in your project. Or see what I did and do your own thing https://github.com/MechWarrior99/Bewildered-Core
Ok, I will see your github repo
Trying to add a right click context menu to my scene view. While the menu works, in 2022, it seems to force the scene view camera into orbit/pan mode. I saw this topic on Unity forums but no solution posted. https://forum.unity.com/threads/survey-and-discussion-right-click-contextual-menu-in-the-scene-view.1332795/
anyone knows how to stop a TrackPropertyValue?
i want to unsubscribe from one before deleting a property
For future guys who are facing the same problem of "Binding Quaternions" or "TrackPropertyValue" error with deleted property:
I avoided binding into the quaternion itself and instead have 2 levels of binding to avoid any unity crashes anymore:
- Binding into 4 hidden float fields for x/y/z/w of the quaternion (relative property of the quaternion property) and registering a callback that writes all of the 4 fields values on change without notify on the Vector3 field of mine (could also use vector4 for this one)
- Value change callback into the quaternion float3 field which writes back into the serialized property and applies the modified properties
why does unity not natively support in ui toolkit quaternions its beyond me
but anywho thats my solution that doesnt crash or throw errors
Man, I jumped into this this morning, and I'm already feeling so fed up with this. I'm using Dreamteck's splines, and there's a problem rendering a simple 3D cube along a mesh, and for some reason, whenever I create a new 3D cube and try to apply it to a spline channel, Unity is applying my first 3D cube mesh, instead (different pattern/color). It's extruding a sphere just fine, though.
Hello! Posted this in code-general but just saw this channel heh. So, I've been trying to get to grips with overlay scripting but can't wrap my head around subscribing to duringSceneGUI only once. I essentially have a method that draws lines between each selected objects, and call it through my button, but it keeps getting called on repeat. If I try to unsubscribe to my event after my iteration is done the handles aren't drawn. Any insight would be great🥺
The way it works is this basically
// += means basically 'add this method to a list of methods to call when duringSceneGUI is invoked.
SceneView.duringSceneGUI += MyDrawMethod;
// The basic implementation in SceneView.cs ...
private void OnGUI()
{
// Draw RenderTexture of scene from camera...
// This is where MyDrawMethod will now be called, every frame.
duringSceneGUI.Invoke(this);
// Some other drawing code.
}
Thank you! So I see this is executed on a per-frame basis, I'm now troubled as I want permanent handles drawn but only redrawn once I hit my button again. I am indeed a bit lost💀
Hmm, maybe you can share a bit more of what you are doing (maybe some of the code too?)
You are right yes, due to the nature of the work however I'm not sure I can.(I know it's trivial but better safe than sorry I guess😅 )
I'll sum it up however:
void GetObjects{
for all selected objects add them to an array and draw a handle line between them}
override CreatePanelContent{
Create buttons/panels etc.
hook up my button to a toggle method which in turn calls GetObjects via sceneview event subscrition
}
So in the draw method, you just loop over the elements in the array, no?
Yes
I'm sorry if this is a bit trivial but I'm quite new to overlays/editor scripting🥹
No, no all good. We all start some where! So are you not sure how to do that, or is there more to it that you don't know how to do?
Well that's the thing I've got the code down, it draws my handles etc, but once the array has been processed and the handles drawn the GetObjects method keeps getting called. I'm assuming this is due to the per-frame nature of duringsceneGUI?
So GetObjects is being called in duringSceneGUI, and it gets all the selected objects and puts them in a array? And the button is actually a toggle, which toggles this on and off?
Yes, yes indeed!
Weell not really no, just thought there'd be another way hehe
Like if I debug my objects position things get scary..
There is! You can also add a callback to Selection.selectionChanged and do GetObjects from there instead (and call GetObjects once when the toggle is activated)
Ah I see so I would move the callback in my GetObjects method?
Nope, you would have two
// In the initializing method or whatever...
SceneView.duringSceneGui += DrawConnections;
Selection.selectionChanged += OnSelectionChanged;
// Later...
private void DrawConnections(SceneView sceneView)
{
foreach(var go in _objects )
{
// Draw connections...
}
}
private void OnSelectionChanged()
{
GetObjects();
}
Something like that @rapid bronze
I see, thank you so much!
You're very welcome! 😄
Anyone know how to add prefab instances to the scene from script without unpacking the prefab? PrefabUtility.InstantiatePrefab unpacks it unfortunately.
Can somebody help me with this? Trying to make propertyDrawer but only for Dictionary with some types. SerializedProperty.FindPropertyRelative("...") is confusing
All looks pretty good. In your property drawer, try removing line 35 to start with.
Just learned the hard way that vertx's serializedRefrenceDropdown and Odin do not play well together. Is there a way around this? (Stack Overflow and/or hard crashes)
Not sure how to stop the value boxes from appearing to the side like that. Or how to configure the massive gap
If i overwrite the text of the GUIContent it looks like this, there must be a middle ground
You are looking for EditorGUIUtility.labelWidth (maybe it is EditorGUI don't remember)
Amazing
Does anyone have any way to reference different Project tabs in a manner that persists between editor restarts? I've found the .dwlt file which holds the overall layout between restarts, but I can't quite get a handle on how to map that to the different Project tabs after load, aside from probably just re-parsing it myself.
Basically I need to associate some custom data with each Project tab and store this in a ScriptableSingleton.
There are a few hacks I have tried like encoding a decimal value in the float of the maxSize fields, but that gets reset to a hardcoded 10000 every domain reload.
When drawing a completely custom component or drawer manually, how do I let the editor know what size the rect that contains my element is ? The Rect that is returned when calling EditorGUILayout.GetControlRect() has proper position and width, but is only a few pixels height, while the component I'm drawing is around 500 pixels high
Nevermind, I think I found what I was looking for. I used EditorGUILayout.GetControlRect() to know where my control is going to be positionned and its width, then used GUILayout.BeginArea() to define the space I was going to occupy
Can someone explain to me if I am totally off the rails in what I am trying to do, because I'm struggling to make it work, or even find documentation related to what I am trying to do, and I don't know if thats because I'm doing something you're not meant to do or if it's because I don't know what terms to google.
I want to make an object that I can edit through a custom editor window to store information that I will later use in game scripts. I have read that a ScriptableObject is probably the best place to store this. I have create a new class , TileSet, that inherits from ScriptableObject that has a single property on it, public string Test { get; set; }
I have created a editor class, TilesetEditor : EditorWindow which has the screenshotted code.
I have added two TileSet objects to my assets folder. When I open my TilesetEditor I can switch between those two objects using the EditorGUI.ObjectField I defined. I can also type in the GUI.TextField, and switching between the two objects shows the relevant text that I have typed as if it is saving it. If I close unity and re-open it, the text has not persisted against the ScriptableObjects, they are back to being blank.
What am I doing wrong?
is tileSet.Test serialized ?
Pretty sure you have to use EditorUtility.SetDirty on the target after the value changes (and Undo.RecordObject before, to support undo). Or just use EditorGUI.PropertyField
It is, yeah
In honesty the text field is just for testing because it wasn't working - in reality it wants to be a list or array of a new Tile class that will have multiple properties itself, which is why I'm not using PropertyField
Is it part of a prefab ? May be try to use a property field (https://docs.unity3d.com/ScriptReference/EditorGUILayout.PropertyField.html) to test as well instead of a GUI.TextField.
Yeah alright - I'll have a play with it next time I have the project open
Why is the Begin/EndArea() I created being completely ignored here please ?
private Rect lastRect;
protected override void DrawPropertyLayout(GUIContent label)
{
GUILayout.Box("This is above my custom control");
Rect controlRect = EditorGUILayout.GetControlRect(); // This doesn't work by itself
if (controlRect.x != 0 && controlRect.y != 0)
{
lastRect = controlRect;
}
GUILayout.BeginArea(new Rect(lastRect.x, lastRect.y, 1272, 620));
for (int y = 0; y < unitGrid.height; y++)
{
float offset = y % 2 == 0 ? 0 : tileWidth / 2;
for (int x = 0; x < unitGrid.width; x++)
{
UnitSlot slot = unitGrid.grid[x, y];
Rect tileRect = new Rect(x * tileWidth + 15 + offset, y * (tileHeight * (InnerDiameter / 1.2f)) + 10, tileWidth - 30, tileHeight - 20);
Rect dragDropRect = new Rect(x * tileWidth + 25 + offset, y * (tileHeight * (InnerDiameter / 1.2f)) + 25, tileWidth - 50, tileHeight - 50);
GUI.DrawTexture(tileRect, hexagon);
slot = DragAndDropUtilities.DropZone(dragDropRect, slot);
slot.unit = DragAndDropUtilities.DropZone<Unit>(dragDropRect, slot.unit);
slot = DragAndDropUtilities.DragZone(dragDropRect, slot, true, true);
unitGrid.grid[x, y] = slot;
DrawSlot(dragDropRect, slot);
}
}
GUILayout.EndArea();
GUILayout.Box("This should be below my custom control");
}
Because BegainArea has the opposite meaning to how you are using it. It is for doing layout within a defined area, not for doing defined rects in a layout.
You want to use GUILayoutUtility.GetRect to get a rect that is reserved by the layout system. And then draw your stuff within that rect.
https://docs.unity3d.com/ScriptReference/GUILayoutUtility.GetRect.html
Ha great, that's exactly what I needed, thanks !
Has anyone managed to get UI toolkit extensions working with Timeline clips? I'm on 2022.3 with Timeline 1.7.6, and it seems like it just ignores any CreatePropertyGUI() or CreateInspectorGUI(), showing "No GUI Implemented" for them. The IMGUI functions like OnInspectorGUI() are working, however. Is there any way to get it to work with UIE?
problem all along with my issue with serialisation and the likes was I was using properties on my class and not fields...
Actually no, that's not true. Even using fields instead of properties, even using SerializedObject and its respective API instead of access the object and its fields directly, it still doesn't work
no wait no it is working, finally 😅
Does somebody know how i'd change the Skybox for the Scene of a PreviewSceneStage?
RenderSettings doesn't work, that's changing the Scene of the Main Stage
How can I add an extra tab to the ModelImporterEditor with extra settings? Most of the code for that is stuck behind an internal keyword
That or is there a way to not break the existing ModelInspectorEditor by doing something similar to DrawDefaultInspector?
[CustomEditor(typeof(Item))]
public class ItemEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Item item = (Item) target;
if (item._stackable)
{
item._maxStack = EditorGUILayout.IntField("Max Stack", item._maxStack);
}
}
}
im trying to make the inspector only show the max stack property when stackable is true but this dosnt show anything wether it is true of false
not sure if this makes a difference but in the IDE
it says both the ItemEditor class and the OnInspectorGUI have 0 references
I would try using SerializedObject and SerializedProperty instead of directly getting and setting the values from the Item
Haven't tried making an editor for these again yet, but I found that APEX that's a dependency of AI Tree by Renowned Games will break all property drawers, which was probably causing everything to be done with IMGUI instead of UIE, which was the cause of this issue.
That time I couldn't bother with this crap anymore and just decided to set both the serialised property and the values of the object directly. 
I was able to achieve what I wanted using reflection, but I keep getting “did not dispose properly” errors about a previous editor when I call OnEnable and OnDisable. How do I prevent those errors and dispose properly? I’m obtaining the editor by doing CreateEditorWithContext — CreateCachedEditorWithContext didn’t make a difference— and I’m calling DestroyImmediate after I call the ModelImporterEditor’s OnDisable method
I'm unsure if this is the right channel, but I'm using atteneder/glTFast to export gameObject as GLB file. I want to do this during runtime. But I'm stuck on setting the reference on glTFast and glTFast.Export. This is what they say in the documentation:
Note: The GLTFast.Export namespace can only be used if you reference both glTFast and glTFast.Export Assemblies in your Assembly Definition.
I've created an asmdef file in Unity with the assembly definition references to the glTFast and glTFast.Export but I got still in my code the following error: Cannot resolve symbol 'Export'. On this line of code: using GLTFast.Export;
Does someone have an idea how I can fix this?
Is there any built in tooltip functionality for MonoBehaviours themselves? I want to add tooltips for level designers, so they can understand what component is about by simple doing mouse over or something like that
Hey folks, is there a way to know the last scene that was opened before playmode? I'm using SetPlayModeStartScene which makes everything forget what scene I was actually looking at before... I need it for a custom editor
If you are talking about fields, there is [Tooltip("text)]
you could save it in a static variable
Does anyone know how to alphabetize this?
Manually with the order parameter in CreateAssetMenu 
Update to 2023, where all menus are searchable and things have been totally reorganised 😄
Im trying to do something in my editor that involves a lot of reflections because of lacking API, and I would really use some help :/ (I know i shouldnt because it wont be stable, but I need it for just one project)
I have AssetReference field (from Addressables) and there is no special fields for this type, so im forced to use PropertyField which creates IMGUIContainer, as its drawer doesnt implement UI Toolkit field. The question is: how can I get the instance of that drawer that draws this property field?
I already have a type
System.Type scriptAttributeUtilityType = typeof(Editor).Assembly.GetType("UnityEditor.ScriptAttributeUtility");
System.Reflection.MethodInfo getDrawerTypeMethod = scriptAttributeUtilityType.GetMethod("GetDrawerTypeForPropertyAndType", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
Debug.Log((System.Type)getDrawerTypeMethod.Invoke(null, new object[] { assetReferenceProperty, typeof(AssetReference) }));
now I need to get the instance of that type that is used to draw this
SerializedProperty assetReferenceProperty = serializedObject.FindProperty("imageReference");
var assetReferencePropertyField = new PropertyField(assetReferenceProperty);
lol I think I got it but it took a lot of reading code I do not uderstand XD
System.Type scriptAttributeUtilityType = typeof(Editor).Assembly.GetType("UnityEditor.ScriptAttributeUtility");
System.Type propertyHandlerType = typeof(Editor).Assembly.GetType("UnityEditor.PropertyHandler");
System.Reflection.MethodInfo getDrawerTypeMethod = scriptAttributeUtilityType.GetMethod("GetFieldInfoFromProperty", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
System.Reflection.MethodInfo getHandlerMethod = scriptAttributeUtilityType.GetMethod("GetHandler", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo fieldInfo = ((FieldInfo)getDrawerTypeMethod.Invoke(null, new object[] { assetReferenceProperty, null }));
object handler = getHandlerMethod.Invoke(null, new object[] { assetReferenceProperty });
Debug.Log(handler.GetType().GetProperty("propertyDrawer", BindingFlags.Instance|BindingFlags.NonPublic).GetValue(handler));
You could fetch all the names, put them into a SortedList and add them back
How do you do that? I only know about the attribute.
MenuItemAttribute
Is there a context in which you can reorder them?
No, there isn't any way to modify them*
* in some versions there are internal methods you could get to add and remove them, but I have been there and it is a massive pain which I do not recommend doing at all.
There is a "priority" property on menu item that is used for sorting
I might write a script that automatically edits to sort
Right... how are you going to get them, and sort them in a way that the menu respects?
Literally edit the cs files
With a script
You're own .cs files? Cause you can't touch Unity's
Yeah they're mine
Oh I thought you mean just the menu items in general!
Well still I'd prefer not to resort to code generation
Yeah priority property on the attribute is what you want.
When creating custom property drawers that use UI Toolkit (by overriding the CreatePropertyGUI method) is it supported to hold a reference to the SerializedProperty and use it later? As long as you call serializedObject.Update and serializedObject.Apply appropriately?
I'm running into an issue where my custom PropertyDrawer breaks down when rendering these Properties within a serialized list, after initialization (VisualElement CreatePropertyGUI(SerializedProperty) call) the SerializedProperty always ends up referencing the last element in the list if I hold a reference to it. I'm using Unity 2022.3.10f1.
That is because Unity reuses the same drawer instance for each field that it needs to draw
A simple and cheep way to get the reference to the property is to set the .userData of the VisualElement to the SerializedProperty so you can get it later
hey man, any luck with this? it is today I stumbled upon this bad guy.
anyway I solved this, just remove the 'Multiplayer Tools' from your package manager.
hello, I'm trying to create new custom nodes for Unity Visual Scripting.
I'm struggling writing custom inspectors for my classes.
If i have a CustomDataType which has only an int as data member, how can I create the interface so that int can be specified directly in the unit or provided by another unit having an int literal?
Right now I have the same behavior of the AotList. I specified the data type is an int, but I can not set the value by linking a int literal coming from another unit.
See screenshot. I would like to have both, to be capable of setting in the int in the unit or to link another unit having a literal of that (or any other unit returning that data type).
I know in this example it seems useless as it is just an int literal...but the main goal is to use any other more complex data type
the actual problem I'm trying to resolve is the following: I have a custom unit (FactorialDesign) that takes as input a list of some custom data type (DiscreteBalancedVariable).
When creating the units for this custom data types (which I'd prefer to create them as a flow of units instead of using a single unit), I have no way to link them to the custom unit accepting a list of them.
is there a way to show the material preview in the bottom of the inspector without using mesh renderer ?
my component is using GL functions to draw and doesn't need mesh filter / renderer , would be nice to have a the standard material editor to be displayed
something like this ( this obviously doesn't work when I directly create material editor and set its target )
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(GLRender))]
class Inspector : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
UnityEditor.MaterialEditor materialEditor = new UnityEditor.MaterialEditor();
var script = target as GLRender;
if( script == null || script.openGL_mat == null ) return;
materialEditor.target = script.openGL_mat;
materialEditor.DrawDefaultInspector();
}
}
#endif
i think i got it
#if UNITY_EDITOR
[CustomEditor(typeof(GLRender))] class Inspector : Editor {
public override void OnInspectorGUI() {
base.OnInspectorGUI();
var script = target as GLRender;
if( script == null || script.openGL_mat == null ) return;
Editor E = Editor.CreateEditor(script.openGL_mat, typeof(MaterialEditor ) );
E.OnInspectorGUI();
}
}
#endif
how would you properly use it ? i tried implementing it like so but each time the scripts gets recompiled its showing me the error :
IndexOutOfRangeException: Index was outside the bounds of the array.
UnityEditor.Editor.get_target () (at <a53e7cd0bf8c4035ac3e78fb7b43c4a6>:0)
UnityEditor.MaterialEditor.OnEnable () (at <a53e7cd0bf8c4035ac3e78fb7b43c4a6>:0)
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Editor.CreateCachedEditor( GLR.openGL_mat, typeof(MaterialEditor), ref catchedEditor);
catchedEditor.OnInspectorGUI();
}
private void OnDestroy() { if (catchedEditor != null) DestroyImmediate(catchedEditor); }
hmmm, it has gone away when i restarted the project , reloading assemblies doesn't seem to show any errors
Weird, that's how we use it internally
so I'd expect it to just work for you as well
(You do this because you have to destroy the cached editor otherwise you have a memory leak)
will DestroyImmediate do the trick ?
Yeah
is there a way to specify different application name and executable name for mac in build script?
for example on windows I can do
PlayerSettings.productName = appName;
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = new[] { "Assets/Main.unity" },
locationPathName = $"{appDirectory}/{appName}/{executableName}.exe",
target = buildTarget,
targetGroup = targetGroup,
options = buildOptions
};
but for mac it's
PlayerSettings.productName = appName;
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = new[] { "Assets/Main.unity" },
locationPathName = $"{appDirectory}/{appName}.app",
target = buildTarget,
targetGroup = targetGroup,
options = buildOptions
};
and I can't see a way to specify executable name (the one that goes into /Contents/MacOS in the app bundle)
can you show me an example ? i have tried in many different ways , and only sometimes it will render ( right now i only have one material and one game objects that renders , everywhere esle its just left as empty sapce )
i was also looking at csReferences to try and figure out how the inspector automatically shows the material at the bottom for anything that extends RendererEditorBase but without luck
also tried reflection to extend my editor with render editor base but doesn't seem like its possible ...
the only thing I could figure out is moving $"{appDirectory}/{appName}.app/Contents/MacOS/{appName}" into $"{appDirectory}/{appName}.app/Contents/MacOS/{executableName}" but I wonder if there is a better way
Hi! I commissioned someone to make some code for me. In 2019, is it possible for a GUI drag section to detect if a folder has been dragged in? The coder says he has been trying a lot but he just can't do it. Is it possible at all?
Please @ me in reply
how do you make a custom editor specifically for a derived class that inherits from a generic base class
eg MyClass : BaseClass<T>
since T could be anything i dont understand how i would use [CustomEditor] attribute for it
CustomEditor(typeof(MyClass))?
Then just use serializedproperties to iterate and draw fields
that would mean every dervied type needs a custom editor no?
Yes
doesnt seem very efficient
It's not 😛
plus i cant cast the target to the type either
You can also make a base class for the generic
Then make an editor for that and derived types
hm i see
Maybe they added support for generic editors when they added serializedReference but I don't think so
even so i still need the target casted to the type
i dont just need the serialized properties
I mean, you can't make a generic editor for the base type and then cast to the derived types since you don't really know about those
I feel like this is an xy problem
well the base is an abstract generic
so i want the editor to just use the derived type automatically
Maybe you can make an intermediate Editor drawing class that is generic that you create based on the type of your component?
i just tried the generic approach but the base class methods dont get called
kinda confused
OnEnable for example doesn't get called
oh i got it working
finally
hmm ui element functions dont work though
public override VisualElement CreateInspectorGUI() this method doesn't get called
so i cant add my custom ui
Hi, I made this "chance list" class but I can't get it to appear in the inspector when I do:
[SerializeField] private ChanceList<GameObject> _objects;
What did I do wrong?
Inheriting List<T> might be problematic. Which Unity version are you using?
I see now you have no serialized fields in ChanceList, you only have a private _maxChance field. Unity will not display any fields from List becomes it's not a serializable type. Unity has special support for array and List fields to serialize them. The serializer considers arrays and List to be the same thing. It's not expecting any types to derive from List and so doesn't have any special support for those.
ok, what can I do about it?
2022 lts
Inheriting from List is not a great idea. It might seem convenient to and allows you to pass ChanceList around to methods that expect a List, but it doesn't work. Your new methods won't be called if you cast ChanceList to List and call those methods from there.
See here for a demonstration.
You can do this instead: https://gdl.space/obopivizop.cpp
Your class wasn't accounting for all cases where the list can be modified anyway, such as AddRange, RemoveAt, assigning new values with the indexer.
Now you have strict control over how ChanceList is used and can wrap around only the methods of List that you want to be exposed.
is there a way to reference internal unity classes without using reflection? Perhaps with assembly definitions? I'm trying to access internal classes of UnityEditor.CoreModule
Yeah you can have an editor/drawer like [CustomPropertyDrawer(typeof(AssetRef<>), true)] but you are forced to use OnGUI for some reason. Ran into that when I needed a custom editor for that generic type 
forced to use OnGUI? wdym
Generic custom drawers don't use uitoolkit from my testing, so you have to use the imgui functions to render it
i see
CustomEditors are only for classes that inherit from unity classes such as MonoBehaviour or ScriptableObject
You want a PropertyDrawer if it's a plain C# class
I tried to inherit MonoBehaviour and then this happened, thanks for info tho:
Yeah, monobehaviours have to exist on gameobjects and that list just has references to those
You could use ScriptableObjects though
They can be instantiated just like monobehaviour
Is there not a way to just get this in the inspector tho?
The entire point of taking this approach was to simplify loot tables in the long run
Here
Alternatively you can draw the list elements manually from a custom editor for the class that holds that list
so I tried to make a PropertyDrawer but failed miserably, even gpt is not able to help :/
Hmm maybe generic property drawers are not supported, but google about that, maybe theres some hack
If not, you will have to use a concrete class (non-generic, but inherits from the generic class)
I wouldn't say that's the issue.
The first int value is displayed but it starts throwing errors after that for some reason.
I am also not displaying the generic value yet so yh :/
What line is the error pointing to?
ca.intValue = EditorGUI.IntField(position, 0);
Try printing out SerializedProperty.type and see what it is?
If it even does what I think it does
that doesn't even execute, same error:
Debug.Log(ca.type);
Oh wait I think I see the issue
ChanceValue is a property. Properties are not serialized
So ca itself is null
it has a getter for a serializedfield var tho
didn't know you could access private vars, thanks
yeah, that solved it, the issue is that the chance isn't appearing either
Well it's a string but you are trying to get a float value out of it
Use the correct type
Or just change it into a float in the class, I dont see why you would want a string
wdym, it's a float in both places:
[SerializeField] public float Chance;
var c = property.FindPropertyRelative("Chance").floatValue;
It was a string here, I never saw your updated code for that class.
Try drawing it with EditorGUI.PropertyField instead of LabelField and reopen the inspector
my bad on that
I want it to be readonly but will try, thanks
@full cedar Your position rect is using the total height of the propertydrawer
You should set it to single line height before you start using it to draw stuff
Talking about position.height
it took all of this just to get them to display 😭
Yep, propertydrawers are messy as hell
the issue now is that I am not setting the ChanceAmount via the property and the onvaluechanged event is never invoked
that causes the chance to never update aswell as the rest of the chances to enver update :/
I was thinking of manually invoking it in the propertydrawer but it doesn't seem doable :/
It should be possible
property.serializedObject.targetObject to get the object that this drawer is drawing
Can you cast it to (ChanceItem<>)?
gtp just recommended that, will give it a try now
will try
it says to cast it like this as ChanceItem<object>; but idk if it loses the generic properties then
doesn't work either way
Make the class inherit from a base class like ChanceItemBase and cast to that?
Move the Action into that base class and invoke it
I am suspecting that this is becuase I am not inheriting from mb, am I wrong?
Is it safe to find assets by GUID if the project/scripts are cloned across computers? Will the GUID be different, and if so, is there a better way I should be storing references to objects? Storing by path seems non-ideal since the referenced objects could easily change path
Ah right, targetObject points to the MonoBehaviour holding the data, not ChanceItem itself, oops 🤦♂️
I am guessing serializedObject is what I am looking for
property.objectReferenceValue?
nope, both the serializedObject and objRefVal are UnityEngine.Object
is it just me or is this system poorly implemented?
There's a way to get the object, you can google it
Might not be possible... unless the hacky stuff in this answer works https://discussions.unity.com/t/call-a-function-from-custompropertydrawer-of-arbitrary-class/174387
@full cedar maybe you should just draw the ChanceItems manually in a customeditor of the monobehaviour class that holds them
Less pain
If there's further problems, make a thread so we don't flood this channel more
@Enenra maybe you should just draw the
Sadly that's not how it works.
You can't cast a generic parameter to another.
.
Using the as will just return null.
You can do string[] to object[] interestingly. Since Array isn't a generic type.
But you cannot cast object[] to string[] if it's originally built as an object array, even if it contains only strings.
"You can't cast a generic parameter to another."
My terribly made covariant hotbar says otherwise

Would type checking be easier? Yes.
Would that be faster? Probably yes too
Maybe? I was just looking up ways to ease coupling data in a generic type slot without having to always type check.
Well, I do use an interface as it's required anyway
Question:
<uie:ObjectField label="Actor" name="actor" objectType="Conversa.Runtime.Actor" />
This doesnt seem to work, to set up the type of the objectfield in UXML
Does anyone know the right syntax?
Gotta be the fully qualified assembly name iirc. I normally use UIBuilder to set it.
@gloomy chasm In the end I had to set it via code
Hi, I am trying to get a custom drawer for my ChanceList to work but it doesn't.
The add button is confirming that there are elements in the list via Debug.Log() but, as you can see on the screenshot, nothing is shown :/
I have to admit that this is maybe my 2nd or 3rd time working w a custom inspector and I am in way over my head tbh
I don't even know if this is a generics issue at this point or if my code is just straight up bad, the part where the obj is null no matter what is just beyond me.
Another thing, it's really annoying that I had to make my ChanceItem and ChanceItem<T> into a ScriptableObject/MonoBehaviour just to be able to cast the objectReference to them, if that can be avoided it'd be awesome tbh
The list will default to null items, since it's an object reference to a scriptable object. Unless you're assigning the reference somewhere else, obj == null will always be true.
When making custom editors and property drawers, you want to try to stick within the SerializedProperty API as much as possible. So instead of trying to convert the array element into the actual class, just use FindPropertyRelative to access _chanceAmount and Item.
I see, well that's a huge issue I ran into, could easily be solved by not having to use the SO/MB but I can't figure out the cast then :/
I tried to make it cleaner by doing that but will see what I can do, thanks
Then you should also be able to revert the ScriptableObject inheritance change, so it's just a serializable class.
(which will never be null)
Another question, the main reason I did the object cast thing is so that I could call a function that's in the list class/raise the event on the changed list element.
I couldn't figure out for the life of me how to invoke the event without directly casting it to something or even call a function, could you help me with that?
This could also be avoided if I could somehow set the value of ChanceAmount variable instead of the _chanceAmount since it has a setter that invokes the event, again, couldn't figure out how to do that and I think osmal said it's not possible.
Are you sure you want to be invoking an event on a serialized class during edit mode? What's the value in that?
updating all the other element's chances and order in the list
that just seemed like the most logical way to do it tbh
You could just use OnValidate for that tbh
Aren't these objects stored in a mb?
c# classes, no inheritance
But what holds those objects?
well other than from the IEnumerable and the ChanceItem itself
are you asking how I am displaying them in the inspector or where ChanceItems are held?
The latter
ok, the ChanceList<T> has a _list variable which is literally a list of ChanceItems
Where is the ChanceList object stored?
chance list is stored in any other class, for example here:
the approach of writing a custom inspector for that other class is not a good one because the whole point of this was simplifying loot tables in the long run
I've also completely changed the approach of trying to draw ChanceItems to drawing the ChanceList, remember you were helping me yesterday so I thought I should let you know so that you don't have a false perception of what I am doing
OnValidate doesn't even go in a custom editor script
It goes directly on the MB/SO
OnValidate isn't great for this, because they want to make ChanceList<T> reusable, so each script that uses it would have to implement their own OnValidate.
yes, that makes this class not completely independent which is kind of a whole point
I have a similar type, but I don't do sorting or weight normalization. I calculate a percentage in the property drawer and show that next to the weight. Is it very important to you?
to have the chance in the script it self? probably not
sorting would be nice but I can definitely live without that
I was just talking about the sorting and weight normalization.
yeah you actually took a much simpler approach to this, I'll try to implement it this way and thanks a lot
sorting I don't need, weight normalization, not entirely sure what that means tbh