#↕️┃editor-extensions
1 messages · Page 96 of 1
try and remove unnecessary loops with cacheing data
Also, if you are doing anything with meshes, make sure you are re copying the mesh data first into an array or list then referencing that list instead
So my editor script is for a ReordableList of custom serialized classes. I'll probably need to cache everything in a lookup and update that lookup in the add/remove item callbacks
Not doing anything with meshes
in this instance, what I did to alleviate a lot of list elements was 2 different things. I setup to limit which segment of the list I wanted to view at a time, but, also, made the segments size adjustable. I also added each segment to a dictionary so I not only didn't need to iterate over an entire list again for certain data, but, in my loop for displaying GUI had a check to see if that dictionary already exists in the first place, so that it wasn't iterating through a huge list of elements if it didn't need it every time
I'm not sure if you need to use a dictionary if you are good with all the different things that a list can do like indexof and range. Not sure if those involve still iterating over the entire list
I think I'll use a dictionary, thanks for your help!
but in the way I do it now, I can use this for arrays also that doesn't have all the native fancy tools a list has
I think I finally get this iterating through serializedProperties
var props = serializedObject.GetIterator();
if (props.NextVisible(true))
{
while (props.NextVisible(false))
{
if (!serializedProperties.ContainsKey(props)) serializedProperties.Add(props.Copy(), new SerializedPropertyExtension());
}
}
gives me the first depth of child properties
What is your serializedProperties variable?
Dictionary<SerializedProperty, SerializedPropertyExtension> serializedProperties = new Dictionary<SerializedProperty, SerializedPropertyExtension>();
Nice, what is the SerializedPropertyExtension for?
I started working on a class to basically extend all SerializedProperties after doing things with just an array Serialized Property. So I can more control how all the data I want to see is spit out to see
and the way I have it setup made it so in my OnInspectorGUI I do
foreach (KeyValuePair<SerializedProperty, SerializedPropertyExtension> kvp in serializedProperties)
{
kvp.Value.GetSerializedPropertyExtension(kvp.Key);
}
the name get doesn't actually fit for what it is doing, but, I haven't changed it yet
I end up doing a lot of these things in the editor because I'm a solo programmer I've been trying to create reusable tools so that future projects hopefully are alleviated. It as made my game development slower... haha
I feel that lol
this just seems sloppy
public SerializedPropertyInformation(SerializedProperty serializedProperty)
{
serializedPropertyName = serializedProperty.displayName;
this.serializedProperty = serializedProperty.Copy();
if (serializedProperty.hasVisibleChildren)
{
SerializedProperty currentProperty = serializedProperty.Copy();
SerializedProperty siblingProperty = serializedProperty.Copy();
{
siblingProperty.NextVisible(false);
}
if (currentProperty.NextVisible(true))
{
if (!serializedProperties.ContainsKey(currentProperty)) serializedProperties.Add(currentProperty.Copy(), new SerializedPropertyExtension());
while (currentProperty.NextVisible(false))
{
if (SerializedProperty.EqualContents(currentProperty, siblingProperty)) break;
if (!serializedProperties.ContainsKey(currentProperty)) serializedProperties.Add(currentProperty.Copy(), new SerializedPropertyExtension());
}
}
amountOfSerializedProperties = serializedProperties.Count;
}
}
basically repeating now to go through visible properties and add depths accordingly. Am I missing some more useful serializedProperty commands?
What is it that you are doing? Looks like you are adding all the child serialized properties to a dictionary with the value of new instance of SerializedPropertyExtension?
(Really bad name btw. Since it is convention to put extension methods in a calls call class <TargetTypeName>Extensions)
yeah, basically, but, I'm more wondering about the iterating process through it all. Outside of SerializedObject.GetIterator() it becomes a mess to iterate through properties, at least from what I can tell, so wanted to make sure I wasn't missing anything. This all starts in the OnEnable of my editorscript with
SerializedProperty props = serializedObject.GetIterator();
if (props.NextVisible(true))
{
while (props.NextVisible(false))
{
if (!serializedProperties.ContainsKey(props)) serializedProperties.Add(props.Copy(), new SerializedPropertyExtension());
}
}
then in my inspector override
foreach (KeyValuePair<SerializedProperty, SerializedPropertyExtension> kvp in serializedProperties)
{
kvp.Value.ShowSerializedPropertyExtension(kvp.Key);
}
Originally this was just an expansion on a custom list, but, I figured I could go even further and just get all the serializedProperties and display them in a manner I want and add more as I go. For example, I have checking if the serializedProperty isArray and send it down the list extension I have, while, atm, just have the rest being display through EditorGUILayout.Propertyfield and foldouts with some extra info before the foldout to make the inspector way less laggy, but, providing me with info the debug essentially
Should I be calling serializedObject.Update() in OnInspectorGUI()?
Also is it possible to see where all of this garbage collection is coming from?
Is there an editable label control available? I want to be able to double click the label to change it, basically like changing a gameobjects name in the hierarchy.
How can by code revert this?
Change the view mode. But you can only see up to a point.
Nope, gotta do it your self. But it isn't hard to do at all.
Basically when a handful of custom serialized properties in my ReordableList are expanded, the inspector becomes pretty laggy. I tried caching my references to the serialized properties but didn't help that much
Are they using custom property drawers?
No I'm drawing the properties of each class from the custom editor script
I assume you already tried profiling it?
Thanks
Yeah, that's what the screenshot is from
A lot of garbage collection seems to be happening
Go to the detail view and see if it says more specifically where it is being called from.
Where is detail view?
Is most of your code directly in the OnInspetorGUI method right now? If so try splitting it out in to multiple methods that are then called in OnInspectorGUI. That may provide more detailed info in the profiler, but I don't remember.
No most of it is actually in separate methods
how are you getting the data? Storing a references won't matter if you are still iterating over significant amounts of data. As in, if you say you want to view index 3050-3100 and index 6000-6050 in a list of 7000, depending on how you are storing the data for this, are you iterating through the entirety of the list to view these?
majority of it is callbacks for reorderable list
I'm using drawElementCallback to get index of serialized property in the ReordableList, then I draw each of the first depth child properties with includeChildren set to true. I don't really see a better way as everything needs to be drawn
Each base serialized property in the list also has a foldout to control it being drawn or not
When I expand several foldouts inspector becomes laggy
I think that that is just a native problem of the GUI system? Have you tried setting it up in a way that if 1 foldout is open to close the other foldouts?
That's not a bad idea
I added a button that closes all foldouts, but I like that better. Only downside is you can't view multiple element's data at one time
you could get fancy and add different ways to allow this, for example if you hold shift while opening a foldout, it doesn't close other foldouts
you could even go as far as auto close foldouts based off it does cause lag
Yeah that's pretty slick, thanks for the ideas
How many is several, and how many controls are you drawing?
Like 5 or more foldouts open
if you do implement something like auto closing based off lag, I'm not sure how to approach that. Possible do a time.deltaTime calc vs the frames, but, anyways, you may want to implement an EditorGUI.HelpBox() to tell you which segments or whatever were opened to better diagnose the problem
and depends on how many properties the class has, some have up to 5 but could have more
But I can see a noticeable spike in the Profiler each time another foldout is open
How are you doing your callbacks? It is iterating or? (Sorry, not familiar with the ReorderableList, I just have my custom one).
aww, I guess onSelectCallback?
So in my custom editor script I call reordableList.DoLayout() in OnInspectorGUI, then I draw each item with drawElementCallback and calculate height with elementHeightCallback
I'm iterating through child properties twice unfortunately because of this
I maybe could try calculating in draw and caching it for the elementHeightCallback
I've been trying to work with child properties, let me copy over some of the stuff I've been doing and see if it helps at all
not saying it will
but since I'm currently doing similar stuff
maybe
public class SerializedPropertyInformation
{
SerializedProperty serializedProperty;
public SerializedProperty SerializedProperty
{
get {return serializedProperty;}
}
Dictionary<SerializedProperty, SerializedPropertyExtension> serializedProperties = new Dictionary<SerializedProperty, SerializedPropertyExtension>();
public SerializedPropertyInformation(SerializedProperty serializedProperty)
{
this.serializedProperty = serializedProperty.Copy();
if (serializedProperty.hasVisibleChildren)
{
SerializedProperty currentProperty = serializedProperty.Copy();
SerializedProperty siblingProperty = serializedProperty.Copy();
{
siblingProperty.NextVisible(false);
}
if (currentProperty.NextVisible(true))
{
if (!serializedProperties.ContainsKey(currentProperty)) serializedProperties.Add(currentProperty.Copy(), new SerializedPropertyExtension());
while (currentProperty.NextVisible(false))
{
if (SerializedProperty.EqualContents(currentProperty, siblingProperty)) break;
if (!serializedProperties.ContainsKey(currentProperty)) serializedProperties.Add(currentProperty.Copy(), new SerializedPropertyExtension());
}
}
}
}
public void ShowSerializedProperty()
{
EditorGUILayout.PropertyField(serializedProperty, false);
if (serializedProperty.hasVisibleChildren && serializedProperty.isExpanded)
{
EditorGUI.indentLevel += 1;
foreach (KeyValuePair<SerializedProperty, SerializedPropertyExtension> kvp in serializedProperties)
{
kvp.Value.ShowSerializedPropertyExtension(kvp.Key);
}
EditorGUI.indentLevel -= 1;
}
}
}
so this is still being edited atm, not where I want it to be, but, does work
and then
public class SerializedPropertyExtension
{
SerializedPropertyInformation spi;
public void ShowSerializedPropertyExtension(SerializedProperty serializedProperty)
{
if (spi == null) spi = new SerializedPropertyInformation(serializedProperty);
spi.ShowSerializedProperty();
}
is just this atm. This actually had more in it, but, just condensed it
so might not be needed
anymore
Thanks!! I will take a look at this a little later and see if it helps.
this doesn't have my custom list code in it unfortunately because A. I don't think you want it atm if using Reorderable List, and B. I haven't implement my own reorderable functionality yet
but, you can check with isArray and actually then throw that serializedProperty that direction
I'm not sure if this will help you, but, if you don't mind, please provide anything you do find to help! I would appreciate it just because I'm also currently working on inspector stuff
Will do!
Thanks again
I do plan to change these all the statics also since I think I don't need new instances of them all, I just haven't done that yet
Is there a way to detect mouse presses when the mouse clicks a control? The mouse click is only registering in my editor script when the mouse clicks nothing.
Get the click before drawing the control.
I know this was directed to him, but, you need to register to the callback for mouse clicks and have it check if that mouse click is within the rect you want to detect if it clicks in
then disable and renable registering to that callback in the script you want to detect, so that the callback isn't happening when you don't want it to
That actually worked lol, thought I was doing that already whoops
his answers are usually simple and elegant XD
Lol, and I'm just using Event.current to detect mouse
btw, I found out another way to get type for a custom class if you are interested serializedProperty.serializedObject.targetObject.GetType()
I know this is possible because I've seen someone do it, but is there a way that I can edit an already existing window? Like the inspector?
Is there a way that I can change/interrupt/override how the inspector draws its elements?
And if so, where could I go to learn about that
Because when I look up "edit windows in unity" (which I know probably isn't the right thing to be looking up), I just get Unity's beginner tutorials about how to open windows, etc.
But don't editor windows only create new windows?
Instead of replacing the appearance/functionality of an existing one?
I have 2 links in there, check out the second one
Alr, thanks
That only works for Unity Objects though
@fossil raft If it's UITK then it's easy to edit, you can just get the rootelement of the window and then traverse teh tree and do w/e you want
Could you point me to a resource/example because I'm not super familiar with custom editors
There's no resources on how to edit existing editors
Is the closest you're going to get
Is there an event or something similar to detect when a custom editor loses focus?
for editor windows there is void OnLostFocus()
Thanks!
Ohh but that is for a window. Is there something similar for custom editor component scripts?
yes, well kinda
you can use public static string GetNameOfFocusedControl();
and have it do something if the name isn't the window you currently want focus
use it in conjunction with public static void SetNextControlName(string name);
also, GUI.FocusWindow
also GUI.UnfocusWindow
here let me just link the GUI page haha
It might seem confusing because the names have window, but, that is what all of the default unity things are
Unity does all of their things through the methods and stuff we have, they just do it through internal classes
This is just returning an empty string 🤔
Control names are set up by using SetNextControlName. When a named control has focus, this function will return its name. If no control has focus or the focused control has no name set, an empty string will be returned instead.
Depending on what you are doing, you can also check out https://docs.unity3d.com/ScriptReference/Selection.html
like I have a universal editorwindow script that registers to Selection.selectionChanged
Although this doesn't deal with windows exactly, you could potentially use it for inspector changes
This still seems to return the last control for the editor script even when it loses focus, I need something more global
And selectionChanged only fires when a different gameobject in the hierarchy window is selected. Not what I need unfortunately
Basically I'm swapping a Label and TextField to edit it, and I want to swap it back to a Label if the editor component script loses focus
you can try out https://docs.unity3d.com/Manual/InspectorFocused.html
System.Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll") is also how to get the type of it
if that helps you come up with anything
also check out https://docs.unity3d.com/ScriptReference/UnityEditor.html for more indepth editor specifc apis
Alternatively, you can also just use inspectorGUI to "hack" it up and use courintines and stuff if the field hasn't been edited to go back to just the label
I think that a great place to start with custom control development is to re-create the GUI.Button and GUILayout.Button controls since these are straightforward to create and helps to establish some of the fundamentals of custom control development. Our custom button implementation will be used in the exact same way as the regular button controls:
Look at the hot control section
I'm looking for a better way to compare serializedProperty.propertyType == SerializedPropertyType.String a SerializedPropertyType.String also falls into isArray catagory also.
and I know some numberFields also do the same, so, wondering if there is a better way to be more specific?
I saw this way for a smarter way to get the type of SerializedProperty but a lot of the responses made me hesitant
What is the result you are wanting?
How does GetControlID() work? Does it give me the last one created?
I'm just looking to using if statements without else statements lol
What is it that you are doing?
if (prop.isArray && prop.propertyType != SerializedPropertyType.String)
Oh, so, I started expanding upon my serialized properties more, and doing
public void ShowSerializedProperty()
{
if (serializedProperty.propertyType == SerializedPropertyType.String) StringExtension.ShowStringExtension(serializedProperty);
else if (serializedProperty.isArray) listExtension.ShowListExtension(serializedProperty);
else EditorGUILayout.PropertyField(serializedProperty, false);
if (serializedProperty.hasVisibleChildren && serializedProperty.isExpanded)
{
EditorGUI.indentLevel += 1;
foreach (KeyValuePair<SerializedProperty, SerializedPropertyExtension> kvp in serializedProperties)
{
kvp.Value.ShowSerializedPropertyExtension(kvp.Key);
}
EditorGUI.indentLevel -= 1;
}
}
as an example, and if I remove the else if a string for example, is also an array, which makes sense, I'm not arguing that, just if there is a more precise route of comparison
yeah, I was thinking about just doing that, I just wanted to check this other way first
Ah, nope, that is the best you will get. I guess you could use reflection to get the actual System.Type but that isn't going to have good performance.
For obvious reasons.
gotcha! Thanks for looking
I'm using reflection on some of my stuff, could that be why my performance is tanking?
That completely depends on how much and how often you use reflection.
GetType() is very fast, so, if using that, you shouldn't have to worry
Actually I forgot I removed a lot of the reflection so its only being used when I click the add dropdown for my ReordableList now.
part of the problem with reflection is if I understand it correctly (still a noob here, so been picking up these things over time) is that reflection goes through potentially several sections of code to do something. So, usually people advise not necessarily to not use reflection, but, that if you can do something without it, to do it that way first.
some people in the past have also suggested in using reflection like you would Start() and Awake() and component finding and gameobject finding etc... Do it once and make sure to save the reference if you do
Not really? A, it is just a lot of code that runs when using reflection (InvokeMethod's main body is over 400 lines of code). B, it needs to get the metadata, and do error handling and what not. It also wasn't a design goal of reflection to be fast.
Here is a good article if you are interested.
https://mattwarren.org/2016/12/14/Why-is-Reflection-slow/
It’s common knowledge that reflection in .NET is slow, but why is that the case? This post aims to figure that out by looking at what reflection does under-the-hood.
I'll check it out. Thanks!
what attribute i need to add to get this in the inspector. (it.s for an icon/sprite object)
pretty sure that is just an object field as a texture iirc
Any ideas why my dark icon is not applying to the asset?
I'm not sure how you are doing this, but, are you calling anything at all the refresh that area of the editor?
It is done by setting the icon of the script, and having a second icon with the d_ prefix. The editor should automatically use the first for light mode and the second d_ for dark mode. As you can see it is mostly working, but for some reason it doesn't on the actual asset.
you might need to specifically call that repaint. I haven't done this yet to figure out how things are updated, but, you might want to try SettingsProvider.Repaint
maybe even public static void RepaintAllSettingsWindow()
``Notifies the SettingsService that all open Settings windows must be repainted.
Call this function to refresh the Settings windows after external changes to the settings.``
I know you are doing it internally
but, who knows
I appreciate the the suggestions, but that is for refreshing the actually settings editor window. And anyway the issue isn't with repainting, it is simply not using the dark mode one.
yeah. I just thought maybe Unity might be doing something to fail to repaint on their end 😦 sorry then
side note, whenever you asking something it is something I haven't delved into yet, and upon trying to help find an answer, I realize that my knowledge of Unity I think I'm getting is much lower than I thought I had gotten to.... LMAO
So, how does one refresh the UI from an editor window when drawing using a UITK UXML?
You don't? What is the result you are wanting/What is the reason for wanting to refresh a UITK editor?
I edit the UXML, it doesn't reload in my editor window
But it's okay, I already gave up after figuring out that there's no Display property in my version
Ah, yeah you just gotta close and reopen the window.
What do you mean? Do you mean for style.display?
yh
What version are you on...?
2018.4
Ah! Got it. I was going to say that there should be, but that makes sense.
Sorry for the newb question, but, in the case of Dictionary<string, Component> targetComponents = new Dictionary<string, Component>(); where I do
void SelectionChanged()
{
if (Selection.transforms.Length != 0)
{
foreach (Transform t in Selection.transforms)
{
transform = t;
GetComponents(t);
}
}
}
I don't actually know if it is better to .clear() or do new. Atm, I don't have enough going on that it matters for either, but, would like to do whatever is better practice?
this might have been better for the #💻┃code-beginner, I just know it is part of my editor extension things so I didn't know XD
Idk what you are asking, but Clear() is better because it does not have to reallocate the memory, it just removes the references to the values.
Okay, and this was for exactly what I was asking! Basically I have a global script that I get some data for in scene gameobjects when I select them, and was doing .Clear() on the dictionary and didn't know if I should actually be doing new instead
Also, don't forget to google, like the top result is a very good stackoverflow question 🙂
yeah, I just woke up and not thinking very great haha
If you are wondering something, or trying to do something. Most likely someone has already wonder that or tried to do that and has asked. This is more true the less complex/niche the thing is.
is there an Invoke that can be used in Editor Windows?
nvm, just ended up using reflection
What do you mean? I am curious what you were trying to do?
I'm trying to call a function with a string to just remove some repetition. It's completely unnecessary lol, but, something I was interested in
Ah, you mean call a method using only the methods string name?
yeah, and all the stuff I could find was only on monobehaviour
well except MethodInfo
so trying that out
Only way to call a method using a string is via reflection.
yeah, okay, good to know!
ahaha, finally got it to work
foreach (Component c in t.GetComponents<Component>())
{
targetComponents.Add(c.GetType().Name, c);
string methodName = "Get" + c.GetType().Name + "Data";
MethodInfo mi = GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (mi != null) mi.Invoke(this, new Object[]{c});
}
Does that work?
I think you switched this and c in the Invoke method from what it looks like.
Also, just a tip but you can do mi?.Invoke(..) instead of doing if (mi != null) mi.Invoke(..)
yeah, it does work, and okay, I've been still avoiding ? for the time being
I'm scared of using it wrong haha
I tried different things with mi.Invoke(this, new Object[]{c}); and that was what just worked, I'm assuming the first part in the parameter is looking for the object the method is in, and comparing it with the first part of GetMethod(), and then the second part is for any parameter in the method, and in this case doing Object allows me to use it for basically any param type I'm using
oh and the first line was me adding to a dictionary, that doesn't matter for this, whoops
correct, the first parameter is the instance of the same type that the method is in, and the second takes an array of object which are the values to pass as parameters to the method when invoked.
why does Tools.handlePosition; say that "Tools" does not contain a definition for 'handlePosition', but UnityEditor.Tools.handlePosition; works just fine?
Because there's another class or namespace with Tools in it
doh, thanks for looking out. I had some old file I forgot about in a sandbox folder called Tools that literally did nothing... For some reason when I clicked it in the IDE I just assumed it was a Unity file lol whoops
still banging my head on how this custom UI thingy was made; all im really confused about is how they actually made the "container" (not sure what you want to call it but the box/rectangle that holds all the properties). I havent found any GUILayout.BeginArea's or maybe anything similar. any type of answer would be a big help.
probably shouldnt copy exactly how they did this but im too deep to pull out now lol
another question, is there even a way to get GUILayout.BeginArea to look anything like that? iv only been able to get an ugly transparent gray box
👍 i will check this out! thank you!
oh this is what im looking for! tho is there something similar to this for the scene view and not play mode?
It works in the scene view just fine
oh? im not able to see it. only when i press play and it only shows up in the Game window
using the first example on the doc
That example is using MonoBehaviour's GUI
which is runtime
you want to use OnSceneGUI or the duringSceneGui delegate
depending on what context you're drawing it from
You'll also need to draw it inside of a Handles.BeginGUI() and Handles.EndGUI() scope iirc
👍 i will give that a shot! thank you!
Hi all. My editor extension called RelationsInspector is now free and open source. It's a customizable node-based editor. Since I don't have time for it anymore, I'm looking for a contributer/maintainer to take it over.
Does anybody know what the equivalent of this code is for Unity 2019.4: VisualElement labelFromUXML = visualTree.Instantiate();
VisualTreeAsset does not seem to have an instantiate method
Ok I found it, its: visualTree.CloneTree(root);
sorry if this has been asked before but does anyone know if it's possible to select the directory node in the Project hierarchy?
I'm trying to add an editor context menu that will apply a unity label to all assets in a directory
select the directory node in the Project hierarchy
What do you mean? You can just useSystem.IO.Directoryto get the directory it self and all the file paths in it if that is what you are wanting.
Thanks for replying
I mean I want to, for example, right click on "Animations" in the screenshot, bring up a context menu, and in the editor script know the path for the item that I clicked on
I can get the context menu to show up using MenuItem("Assets/Apply Label")
I just haven't figured out how to get at the item that was click on
Ah, you just use the Selection class.
hmm I tried that, Selection just seems to contain a reference to the last asset/gameobject in the Inspector window rather than the directory I clicked on.
Maybe there's isn't a way then
unless I've missed something
Folders are assets, and when you context click it also selects the asset. So you just need to get the path of the selected asset.
ah! got it, you have to use Selection.assetGUIDS to get the guid then AssetDatabase.GUIDToAssetPath to get the path
Thank you for your help!
TIL you can do
#if true
#else
#endif
Could it be that the Node position in a node graph is somehow relative to its default position? Setting nodes position to (0,0) makes them always end up in the position the have been created
Logging all node positions always returns 0,0 🤔
In what API? UITK GraphView?
yes
How are you getting it's position?
foreach (var outputNode in this.graphView.nodes.ToList())
{
Debug.Log($"Node {outputNode.GetPosition()}");
}
This returns "Node (x:0.00, y:0.00, width:227.00, height:77.00)" for all nodes
width and height varies but x and y are always 0
Also if I set any nodes position to 0,0 by SetPosition it will just reset it to its original position after moving it via drag
I am not even sure where this original position is coming from
The UIElements Debugger although says it has and "Absolute" position of top:0 left:0
all the parents have 0,0 too but somehow the nodes manage to have a WorldBOund which is not 0,0
is there a way to either get the internal GUIContent set on a property or a native function that already exists to copy the summary from the metadata?
would SerializedObject.FindProperty be a better route to go instead of .copy ? I'm confused by Note that if you keep a reference to an array property and that array is subsequently resized then the stored reference is no longer reliable and should not be used. and not sure if this only applies to arrays, or is an example that applies to everything
What are you trying to get?
Basically, trying to have the tooltips that already exist for a lot of the native properties
for example, if I were to hover over a Vector3, the default tooltip be,
//
// Summary:
// Representation of 3D vectors and points.
and if I were to hover the x
//
// Summary:
// X component of the vector.
Where doing EditorGUILayout.PropertyField you don't seem to get those. I can recreate them with GUIContent, but, didn't know if there was already something that exists?
OH, do you mean doc comments (Also known as XML comments) that you see in your code editor?
no, I'm talking about the tooltip part of GUIContent. If there was a way to maintain the internal tooltips used when doing EditorGUILayout.PropertyField or a native method that already exists to extract the summary of what something is for from the metadata to use as a tooltip
for example, this what I did for my skinnedmesh custom editor
Could try the serializedProperty.tooltip property
static GUIContent updateWhenOffscreenGUIContent = new GUIContent(LocalString("Update When Offscreen"), LocalString("If enabled, the Skinned Mesh will be updated when offscreen. If disabled, this also disables updating animations."));
oh okay, lol let me try that, I hope it wasn't that ez XD
Sweet, works great! Now I can easily just worry about fields that don't already have a tooltip instead
oh cool new thing I learned today that I never payed attention to
you can use EditorGUILayout.PropertyField() in an if statement that will return true if expanded and showchildren set to false, like
if (EditorGUILayout.PropertyField(serializedProperty, new GUIContent(serializedProperty.displayName, serializedProperty.tooltip), false))
{
Debug.Log("Test");
}
for example
How can I make a custom editor for a type that also works when it's a field on an object?
im looking into property drawers
You make a custom editor of that class instead/also. Depending on how you are handling your custom editor, displaying things in the inspector or an editor window doesn't alter the data unless you alter it.
well i shouldnt need to duplicate code for every object that contains this class
You make an extension, so, when you get the serializedProperty is that field
it displays your custom editor instead
would custom property drawers work?
I'm not sure. I haven't messed with custom property drawers since my scope of things I mess with involved more than that
but, for an example, you can do if (serializedProperty.type == "Name Of Custom Class") you can make it so your custom stuff applies then
custom property drawer was the correct solution
works any time that type is being drawn in inspector
is there a way I can write a self contained bool in EditorGUILayout.Foldout?
No idea what you mean, but IMGUI is stateless
You should generally use the expanded state of a serialized property with foldouts as it's persistent
yeah, I have been, I was just curious about how to write a method to create a bool that would be different in a static method? However, upon further examining, I see that there is an overload for toggleOnLabelClick so I'm going to see if that does what I'm looking for
oh okay
okay, you gave me an idea, and instead I wrote it out as serializedProperty.isExpanded = EditorGUILayout.Foldout() tyvm
Hey everyone 🙂 I am running into an issue with the "Enter Play Mode Options - Scene Reload". We are organising our data in chunks and we have an editor script that spawns these chunks for us when working in the editor. We already managed to find a solution that allows us to keep the data in memory when changing the play mode state but we'd like to keep them spawned in the scene as well to keep our iteration times as low as possible by avoiding destroy/spawn. My understanding of the "Scene Reload" option is that it should allow us to do just that. But the chunks we are spawning (marked as HideFlags.DontSave) still get destroyed when entering play mode. Any ideas why this might be the case? Shouldn't those objects persist as well?
BadImageFormatException: Expected reference type but got type kind 17 Im getting this error when using the UI toolkit? I have no idea how to debug
Is there something wrong with me or does that it is normal that UI Elements based EditorWindow gets cleared after playmode change? It seems like the rootVisualElement is being cleared after for example entering playmode
That is normal since it reloads the domain. OnEnable and OnCreate are both called so as long as you are creating your UI in one of them (like you should be) it should be fine.
got it, thanks!
when using the UI toolkit
What do you mean? The editor is always using UITK. Do you mean when you make a custom editor/window?
Does anyone know if there is a way to get the 'usable' width of the inspector? I feel like there was a way, but I don't remember it now. I know there is Screen.width, but that doesn't account for the padding.
hey guys how do i take out this line on the game screen like i accendtly did something to the main camera and its appering this
Top right of the game window "Gizmos" toggle.
In an effort for better understanding, I was hoping someone could help me understand this. Why when I open the metaData for something like EditMode which appears as
namespace UnityEditorInternal
{
[InitializeOnLoad]
public class EditMode
{
public static OnEditModeStopFunc onEditModeEndDelegate;
public static OnEditModeStartFunc onEditModeStartDelegate;
public EditMode();
public static SceneViewEditMode editMode { get; }
public static void ChangeEditMode(SceneViewEditMode mode, Bounds bounds, Editor caller);
[Obsolete("Use signature passing Func<Bounds> rather than Bounds.")]
public static void DoEditModeInspectorModeButton(SceneViewEditMode mode, string label, GUIContent icon, Bounds bounds, Editor caller);
public static void DoEditModeInspectorModeButton(SceneViewEditMode mode, string label, GUIContent icon, Func<Bounds> getBoundsOfTargets, Editor caller);
[Obsolete("Use signature passing Func<Bounds> rather than Bounds.")]
public static void DoInspectorToolbar(SceneViewEditMode[] modes, GUIContent[] guiContents, Bounds bounds, Editor caller);
public static void DoInspectorToolbar(SceneViewEditMode[] modes, GUIContent[] guiContents, Func<Bounds> getBoundsOfTargets, Editor caller);
public static bool IsOwner(Editor editor);
public static void OnSelectionChange();
public static void QuitEditMode();
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Obsolete msg (UnityUpgradable) -> UnityEditor.EditorTools.ToolManager.RestorePreviousTool()")]
public static void ResetToolToPrevious();
public enum SceneViewEditMode
{
None = 0,
Collider = 1,
ClothConstraints = 2,
ClothSelfAndInterCollisionParticles = 3,
ReflectionProbeBox = 4,
ReflectionProbeOrigin = 5,
LightProbeProxyVolumeBox = 6,
LightProbeProxyVolumeOrigin = 7,
LightProbeGroup = 8,
JointAngularLimits = 9,
GridPainting = 10,
GridPicking = 11,
GridEraser = 12,
GridFloodFill = 13,
GridBox = 14,
GridSelect = 15,
GridMove = 16,
ParticleSystemCollisionModulePlanesMove = 17,
ParticleSystemCollisionModulePlanesRotate = 18,
LineRendererEdit = 19,
LineRendererCreate = 20,
ParticleSystemShapeModuleGizmo = 21,
ParticleSystemShapeModulePosition = 22,
ParticleSystemShapeModuleRotation = 23,
ParticleSystemShapeModuleScale = 24
}
public delegate void OnEditModeStopFunc(Editor editor);
public delegate void OnEditModeStartFunc(Editor editor, SceneViewEditMode mode);
}
}
appears differently than https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/EditMode.cs
am I updating something improperly?
The repo has not been updated since 2020.2.0a13.
@neon star
using(var reader = File.OpenText("blueprints.yaml")
{
var deserializer = new Deserializer();
var blueprintsById = deserializer.Deserialize<Dictionary<int, YamlBlueprint>>(reader);
// Use the blueprintsById variable
}
foreach(var entry in blueprintsById)
{
entry.Value.Id = entry.Key;
}
ohhh
let me try
don't forget to include System.IO
hello
https://docs.unity3d.com/Manual/FormatDescription.html see if that has anything
ok
you should be able to use this info to create a loop through the above loop I'm assuming
to find what you need
ohk
but i wonder one thing
I want to get typeless data from the yaml
i can get the data either by opening the file as well
but i want to load it with a script
dont know how to?
i heard that for getting the string inside a yaml as an object you should deserialize a yaml file
what is typlessdata? I mean, the name implies what it must be, but, can you not loop through image data and get the typlessdata?
the typeless data is the raw binary pixel
it is the texture data
the original texture
if you copy and paste the text inside the typeless data into another text file
and load it with a Texture2d then it will load the texture
but i want to get that typeless data from C# code as an object or a string
here
Lets make something awesome together!
The first number after !u! indicates the class of the object (in this case, it is a GameObject).
Then my shitty parsing code:
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.WithNodeTypeResolver(new UnityNodeTypeResolver())
.Build();
var result = deserializer.Deserialize<Dictionary<object,object>>(document);
foreach ((object key, object value) in (Dictionary<object,object>)result["Texture2D"])
{
Debug.Log($"Key: {key}");
Debug.Log($"Value: {value}");
}```
lol
lemme read
in amongst there is the value read from yaml
wait wait
how did you do that
??????
I posted all the code
I linked it earlier.
understood
sorry cant find it
No, I edited it slightly from something I found. Though, it would have been straight forward to make
you're missing a bracket
If you're still getting an error (something about a feature not being supported in your version) just change the foreach to a normal dictionary foreach with KeyValuePair instead of using deconstruction
ok
Sorry but cant understand how to
foreach(var pair in ...
Then you can use pair.Key and pair.Value
understood
done thanks!
it is only showing this
😢
what did i do wrong here
public class yaml : MonoBehaviour
{
public TextAsset text;
public void get()
{
string yaml = text.ToString();
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.WithNodeTypeResolver(new UnityNodeTypeResolver())
.Build();
var result = deserializer.Deserialize<Dictionary<object, object>>(yaml);
foreach (var pair in result)
{
Debug.Log($"Key: {pair.Key}");
Debug.Log($"Value: {pair.Value}");
}
}
}```
@visual stag sorry for the ping but can you please help here???
If you don't really understand this part I fear you're going to just continually be pinging me for help
sorry
you have a dictionary, access its members!
I accessed it in my example and iterated the children
there are 2 right?
There's a whole bunch of nested data
I really cant understand it
which library i am missing for what it shows me error on this step
What step, there is no library you need
foreach ((object key, object value) in (Dictionary<object, object>)result["Texture2D"])
That's irrelevant, it's just a new C# version because I'm using an alpha version of Unity. Your normal foreach loop does the same things
You're just not indexing into the first dictionary at all: result["Texture2D"]
foreach (var pair in (Dictionary<object, object>)result["Texture2D"])
{
Debug.Log($"Key: {pair.Key}");
Debug.Log($"Value: {pair.Value}");
}```
ok
I am not deserializing an object
ohhh
thx bro
fixed it
is there a way to find a specific data related with key as well?
I don't know what you mean. I'm not very familiar with YamlDotNet, and I'm sure they have examples on how to properly use their deserializer if you want to create types for it to deserialize into
I only could be bothered doing the basic Dictionary of object as I was hoping you would take it from there
can we choose a specific object out of all object to deserialize
something like I only need the typeless data and ignore all other objects
is that possible?
No. But you can just get that value from the dictionary
can we check each and every value alphabets
like no of alphabets
check all the values and if the alphabets are more than 8 then that value will be selected
I have no idea what you mean. You have a dictionary that contains the entire datastructure. Just use it. If you want to do more advanced stuff then that's something you're going to have to figure out. I cannot help you further
ok then
bye the way thanks
@visual stag can we do something like this here
load the file from an integer of loaded file
?
like
string text = file(1);
load from a specific number
same here
pair.Key(1)
??
I have absolutely no idea what you're trying to do with that number
The thing is that I only want to load this value
Then get it from the data structure you have loaded
You can't not load the rest of the file if you're parsing the yaml
understood
var p = deserializer.Deserialize<Person>(yml);```
can you please tell me what is the person here
The type you want
A type that matches the datastructure you're deserializing
and what type is of my yaml
You'd have to make one yourself
🤷
sad
look up how to serialize/deserialize objects into yaml file or something like that
okay, thanks to vertx I think I can finally write these better from understanding more
public static class EditorExtensionMethods
{
public static void ShowSerializedPropertyAsFoldout(this SerializedProperty serializedProperty)
{
serializedProperty.isExpanded = EditorGUILayout.Foldout(serializedProperty.isExpanded, new GUIContent(serializedProperty.displayName, serializedProperty.tooltip));
}
}
This does work, but if someone can look over something like this and let me know if I'm doing this correct when they have time
ShowSerializedPropertyAsFoldout seems redundant as it's an extension of SerializedProperty. Just call it ShowAsFoldout or something
true, ty!
Hi! i've got an input field, and some kind of custom regex validator here:
possScenarName = EditorGUILayout.TextField(possScenarName);
if (ScenarioIDValidator.isValidIDForNow(possScenarName))//Returns true if possScenarName is valid through regex, false if no
{
previousScenarName = possScenarName;//We "reset" the previous scenario name to the actual one (since it's valid)
}
else
{
possScenarName = previousScenarName;//We "reset" the actual scenario name to be the last valid one, because the new one wasn't valid.
}```
The regex works just fine: when i enter a character that's not validated by the regex, it's "erased" (see code)
But thing is i have to click away from the field to validate. Like it if needed to get refreshed or something. Can i modify this...?
you can try EditorGUI.BeingChangeCheck()
ooooh i see, thanks!
also, depending on where you are calling serializedObject.update and serializedObject.ApplyModifiedProperties you shouldn't need to use EditorGUI.BeginChangeCheck() since every character change should be creating changes
well uh
i don't have any SO 👀
it's a custom window
didn't have to use any of that for now
but welp
you still don't need t if you don't want to. I haven't messed with much yet outside of Unitiys serialization so I just throw SerializedField onto everything, but, I'm assuming you could either make something a serializedObject through casting through the proper channels, or, just use things like EditorGUI.BeginChangeCheck() and setdirty
Hi there I'm having trouble with a custom undo action in an editor script I'm working on.
Specifically I'm running a function that transforms an object at frametime and I'm struggling with recording the entire process as a singular undo. I've tried with CollapseUndoOperations but without luck.
Let me post some code snippets
frametime?
at runtime so every frame
using System;
using System.Collections;
using UnityEngine;
using UnityEditor;
public class moveObjectShortcut : EditorWindow {
//[...]
static void OnSceneView(SceneView sceneView){
//[...]
if (ctrlHeld)
{
if (e.type == EventType.MouseDown)
{
if (e.button == 1) lastMousePosition = e.mousePosition;
}
if (e.type == EventType.MouseDrag)
{
mouseDelta = e.mousePosition - lastMousePosition;
lastMousePosition = e.mousePosition;
if (e.button == 1) moveObject(mouseDelta, "x", sceneView);
}
}
//[...]
}
private static void moveObject(Vector3 distance, string axis, SceneView sceneView) {
var selection = Selection.gameObjects;
//[...]
for (int i = 0; i < selection.Length; i++) selection[i].transform.position = selection[i].transform.position + distance;
}
}
I hope this is enough to make sense
Basically I'm calling a function every frame on holding a key and dragging the mouse
And I want all the actions from the function in one undo step as soon as I release the mouse
I've tried something like this already:
if (e.type == EventType.MouseDown)
{
Undo.IncrementCurrentGroup();
undoID = Undo.GetCurrentGroup();
}
if (e.type == EventType.MouseDrag)
{
//call my function
}
if (e.type == EventType.MouseUp)
{
Undo.CollapseUndoOperations(undoID);
}
}
private static void moveObject(Vector3 distance, string axis, SceneView sceneView)
{
//Put all selected objects into array
var selection = Selection.gameObjects;
for (int i = 0; i < selection.Length; i++)
{
Undo.RegisterCompleteObjectUndo(selection[i], "move");
selection[i].transform.position = selection[i].transform.position + distance;
}
}
But with no luck
And please bear with me I'm a 3D artist by trade and coding is really more of a hobby I enjoy doing
EditorWindow doesnt have default access to SceneView
where are you registering to it?
further up in the code I left that out cause of the character limit. I'm doing it with
static moveObjectShortcut(){
//avoid registering twice to the SceneGUI delegate
SceneView.duringSceneGui -= OnSceneView;
SceneView.duringSceneGui += OnSceneView;
}
this is the full current code as it stands
idk what if (!globalDisable) is but have you done a Debug check to see if you are even passing this?
Should use onenable/ondisable for this tbh
I see that you have the field false on it, but, do you have anywhere else that is possibly enabling it?
I mean if it's moving then it's passing that
you have it as public, so, I'm assuming you intend to access it from in and out of the script
Idk why you're questioning that
because if its enabled he has it so nothing is registered
it's literally at the start of his scenegui
like
he cant even get ```cs
if (e.keyCode == KeyCode.LeftControl) ctrlHeld = true;
if (e.keyCode == KeyCode.LeftShift) shiftHeld = true;
if its enabled hehe
global Disable is a menu item for disabling the script. And yes everything works perfectly I just need to get the undo working
And she :)
But yeah it's definitely enabled cause the script all works 😄
I just want to implement a way to undo the transform
oh you want undo my bad
Yee
And I'm struggling because the transform function is called once every frame and I can't manage to collapse the undos
have you tried Undo.RecordObject?
IIRC they should collapse if they're the exact same name
I just tried it instead of RecordObject since that also didn't work
Ah ok
But yeah RecordObject also didn't work
oh ya
that does say Almost all property changes can be recorded with this function. The transform parent, AddComponent, object destruction can not be recorded with this function, for that you should use the dedicated functions.
And you used CollapseUndoOperations right?
yeah I tried it here: #↕️┃editor-extensions message
If I did that right I'm not sure
but I'm not transforming a parent am I?
Seems like it, are you sure it's not being set multiple times?
so
what you need to do is use a serializedProperty of the position, and undo and reapply that way
does that make sense?
That doesn't work
so, before you save the object
it should, if the object hasn't been saved to memory yet
Since they want changes over multiple frames that are visualized they have to apply every frame, which in turn would break undo
they can loop through a specific amount of frames
I'm not sure, editor scripting and the undo system is very new to me
{
Undo.IncrementCurrentGroup();
undoID = Undo.GetCurrentGroup();
}
Can you add a debug log in here and make sure it's being executed multiple times?
Already did that Mouse down and Mouse up are called and only once
So
what you need to do
is use serializedProperty.copy
and put it in a list
or serializedproperty.duplicatecommand if u want
Are you sure there's no more elegant way? It seems like that's exactly what undo is for
Undoing should work, but, if you are overwriting overwriting the serializedProperty from the original reference and save it to memory how is it going to keep undoing?
but then how do I go from a list of changes to actually undoing them?
you essentially make every copy its own serializedProperty
The ugly hack is to reset it back to the original position, then call record and move it to the end
I don't see why what you're doing is not working though
so basically you can loop through to undo, but doing something like this if (SerializedProperty.EqualContents(x, y) to do the next Undo
You could try flushing after collapsing
but this will also allow you to maintain every frames position also
Or try their revert call and see if that reverts to the beginning, just to confirm it's all in the same group
Or set a group name and query that to make sure it doesn't change
what is that?
Hm yeah I can try that
I doubt it'll do much but worth a try
It's getting late here so I will call it quits for today and try this tomorrow and maybe get back to you. Thanks for the help both of you 
what are you exactly doing if you don't mind saying? I see you want to undo, but, like, do you WANT every frame of position of changes to basically see an animation in reverse? Or just to go back to the starting position?
This script is adding a feature that unreal has where you can move any selected object using ctrl and mouse click drags without having to grab its pivot handles
Unity doesn't have that but it would be a really nice feature so I made that
but of course I also want to be able to undo any moving that I do
why not jut store the initial position and have it always undo to that?
seems like easier than doing with undo
Yeah but how do I specifically do that with the Undo scripting api?
or do you mean just make my own ctrl z input check?
yeah, make your on ctrl z input check (imo). Then you also have more control of what undo can and can't do basically
I think you are looking for undo groups maybe? You only need them if multiple undos are registered and you want them to all be undo/redo as if they were one operations.
// Cal before making any changes.
Undo.RegisterCompleteObjectUndo(gameObjectToMove);
int undoGroup = Undo.CurrentGroup();
// do all your movements here
// When your movement/action is finished
Undo.CollapseUndo(undoGroup);
thank you I will try that tomorrow and if that doesn't work just go the workaround from @opaque zenith
thanks to all of you 
yeah, sorry, I'm not as good as these guys hehe, but I'll try to help
I mean I'm mainly a 3D artist I just enjoy coding but I only have very basic understanding of "good practices"
usually for me if it works it works
and that's probably just the easiest way of doing it tbh
also btw feel free to also use this idk why but I expected unity to have some feature like this
cause a lot of times you wanna move an object or prefab or several objects without having to change your view for the pivot
hi, i'm drawing a ton of stuff in the editor using gizmos and handles. it works ok, but if you draw a ton of stuff the editor really slows down, and also the lines are kinda ugly.
I know there's some more advanced way of drawing things in the editor window, but I cannot find a reference to it. Can anyone point me in the right direction?
there is a mixture of a lot of things you can. Don't draw as complex handles, for example, use something like a square cap instead of a cube. Don't draw unecessary things unless you have to, for example, if you have a handle that display names, don't have those names on while using other handles if you don't need them on. remove as much as you can from loops if it doesn't need to be in there. Instead of constantly getting data and then drawing it, cache it and check if it needs to be drawn
I'm doing all that, just want more control and performance.
What about using GL (https://docs.unity3d.com/ScriptReference/GL.html). I see unity's tilemap editor uses it. Is it faster?
Can one create sprites and meshes and somehow mark them as not part of the scene, just there for UI purposes?
Love it when I get to leave comments like this in my code, thank Unity. /s
I'm confused by the comments? Unity says using their haschode implementation changes the hashcode every time anything with serialization happens
it's why there is .GetSafeHashCode() for some things
It doesn't matter since I am not serializing the HashCodes. I copy the elements in the HashSet to a list in OnBeforeSerialize, and then add them back to the list in OnAfterDeserialize.
but are you serializing the objects?
Yes. It is basically this (Or it should be)
class SerializableHashSet<T> : HashSet, ISerialCallReciv
{
[SerializeField] List<T> _serializedItems;
void OnSerialize
{
_serializedItems.Clear();
foreach(var element in this)
{
_serializedItems.Add(element);
}
}
}
None of the values in the HashSet<T> are (or at least should be) serializable, so you don't need to worry about the hashcodes.
I guess I'm just confused. An objects hashcode can constantly be changing and unity doesn't serialize hashsets, so I guess I just don't understand haha
The HashSet is only used at runtime. Otherwise it is treated like a list by the editor.
Another way to think of it is I all the elements from the list get added to a HashSet right before entering play mode.
(This is not exactly accurate but I think it helps get the idea across)
gotcha, I've been trying to mess with hashcodes a little more because I like the idea of a... uh... fingerprint? But, I just recently found this file id with all the Serialized Property things Ive been doing and been thinking about using that instead
You should know that hashcodes are not unique. So be careful when using them! 🙂
What is it that you are doing with SerializedProperties?
I was just finding that iterating over properties and storing them in a dictionary with .name as their key sometimes ran into issues, with some things. Not a big deal, can fix it ez enough for things like m_size, but, was going to use a hashcode and was running into problems with it constantly changing, so, was thinking I might use the file id. I just ignored it for now since it was something I don't really need to do atm haha
@opaque zenith If you want to see how I actually did the serialization you can see it here. https://github.com/MechWarrior99/Bewildered-Core/blob/main/Runtime/UHashSet.cs#L263
Is anyone here really good at troubleshooting intellisense?
Perfect, thanks.
Hey, quick question, I have an object with several copies of the same component, and I tried making a custom inspector for that component. Thing is, I get a "Multi-object not supported" error even though I specified [CanEditMultipleObjects]. Any ideas?
Code :
[CustomEditor(typeof(TileRule)), CanEditMultipleObjects]
public class TileRuleEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
}
}
Google finds nothing
1 object with multiple copies of the same component?
How are you creating your editor instance?
what do you mean my editor instance ?
I just click AddComponent
Wait nevermind
I changed nothing but it suddenly works
computer science, amiright ?
Ah yeah, if you have it selected and the code reload it always gives that error smhw
¯_(ツ)_/¯
Hi i have a question, how can i make something like a folder in the editor? the same thing that hides a list?
Is there a way I can generate a custom preview image for the object selector window (shown in image)?
I can generate custom previews for the project view and inspector icon using RenderStaticPreview but that doesn't effect the object selector
nvm I found it, doesn't work atm for the object selector but according to the documentation this is how you do it
[CustomPreview(typeof(PhysicsItem))]
public class ItemEditorPreview : ObjectPreview
{
public override bool HasPreviewGUI()
{
return true;
}
public override void OnPreviewGUI(Rect r, GUIStyle background)
{
Item item = target as Item;
if (item.ImagePreview == null)
{
GUI.Label(r, $"{item.Name}, has no preview image");
}
else
{
GUI.Label(r, $"{item.Name}, has a preview image");
GUI.DrawTexture(r, item.ImagePreview);
}
}
}```
You create a class inheriting from ObjectPreview (https://docs.unity3d.com/ScriptReference/ObjectPreview.html) and override OnPreviewGUI
You don't afaik, you could make a normal object and then use subobjects but that's far from ideal
i actually found out how to recreate the same dropdown as the list, took me too long to realize its a Foldout that i needed
Ah I thought you maent in the project view 😅
Hi all is there a way to stop unity cloning the last item when adding a new list item in the inspector?
Update from yesterday, I tried a few other combinations for the undo as well as trying to implement manual undo with ctrl z combination and neither worked :(
I'm giving up at this point and will ask a coworker to continue working on it
As I'm out of ideas at this point
hey Mech! Thanks for this info, I'm checking it out now!
yes, you found it, and you have to mess with it. Not a ton of documentation on it, but, for example, I have onpreviewGUI on scriptableObjects
Sure, hope you can learn something from it 🙂
I'm having a little trouble saving a scriptable object/undoing for my level editor. For some context, I have an Editor script, which calls functions on the Monobehaviour in scene matched to it, which will call functions in a stored POCO inside a given scriptbale object, as well as do things itself to show the level in scene. The POCO is the thing that needs saving and undoing and such, but the Monobehaviour also needs to at least know to update its scene reperesentation, if not just save it's stuff too.
Here's an example of what I've tried. This is a function inside that Monobehaviour file, and level is the scriptable object. The Monobehaviour is responsible for the stuff saved with UpdateHexagonDisplay();, and level only for the stuff within it.
public void ResetLevel() {
level.GetHexGrid().Reset();
UpdateHexagonDisplay();
Undo.RecordObjects(new Object[2] { level, this }, "Reset level");
EditorUtility.SetDirty(level);
EditorUtility.SetDirty(this);
}
Nothing happens with this in there, and I'm not sure why. I've also tried adding SerializedObject.Update and SerializedObject.ApplyModifiedProperties in the Editor script but no luck there either (I can imagine why not but worth a shot).
Anyone know why this isn't working?
How can I check how much height a LabelField will need when using wordwrap?
you can either do something like EditorStyles.label.CalcSize(GUIContent).y or put that into something like a Debug.Log and then use that exact number in GUILayout.Height
iirc CalcSize does not account for word wrapping.
You want to use EditorStyles.wordWrappedLabel.CalcHeight(guiContent, width)
GUIStyle labelWordWrap = new GUIStyle(GUI.skin.GetStyle("label"))
{
wordWrap = true
};
labelWordWrap.CalcHeight(myContent, 120);
This also seems to work.
Does EditorStyles just use the default GUIStyles?
Sure does. It is just the cached styles basically.
Also note that when copying a style that you can just do new GUIStyle("label"), no need to get the skin. the GUIStyle has an implicit conversion from string to GUIStyle. So any parameter that takes a GUIStyle you can just give it a string. However iirc this requires it to load the style so using EditorStyles. will be a bit better.
It'll always be loaded anyways
EditorStyles just returns a reference rather than a new instance afaik
Thanks!! I'll just use EditorStyles, didn't realize there was an instanced one built in.
I mean that if you use the string it will have to go and load it and create a new instance vs just returning an already created instance.
hey guys, i have a problem where when i select certain instances of a prefab, it freezes the editor (cant play the scene either). I want to see what is different about these instances versus other ones that causes the freeze, but since it freezes upon selecting it, i dont really know how i would go about this
If you guys want to take advantage of SerializedProperty what do you do if something isn't already serialized? Like, from an editor script? I think that might be something I could learn from your code @gloomy chasm, but, not sure if I'm fully understanding it? Instead, I ended up making a custom class in the runtime script of all the info I want to view with a serializedfield. IDK if there is a extension method or something that can just be written?
do you have huge lists being generated in the inspector?
I have a weird issue with an Editor Extension I'm making. I keep using this in OnGUI()
_controlRect = EditorGUILayout.GetControlRect();
And if I read something like _controlRect.width it gives me the accurate width in real time if I resize the EditorWindow.
But if I read _controlRect.height the value never updates.
What do I do?
hmm, it sohuldnt generate any lists in editor time, but it does have an uma component which i didnt make or am 100% familiar with, so many theres something wiht that which bugs out
ive posted a help question in their discord too, to see if theres something there that could cause something, but at this point im just stuck here unable t odo anything
I'm not 100% sure since from just that line of code, you should be able to get a width and height. Are you overwriting the height somewhere? Y increases downwards on a rect if that helps
something isn't already serialized
You implement theISerializerCallbackReciverinterface. But if you can give an example I could tell you more specifically what you need to do.
Let me show all the code just in case:
private void DrawHorizontal(float yPos, float padding, Color color)
{
Vector2 start = new Vector2(0f, yPos + padding);
Vector2 scale = new Vector2(_controlRect.width, 1f);
GUI.color = color;
GUI.DrawTexture(new Rect(start, scale), _lineTex);
}
private void DrawVertical(float xPos, float padding, Color color)
{
Vector2 start = new Vector2(xPos + padding, 0f);
Vector2 scale = new Vector2(1f, _controlRect.height);
GUI.color = color;
GUI.DrawTexture(new Rect(start, scale), _lineTex);
}
private void OnGUI()
{
_controlRect = EditorGUILayout.GetControlRect();
_lineTex = new Texture2D(1, 1);
float padding = 32f;
for(int pos = 0; pos < 256; pos++)
{
DrawHorizontal(pos, padding * pos, Color.green);
DrawVertical(pos, padding * pos, Color.red);
}
}
The height should be something like 18 or 21 or something right?
All the method is doing is getting a rect that is the size of a standard field.
No, ControlRect returns a new Rect for a field control.
If you want the size of the window then position.size should do.
Another way is Screen.width and Screen.height
I was trying to setup an editor for the MeshFilter and SkinnedMeshRenderer for better customization. Mesh isn't a part of the native serializedpropertytypes so in an effort to get all the things from it, I would cast it as a mesh, but, I didn't know how to cast it back if I wanted, well, I instead just found the property again. Anyways, I have a custom thing already for lists and stuff, but, it just made me wonder if I could somehow on the spot make a new field a serializedProperty, for example, List<Vector3>
So if I haven't created a custom viewing for something yet I could just default it basically
As far as Unity's SerializedProperties go, everything at it's core is one of the supported types int, float, string, bool, long, byte, etc. or an array. A Vector3? That is just 3 floats. A List<Vector3>? that is just an array of Vector3s. A Mesh? That is just several arrays of Vector3s ints, etc
yeah, but, what I mean is, let's say I haven't setup how I want something like Bounds to appear in the inspector, I would rather just use the SerializedProperty version of it atm, but, IDK how to cast something into a SerializedProperty. I seem to be riddled with errors when trying to, like trying to do SerializedObject = new SerializedObject(target), but, I'll look over more of your code you shared with me and the ISerializerCallbackReciver
What is target in this example? Is it a Bounds value?
yeah
Also, for learning how ISerializationCallbackReciver works looking at my Dictionary or HashSet implementation is a bad idea because it is more complicated than need be so that it plays nice with GUI code.
Well that isn't going to work.
You can only make a SerializedObject from a UnityEngine.Object.
You do that and then use .FindProperty(..) to get the SerializedProperty that you want.
May want to give this a read.
https://docs.unity3d.com/ScriptReference/SerializedObject.html
sorry, I lost internet earlier 😦
and yes. I read about casting as an object, and then as a serialized object. This works sometimes, but, most the time I get an invalid pptr (or is it pttr, I don't remember atm)
But, I was looking at creating an extension method that serializes anything and returns it serialized. Your code looks like it does something like? I'm still studying it
well, serializeField does that
but not in the way I'm looking for?
but I guess in the way I'm looking for? haha, since that is what I ended up doing. I'm just looking at reducing some of the middle man stuff I made
I'ma be honest. I don't think you understand how serialization and serialized objects work in Unity. Firstly, I would read that entire manual page. Secondly, don't say cast because that is a thing in C#
(int myValue = (int)0.25f; This casts a float value to an int value. It is called an explicit cast because I am telling it what to cast to (int). int myValue = 0.25f;, this is called an implicit cast because it just does it automatically without me telling it what to cast as).
Would it be pointless to purchase a toolset while making a similar toolset that you’ve been trying to build?
is there a way to draw an ObjectField that is read-only but clickable so you can click it and jump to the object in the scene/project?
Probably not
But you can just make a button or not assign the objectfield return value to anything
somehow Odin does it, but 🤷♂️
I mean you can make a button that looks like an objectfield, but that's a fair bit of effort
I'm assuming you already tried gui.enabled = false right?
Yeah, you would basically have a rect that is over the button that opens the object picker window, and have it eat/use any mouse down events. Then have another rect over the main field and use any drag and drop events, but not mouse down.
That should get you what you want. You will need to figure out the rects yourself though.
make a read only attribute that uses ping
EditorGUIUtility.PingObject(Selection.activeObject);
rather, use GameObject.find instead of selection
beatifull , einit ?
Looks pretty nice. I would maybe try having the toggle in front of the label, also make the background area lighter.
We basically just draw our own from scratch using the styles of the original 🙂
I need a plugin for my images to shake in the menu
??
thanks all, will look into ping. for now I don't care enough to try to do too much from scratch
new question, is there anyway to reset non-serialized state on a ScriptableObject on editor play?
short of having a look up table for every SO and calling something like DoReset from a monobehaviour
Hi fellas, I got a question:
This is my OnDestroy for my editor window. A classic example of a "Save/Discard/Cancel" menu.
My doubt is about "unmaximize" the window. Apparently, when I do this, OnDestroy is executed. Now, I guess the normal procedure would be, like with "Cancel", make a clone of the window. But in this case, I do not really want to those the "Close Dialog ". How could I know when to show it, or not?
I downloaded itween buh the namespace errors are too many
answering my own question I can use OnEnable a-doi 🤦♂️
Note that OnEnable is not called if domain reloading is off in the scene settings.
good point, but can't win 'em all lol
Sure you can. Ya using #if UNITY_EDITOR and check if it is in play mode 😉
Here you go.
private void OnEnable()
{
_value = _initialValue;
// OnEnable is not be called if the enterPlayModeOptions are enabled, so the value will not be reset.
// So we need to register to the event that is triggered when the play mode state changes and reset it there.
#if UNITY_EDITOR
if (EditorSettings.enterPlayModeOptionsEnabled)
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
#endif
}
#if UNITY_EDITOR
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.ExitingEditMode)
_value = _initialValue;
}
#endif
Normally I wouldn't just give the code. But I already had it and it isn't much, so there you have it 🙂
🙇♂️
There a way to embed a viewport into a custom editor window? So if would have all the functionality of a sceneview in that you can drag the camera around, but also add gizmos in there and such things. I saw something that's a previewEditor whereby you can preview an object and rotate around it etc, but I don't know if that let's you add gizmos to it or not. I just started with editor stuff so I know basically nothing about it...
mayor no

It is possible for sure. However you have o do things like movement your self. Overall this is a rather complex task especially for someone brand new to extending the editor. But if this is what you want to do, I can tell you that you would use a class called RenderPreviewUtility.
ah you star, so just to double check, I'll be able to do things like draw gizmos (circular handles) and then move them about etc right?
Should do iirc.
thanks man, huge help
What they said.
"It is possible for sure. However you have o do things like movement your self. Overall this is a rather complex task especially for someone brand new to extending the editor. But if this is what you want to do, I can tell you that you would use a class called RenderPreviewUtility."
No I was agreeing.
@rigid spear Don't troll the channels. Your next mute will be much longer.
You guys are too serious. Here's the thing, mate. Nobody cares. Go fuck yourself dude lol
MayorOfTittyTown#3328 was banned
lol, I like how mesh.optimize is just
public static void Optimize(Mesh mesh)
{
OptimizeIndexBuffers(mesh);
OptimizeReorderVertexBuffer(mesh);
}
if I am using GUILayout and stuff is there any convenient way for me to walk the rendered UI and inspect different elements (for things like accessibility or localization)?
No
this is awesome!
I think the toggles in orthographic order makes more sense
As for the background, thanks for the advice, it would look better with light background I guess :D
I'm terrible at colors lol
I just paint everything dark so my clients won't complain ( you know, everybody love dark and they think there's been some deep thoughts for each color )
Would add foldouts tbh
Hey Folks, I'm working on a Attribute System for a rpgish game and trying to find a clean way to wire it up and fill it with info. I made a class that describes an attributes behaviour & basic data and I'm able to add various attribute modifiers (For Buffs, Equipment and so on). Now I'm on the topic of creating the attributes and I want to be able to define attribute dependances.
Coming to my problem: The idea was that I make the class StatSet (Containing all the various attributes) a scriptableobject to be able to set the values of the Set for various different Monsters etc. in Editor and give it a slot for a scriptableobject StatDependancies in which I can throw the current config for them.
Is there a way I can design a StatDependancy or the StatSet so that one can create Statdependancies in Editor and it "knows" about the various attributes I implemented so I can choose "Strength" linked to "Health" Factor "2" and don't need to maintain a index list, string list or enum in Statdependancies mapping the names of the attributes?
Put it in here because I realized I might need to make an editor extension to realize this behaviour, as my search hasn't really shown any ways besides that.
If there are more clean or clever ways to approach this problem than scriptableobject massacre I'm happy about proposals there too.
For clarification, when you say "Attribute" do you mean the concept, or do you mean the C# [Attribute]?
The concept of characterstats or characterattributes is meant with "Attributes" and "Stats" in the whole text. Sorry for the confusion 😅
Okay, I have read over it 3 times and I still don't get what you are wanting to do. You mention linking and maybe some logic? It isn't clear (at least to me) what the structure of this is or how it works. Maybe some example code snippets would help (can be pseudo code, just as long as it demonstrates the structure)
(Or just explain it a bit more)
Sorry need a sec, PC hung up
Let me ask this, you say "'knows' about the various attributes I implemented". What does "Implemented" mean? Is it an interface, or an item in a list, something else?
At the moment it is a scriptableobject holding the various attributes as fields called StatSet, but it would be okay to change this to get the behaviour I want that's why I left it generic in the opening question. Now when I add an new attribute to the list I don't want to go to the class of AttributeDependacy and add it to the list there too to make it a choosable option when creating a new AttributeDependancy in the editor. I would love to find a way to declare the attributes in a central spot and the other scripts register their existance.
Or rather I can create a serializable field in some script so editor gives me the options of the attributes that are currently available
On runtime I could take a list of all Objects with the Type <Attribute> but how I accomplish this on editor time?
I still don't know what StatSet or AttributeDependancy, or StatDependancy actually is, or how they relate to each other really.
How much code is it? Can you just plop it on Hastebin?
It's not much, but AttributeDependancy doesn't exist due to me looking for the idea of how to implement it. Wait a sec I will dump existing parts there and try to write some pseudo code or so to visualize it. Sorry for the vague and unclear question
https://hastebin.com/zoxupemayi.csharp changed the link to a better formatted version
I hope that clarifies my need 😅
That does help some yeah. Your naming makes it rather difficult though ( 😛 ).
I still don't really get what you are doing. But if you want to get a list of fields and their types, then you can do that with reflection.
😅 I know, I have a hard time to make it clearer and might use misleading terms due to not being native english speaker. Thank you a lot! I will take a look into it
No problem. I would recommend changing Attribute to CharacterStat for clarity. And in class names instead of using plurals (like Attributes), use things like Container or in your case maybe something like CharactereDefinition or something.
Will do that! I appreciate every critique or pointing towards better practices a lot. I derive my knowledge about game engineering from tutorials, articles, ... and try to work on a cleaner code in general, what can be mind breaking without pointing towards the general right direction from outwards 😅
Can anyone help me troubleshoot intellisense for Unity with VSCode?
#💻┃unity-talk or #💻┃code-beginner I think would both be appropriate places to ask. This channel is for creating extensions to the editor.
If you haven't already, then also take a look at this forum post to see if it helps. https://forum.unity.com/threads/intellisense-not-working-for-visual-studio-code.812040/
Thanks for the reply, I have seen that and worked through it with no luck so far. I'll ask a few other areas though
Does anyone know how to do a bool checkbox that indicates that some selected objects are true and others are false in a custom editor window?
EditorGUI.showMixedValue
ah wonderful thankyou
I got a API design question. I am making SerializedProperty extension methods for working with my serializable HashSet and Dictionary.
There are some methods that can be grouped together for them, like getting size, deleting, inserting, and clearing.
However A. I'm not sure if from a usability stand point that makes sense, and B. What to call them, right now I am thinking HashCollection (example: InserhashCollectionElementAtIndex(..))since it kind of feels like it refers to both HashSet and DIctionary. But I'm not sure. Thoughts?
Would it be more intuitive to just have them separated, so InsertHashSetElementAtIndex(..) and InsertDictionaryElementAtIndex(..)?
In terms of naming, I have no idea. I'm not good at names. However, I separate everything that is i something else into it's own method so if I have to add extra to it later, it's easier to not worry about screwing up something else. There is no negative really in doing so, even if you don't do something with it later. For example, Bounds and Position both use Vector3s. So, I have a method for Bounds, position, and vector3. Both Bounds and Position use the vector3s method, and the vector3 can be used on its own for something else. You could also do just 1 method if you want with null overloads and checks in the method, but, I find this approach to be possibly more confusing if sharing your code with others, especially when using a ternary operator for nullable types if someone looking at it doesn't understand, though you could condense your code
I'm having a hard time trying to understand how to implement handles into the OnPreviewGUI. Does anyone have any familiarity with this?
I'm using EditorGUI.IntField in a custom inspector and the int can't be changed by dragging left/right on the label -- any easy way to add this functionality?
Show code please. It is almost definitely a problem with how you have it set up.
here's an example using PropertyField:
in a PropertyDrawer
the other example is a bit more convoluted to get there but resolves in:
in an Editor
You are using prefixlable
Use the parameter in the field methods that take a string/guicontent for the label.
aha, let me try that
Hey,
Taking my first steps in custom editors and I'm trying to create a custom property drawer https://hastebin.com/ikaqubelum.csharp should be the relevant code. Can anybody help me on how to set the correct height to the property?
Which I'm guessing is the reason why above bug appears. When adding multiple items to the list they also overlap.
Here with multiple elements, should be 6 popups but they overlap
You need to override the GetPropertyHeight method 🙂
Ah! Tried several cruel things with it but not overriding thanks!
You can also use EditorGUIUtility.singleLineHeight to get the normal height of a single line field in the editor (I think it is 18px if memory serves)
And there is also EditorUIUtility.standard VerticalSpacing which is the spacing between two controls.
Btw, I recommend naming custom property drawer classes either MyClassNamePropertyDrawer or MyClassNameDrawer (pick one or the other way of naming and stick with it though). This will help keep things recognizable as you make things.
Like wise, name custom Editors either MyClassNameEditor or MyClassNameInspector. Just a suggestion though.
Thanks for the tips! In the process of boiling this together the drawer was confused if he will be a drawer or editor thus the name 😛 You're right I changed it.
It doesn't find a GetPropertyHeight to override. Do I need to do that for another class?
Na, I just don't remember the name. Just type override height and intellisense should find it for you 😛
Oh weird one, it has and I don't know where the error was but
won't complain ¯_(ツ)_/¯
What?
The proper override method was found, but it's the same as I tried a few minutes ago, just wondered where the error was.
Ah.. Maybe forgot override or float as the return type?
🥳
Might be, was too curios if it works to check back
From one bug to another 😄 It's displayed properly now, but the boundaries to click the popups don't match their boundaries
You are using position in the first popup which now has a height of 2 fields. I assume that is it at least.
Anybody has an idea how to set absolute node position on graphView? I dont get how the node positioning works. SetPosition seems to set the node position to be absolute but putting in 0,0 does not move any of the nodes
foreach (var node in orderedNodes) node.SetPosition(new Rect(0,0,0,0)); has no effect at all
Aw thanks, yeah that 's probably the thing
#↕️┃editor-extensions message
In the picture where it shows "Strength" and "Health" periodically that's another bug I tried to wrap my head around now for a while. If one index declaring the content of a popup gets changed all others get changed too.
I meanwhile get that always this exact CustomPropertydrawer is called and so the saved indices are the same, but I can't find a workaround to save information on that specific item on the list. Tried to log the property to their indices in a dictionary or to access the objects to store the information there, but doesn't seem to be the way. It seems like for every call a new serializedproperty is produced? Is there a documentation of the editorloop on that topic?
It is because the same PropertyDrawer instance is used for all elements in a list.
If you don't want it to do that then there is an override, something along the lines of CanCacheDrawer.
There's only CanCacheEditorGui, but that sadly doesn't do the trick
Do you return false from it?
Yes
Still all popups deriving their index from the same field in the propertydrawer change when one of them is changed
It wasn't Exit that was an Object, it was the parent
its an object not an Object
the parent is an objectReferenceValue
which is weird
but it can't be an Object I dont think
otherwise it will be only selectable
Which means that you need to make a new SO out of it to iterate its children (ie. get the exits)
im not sure what that means exactly
isn't it already one?
also the room is the issue, not the exit
if you want to iterate a UnityEngine.Object's children you need to make a SerializedObject
As I said the parent containing the exits array is an objectReferenceValue
Yes, room is the Object
no, the exits property is serialized in a different hierarchy that you'll need to retrieve by creating a new SerializedObject from the objectReferenceValue
I go over it all here https://help.vertx.xyz/?page=programming/editor-issues/serialisation/serializedobject-how-to#objects
Though I wrote this earlier in the week, so let me know if I can clarify it a bit
.serializedObject is the base SO containing room, which is the one the editor provides
thats so weird
imo
also a quick tip for your site: you should let people scroll anywhere I didn't realize I could for a minute
Ah, thanks, I think I must have fucked that up with the changes I made earlier in the week 😄
you did a good job on the look of it
very sleek
alright that works
super weird lmao why cant I just use .serializedObject
Ill go with it tho
.serializedObject is the owner of that SerializedProperty, which is the one you iterated through to get it
ohhh
I see
thank you
ok weird thing: when I try to find the newly created exit it can't be found
is there something about it not updating in the serialized object yet?
If you don't create it using SerializedProperties then yes, you'll need to call Update on the SO
Sweet 👍
like, autosave for editor? or runtime? or
what are you looking for
regardless, check out https://docs.unity3d.com/ScriptReference/EditorWindow.OnProjectChange.html
@visual stag I know that link earlier was for someone else, but, I appreciate it a lot. Been doing a lot with serialized properties and objects and that is quite handy in understanding
Thanks 🙂
I guess I'm confused by this. I have never had a problem with Unity not autosaving? That's why I was trying to figure more out what you are trying to do. The provided link is an example of an event you can register to do things like AssetDatabase.SaveAssets if you need to. Are you talking about saving editor prefs, you have https://docs.unity3d.com/ScriptReference/EditorPrefs.html or you can setdirty etc... are you talking about templates? https://docs.unity3d.com/Manual/ProjectTemplates.html are you talking about saving your layout? https://docs.unity3d.com/Manual/CustomizingYourWorkspace.html your WORKING autosave is very vague
I used https://docs.unity3d.com/ScriptReference/AssetPostprocessor.html for example to create templates for scripts to have default namespaces etc...
you can also register to https://docs.unity3d.com/ScriptReference/EditorApplication-update.html and do autosaving through that. Point is, there is a plethora of things to do, what I can only assume based off the info you have given, things Unity already does
(You can surround links in < > to remove the preview)
oh okay, ty
maybe you are looking more for something like https://docs.unity3d.com/ScriptReference/EditorSettings-prefabModeAllowAutoSave.html
Hi all. So i just finished blasting down the raw texture files in my project. Just wanna fit it to the repo (no i'm not talking about max resolution in import settings)
I'm also converting all of the existing textures to .jpg, from another extension
Now, the next step seems to be to delete the original hi res textures
But is there a way to point all existing references of the old textures, to the .jpg ones? They all got the same name
I assume after the originals are deleted, the references will become "missing", and this still holds the name of the ref'd files. Can this be done at this exact point?
Unless the links are already by GUID at this point...
You can change the GUID for your new texture to be the same as the old one, you can't have duplicates so by that point yuo need to have removed your old ones
Hmm ok. So the old texture's meta is still abc.tga.meta
And there is no abc.jpg.meta yet (i haven't let unity reimport)
If i just change all .tga.meta into .jpg.meta, will this work?
Which is fine
Damn i should've tested with 1 file first
Haven't slept, kinda hasty
How do i even batch rename this tho?
(outside of unity)
Find *.tga.meta, change to *.jpg.meta. But only do this if... there's no .jpg.meta for the same * ?
did you find a solution? If not, i've got an idea, but it would be from within the Unity Editor
Basically, you could create a static method somewhere with a [MenuItem] attribute
which opens the OpenFilesDialogue (or some similar name) from EditorUtility, set the filter to *.tga.meta,
on submit you could loop through the selected files, check if there is a file with the same name but the .jpg.meta extension in same directory,
and if there isn't, you could copy (or even replace, but won't recommend) the selected file and save it as a jpg.meta instead of tga.meta
I cant do it from unity bcoz it'll do reimport. Maybe i can stop the auto reimport first before opening
But either way, i did all this with a few programs
Bulk rename, treesize, faststone texture resizer
Does anyone know why it doesn't work? It doesn't select the option from the dropdown
Hey, i have a Script, in the Editor you can choose a enum. And everything is working. But is there a way when you choose a specific Enum to show more options. Like when you choose a Enum named OP, it will show an other int. Does someone know how, or is there even a way to do this
I guess you could do it when you check for what the enum option is 🙂
but I am not so good, you could try
Been playing around with getting blender style workspaces. They work pretty good, only a little flickering when switching and it saves the window state when switching workspaces.
nice
I'm not super familiar yet with EditorWindow.OnCreateGUI() but, is https://docs.unity3d.com/ScriptReference/EditorWindow.CreateGUI.html the route I would go to make more persistent GUI so there isn't being draw calls more than needed?
There are two ways to draw GUI, one is Immediate Mode GUI (IMGUI, this is the OnGUI method and classes like GUI and EditorGUI) this acts like an Update method does and reconstructs the UI each update.
The other is called Retained Mode GUI, this is where the UI is stored and only updated when needed. In unity you use UIToolkit(UITK) (aka UIElements) to do this. not GUI and EditorGUI.
You use CreateGUI or OnEnable to create UITK based GUIs.
okay, thanks!
I think I'm going to be delving into some of the things you had questions for a while back now haha
I'm just finding things like
foreach (KeyValuePair<SerializedProperty, GUIContent> kvp in defaultSerializedProperties)
{
kvp.Key.Show(kvp.Value);
}
to be having more.... overhead?
I have no idea what that is. However I can tell you that for showing a large number of items on the screen UITK will most likely have better performance.
("most likely" read as "Almost always")
it's just my loop to display serialized Properties in the public override void OnInspectorGUI(). And it made me think that there is no reason to keep redrawing something that is already drawn
I just didn't know how to approach that though, but will definitely check out the UITK now
I dunno if I missed something, but is there any event called when the "save" is hit in the editor?
I'm trying to refresh a list of serialized objects based on their dirty state, so I want to know when things get saved instead of polling or etc, unless there is some other better way to go about it.
EditorUtility.IsDirty
EditorUtility.GetDirtyCount
Would serializedObject.UpdateIfDirtyOrScript() do?
Hey fellas. Does it happen to u that some variables suddenly stop being editable?
Like a bool won't be clicked. Or a reference field suddenly can't be set to anything. It shows us the selection menu but it won't actually change when we select anything
This sometimes happens with my custom editors. But also sometimes with some default editors... That's annoying and I'm sure I'm doing something wrong here... Anyone has any ideas. ?
I think you could make a checking method to check if it has to save or not. Then pass that method to when exiting editor, when entering play mode , and when manually pushing a button.
Because other than those, nothing out of ordinary should happen to lose datas, unless a unity crash happens a lot in your project
hey again. i fixed that by removing the following line from any OnGUI method :
property.serializedObject.ApplyModifiedProperties();
and instead putting them inside a check like so:
if (EditorGUI.EndChangeCheck())
{
property.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(property.serializedObject.targetObject);
}
Hey. I programmed a Custom Inspector / Editor, but everytime it loses his settings
Does someone know why. And also here is my Code:
[CustomEditor(typeof(Button))]
public class ButtonEdit : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var button = (Button)target;
if (button == null) return;
EditorGUILayout.LabelField("Enum");
Button.type = (ButtonType)EditorGUILayout.EnumPopup(Button.type);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Enum Values");
if (Button.type == ButtonType.Door)
Button.door = EditorGUILayout.ObjectField("Door", Button.door, typeof(GameObject), true) as GameObject;
Button.doorY = EditorGUILayout.FloatField(Button.doorY);
}
}
#endif
Use serialized properties
What is that?
@fresh wren that's literally just serializedProperty
It's basically the shared property between the editor and your normal class
When u assign something through that, it's safely saved and loaded
Your variables all seem to be static, and are not SerialisedProperty. Static variables are not serialised and do not interact with SerializedObject
Are you just calling that from an EditorWindow. Also no need to set dirt. ApplyModifiedProperties already does that for you.
Anyone here use NaughtyAttributes? I've been told its not possible to have [Button] inside of [Foldout]'s. is this true?
I don't know what NautyAttributes are, but yes it it is definitely possible
I do it with a lot of my GUI
Never used it but I assume that is true. The reason being is because the foldout only gets the attributes from serialized properties and handles their layout.
its a custom inspector wrapper thing
sec
Yes it is possible for the developer (or community member) to add that functionality, but it is not currently possible. https://github.com/dbrizov/NaughtyAttributes/blob/master/Assets/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs#L110
foldouts have .isExpanded that can be checked, where you can put more GUI code into
i want these buttons inside the corrisponding foldouts
He is talking about if it is possible using only Naughty Attributes, and the answer is no.
yeah, I meant to clarify that he could do it outside of that if he wanted to deviate from it
example
You will need to edit the source in order to do that. I liked to the relevant line to get you started if you want. You can always add the feature and make it a PR so others can do it to 🙂
Or make it an issue on the github for someone else to consider doing if you don't feel like you can/don't want to spent the time.
I'm not that familiar with github or editor scripting to do that
i mean if its easy i'll give it a go, but if its a massive faf, i probably wont be able to do it
If you haven't done much editor scripting before than it will most likely be a bit challenging, especially since you need to understand what Naughty is currently doing.
yea i have no idea what it does backend, i just know what it lets me do
Or atleast in this instance... not let me do
Could i do this without naughty attributes? and if i can, could you help me achieve it?
Do what? Group properties and buttons together in a foldout?
Yea, i want these buttons inside this foldout
Nope, if you are using Naughty for that then the only way to do it would be through Naughty.
Damn. How do i raise an issue? Hopefully it could be updated
Go to their github
if you end up straying away from naughty check out https://docs.unity3d.com/ScriptReference/EditorGUILayout.Foldout.html and https://docs.unity3d.com/ScriptReference/EditorGUI.BeginFoldoutHeaderGroup.html
i did have a custom inspector before this, but i didnt have the knowledge to do what i wanted, so i tried out NA
Looking at it, it wouldn't be that hard to add support for it.
You say that... But im not a very smart man
Sure you are, you just lack experience an and knowledge in this area! 🙂
teach me
What you would do is after https://github.com/dbrizov/NaughtyAttributes/blob/master/Assets/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs#L27
iterate over them again and remove all of the methodInfos that have a FoldOutAttribute and put them in to a dictionary like what GetFoldoutProperties does. Then down after Line 30 you would draw the buttons like the properties are drawn.
Errr
May i request some hand-holding? Perhaps in the DM's to not clutter here?
Totally fine if not, like
Sure, I don't mind, but I'm not going to spoon feed you the code. If ya wanna do it you will need to learn what it is doing, not just copy paste code.
I can do that
ExitDrawer.cs
Exit.cs
Console
why can't it find the events property??
Exit is not a UnityEngine.Object so it should be find right?
SerializedProperty is the Exit Property
m
Thats good to know. Thanks :D
I'm not using them in an editor window, no. It's a property drawer for some class
U got the idea. But just to clarify, it is a property, but it's not serialized
imo get/sets should 100% be allowed to be editor properties but I see the issues with it
I think u could make a wrapper for it just for the editors' sake
I fixed it another way
but it would be nice
its weird to be I can't get object values tho
kinda annoying
U can make editor for them, but not through the serialized objects nice setup
unless they are UnityEngine.Objects they are invisible
true true
still can't actually get their values tho
unless I have some roundabout way of getting the object
which in this case I luckily do
Oh, you do not call ApplyModifiedProperties in a propertyDrawer
I always do this :
Class myDummyClass
{
...
#if UNITY_EDITOR
class editor : editor thing
{
...
}
#endif
}```
This way u got all the access to your values without having them serialized :D
wait how??
Oh, really? So just the begin and end check ?
just cuz its a child class doesn't mean you get the values...
Why do you need an begin and end check?
Yes u actually even have access to all the private values as well
what values tho
Well, to check for saving ? I read it in docs that whatever we do between the two, unity checks and saves
you need the object
Please don't do this...
otherwise it has no idea what it even is
No, all saving should be handled by the Editor or EditorWindow.
You will break things if you ApplyModifiedProperties in your drawer.
I know many people argue over that it's not the supposed way and it looks messy and all. But actually in action I never put the two in the same file. I make the class partial and put the editor in a separate file , with a big UNITY_EDITOR check at the beginning and end
still doesn't solve my issue
oh. That's explanins a lot. I'll try removing them to see if they still work. Thanks mate!
I can't get the object that pertains to the property that its drawing
cuz its not a UnityEngine.Object
which to me is weird
There's this target variable in case u didn't know
That really is a bad idea. It makes your code so much harder to read. But if it works for you I guess...
And you also expose things without serializing them...
THERE IS???
@wanton arrow Wait
Sorry I thought u r using that editor thing
Yeah my way doesn't work with gizmos
What are you wanting to get in the propertyDrawer?
But what are you wanting to do with the object?
Yeah, but also in the other hand, the whole point of serialization is to expose stuff... Though I believe there is a way to just serialize anything in c# , because as they say, nothing is impossible in c# , but until someone figures that out, I see my way as the only workaround to get non-serialized data and properties
I say my way but it's actually from a guy from some stack overflow. Credits to him
there are no bad ideas on personal projects only foolish ones 😏
If you want I have a method that lets you use reflection to get the value of the target of a serializedproperty.
@wanton arrow dude. I just saw your code. That has a serializedProperty, so u can access it's object lol
Yeah sorry mate, u no dude
But u can still cast it as a unity object :D
no...
As far as it's nullable
unless im missing something you cannot
The point of serialization is most definitely not to expose stuff, that is just a side effect. If it is not serialized and you want to access it, then make it a property.
U can't do this ?
sp.TargetObject as UnityEngine.Objecy as System.Object
?
The .objectReferenceValue is only if the serialized property is of a field that is of type UnityEngine.Object i.e [SerializeField] private ScriptableObject myField;
but you cannot use it on a serialized property for a field like a float [SerializeField] private float myFloat;
It is invalid, just doesn't work.
Hmm let me check in action. I remember there was something in that serializedProperty that I always used , to get the actual object ( the Target )
There is not. Best you can do is serializedProperty.serializedObject.target.
@gloomy chasm I'm opening unity rn. Just to double check though, if u use OnGUI for property drawer, it's the same as for her problem, right?
What do you mean?
of the two
What is this referring to?
This serializedProperty, and OnGUI's serializedpy
That I mentioned just above
yeah I would assume its not just magically there if I cast it into a System.Object lmao
Did you still actually have a problem or question that you needed help with?
What is weird?