#↕️┃editor-extensions
1 messages · Page 26 of 1
Probably better to ask in the Odin Inspector discord server.
yea I came to that same realization
it's [HideLabel] on the wrapper class definition in case anyones wondering
Hi, I am trying to detect key inputs so I can create custom binds(unity has very few useful ones).
For example, I wanna create a new script when you press ctrl+alt+s.
Issue is, now matter what I do, best solution I could find is hovering over the scene view to detect key presses with this:
public class EditorBinds : MonoBehaviour
{
[UnityEditor.Callbacks.DidReloadScripts]
public static void ScriptsReloaded()
{
SceneView.duringSceneGui += DuringSceneGui;
}
private static void DuringSceneGui(SceneView sceneView)
{
var e = Event.current;
if (!e.control || !e.alt) return;
if (e.type != EventType.KeyUp) return;
if (e.keyCode != KeyCode.S) return;
Debug.Log(e.keyCode);
}
}
I tried using Input.GetKey() too but it didn't work either.
I only get S when I am hovering the scene with the first approach.
Is this something that's even possible or am I out of luck?
please @ me if you are able to help, I won't see the reply otherwise
Why not use a ShortcutAttribute?
I'll look into that
that looks like the thing I needed, will try to implement it a bit later, thanks
yeap, that worked, thanks a ton!
[Shortcut("NewNnScript", KeyCode.S, ShortcutModifiers.Control | ShortcutModifiers.Alt)]
private static void NewScript() =>
ProjectWindowUtil.CreateScriptAssetFromTemplateFile("Assets/NnUtils/Scripts/Editor/NnScriptTemplate.txt", "NnScript.cs");
how can i draw custom editor ABOVE my script variables?
Call base.OnInspectorGUI() after you draw everything else
huh
like
draw editor stuff
base.inspector gui
draw default inspector?
base.oninspectorgui will draw the default inspector
oh
So yeah draw your custom stuff first, then call that
Check the second-last message here:
https://forum.unity.com/threads/hide-script-objectfield-in-custom-editor.888577/
That should be it
If you do that, don't call base.OnInspectorGUI
Do you have a property/variable named PlayFabManager?
its script name
You were supposed to exclude m_Script
the one i want to remove
I think just doing this would work
DrawPropertiesExcluding(serializedObject, new string[] { "m_Script" });
If you want to draw everything but the script header/objectfield
i have this now
lol
What exactly did you type
EditorGUILayout.LabelField("Player Info", EditorStyles.boldLabel);
EditorGUILayout.TextField("PlayFab ID", playFabManager.PlayerID);
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"));
DrawPropertiesExcluding(serializedObject, new string[] { "m_Script" });
Again, you only need this #↕️┃editor-extensions message
And before that, draw your custom stuff
This line ```cs
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"));
Draws the script object field manually so you dont want that
@real spindle do you know how to draw lists by any chance
this thing is so confsuing 😭
See the answer on Stack Overflow
Hello, I am trying to figure out what is being called in a string method in the inspector.
So when you click into the inspector to edit a string what method does unity use to know this string has changed and you have clicked off of the inspector.
I am using OnValidate to update data after you exit a string.
right now I have found that
EditorGUI.EndChangeCheck()
will check when a change ends but this is called every time I update the string I would like something that will be called when I exit the string in the inspector.
Here is what I have for code
private void OnValidate()
{
if (autoUpdate == false) { return; }
if (previousAssetName != AssetName && nameUpdated == true)
{
if (EditorGUI.EndChangeCheck())
{
nameUpdated = false;
UpdateName();
}
}
}
Hello guys, i have a small problem about repainting a property,
i a using a custom editor to draw a property, but the repaint is doing only if I move my mouse.
i have try InternalEditorUtility.RepaintAllViews(); but this is using too much performance (5 fps)...
do you have a solution to repaint my property every 0.5sec, so i keep my fps ?
Is this what you're looking for? https://docs.unity3d.com/ScriptReference/DelayedAttribute.html
So Unity 6000 deprecates CanCacheInspectorGUI
[Obsolete("CanCacheInspectorGUI has been deprecated and is no longer used.", false)]
No alternatives mentioned, anyone got any ideas?
That'd be nice if Unity rewrote my existing editors to be retained mode
I'm just the messenger
It's interesting they don't mention it in the release notes either
That is weird since there are still a lot of IMGUI Property drawers. Maybe they are doing it to 'encourage' people to move to UITK.
For anyone that implements an ObjectField that shows that object's in the inspector, how do you deal with circular references? Setting an object A that shows B that shows A, etc...
object a
object b
object a
object b
etc...```
You don't/can't
Right now I'm using property.depth and limiting to 10.
In the future I can only see the implementation of a cached ancestry tree for this FieldInfo from the same SerializedObject, following all the custom elements of the same type
Is this via a PropertyDrawer or a custom Editor for MonoBehaviour/ScriptableObject?
PropertyDrawer
Hmm, okay actually I know what you can do if you are using UITK. Add a class to it, and then you can just not display the editor
I’m not following
Well, there is a couple of ways to do it. But one way is to in the AttachToPanel event, check if an ancestor has the custom class. If so, then don't show the Inspector for the object field.
Is it possible to hide some of the Create-Elements I am not using with custom editor code? Feels a bit bloated
Anyone know where I can find the replacement for SetIconForObject, it doesnt seem to exist anymore
private static void AssignLabel(GameObject g)
{
var tex = EditorGUIUtility.IconContent("sv_label_6").image as Texture2D;
var editorGUIUtilityType = typeof(EditorGUIUtility);
const BindingFlags bindingFlags = BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic;
var args = new object[] {g, tex};
editorGUIUtilityType.InvokeMember("SetIconForObject", bindingFlags, null, null, args);
}
nvm found it
Depends on how desperate you are. There is some internal classes with methods that let you remove menu items. Look for MenuUtility, and Menu iirc.
in a class that inherits from TextValueField<string> how can i get the start and end index of a selection?
.textSelection.cursorIndex to selectIndex
i need to get them in override void SetValueWithoutNotify, but they are the same
public override void SetValueWithoutNotify(string newValue)
{
Debug.Log(selectIndex);
Debug.Log(cursorIndex);
if (string.IsNullOrEmpty(_oldValue) || string.IsNullOrEmpty(newValue))
{
base.SetValueWithoutNotify(newValue);
return;
}
int richIndex = GetRichIndex();
int modifiedLength = _oldValue.Length - newValue.Length;
if (modifiedLength > 0) _richBuilder.Remove(richIndex, modifiedLength);
else
{
int lastIndex = richIndex + Mathf.Abs(modifiedLength);
for (int i = richIndex; i >= 0; i--)
{
}
// for (int i = index; i < lastIndex; i++)
// _richBuilder.Insert(index, newValue[i]);
}
_richTextElement.SetText(_richBuilder.ToString());
_oldValue = newValue;
base.SetValueWithoutNotify(newValue);
}```
and if i register the mouse down event, i doesnt get trigger when i click on the text box
I can only imagine that there is no selection at that point in time
yea i think, but idk what event should i register to
You'll have to provide some more info about when this is being called
its the built in function, i just override it
Hello, I'm a bit new to creating custom editors, and this would help me a lot
I have a base abstract class Fruit.
I have children classes, Apple, Banana and Orange, each with different parameters to change.
I want an editor that can select one of the children classes of Banana from a dropdown and use that class's field editor.
For example, I have a List<Fruit> fruits, and in the editor I add a new element. It shows a dropdown, and once I select class Banana, it allows me to change the parameters of that Banana object; when I find it on the code, I can cast that Fruit object to Banana and use its parameters.
How would I do this?
field.RegisterValueChangeCallback((callback) => function.Invoke(target, null));
does anyone know why the callback triggers when i move or add components in the inspector?
this is inside a property drawer
I ended up doing this. I should have thought of it but I was just brain dead
public static bool IsCircularReference<TElement>(this TElement element, Object value)
where TElement : VisualElement, INotifyValueChanged<Object>
{
bool isCircularReference = false;
VisualElement parent = element.parent;
while (parent != null)
{
if (parent is TElement parentElement)
{
if (parentElement.value == null)
{
break;
}
if (parentElement.value.Equals(value))
{
isCircularReference = true;
break;
}
}
parent = parent.parent;
}
return isCircularReference;
}```
Weird question, but is there a way to force unity to focus, force a dialogue to pop-up to tell the user to focus (ShowDialogue requires a focus first), or to fake a focus so my InitializeOnLoadMethod function can start running? I have to do a few restarts for an editor tool and if the editor isn't focused when it restarts, then it won't keep going until you do.
Figured it out, EditorApplication.delayCall requires an initial focus, while EditorApplication.update doesn't, so I just that for a frame and just deregister once it starts.
Does anyone know if there is a callback that I can hook into during the build when a scene is being added to the build? I'd like to run some processing on scenes at build time, but it seems like the only callback I can find occurs before the build starts.
Thanks!
is there a way to rename the scene name in the hiereachy only? i need multiple instances of this scene, and want them to be named differently each, but i cant get a reference to the ui object representing this scene
I don't think so.
Simply right-click on your scene in the Hierarchy and click Select Scene Asset. It's going to select the scene in the Assets. Press F2 or right-click and click Rename to rename it.
i dont want to rename the scene though
Got it, I thought you were referring to renaming it via Hierarchy
No, there is no way
😔
And I don't see why you would have several scenes named the same way
Also, I don't know whether it's possible
i have a multiplayer game
its not several scenes named same way
its 1 scene opened multiple times
There is no way.
that sucks... https://yarnthen.github.io/yarnthencohosking/how to/2018/04/25/Unity-Custom-Hierarchy.html i found this article to manipulate the game objects display and name in the scene hieararchy, but cant do it for the scene itself. so weird limitation...
How to create a custom Hierarchy for your Unity 3D with an editor
I want to create a prefab asset with sub-assets at once, how can I do that?
You make a prefab asset... and then add sub-assets to it...? Not sure I understand the question
sorry for poor description 😅
I have been getting a bunch of "broken text PPtr record" or something errors when I was trying to create a prefab with sub-assets in script.
I was just trying to do the following:
create a game object, add component, create new material and shader, assign them to the component fields, then save this game object as a prefab and the material and shader as sub-assets
now when I made a modification and rolled back somehow I don't get PPtr errors again...
Is there any way to serialize unknown class?
similiar to PropertyField but without actually having SerializedProperty
I need to make custom drawer for [SerializeReference] collection
but I can't figure how to make property fields
my class does not derive from UnityEngine.Object
Hmm, I would try doing it with just making them normal assets instead, and see if that works. Could also try some of the assetDatabase methods, like ForceImport (or something like that)
Inherit from PropertyDrawer
Huh?
Maybe I don't understand, but it sounds like you are just wanting a PropertyDrawer for a POCO
I have VisualElement root and System.Object instance. I need to make a serialized property field for it
I want to visualize int/float/ushort/string field based on what type is it
hmmm, with CreateAsset but using .prefab in path? I could try, currently I have been trying with the PrefabUtility.SaveAsPrefabAsset(newlyCreatedGO)
No, no I mean instead of saving the Material as a subasset, save it as a normal asset.
Can you maybe give a bit more context of the scenario and surrounding code?
[SerializeReference]
internal IKek[] variables = Array.Empty<IKek>();
I want to make a custom drawer for this collection
where I simply would serialize each instance separately
so I got my custom drawer, I got my instance. I iterate this collection... but what do I do to serialize each of those IKek instances?
I don't know which type is it
I only know, that Unity can serialize it for sure
because they are simply primitives
Ugh, IKek is an interface? Good luck with that...
Okay, so lets clear a couple of things up.
- They are already serialized.
[SerializeReference]tells Unity to serialize the values. So that is already taken care of. - The way you normally have custom field drawing for a type in the inspector, is by making a class that inherits from
PropertyDrawer. PropertyDrawercannot draw for Lists or Arrays.- This leaves you with three options.
- You make a
PropertyDrawer(orEditorif a UnityObject) for whatever class contains theIKek[] variables. Iterate over the SerializedProperty and check the type, and draw whatever field is appropriate for that type. - You make a PropertyDrawer for
IKek, check the actual type, and draw the field for it. - You make a PropertyDrawer for each type that implements
IKek.
- You make a
Option 1, lets you change how the list looks and how the IKek variables are draw specific for that use/object.
Option 2 and 3 change how the IKek field is draw in the inspector no matter where it is used.
Does that make sense @north sphinx?
oh hmm. Didn't know I could make property drawer for interface
Ahh, yup, can make them for generic classes too
You taught me this last time 😅
Haha
but anyway
it's not really a solution
because I don't know how to actually make a property
I have my UnityEngine.Object which contains this IKek[]
I'm trying to make a drawer for each of IKek
separately
but so far I have no idea how
foreach (var kek in ikeks) { ??? }
Where do you have that?
Wait... that is different
well, yeah
So are you making a PropertyDrawer for a UnityEngine.Object?
yes, SO which contains this array
but I want it to simply make drawer for each, without showing list view
practically as if it was a field
Ahh, okay that makes more sense now
So you want to just show it like a list then?
Normal old list, nothing special?
no
I want it to show as if it was drawn as fields
public IKek one; public IKek two;
this would give me exactly how I want drawer to be
but I need this in a collection
I can't hardcode it
So, at the simplest you do
foreach(SerializedProperty kekProp in serializedObject.FindProperty("variables"))
{
root.Add(new PropertyField(kekProp);
}
huh? let me check
seems easy enough
I can't remember if PropertyDrawer is cached when using with UITK. If it isn't this is easy-ish.
Assuming you have a ObjectField, for your UnityEngine.Object that contains the IKek array. You create a SerializedObject when the value changes, and assign it to a field in the PropertyDrawer, and recreate all of the IKek field elements.
And in DetachPanelEvent you dispose of the SerializedObject
Oh.. yeah Odin has a custom property drawer already for all UnityEngine.Object fields
Does anyone know why my Colors in the inspector default to black w/ 0 alpha despite doing this [SerializeField] public Color controlColor = Color.white;
can you not set default values for colors?
Probably because your thing has laready been serialized?
nah tried resetting
if thats what u mean
actually it might be because its in a serialized class
Im having an issue with trying to add a bool toggle to a preexisting component using UnityEditor.
I cant find any good source the expand on how to make bool toggle.
Heres a simplified ver of my script
public class SnapTransformComponent : Editor
{
public bool posX = false;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Transform transform = (Transform)target;
GUILayout.Space(10);
GUILayout.Label("Position");
GUILayout.Toggle(posX, "X");
}
}
The issue is when in the inspector and I click on the bool toggle, it sets it to true and instnatly to false. Nowhere in my script sets the bool to false. I may have written the toggle box incorretly though however, any suggestions?
you should be assigning posX = GUILayout.Toggle(posX, "X")
and maybe use ChangeScope or imperative Begin/EndChangeChecks https://docs.unity3d.com/ScriptReference/EditorGUI.ChangeCheckScope.html
these function have two purposes:
- they draw a gui element
- they return new value of the clicked control
ah alright, i'll have a look, also thank you, it worked.
I thought the posX after GUILayout.Toggle was the variable it was using.
also: is there a reason you are not using the modern UIToolkit?
well, it is using the variable to render, but it's not passed by reference but by value, so there would be no way for it to update it without you manually asigning it
Honestly, I only just heard of that term today. Does it allow me to edit UI from pre existing components? The script I was making was just a "for fun" script that just snaps XYZ, Pos,Rot,Scale by either Floor, Ceil, Round. Has no real use, it was just for fun and practice
ohh that makes sense
it lets you write modern Editor windows and whatever, it's basicallty the tech unity is migrating to
ah, well I shall look into that
yeah, check out the docs, maybe some YT videos about what it really is
it's a lot easier to use than the old system
Hello there
does anyone know a way to change the background color of a referenced object in the hierarchy?
like, when I select one object, and another in the same hierarchy is referenced by it, also change its background color
specifically, I figured out how to change the style of a single object in hierarchy, but dont know how to get the rect of the referenced one
I am actually not sure, whast the best place to ask for. Is there any guide or walkthrough on how to deliver a current projects basesystem as a package for others to be included from lets say git repo? Just wondering if I can just throw all assets in the Runtime folder and copy paste the json package manifest content as dependencies in the package.json?
Heyho 🙂
In a project i'm working on, they're making use of "scriptable object event channels". I'm sure a lot of you might be familiar with them, since UOP used them and they're mentioned in unity's ebook etc.
What i'm trying to do is to extend the editor in such a way that you can select those event channels, and raise the event with a button. That part is working, but when it comes to draw some fields to pass as the arguments for the selected channel, i'm starting to struggle.
Those arguments that are passed might be primitives, but also some custom EventArgs struct, which in turn could contain several members, including interfaces. What are my options to pick an object that implements said interface?
Here's some shortened code: https://gdl.space/viyotuviyo.cpp
I'm sure there is a less repetitve way of handling this, without all the repetition, but my first attempt to handle it with reflection and so on failed, so that's the current attempt. 🙂 I hope i'll figure something out later on, but for the moment i try to handle the issue with interfaces.
Maybe https://discord.com/channels/489222168727519232/497872424281440267 would have been a better place, but i'm also not sure 🙂 Doesn't feel like it belongs into this one tho 🙂
Have you read https://docs.unity3d.com/Manual/CustomPackages.html and https://docs.unity3d.com/Manual/cus-share.html ?
Yeah, Ive been digging into it the last hour and getting rid of errors on my side, but will get back to unity talk, if it persists to not work 🙂 Thanks for the help tho! 🙂
Just change protected TArgs Args = default!; to be serialized field. And make a SerializedObject of the editor itself, then you can just draw a PropertyField for the Args serialized field in the editor
This sounds great, might simplify a lot of things. I'll give it a try later. Thank you 🙂
So i followed these steps, had to mark the struct as serializable and the interface as SerializeReference to at least show up. But this leaves me with uneditable fields in the inspector.
Did i miss something obvious?
afaik unity still has no built in support for editing serialized references like this, you'd need a custom drawer
Don't know unless ya show the code. Though this does tickle something in the back of my brain about a bug that used to be in Unity... 🤔
Yo peps, is there an easy to use serializable array?
Are arrays not already serializable?
They are, i just meant to easily format those.
There is an undocumented one. But it's pretty hard to use. :p
So, you don't have an actual serialized array, but you want to draw an array in the inspector that can be edited, as if you had a serialized array?
Yes, draw.
Because if you had a serialized array or List, you could just make a PropertyField for that to draw the default property drawer.
Please elaborate on what you're actually trying to achieve
But otherwise you have to use something ListView, which is the UI Toolkit equivalent of the undocumented ReorederableList.
https://docs.unity3d.com/ScriptReference/UIElements.ListView.html
You're asking for a solution while we don't even know what your problem is currently
Here's the updated version. https://gdl.space/vadahupiru.cpp
Hmm, it is possible the HideFlags on the Editor default to not being editable in the inspector. You could try clearing the flag...
AssetPostprocessor.GetVersion's return value should be increased at least every time I publish an update to a package, correct?
I've been increasing it every time I change the script so that Unity will reimport assets properly
Sorry which flag do you mean here?
Hello. I've been learning about creating editor extensions and I'm trying to learn how to make a viewport within an inspector but I am having a hard time finding resources. Essentially, what I would like to create is a tool that can create a "solar system" scriptable object. I want the ability to add a sun or multiple suns, planets, moons, celestial bodies. For the parts about creating the scriptable object and populating the data that is no problem, but when it comes to visualizing it in the editor window, I am at a complete loss. Any documentation you guys might recommend or perhaps just proper keywords to search up online as I have not found much so far.
Hi! I'm submitting a package and it has content that's under the MIT license (a version of naughty attributes)
it got rejected because i dont have the license attached, is that correct? I thought with MIT license it didn't matter?
Basically what you are going to be needing to do is to make a PreviewScene, add a camera to it and whatever objects you want, and then render it to a RenderTexture and draw that. There however is some caveats, like needing to setting the RenderSettings, otherwise it will use the current Scene's settings, and messing with clipping and stuff.
Unity provides a undocumented PreviwRenderUtility class which could do what you need. You can probably google to find some community tutorials and info on how to use it. Looking at the source code for how it is implemented and where it is used might also provide good insight . But there are things online on how to use it, so I would start there.
Thank you. I'll definitely look into this as what I've found so far looks to be way above my pay grade. (Mesh api)
Yeah, no need for that. Quick google led me to this which at a quick glance, looks right https://gist.github.com/chrisyarbrough/52ecc71c616614231e3fc0aacde0c08a
Amazing. I really appreciate it. I had no idea what key words to use for my search. As you can imagine, I was getting some pretty bad search results.
Yeah I just did Unity previewRenderUtility 🙂
Simple always works best!
Read the license, it's not long.
ui toolkit really good for making Editor script, but for me it's still full of mystery....first: how to get visual element position in screen space?, then second how to get its screen position relative to parent or even root visual element?
https://forum.unity.com/threads/how-to-position-visualelement-at-specific-screen-coordinates.1283957/ Take a look at this.
To position relative to parent, you can set margins, set positions, etc... To set relative to root, set visualElement as absolute and position it like before.
Now i know why the string can't serialize.
I'm totally setting it with a string type tho, but i guess the content got too arbitrary.
Not true
The type probably isn't right
I'm not sure if that's physically possible since i would get type errors if i tried that.
I was trying to cast some byte data into chars array, then string. Then tried to serialize that. I guess unity didn't like that.
Right now, its all too abstract to be able to help you
Neither am i too interested to ask for rn anyways. 
thanks for reply....i did figure that out, but how about its position in screen space? do you have any information about that??, as example case, i work mainly for editor script today, and i want to display a search window or advanced dropdown on top of the desired visual element, with adjustable position by offset, but get the screen space position of that visual element is so confusing
the editor window has position property with it, but visual element is not
Hi ! I am struggling with a PropertyDrawer. It is like like this
- PropertyDrawer A uses UIToolkit and contains a PropertyField which displays another custom PropertyDrawer B.
- PropertyDrawer A is used for a class, and I have a list of this class which is properly displayed.
- PropertyDrawer B is fairly simple and contains a GUILayout.Popup, which is displayed correctly.
My issue is, when I use the popup and select a value, on selection, the element in the list gets hooked to my cursor as if I was reordering the list. I'm using Unity 2022.2.17. Maybe I'm missing an event consumption at the popup level, but I'm not sure what kind of event I have to catch in the first place...
How od I get UITK to align these toggles properly?
Or rather, how do I get the inspector behaviour of aligning all field inputs?
IIRC, you have to this class to your element : unity-base-field__aligned
toggle.AddToClassList("unity-base-field__aligned");
Is what I just added but it doesn't seem to do anything
The doc doesn't give much more info on this unfortunately. I'm trying to find MechWarrior's message on this subject since this question is often asked.
Here. This message and the ones following may help
Yeah that's basically what I have
It's in a custom editor window by the way
Adding unity-inspector-element to the parent seems to have worked
But now everything has an extra indent
jfc this is a mess
Especially since these are default controls...
To illustrate my issue, here is a small example of the random stuff that happens when I use the popup
The element sticks to my mouse for no apparent reason. I tried to see if a drag event was fired, tried to consume current event at the popup level, to no avail
That should work with toggles or any other field that is displayed in the inspector
Yeah that's what you'd think
var defaultFormatEnumField = new EnumField(formatProperty.displayName);
defaultFormatEnumField.BindProperty(formatProperty);
defaultFormatEnumField.AddToClassList(UNITY_BASE_FIELD_ALIGNED);
var standaloneFormatEnumField = new EnumField(formatProperty.displayName);
standaloneFormatEnumField.BindProperty(formatProperty);
standaloneFormatEnumField.AddToClassList(UNITY_BASE_FIELD_ALIGNED);``` Pretty sure. I've been using UIToolkit for months now
In a editor window or inspector?
You're right. I never noticed. I usually use InspectorElement to draw UnityEngine.Object
If you can somehow get a value to check if the popup is open or not, you can StopImmediatePropagation of an event at the UIElements level. I'm not sure if this will work.
Not sure there is such a value for a Popup. I might be missing the info, but the only thing I get access to is the returning value, which is the selected option index
Or check if the IMGUIContainer that contains the Popup is being focused
I am writing an AssetPostprocessor that uses a second file to update an imported mesh.
I'm using context.DependsOnSourceAsset(path); to indicate that I depend on this file, and it's mostly working. When I update the second file, the model gets reimported.
However, if the model is imported without that file present, and I then create the second file later, nothing happens.
It doesn't look like DependsOnSourceAsset does anything if the file doesn't exist...which I guess is reasonable
but can I do anything about this?
so, I need:
- Unity imports Foo.fbx normally
- I create Foo.uv
- Unity reimports Foo.fbx
actually, hmm, the reimport on file change isn't quite working right either -- it does reimport, but it doesn't run my postprocessor..?
a-ha! I get it -- I was cycling through a few different sets of data for the second file
Unity was recognizing it had already seen them before and just used the relevant import result
I was not incrementing the version of the importer.
now i just have the original problem (:
Anyone knows where the internal styles are defined?
I figured this out, the parents of the aligned field need to be unity-inspector-element and unity-inspector-main-container (somewhere in the hierarchy), main needs to be higher in the hierarchy and can't be the same object, nor can it be the rootVisualElement. You still need the UNITY_BASE_FIELD_ALIGNED class too
Does this mean you'd still have the problem in an EditorWindow ? I assume both those class are only in the context of an inspector
By default but you can add them yourself as just empty visualelements
Pretty frustrating to be forced to use that kind of workaround 😅
I was interested in this earlier, but I couldn't work it out
I was having problems with deeply-nested IMGUI elements suddenly winding up with bad horizontal positions
looking at the computed styles, it just didn't define styles past a certain level of nesting
Lol
It's been what 4 years since uielements, and I still can't believe they're committing to it in such a bad state
Hear hear, and ironically enough UI Builder has the worst UX of anything in Unity.
Anyway, for my question:
https://docs.unity3d.com/ScriptReference/PrefabUtility.LoadPrefabContents.html
Im trying to load the prefab of the ScriptableObject I double click, but nothing is happening, why would that be?
#if UNITY_EDITOR
[UnityEditor.Callbacks.OnOpenAsset(callbackOrder: 1)]
private static Boolean OnOpenAsset(Int32 id, Int32 line)
{
UnityEngine.Object __obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceID: id);
if(__obj is not Recipe __recipe) return false;
if(__recipe.Prefab == null) return false;
String __assetPath = UnityEditor.AssetDatabase.GetAssetPath(__recipe.Prefab);
Debug.Log(message: $"Opening Recipe: {__recipe.name} with prefab: {__recipe.Prefab.name} at path: {__assetPath}");
UnityEditor.PrefabUtility.LoadPrefabContents(assetPath: __assetPath);
return true;
}
#endif
Loads a Prefab Asset at a given path into an isolated Scene and returns the root GameObject of the Prefab.
Does this not mean it actually opens the scene in editor like it does when you double click a prefab?
If not, then how do I mimic that?
Oh, seems I was too hasty here, the third Google result had my answer, this indeed does not do what you'd think, it's all behind the scenes.
You need to use UnityEditor.AssetDataBase.OpenAsset()
#if UNITY_EDITOR
[UnityEditor.Callbacks.OnOpenAsset(callbackOrder: 1)]
private static Boolean OnOpenAsset(Int32 id, Int32 line)
{
UnityEngine.Object __obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceID: id);
if(__obj is not Recipe __recipe) return false;
if(__recipe.Prefab == null) return false;
UnityEditor.AssetDatabase.OpenAsset(target: __recipe.Prefab);
return true;
}
#endif
Apparently this is even better?
Not sure what the exact differences are though.
UnityEditor.SceneManagement.PrefabStageUtility.OpenPrefab(prefabAssetPath: UnityEditor.AssetDatabase.GetAssetPath(__recipe.Prefab));
I'm curious to see what's your Debugger tree like. I never made it work like you did
I currently have something like
.unity-inspector-main-container
|
--- ... (some hierarchy levels)
|
--- .unity-inspector-element
|
--- ... (some hierarchy levels)
|
--- CustomField.unity-base-field__aligned
|
--- Label```
I can show you tomorrow
I've been trying to write an editable text field in a unity Editor window and like, nothing I do lets me edit it. I cant find a single reason why I can't edit this field, there's nothing special about it. I assume something I dont know or dont understand is preventing it.
// Initialize the edited damage string if not already set
if (string.IsNullOrEmpty(guiAttackData.EditedDamageString))
{
guiAttackData.EditedDamageString = guiAttackData.TotalDamagesString;
}
// Display the text field for editing damage
Rect textFieldRect = GUILayoutUtility.GetRect(200, EditorGUIUtility.singleLineHeight);
guiAttackData.EditedDamageString = EditorGUI.TextField(textFieldRect, "Total Damage:", guiAttackData.EditedDamageString);```
Is there any obvious reason there why I cannot edit the EditorGUI.TextField? when I click in it and select the text, but I cannot edit the text. Hitting keyboard keys do nothing
All the other fields let me edit them just fine, but something's special about THAT stacks of fields that prevents it
Here's the full stack that leads to the field being drawn:
spent about 4 evenings on this now, the fields just arent editable no matter what I do
not editable either 🫠
something haunted has to be going on, this field isnt editable no matter how simple I make it
private void ChatboxInputField()
{
textFieldInput = GUILayout.TextField(textFieldInput, GUILayout.ExpandWidth(true));
if (Event.current.type == EventType.KeyDown)
{
SubmitInputField(textFieldInput);
Event.current.Use();
}
if (GUILayout.Button("Submit", GUILayout.Width(100)))
{
SubmitInputField(textFieldInput);
}
}```
THIS was the problem, I finally found it 🫠
somehow this was eating all subsequent inputs
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return)
this made it stop consuming all inputs but I dont really understand why
when you Use() an event, you're indicating that nothing else should process it
Does this help?
I had to add extra padding to the dropdownfield though since htat wasn't indenting correctly
bit of a question about writing my own asset importer.
I am going to be reading a binary file and extracting many records from it. For each record, I want to let the user configure how to handle that record.
How should I do this? I guess I could make a List<RecordInfo>, but ideally the user shouldn't be able to manually create or remove entries from this list
Perhaps I need to make a custom editor.
Definitely. You should serialize the list on the ScriptedImporter and that'll end up in the meta file
Do I need to mark something dirty after updating the list, or would that only be relevant if I was modifying the importer’s settings and needed it to import again?
Hello there
does anyone know how to check in a custom editor when someone has finished editing a property?
Like, when I have a list of ints and want to sort them
but when I try to do it in OnInspectorGUI, the sorting happens on each new character input
https://docs.unity3d.com/ScriptReference/AssetImporters.ScriptedImporter.html mentions this, but this is clearly for when you're modifying an importer externally
rather than updating its serialized data as part of the import
so that makes sense, yeah
Use a delay field so the value isn't returned until the user pressed the enter key or the control loses focus https://docs.unity3d.com/ScriptReference/EditorGUILayout.DelayedIntField.html
anybody knows how to get selected assets in tree view of project window?
Selection.objects or Selection.activeObject
A note: you can get folders. Folders' assets are of type DefaultAsset (folders don't have a types)
thanks, but as i tested Selection.activeObjects does not include objects that selected in tree view
but i found working solution:
_treeViewSelection = Selection.GetFiltered<Object>(SelectionMode.Assets);
Oh yeah. Forgot to mention that. My bad
np
I had feature in my inspector so that part of it glows when hovered.
It was very unresponsive (basically updated when inpector gets redrawn which was about every second)
Dont want to update my inspector all the time but when being hovered, i think it is okay
This code solved my problem which was not visible at first but started to appear now
if(checkRect.Contains(Event.current.mousePosition)) {
EditorUtility.SetDirty(target);
}
Now when hovering over inspector, cursor keeps switching to loading icon and back
Searched far and wide over internet and can't figure out how to make this happen
To note, this code is executed on object inheriting ": Editor"
You can just call Repaint() inset of EditorUtility.SetDirty(target)
It just works
I have been trying to find the answer for this for months (on and off)
and never saw that
Great, glad I could help 😄
Is there a way to modify the class header inspector? I know there is OnHeaderGUI() but there is no information about it. Everything I tried didn't worked so far 😄
Are there any differences between OnDrawGizmos (https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnDrawGizmos.html) and DrawGizmoAttribute? (https://docs.unity3d.com/ScriptReference/DrawGizmo.html)
Is one way recommended over the other for some reason?
looks like they both achieve the same thing, only in two different ways with some other constraints (e.g. one only available in classes derived from MonoBehavior, another available anywhere as a static function)
is this what you mean by "class header inspector" ?
ah, editor window ≠ inspector header, it might not be what you are looking for...
yeah excatly, but i figured it out! Messing with inspector toolbar isn't worth it - that's the conclusion 😆
I'm having a weird one. My scene view only ever updates/renders if I'm moving/looking/scrolling or if I'm in play mode. Was messing around with editor scripts and render pipeline asset/camera stuff and not sure which broke it. I've since deleted the editor script but could there be a chance the internals haven't updated? Do I need to recompile Unity somehow?
Anyone know how I can figure out how to fix this?
Seems like its localised to a single scene and still happens even if I remove everything in the scene. What??
@whole steppe is Always Refresh on?
Oh my god thank you so much. I was just about to redo an hour of work
I was hoping that was the issue! Gets me often, as it's off by default to save on resources 😄
huh, interesting, I wonder does it do the same thing as EditorApplication.QueuePlayerLoopUpdate();?
as that's what I was using for editor tool, as the updates were happening in a very slow rate, mostly when moving mose, moving camera etc, similarly to Cloudy's case
Hi! So I'm trying to write an editor tool that processes some levels, and I encountered unusual thing.
How do I assign a prefab to a script programatically?
Basically I have a component CoolScript that contains List<GameObject> myPrefabs; and which does totally awesome stuff with them, and so far I've been filling that list manually. In older version of my scenes I have just instantiated the objects directly in the scene. However, with the magic of EditorUtility.GetPrefabParent() I can get the prefab from the instantiated objects.
So, once I've found that prefab, I want to feed it into the CoolScript.myPrefabs, alas it is Object and not GameObject (as the prefab is not instantiated, but lies waiting in my assets). Considering you can drag and drop prefab in inspector onto a GameObject field, it follows that I should be do it programatically, but I can't figure out how.
It is a GameObject, you just gotta cast it 🙂 (GameObject)thePrefabYouFound
Uhh Debug.Log(thePRefabYouFound); it
It is possible you are not getting anything at all.
oh god never mind, I'm such a doofus
the list wasn't allocated
sigh
I've been looking at this code for like an hour now
everything was being casted correctly xD
Haha, been there
Hi ! Is it possible to replace the popup that a DropdownField show ? Like if I wanted add a searchfield.
Hello everyone! I wanted to ask for a suggestion about how to proceed on an editor implementation. I want to show a custom property drawer for a field, which is an array of scriptable objects. The editor for this component is currently a custom editor in UI toolkit.
I tried creating a custom component with BaseField<MyScriptableObject[]> as base, and use it in the UXML by binding it to the field I want to show, but I guess BaseField does not work with this type (I never get any SetValueWithoutNotify calls, whereas it works if I switch to, say, a BaseField<string> and bind it to a string field). In that regard, I wonder where it's written the types of fields it work with.
I also looked at how ListView is implemented, which surprisingly enough only inherits BindableElement but does not implement INotifyValueChanged (but I admit I still have to get the reason why we have two interfaces for this, so there must be a reason there); in any case the implementation looks pretty complicated and quite tailored for the specifics of ListView, so I don't know if this would be the correct route.
I guess I'm missing something pretty basic, but before I go further I wanted to get some suggestions about the simplest way to go.
[MenuItem("GameObject/Microlight/SpriteRenderer Health Bar")]
private static void AddSpriteRendererHealthBar() {
// Get prefab
GameObject go = MicroEditor_AssetUtility.GetPrefab("SpriteRendererMicroBar");
if(go == null) return;
go = Instantiate(go); // Instantiate
go.name = "HealthBar"; // Change name
if(Selection.activeGameObject != null) { // Make child if some object is selected
go.transform.SetParent(Selection.activeGameObject.transform);
}
}
[MenuItem("GameObject/Microlight/UI Image Health Bar")]
private static void AddImageHealthBar() {
// Get prefab
GameObject go = MicroEditor_AssetUtility.GetPrefab("UIImageMicroBar");
if(go == null) return;
go = Instantiate(go); // Instantiate
go.name = "HealthBar"; // Change name
if(Selection.activeGameObject != null) { // Make child if some object is selected
go.transform.SetParent(Selection.activeGameObject.transform, false);
}
}
I have this code that allows me to spawn 2 prefabs from the folder. This code works.
My question is, how to make this dynamic? So that is searches for all of the prefabs inside the folder and generate menu item for the each of those.
Ideally, I dont know exact folder (if user moves folder from "Assets/Plugins" to for example "Assets/OtherStuff")
hey yall, it's my first time making a custom inspector for a script and I think I made some sort of rookie mistake here.
While all fields drawn are editable, only the Y Rotation Limit fields and Y Position Limit fields retain their values. Everything else resets to 0 when clicking off or hitting enter after inputting some value. As far as I can tell, all 6 of these are identical so I don't know what's causing it. (Don't mind how X Rotation Limit has different display, i was fiddling with a better organized field)
Couple of things, firstly, it is because the other draw methods are actually setting the xPos/xRot values not the x/y/z that they should.
Additionally, none of the values will be serialized since the fields are not public or marked with [SerializedProperty], and the object is not set to dirty.
Though really it would be much better to use SerializedProperty and SerializedObject for getting and setting the values, as that supports undo/redo automatically, along with allowing prefab overrides
I think I finally found my answer in here: https://docs.unity3d.com/Manual/UIE-bind-to-list-without-listview.html
Apparently, the solution is not binding to an array property but manually handle the array operations. Seems strange to me, but here it is. I wonder now how exactly ListView can work though, because ListView can definitely bind to arrays.
_listView.RegisterCallbackOnce<GeometryChangedEvent>(_ =>
{
_listView.Rebuild();
});``` is this the way we successfully draw a `ListView` for the first time? After `AttachToPanelEvent`
What do you mean "successfully draw a ListView". What is it you are asking exactly?
The ListView only populates if I Rebuild it after on GeometryChangedEvent. This a sequence of things that are supposedly built on EditorWindow's CreateGUI
I wonder what are the conditions to build it before
A listview should work just fine without that. No reason at al that it needs to be build after a geometry change event.
Could try calling Refresh(), and Rebuild() (don't remember the order) though it shouldn't be needed.
Rebuild is replacing Refresh (obsolote). But either way, I had to workaround it like this.
Nah there is another refresh, like RefreshAll or something. Unless they changed it again...
If you really did, then it is a bug.
The specific case is I first create and add the ListView in the default ctor, then on the parameter ctor (that comes after default ctor) it builds the list and should populate it
show?
public TwoDimensionalDirectionClipNamesField()
{
styleSheets.Add(SpriteAnimationClipperStyleSheets.TwoDimensionalDirectionClipNamesField);
Add(_listView);
}
public void BindProperty(SerializedProperty property)
{
var activeDirectionsName = nameof(SpriteAnimationClipperData.activeDirections);
var activeDirectionsProperty = property.FindPropertyRelative(activeDirectionsName);
var clipNamesName = nameof(SpriteAnimationClipperData.ClipNames).GetBackingFieldName();
var clipNamesProperty = property.FindPropertyRelative(clipNamesName);
_listView.bindItem = BindElement;
_listView.itemIndexChanged += ItemIndexChanged;
var newActiveDirections = GetActiveDirections(activeDirectionsProperty);
_listView.itemsSource = newActiveDirections;
_listView.RegisterCallbackOnce<GeometryChangedEvent>(_ =>
{
_listView.Rebuild();
});
(...)```
The BindProperty is called in a cascade of BindProperty methods that start in a constructor of a VisualElement
Hey, by chance is this method in something that inherits from the Bindable element? Casue, that could be messing things up with the extension method
To keep it simple, I usually inherit exclusively from VisualElement
Hmm, I don't see you assigning a MakeItem callback
It’s initialised in the declaration
can i make this propertydrawer only display the field as the type? Rather that the name of gameobject + type?
Probably not with using the default objectfield
Since this comes up every now and then https://discussions.unity.com/t/its-possible-to-create-menuitems-with-out-attributes/171587/3
I would probably make the the top section with the "Refresh", "Auto Save" etc. in to a Toolbar and use the Toolbar equivalent for the controls, like ToolbarButton instead of Button
ugh, what am i doing wrong here
inheriting from U.Object just gives me just a pointer field
is it even possible to write a custominspector for a serailzed poco?
Nope, you do make a PropertyDrawer for it
oh gosh u right lol, im entirely in the wrong direction 
Editor -> how a UnityEngine.Object looks in the inspector.
PropertyDrawer -> How a class field is drawn in the inspector.
The inspector can serialize and display uints. How do I display them in a property drawer? There doesn't seem to be a EditorGUI.UIntField() method.
Right now I'm just using a long field. Is doing this and clamping it at 0 that the correct way?
Also, I seem to be unable to get the serialized property I need through FindPropertyRelative?
Code for debug log:
var iter = new SerializedObject(property.objectReferenceValue).GetIterator();
iter.NextVisible(true);
do
{
Debug.Log($"{iter}: {iter.name} - {iter.propertyType}");
} while (iter.NextVisible(false));
Code for getting property:
SerializedProperty stats = property.FindPropertyRelative("<BaseStats>k__BackingField");
SerializedProperty name = stats.FindPropertyRelative("<WeaponName>k__BackingField"); // line 41
In fact, I copied <BaseStats>k__BackingField straight from the debug log and it didnt work.
this is in a property drawer script in the OnGUI method. I'm pretty sure I'm suppose to use property.FindPropertyRelative here. Maybe there's just something easy I'm missing?
It might just be BaseStats, iirc unity does some checking to see if it is a backing field
Try printing path
To make sure an name is right I recommend getting the field name reference directly from the class instead of using typed strings, like so:
var someFieldName = nameof(SomeClass.SomeField) or SomeClass.Private_SomeField_Name;
//if its backed
var someFieldBackedName = $"<{someFieldName}>k__BackingField";
var someFieldProperty = property.FindPropertyRelative(someField or SomeFieldBackedName);```
Second, does the WeaponName field live inside BaseStats? That's... odd...
You are trying to get the WeaponName from BaseStats. stats.FindPropertyRelative("<WeaponName>k__BackingField");
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
whats up with this bot?
Yes BaseStats is a scriptable object with a Property WeaponName
!warn 859849705214967808 Don't spam commands on the server.
yaboihammad has been warned.
I think FindPropertyRelative is just bugged? If I convert BaseStats to a serialized object and use FindProperty instead of FondPropertyRelative it works.
It's not each unity object is a separate serializedobject
im not sure what you mean by that statement
If I serialize BaseStats by doing new SerializeObject(stats.ObjectReferenceValue) and then do FindProperty which finds the backing fields, shouldn’t stats.FindPropetyRelative find the backing fields?
That’s how you do it if it’s an ObjectReference
Oh, when do you use find property relative?
Quote from the docs:
When the SerializedProperty references a compound type, such as a struct, class or array, then this method can be used to lookup a child property by name.
The property is a class, so it sounds like it should work
Unity seralizes public ScriptableObject myObject as a reference to the scriptable object. So FindProperty/FindRelativeProperty just finds the reference to the object (like an int id basically), and not the actual object.
And the serialized property returned by FindPropertyRelative doesn’t have any further paths for other serialized properties that can be found with another FindPropertyRelative?
Yeah, think of it like a 'link' to another object.
Well i can comprehend the idea of references, i just think its a bit weird FindPropertyRelative doesn’t work with it
We all do
why not use Localization package
Is there any way to autmatically import the changelog from unity asset store into my own asset as a text file?
Also, I know that with UnityEditor.PackageManager.UI.Window.Open("name of the asset") i can open the package manager with an asset selected. Is there any way to also be on the samples tab?
Is there a way to get the folder where a script is located from a static function? If I have an instance of a scriptable object I can use eg AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)), but I'm looking for a method that doesn't require that I have an instance
Hello! I don't know if I'm asking in the right place, but I have some problems when I try to build a unity 2023.2.18f1 project, I get all kinds of errors. Pls help
i dont understand why my buttons arent aligning with the rest of the fields.
RichTextStyleButton is derived from Button and has this uss
:root
{
flex-grow: 1;
border-radius: 0;
margin: 0;
}```
```cs
internal sealed class RichTextStyleField : VisualElement
{
private void Initialize()
{
this
.AddStyleSheet()
.AddClass(BaseField<bool>.ussClassName;);
_label = new Label("Style")
.AddClass(BaseField<bool>.labelUssClassName);
// same thing for _singleButtonsRoot
_multipleButtonsRoot = new VisualElement()
.AddClass("buttons-root");
_boltButton = new RichTextStyleButton("B", FontStyles.Bold);
_italicButton = new RichTextStyleButton("I", FontStyles.Italic);
_underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
_strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);
}
private void Compose()
{
_multipleButtonsRoot
.AddChild(_boltButton)
.AddChild(_italicButton)
.AddChild(_underlineButton)
.AddChild(_strikethroughButton);
_singleButtonsRoot
.AddChild(_lowercaseButton)
.AddChild(_uppercaseButton)
.AddChild(_smallcapsButton);
this
.AddChild(_label)
.AddChild(_multipleButtonsRoot)
.AddChild(_singleButtonsRoot);
}
}```
and the uss
```css
.buttons-root
{
flex-grow: 1;
flex-direction: row;
overflow: hidden;
border-radius: 7px;
}```
Hi! Can somebody help me with this?
This channel is for making your own editor extensions. I think #💻┃unity-talk would be the correct place to ask.
Need to add .unity-input-field__aligned
i tried
putting all the buttons in a visualelement and then ass the class, but nothing
Probably have to add unity-input-field__label as well to the label
i tried that too
i think i was testing combinations when i wrote that message because i have it rn
You mean it is working or it is already there?
private void Initialize()
{
this
.AddStyleSheet()
.AddFieldClass();
_label = new Label("Style")
.AddLabelClass();
_multipleButtonsRoot = new VisualElement()
.AddClass("buttons-root");
_boltButton = new RichTextStyleButton("B", FontStyles.Bold);
_italicButton = new RichTextStyleButton("I", FontStyles.Italic);
_underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
_strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);
_singleButtonsRoot = new VisualElement()
.AddClass("buttons-root");
_lowercaseButton = new RichTextStyleButton("ab", FontStyles.LowerCase);
_uppercaseButton = new RichTextStyleButton("AB", FontStyles.UpperCase);
_smallcapsButton = new RichTextStyleButton("SC", FontStyles.SmallCaps);
}```it is there and its still not aligned
I don't see it there?
public static T AddLabelClass<T>(this T target) where T : VisualElement
{
string labelClass = BaseField<bool>.labelUssClassName;
return target.AddClass(labelClass);
}```
this function adds it
Ahh, so lets do this, add the ussClassName to the root, add the alignedLabelUssClassName to the root, add the labelUssClassName to the label.
private void Initialize()
{
this
.AddStyleSheet()
.AddFieldClass()
.AddAlignedFieldClass();
_label = new Label("Style")
.AddLabelClass();
_multipleButtonsRoot = new VisualElement()
.AddClass("buttons-root");
_boltButton = new RichTextStyleButton("B", FontStyles.Bold);
_italicButton = new RichTextStyleButton("I", FontStyles.Italic);
_underlineButton = new RichTextStyleButton("U", FontStyles.Underline);
_strikethroughButton = new RichTextStyleButton("S", FontStyles.Strikethrough);
_singleButtonsRoot = new VisualElement()
.AddClass("buttons-root");
_lowercaseButton = new RichTextStyleButton("ab", FontStyles.LowerCase);
_uppercaseButton = new RichTextStyleButton("AB", FontStyles.UpperCase);
_smallcapsButton = new RichTextStyleButton("SC", FontStyles.SmallCaps);
}```
public static T AddFieldClass<T>(this T target) where T : VisualElement
{
string fieldClass = BaseField<bool>.ussClassName;
return target.AddClass(fieldClass);
}```
Not sure, I would open up the UITK debugger and look at a base input field (like that Text fiedl right above it) and copy over classes until you get it. Also possible that the right side is forcing itself to be too big, but I don't think so.
ill do that, thanks 😄
Hey, I wonder how to get not connected ports in editor.
I'm getting all connection by doing var connections = (GraphView)view.edges.ToList()
its from UnityEditor.Experimental.GraphView;
and it only returns connected ports
okay, i've found a way
public List<Port> GetUnconnectedPorts(GraphView graphView)
{
List<Port> unconnectedPorts = new List<Port>();
foreach (var node in graphView.nodes.ToList())
{
if (node is Node myNode)
{
foreach (var port in myNode.inputContainer.Children().OfType<Port>())
{
if (!IsPortConnected(port))
{
unconnectedPorts.Add(port);
}
}
foreach (var port in myNode.outputContainer.Children().OfType<Port>())
{
if (!IsPortConnected(port))
{
unconnectedPorts.Add(port);
}
}
}
}
return unconnectedPorts;
}
private bool IsPortConnected(Port port)
{
return port.connections.Any();
}
Hi all, I'm having a lot of trouble understanding unity Serialization and how to do custom inspector and property drawer. Given the example below, how can I make the "test" field of my scriptable object display not a PropertyField, but the actual Inspector Element of the object ? (So in this case it would expose the name field of the SERIALChannel class).
[Serializable]
public abstract class COMChannel : UnityEngine.Object
{
[SerializeField]
public bool isOpen;
}
[Serializable]
public class SERIALChannel : COMChannel
{
[SerializeField]
public string name = "hello";
}
[CustomPropertyDrawer(typeof(COMChannel), true)]
public class COMChannelDrawer : PropertyDrawer
{
private VisualElement root;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
root = new VisualElement();
Debug.Log(property.displayName); //Does output test, which is the name of the field
//generate the error : InvalidOperationException: managedReferenceValue is only available on fields with the [SerializeReference] attribute. But... the field DOES have the [SerializeReference] attribute...
Debug.Log(property.managedReferenceValue);
return root;
}
}
[CreateAssetMenu(fileName = "E6Settings", menuName = "New E6Settings")]
[Serializable]
public class E6Settings : ScriptableObject
{
[SerializeReference] // Or [SerializeField] ? I don't know.
public COMChannel test = new SERIALChannel();
}
Well to start off with, you can't inherit from UnityEngine.Object. Looking at what you have, you can just inherit from nothing and it should all work as you are expecting it to.
@gloomy chasm Yes indeed I was about to post that I found the solution. I'll post how I did it, but mostly my issue was coming from that inheritance
Yeah the only runtime types you can inherit from is MonoBeavhiour and ScriptableObject. Can't inherit from like Component, or Mesh or Texture2D or any others.
It was as simple as that :
[Serializable]
public class COMChannel
{
[SerializeField]
public bool isOpen;
}
[CustomPropertyDrawer(typeof(COMChannel), true)]
public class COMChannelDrawer : PropertyDrawer
{
private VisualElement root;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
root = new VisualElement();
root.Add(new PropertyField(property));
return root;
}
}
I even managed to add a dropdown that allow me to switch between different subType of the COMChannel and everything works fine :
property.managedReferenceValue = Activator.CreateInstance(availableChannelTypes[changeToChannelType]);
property.serializedObject.ApplyModifiedProperties();
property.serializedObject.Update();
It did took me a while tho to understand I had to manipulate the managedReferenceValue... not a lot of information about that.
Ahh yeah, nice going!
A note if you aren't already, you can use the TypeCache class to get all types that derive from class or interface
I'll check that, I'm relying on reflection to do so for the moment and it seems to be working fine.
Thanks for the help !
Yeah it is super easy and much better performance than reflection, so I totally recommend it! var types = TypeCache.GetTypesDerivedFrom<COMChannel>();
hi, i'm trying to get the inspector to show different UI based on different values but i cant get it working, i want the fields to disappear /appear based on action type
[CustomPropertyDrawer(typeof(ActionInfo))]
public class ActionInfoDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Debug.Log("Drawing ActionInfo");
SerializedProperty actionTypeProperty = property.FindPropertyRelative("actionType");
// Draw the actionType dropdown
EditorGUI.PropertyField(position, actionTypeProperty);
position.y += EditorGUIUtility.singleLineHeight;
// Customize the GUI based on the action type
switch (actionTypeProperty.enumValueIndex)
{
case (int)ActionInfo.ActionType.UnitTarget:
// Show options for UnitTarget
EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property.FindPropertyRelative("baseRange"), GUIContent.none);
break;
case (int)ActionInfo.ActionType.GridTarget:
// Show options for GridTarget
EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property.FindPropertyRelative("aoeRange"), GUIContent.none);
break;
// Add more cases as needed
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
// Return the height needed for the number of properties you are displaying
return EditorGUIUtility.singleLineHeight * 3;
}
}
[CreateAssetMenu]
public class ActionInfo : ScriptableObject
{
public string actionDescription = "Action Description";
public int baseRange = 0;
public int baseDmgAmount = 0;
public enum ActionType
{
UnitTarget,
GridTarget
}
public ActionType actionType;
public int aoeRange = 0;```
PropertyDrawer is for saying how a serialized field (property) is drawn in the inspector. So how [SerializeField] private ActionInfo _actionInfo; is drawn.
Editor is for saying how a UnityEngine.Object's inspector is drawn when the object is selected.
You want a Editor not a PropertyDrawer
hmm i dont get it, i updated to this but still not showing something
[CustomPropertyDrawer(typeof(ActionInfo))]
public class ActionInfoDrawer : Editor
{
protected void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Debug.Log("Drawing ActionInfo");
SerializedProperty actionTypeProperty = property.FindPropertyRelative("actionType");
// Draw the actionType dropdown
EditorGUI.PropertyField(position, actionTypeProperty);
position.y += EditorGUIUtility.singleLineHeight;
// Customize the GUI based on the action type
switch (actionTypeProperty.enumValueIndex)
{
case (int)ActionInfo.ActionType.UnitTarget:
// Show options for UnitTarget
EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property.FindPropertyRelative("baseRange"), GUIContent.none);
break;
case (int)ActionInfo.ActionType.GridTarget:
// Show options for GridTarget
EditorGUI.PropertyField(position, property.FindPropertyRelative("actionDescription"), GUIContent.none);
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property.FindPropertyRelative("aoeRange"), GUIContent.none);
break;
// Add more cases as needed
}
}
}
[CreateAssetMenu]
public class ActionInfo : ScriptableObject
{
public string actionDescription = "Action Description";
public int baseRange = 0;
public int baseDmgAmount = 0;
public enum ActionType
{
UnitTarget,
GridTarget
}
public ActionType actionType;
public int aoeRange = 0;
}
Though as a note, I recommend using UIToolkit instead of IMGUI as it is much easier to style, and just generally easier to use. (Also what Unity is moving to)
How can I add a context menu to a folder in project?
This is what I've tried:
const string BatchMenu = "CONTEXT/Object/Scripts/Batch Enable Nullable";
[MenuItem(BatchMenu)]
static void BatchEnableNullable(MenuCommand command) {
var path = AssetDatabase.GetAssetPath(command.context);
I know folders are of type DefaultAsset but I tried Object because that feels like the most general type.
Can you screenshot which menu you'd like it in? Because if it's the one when you right-click a folder in the Project View that's just "Assets/..."
(and you would make a validate version that greyed it out if it wasn't a folder, not ideal I know)
Can you access the context object if you do that?
That's what I had working now
The are problems with the vertical split project view though. Right clicking the left pane doesn't select the folder
(I'll try it myself after lunch)
Oh god I tried to use the debugger for this and things are not happy
Yes, but it won't work anyway. This approach seems to:
const string BatchMenu = "Assets/Scripts/Batch Enable Nullable";
[MenuItem(BatchMenu)]
private static void BatchEnableNullable(MenuCommand command)
{
string path = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]);
}
[MenuItem(BatchMenu, isValidateFunction: true)]
private static bool BatchEnableNullableValidate(MenuCommand command)
{
string[] guids = Selection.assetGUIDs;
if (guids.Length != 1)
return false;
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
return Directory.Exists(path);
}
Yeah, unfortunately that just disables option on the left of the project view
Because it's not part of the selection
Okay it's slightly different to what I tried, I'll take a look
Thanks @visual stag. I'll let you know how it goes after lunch
Okay, this is working, but I can't quite understand why what I had wasn't working
it's possible that activeObject differs when a folder is selected
@visual stag well that works a treat, not sure what was going on before.
Thank you! <3
Pretty annoyed that i have to do this, I enabled nullable refs in the csproj and then found out that the VS editor extension generates an old style of csproj that doesn't support that specific option.
So now I'm making a tool that prefixes files with #nullable enable en masse hahah
So annoying
We have three programmers each using a different IDE
Who's using the correct one

Not me
Vscode 4 life
Debuggers are overrated
🔨
You misspelled notepad
I'm writing an Overlay. I want it to show a button if the currently selected object has a specific component on it.
the point is to be able to hide everything except objects referenced by that component
wait, this is going to be a UIToolkit question
I will ask it there in a bit
is there a way to analyze the project and throw some sort of error if there is an asset reference comming from a "forbidden" folder?
Context: I have a "dev" folder where each dev has their own experimental stuff. Nothing outside the dev folder should reference the dev folder. Can I somehow do something so the editor gets really mad if something references this evil folder? 🤔
Yes, fastest would probably be to use something like grep to find all GUIDs and then try check whether they're in the dev folder or not
This sounds like an editor Overlay question. I don't fully get your question, but I am pretty sure this is the right place for it. Overlay has stuff for showing an overlay based on selection and stuff.
Or you can walk the tree with SerializedObjects/SerializedProperties but that's slooooow
perhaps it is! could you tell me more about showing it selectively?
This interface is what like the Camera uses to show/hide the camera overlay that shows the gameview. Basically just check if there is a selection and if it has x component.
They said they were had something else/better in the works... but... 🤷♂️
It is basically just checked every x ms to see if visible is true or false hah
related problem: the Overlay I'm writing searches for all objects of a certain type to do work on
I want to limit this to just the current prefab stage if one is open
Should I just grab the root object from the PrefabStage and use GetComponentsInChildren?
(it's a component)
Hmm... this sounds a bit funky like this isn't the intended way to do it. Maybe it is, but can you share a bit of context to what you are doing? There might be an easier way.
Yeah that would be how to do it I think.
imagine you have three different groups of objects in a prefab, and you want to be able to show just one of the three groups at a time
the problem is that FindObjectsByType is searching all of the open scenes
on the bright side, SceneVisibilityManager.instance.ShowAll(); does only affect the currently active prefab stage
so that's convenient
Ahh, so yo want to show all available groups in the overlay.
Well, that'd be a nice stretch goal!
I'm not sure how I'd do that.
with IMGUI it's obvious, since you're drawing the entire GUI every frame
I have minimal UITK experience
Are the groups defined just in a component then?
Each group is a component that references other renderers, lights, and a few other specific things
So yeah, that's the gist
I don't want to actually turn things on and off, so I'm showing and hiding the game objects those referenced components are on instead
(which is close enough)
What I normally do for this sort of thing is setup a singleton with a list (or even a static works) and would have my group component have [ExecuteAlways] and in OnEanble and OnDisable add/remove the group to that list.
Then you can just check that list instead of having to do big potentially expensive searches
I'm okay with doing a search each time
(and that might make the problem worse!)
restricting myself to the current prefab stage, that is
Yeah but then you can have a event for each time a group is added/removed and easily update your UITK elements. So adding a group component would 'automatically' update the UI
And you can do PrefabStageUtility.GetCurrentStage()?.IsPartOfPRefabContents(group.gameObject) to see if it is in the stage
and just make the group fire an event when created or destroyed, even though I don't keep a list
That's a good idea.
So in that case, a singleton list would be workable
Also, how would I do this? Can I display a new root VisualElement, or should I be storing a reference to one of the VisualElements so that I can get rid of its old children and create new ones?
the latter is what I'd do with UGUI
Well, assuming this is within a Overlay, just have a VisualElement that would contain the 'group' buttons (or whatever the control would be), and I would just add/remove a button when groups are added or removed. No need to pool or reuse them.
Okay, so roughly what I was imagining
I’m just unfamiliar with the “rules” for UITK. Gotta play around with it a bit
So far I’ve only used it in very basic property drawers, where the layout never changes after creating it
Ahh yeah, totally get it, feel free to @ me with any questions. 😄
Maybe I’ll go nuts and replace my old IMGUI debug menu with UITK
Immediate mode is just so convenient, though..
I ran into a wall with scroll views, though. Can’t get them to grow up until a maximum size and then start scrolling
Hmm, need to set them to style.flexGrow = 1?
(In IMGUI, I mean!)
How should I subscribe to/unsubscribe from this event? I guess I could subscribe in CreatePanelContent, but I don't know how I'd unsubscribe when the overlay is closed
ah, isn't there a static even that fires after a reload?
AttachToPanelEvent and DetachFromPanelEvent would be the safest way to subscribe/unsubscribe to outside events (events not to/from other VisualEleents)
Yeah exactly
great, thanks (:
Do you know if Unity is constructing a new MyOverlayClass every time it shows the overlay? I see that CreatePanelContent is an instance method..
if so, I presume I can store some references to my visual elements in fields
(i will
!)
Nope, it just basically sets the style.display property (It might remove it from the VisualTree but I don't remember)
it looks like it's re-using the same object
that's still fine, really
unless it can somehow display the same overlay multiple times
i did see you can make any editor window support overlays...
time to join the Bad Idea Club
Actually, you know when you hide an overaly, it is actually still there haha.
speaking of, it'll be nice to convert some of these editor windows into overlays
well, at least this one
it's literally just a toggle
I know, and I realy want to do it, but I haven't come up with a good execute idea for one yet
maybe a custom graph editing window
Yeah, all I can think of so far is graph/node windows
Ah I know, a custom editor window, where each component is an overlay hahaha
custom game view where it's rendered entirely by overlays
Hahaha
Okay, it looks like it creates a new object for each place the overlay is shown
(i'm logging the hash code of the Overlay in response to AttachToPanelEvent)
interestingly, it's logging twice every time I click on the overlay
well that's a bit weird, actually...
it's logging once for each instance of the overlay that's open
Welcome to UIToolkit 🙂
i'm surprised it's firing every single time I click on the overlay
It is because it starts to drag it out
ah, that's why it was randomly firing once or twice
clicking on the label caused one pair of detach-attach events
clicking on the title causes two pairs
it's not actually related to how many overlays are open
This is what is happening each time you click and why it makes a new one.
Basically it deletes whatever the overlay is currently, and then makes a new one for whatever the overlay's 'free form' look is
bonus gotcha: you can't ask if a game object is in a prefab during Awake or OnEnable!
I am now using EditorApplication.delayCall to wait a bit before updating the overlay
(and using a bool flag so I don't try to update it 30 times in a row)
Looks like it's behaving itself now
So, I have a IMGUIContainer that draws a list of asset previews. When the mouse hovers over an item for x time I want to draw a custom 'live' preview.
I have two (really one) issues though, the preview doesn't show smoothly due to the lack of repaint events, and it doesn't show in the correct amount of time since it lacks update events.
Suggestions on the best way around this/trigger repaint events for a IMGUIContainer?
And ideally, it wouldn't just constantly be repainting because that would be a bad idea for performance
Can't you just do some custom repaint behaviour that starts on enter and keeps going until you exit?
You might be able to play with editor coroutines for both the hover for x time and to run repaint quickly for the previews to show smoothly. But there’s probably no getting away from constantly repainting if you want the previews to stay smooth.
Is there a way I can use AssetDatabase.LoadAssetAtPath with a string as the type? Or somehow save a type with JSON? This seems to return null:
typeName = "UnityEngine.GameObject";
var obj = AssetDatabase.LoadAssetAtPath(assetPath, System.Type.GetType(typeName));
Debug.Log(obj, obj);
But this works fine:
var obj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.GameObject));
Debug.Log(obj, obj);
What im trying to do, is make a way I can store a reference to a prefab in my project through a JSON file, essentially store the path to the asset, and when I need to, load that path, but LoadAssetAtPath requires me to also know the type, so I need a way to store that type as well, or is there maybe another way I can approach this whole thing?
You can use AssetDatabase.LoadMainAssetAtPath instead unless you need to load a subasset. Also I recommend storing the reference by the GUID instead of path to make it safe from moving the asset, unless you need it at runtime too and it is in the resources folder.
i just noticed unity 6 has an actual Type tree view?
at least it seems like it has it in ui builder
does someone know how this is setup? i'd like to use it for a SerializableSystemType to well, serialize system types
btw the reason that type name doesn't work:
https://learn.microsoft.com/en-us/dotnet/api/system.type.assemblyqualifiedname?view=net-8.0&redirectedfrom=MSDN#System_Type_AssemblyQualifiedName
Probably custom to UIBuilder. You can check the source code to see, shouldn't be hard to find if it is.
I was thinking of LoadMainAssetAtPath but to my understanding, it is not intended to load things like meshes a part of a fbx, which is one thing I may need to do with some assets - I am also trying to use both the GUID and path, where the code will first try a path, if it fails to find an asset at the path itll try the GUID, for cases where an asset might be re-imported or pulled from a git, then even though the asset is the same and nothing about its size or anything changed, Unity might assign it a different GUID, so in those cases, im hoping the path will be enough (assuming the name of the asset doesnt change)
Also thanks for this, I couldnt seem to find exactly why my example didnt work online, but this makes sense and was very helpful
You can always load UnityEngine.Object and then cast to the desired type. All assets inherit from that type.
oh nvm, doesn't apply.
Self-necroposting just to add, in case anyone ends up in this conversation, that I discovered how ListView does it: there's literally a special case in the internal code for bindings that check if the component is a ListView and then handles the binding to itemsSource. ¯_(ツ)_/¯
Can someone explain to me why these disturbances are happening?
Is it related to style?
Why does the list view that does not cause problems when the graph view is added to the rootVisual element cause problems when it is put in a foldout in the extension view in the node?
Working Case
private static void TestCase1()
{
_instance.rootVisualElement.Add(TestCaseListView());
}
Problem Case
private static void TestCase2()
{
var node = new Node();
var contentSpace = new VisualElement();
contentSpace.name = "Content Space";
contentSpace.style.width = 200;
contentSpace.style.height = 100;
contentSpace.style.backgroundColor = Color.white;
contentSpace.style.flexGrow = 1;
contentSpace.style.flexShrink = 1;
node.extensionContainer.Add(contentSpace);
var foldout = new Foldout();
foldout.style.flexGrow = 1;
foldout.style.backgroundColor = Color.grey;
contentSpace.Add(foldout);
foldout.Add(TestCaseListView());
node.RefreshExpandedState();
GPView.Instance.AddElement(node);
}
And also here is list view creation same as api doc
private static ListView TestCaseListView()
{
const int itemCount = 10;
var items = new List<string>(itemCount);
for (int i = 1; i <= itemCount; i++)
items.Add(i.ToString());
Func<VisualElement> makeItem = () => new Label();
Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = items[i];
const int itemHeight = 16;
var listView = new ListView(items, itemHeight, makeItem, bindItem);
listView.selectionType = SelectionType.Multiple;
listView.itemsChosen += objects => Debug.Log(objects);
listView.selectionChanged += objects => Debug.Log(objects);
listView.style.height = 200;
listView.style.width = 100;
listView.reorderable = true;
listView.reorderMode = ListViewReorderMode.Animated;
listView.style.flexGrow = 1.0f;
listView.style.flexShrink = 1.0f;
return listView;
}
Can someone help me with this editor script? I'm trying to just refresh some properties of a "LegConstraintRig" script I have every time the transform handle is moved in the Scene view, and the position seems to be updating when I move it (as seen with the Debug.Log statement), but EditorGUI.EndChangeCheck() always seems to return false so RefreshProperties() never gets called.
I'm basing the script off of this docs page : https://docs.unity3d.com/ScriptReference/Handles.PositionHandle.html
I can't seem to find any difference
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(LegConstraintRig))]
public class RiggingEditor : Editor
{
void OnSceneGUI()
{
LegConstraintRig rig = (LegConstraintRig)target;
EditorGUI.BeginChangeCheck();
Vector3 newPosition = Handles.PositionHandle(rig.transform.position, rig.transform.rotation);
Debug.Log($"newPosition: {newPosition}");
if (EditorGUI.EndChangeCheck())
{
Debug.Log($"Property changed");
Undo.RecordObject(rig.transform, "Move Transform");
rig.transform.position = newPosition;
rig.RefreshProperties();
}
}
}
Quick question, Am I allowed to create a custom editor for a struct or does it only work with MonoBehaviors/Components?
I ask because I tried doing what I want with a PropertyDrawer, but that seems to not give me much flexibility when it comes to running extra functions.
You can only make a custom editor for classes that inherit from a class that inherits from UnityEngine.Object (like ScriptableObject and MonoBehaviour.
For POCOs you use PropertyDrawer
dang kind of figured that was the case.
You should be able to do 'anything' with a ProeprtyDrawer though that you can with an Editor
What are you trying to do which you were having a hard time with?
Yeah but I have this issue where the data I have doesn't populate until after my scenes load and so my editor tool doesn't update until after it click on a object and then it populates the data when the inspector is drawn.
So I have a custom TimelineClip taht needs a serializedProperty that my PropertyDrawer updates. And it doesn't update until after the PropertyDrawer has finished being drawn.
So I have to click on each timelnie clip to have the data be propagated.
Which I don't want to do everytime a scene is loaded.
That sounds like you are assigning data in the draw it self, which you shouldn't be do at all.
For PropertyDrawers or Editors.
Well no what I was trying to do was set a SerializedProperty from said PropertyDrawer when it was loaded but forgot that isn't a thing that can be done since you have to have the Drawer in loaded in the inspector for its drawing function to be called.
So I instead have to populate the data I want when the scene loads instead of when the PropertyDrawer is told it needs to draw something.
And that seems to work out for me.
private static void OnPlayModeChanged(PlayModeStateChange obj)
{
EditorCoroutineUtility.StartCoroutineOwnerless(
SetDataRoutine());
EditorCoroutineUtility.StartCoroutineOwnerless(
SetObjectRoutine());
}
private static void OnSceneOpened(Scene scene, OpenSceneMode mode)
{
SceneName = scene.name;
Debug.Log(SceneName);
EditorCoroutineUtility.StartCoroutineOwnerless(
SetDataRoutine());
EditorCoroutineUtility.StartCoroutineOwnerless(
SetObjectRoutine());
}
Basically putting the code I want in here fixes my problem
I'd have to disagree with you there. I'd say you can do it from editors since there are ways to do it properly.
small question, is EditorApplication.hierarchyWindowItemOnGUI cleaned up on Domain Reload by Unity or do i need to remove my Listener(s) manually when that's happening?
If i need to do it manually, what is the proper way to do so?
Is, for example, EditorApplication.quitting called before a Domain Reload? (Nope, it isn't, just tried it out)
I have no idea where i should hook into for unsubscribing (if that's even necessary) ~.~
Did you see these ones? Look like a good fit: https://docs.unity3d.com/ScriptReference/AssemblyReloadEvents.html
Whether you need to unsubscribe or not, you can verify by yourself... Try adding a Debug.Log and see if it gets sent multiple times after code is recompiled.
Oh damn, didn't know these exist! Thank you very much, seems to be exactly what i need 😄
Hey, I'm trying to create an atlas v2 through script. Basically what I'm doing is:
var atlas = new SpriteAtlas();
atlas.Add(spritesArray);
AssetDatabase.CreateAsset(atlas, "Assets/SomeName.spriteatlasv2");
But doing so causes a native error to appear saying that this extension is not supported. Removing v2 from extension lets me create atlas, but it's a v1 one. I've searched everywhere, but couldn't find a way to create v2 atlas through code, any ideas?
is it possible to interact with scene window with an editor window tool ? or is that only possible with editor scripts relating to monobehaviours and scriptable objects
eg clicking in the scene to get a world position
i think so ? ill try it
kinda wish unity would explain that better in the docs some where
is it possible to bind to a field in the EditorWindow itself?
public class CreatorTool : EditorWindow{
[SerializeField]
string _error; //bind label to this
...
}
i tried putting _error as the binding path but i think that only works if the editor relates to an actual object
SerializedProperty environmentId = _self.FindProperty("targetEnvironment");
DropdownField environmentSelect = new DropdownField();
environmentSelect.BindProperty(environmentId);```
_self is new `SerializedObject(this)` in an editor window
ah so like this:
var errProp = new SerializedObject(this).FindProperty("_error");
_errorLabel.BindProperty(errProp);
_errorLabel.RegisterValueChangedCallback((evt) =>
{
var target = evt.target as Label;
target.style.display = evt.newValue == "" ? DisplayStyle.None : DisplayStyle.Flex;
});
You still have to dispose the serializedobject on window destroy
oh its not garbage collected?
If something implemetns a dispose method, you're supposed to call it
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/SerializedObject.html makes no mention of it here or in their example code
~SerializedObject()
{
Dispose();
}
``` seems they call it for you when garbage collects it
Looks like it's caled when it's GC'd but it's still good practice
It gets called, eventually
I...did not realize that you need to dispose SerializedObject though, haha
good to know
i'm having a weird behaviour with a custom visual element i'm making to control a property drawer.
Basically its for a custom serialization solution for classes not derived from Object, it basically accepts a System.Type in one of its properties, and depending wether or not the fed Type is null or not, it should either Hide a HelpBox and Enable a container, or do the oposite (show the help box and disable the container)
the issue i'm having is that... it seems like the UI is not updating itself correctly? https://i.gyazo.com/f7e5d0cd797d4c41e60f00e9c08391c5.gif
Its weird because i have checked the code with a debugger and the behaviour i'm looking for at attachment (check if the type to serialize is null or not, and affect the ui accordingly) is running, but nothing happens in the inspector itself until i update it
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
here's the code itself
SetDisplay is an extension method i made that just sets the display style to flex or none depending on the bool value, rest is vanilla uitoolkit
using unity 6 btw
ok now i'm even more confused
Decided to set the typeBeingSerialized on CreateInspectorGUI and it works now (??)
Ya gotta share all of the code, otherwise there isn't much anyone can say to help.
fair, i'll setup a repo rq
No I just mean the rest of the class
oh
derp
give me a sec
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
there it is
keep in mind that my issue was happening because i wasnt setting the typeBeingSerialized on CreateInspectorGUI, which... confuses me
since i am setting it on the UpdatEFieldCollection method, which gets called as the PropertyField gets bound afaik
Ahh that is where the confusion is, the RegisterValueChange callback does not get raised when the visual element is first created
You could avoid this partially I think my making SerializedFieldCollectionElement inherit from Bindable and write it like the base control are.
I mean, it does get ran later on, why would the timing matter? 🤔
Where does it get run later?
The only time the typeBeingSerialized is set, is from the UpdateFieldCollection method which is only called in the RegisterValueChangeCallbackwhich dos not run on startup
i beg to differ
you can see in the video that the method does get called
which is why i'm confused on this behaviour
Hmm.. PropertyField might behave differently then... but that is weird....
definetly
i'll try what you suggested with the bindable bit
is there an event for when a serialized object is bound to an element?
Nope, (well yes, but lots of reflection). The way you wanna do this is have it bindable to a string, then when the value changes you convert that string to the type you want
Is there a simple process if I have a standard cs project, but want to also support a unity package version? I'd use a dll, but those can't get defines to strip code after compiling. Or would I essentially have to maintain a unity specific repo just with the package format + a duplicated file structure of the main repo? 🤔 (figured this was fine here as it is package related)
Hmmm... you could have the custom defines in (like #if PACKAGE) and then compile two versions, one with the define enabled and one with it disabled.... I think..
Not sure if that would fit your needs.
Is it possible to add a custom play button here? I would like to make my own next to the original one that makes my character spawn from the editor camera positon
cool thanks 😄
Hi ! Could somebody exlain to me how OnValidate is triggered when modifying a field ? Since it's not triggered when I set my object dirty with EditorUtility.SetDirty(), I assume it happens at another level
Do you need more of an explanation?
Yeah I read that already. I wanted to know how a change in a field is different from a dirty serialized object in the eye of OnValidate
Dirty just tells Unity that the object does in fact need to be saved, whenever Unity next saves.
While something like setting the value with SerializedObject/SerializedProperty, updates the serialized data.
OK. So it doesn't have anything to do with the change detection. Thanks 🙂
Yeah, exacty. 🙂
hello there
is it possible to add a custom icon/text to the bottom/top bar of the unity editor?
Haha, actually scroll up a tiny bit and you will see Navi actually just answered that exact question. For the top bar at least.
damn, awesome ^^
It is also possible for the bottom bar in the same manner that the linked extension does it for the top bar. So you can take a look at the code and the unity source code and add support for the bottom bar as well.
Hey all, would it be possible to bind a TextField to the currently selected Asset filename ? I'm developing a Custom Editor Windows, and for a specific type of asset, when it is selected I would like to be able to see and edit the name of that Asset. And I was wondering if I could use binding for that. If not I guess I'll have to write all the logic in a ValueChange callback but that's only one-way, if the asset name is changed from elsewhere it won't be reflected in my custom editor windows...
The way I would do it is to make a SerializedObject of the selected asset, and bind the field to the name property. And on selection change, dispose of the SerializedObject (if one exists) and create a new one with the new selection (if appropriate)
And rebind to the new SerializedObject of course
That sound reasonable. I'll give it a shot ! Thanks
Sure thing!
@gloomy chasm So I did something like this (sorry for the long variable name...). But it seems I can't retrieve the name property on the gameObject, it return null. (My asset is a Prefab)
private void OnSelectedCompositionChange(Composition newSelection)
{
Debug.Log($"Changed selection to {newSelection.gameObject.name}");
// Dispose the old selection serializedObject and serialize the new Selection
if(serializedSelectedCompositionGameObject != null )
serializedSelectedCompositionGameObject.Dispose();
serializedSelectedCompositionGameObject = new SerializedObject(newSelection.gameObject);
Debug.Log(serializedSelectedCompositionGameObject.FindProperty("name")); // Can't find the name property...
// Bind the serialized object name to the text field
if (compositionNameField != null)
compositionNameField.BindProperty(serializedSelectedCompositionGameObject.FindProperty("name"));
serializedSelectedCompositionGameObject.ApplyModifiedProperties();
serializedSelectedCompositionGameObject.Update();
}
m_Name
Haaa, how do you find a list of property like that in the doc ? I think I've encouter this kind of issue a lot of time. Is it because it is private so a "m_" is automatically added ?
You can switch the inspector to debug mode or I think hold the alt key. Unity (most of the time) uses Hungarian notion. Where they prefix member fields with m_ and static with s_
Yeah I kinda found a post that explain that a bit : https://forum.unity.com/threads/unityengine-object-properties-when-serialized-have-m_-prefix-why.479491/
Anyways, it's working ! Thanks
Glad its working! Make sure to dispose of the SerializedObject when the window closes too (it is good practice to always cleanup the SerializedObjects you create).
For info, it doesn't rename the Asset prefab. I still have to use AssetDatabase.RenameAsset method in the ValueChange callback. I was a bit too quick earlier ^^.
https://github.com/sebas77/Svelto.ECS/blob/master/.github/workflows/upm-release.yml found an example from another project that generates a upm release branch 👀
Although then you can't add via git url anymore... which seems fine?
hey yall, maybe a beginner question here, but is there a way to listen to a value changing in the inspector and call a function to change to a different variable in the object?
you can use OnValidate: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnValidate.html
but if you need it to be more specific you can either do a custom inspector script get the property you want to check if it changed, listen to the change event and modify the property you want
or you could use my free package that adds an attribute that does exactly just that: https://editorattributesdocs.readthedocs.io/en/latest/Attributes/MiscellaneousAttributes/onvaluechanged.html :)
Hey all, I've a quite particular question. When editing prefab in the isolation context you can set a scene as a environment scene. But, the GameObject inside that environment scene do not visually update. To make it simple in the scene I've a cube with a Script attached to it that move the cube around, the script is set to be ExecuteAlways and the update function does get trigger while I'm in the Prefab Editing context (Checked with a Debug.log). But my Cube isn't moving... if I quit the prefab context it start moving again. Is it a bug, something I didn't understood or simply not possible ?
Nevermind, it had to do with my scene being opened in the Hierachy and in the Prefab context at the same time. I guess that "duplication" is causing this probleme and quite a lot of other problem...
anyone knows why i am getting an erorr on this ?
How do you guys auto-update your builds? Or at least have the Unity editor auto-download the newest Unity version so your project are ready to use it?
Also, how do you auto-update radeon drivers?
Why would i want to download each editor version evry time new one just come out thou?
#💻┃unity-talk would be the correct channel. This one is for making editor windows and the like.
#💻┃unity-talk would be the correct channel. This one is for making editor windows and the like.
Ok sweet, thank you
where can I put a something that I only want to happen when the dev/me click a GO with a customeditor?
onGUI is constant while the editor is open, I want only when it opens
Unity hub has a CLI I think
Check out game-ci for a suite of scripts for building
We ended up using our own machine though because GitHub actions run out of memory quickly
But you can still use them as a reference
I think you can grab unity hub from chocolatey too... Sorry just going from memory
There is definitely a way to grab it with curl or similar
Then you can give it the right arguments to download the editor you need. You can pull that from the project unity version file
Hello guys, I'm beginner with no experience in editor scripting.
Any recommendation of where you I start? Thank you in advance.
Probably start by having a goal
Then Google how to achieve that goal
Would you kindly give examples of goal in this context?
Are you joking?
No, I’m genuinely beginner to this topic. I appreciate yourhelps and advices
Most people start looking into editor scripting because they have a problem they want to solve that can be solved with editor scripting.
So like… find the problems I have with it and solve with editor scripting it?
Interesting, thank you very much.
Not problems you have with editor scripting. Most people using Unity are making a game. Their goal isn't to learn editor scripting, it's to make a game. Editor scripting can make it easier to make games.
The type of editor scripting that can be useful depends on the game you're making and the problems you need to solve to get there.
Appreciated 😄
Editor scripting is generally pretty unpleasant in unity, usually it's something you'll do because you have a problem in your workflow that you want to resolve. For example any kind of repetitive editor busywork or an error prone user procedure, like building your game.
Cool, thank you! I found the site. Now just to figure out how set to to default to the latest version, instead of me specifying each minor version as well.
Help, how to update the inspector when the serialized object changes?
For example assume I need something like Diagnostics[] to show in inspector when somehting is not OK with the component, e.g. it's referencing other objects and when they don't meet some criteria it should show in the inspector a helpbox saying "object X, Y, Z don't meet certain criteria"
Depends, UITK or IMGUI?
uitk
The easiest would be to use a ListView
and just bind it?
Yup
but to write custom controls for each diagnostic, or can I generate helpboxes "on the fly" by transforming the Diagnostic somehow?
What do you mean?
I guess I should be clear, is Diagnostics[] in a SerializedObject (or stored in a UnityEngine.Object) or is it in some non-serializable class?
If I can bind to an array Diagnostics[] (where it's defined as struct Diagnostic { Severity severity; string message; }) and tell uitk: "here, for each of them create a single help box"
it is annotated with [Serializable] and is just stored there in the component
because honestly I didn't know of a better way to do that
Yeah of course, that is what the listView.makeItem and listView.bindItem callbacks are for. Or you can just make a property drawer for Diagnostic and then you don't have to do anything
Hey, I can't find in the Doc a proper way to update a DropdownField choices list when the user open the dropdown. I tried this :
dropdownField.RegisterCallback<ClickEvent, DropdownField>((evt, dropdown) => {
dropdown.choices = composition.motionLayersName;
dropdown.MarkDirtyRepaint();
}, dropdownField);
But the Dropdown popup is shown before the change to the choice is made, so I've to click it a second time to actually see the change...
Any idea ?
You are not really meant to update the list when it is clicked. You are generally meant to do it at the time of creation.
You could try doing it on the PointerDown event (can't remember if you would want trickle down or no trickle down)
@gloomy chasm As an example, I would like my dropdown list to reflect the list of GameObject in the hierarchy. But this can change at any time so i've to update at some point the choice dynamically. I could have some event to listen for a change in that hierarchy and update the dropdown there, but In my actual use case it's a bit more tricky so it's much easier if I recompute the choice list when the dropdown get's opened.
i'll try the PointerDown event
Perfect that worked ! Thanks
Wouldn't you want to read the version from the project you're building?
Like, I'm looking to use Unity 6. As long as I'm using the latest Unity 6, then I'm happy
I don't like having to check everytime if theres an update
it might be worth to mention why its not greates idea... each version require a disk sapce from you. unless u want to also recycle old one... but generally the is no point to go for every minor update... just do it once you see there is feature or bug fix you need
More importantly every update no matter how small has a chance of introducing new bugs or breaking things. So it is a good idea to stay on a single version for the majority of your project. When you are on a LTS it is safer to update for the LTS bug fixes, but it still comes with risk.
That is the main reason why it is not recommended to update versions automatically.
Not a small chance lol
Also you'll be desyncing the version you're working in and the one you're building
Any bugs you notice might not be present in the other
I mean no matter how small the update is, not the chance. The chance is definitely not small hahah
Oh
Hi ! Is there a way to listen for shortcuts in UIToolkit ? I tried listening to keyboard event on my inspector, but it is bypassed by default shorcuts apparently (i suppose it's a matter of focus)
In the end, I grabbed the panel my inspector gets attached to and subscribed to KeyDownEvent at this level. Looks like it does the job.
I would strongly advise against doing this.
Most unity updates break our project and need manual repair. Upgrading Unity is a big deal that I usually leave until I absolutely need to update. Especially if you're using a non-LTS version.
I usually timebox two hours for the update and the whole team needs to merge in their branches first, then if I can't get the update done in that time (due to various plugins and whatnot breaking) we reconsider why we're doing it. I'd advise staying with the latest LTS version for as long as possible and only upgrading if you have an engine bug or there is an absolute must-have feature.
You don't need to check every time there's an update, you just don't update.
We're still at the early phase, and we want to keep things compatible with the latest. Plus I like having Unity bugs resolved and new features added along the way.
I'm worried if we ignore updates, we'll have a bigger problem down the road
I can only speak from experience, you're the master of your own destiny.
Thanks for the advice though!
Down the road, I can see myself gravitating to your methodology
Me too lol
Meanwhile when working on personal projects I'm always on the most cutting edge version. Though I'll keep the previous version around to roll back if something is busted
I think it definitely depends on the size of the team and what experiences the project has had with upgrades
can end change check be used in this manner ?
var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( assets[0] );
UnityEditor.EditorGUI.BeginChangeCheck();
RF.SetActive( true );
RF.passMaterial.SetFloat("_Fade", 1.0f );
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
UnityEditor.AssetDatabase.SaveAssets();
}
ehh... nvm i see where my logic falls flat
hmmm it still doesn't work
here is what i got so far :
[RuntimeInitializeOnLoadMethod]
static void Save()
{
var assets = UnityEditor.AssetDatabase.FindAssets("FullScreenRenderFeature");
var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( assets[ 0 ] );
RF.SetActive(true);
RF.passMaterial.SetFloat("_Fade", 1.0f);
var guid = UnityEditor.AssetDatabase.GUIDFromAssetPath(assets[0]);
UnityEditor.AssetDatabase.SaveAssetIfDirty(guid);
}
[UnityEditor.InitializeOnLoad]
public class Hook : UnityEditor.Build.IPreprocessBuildWithReport
{
static Hook() => hook(); // On Launch
public int callbackOrder => 0;
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) => hook(); // On Build
static void hook()
{
var guids = UnityEditor.AssetDatabase.FindAssets("FullScreenRenderFeature");
if (guids.Length < 1) { Debug.LogError("not found"); return; }
var path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);
var RF = UnityEditor.AssetDatabase.LoadAssetAtPath<FullScreenPassRendererFeature>( path );
// Save Render feature
RF.SetActive(true);
UnityEditor.AssetDatabase.SaveAssetIfDirty(new UnityEditor.GUID( guids[0] ));
// Save material
RF.passMaterial.SetFloat("_Fade", 1.0f);
var m_guid = UnityEditor.AssetDatabase.GUIDFromAssetPath(UnityEditor.AssetDatabase.GetAssetPath(RF.passMaterial));
UnityEditor.AssetDatabase.SaveAssetIfDirty(m_guid);
// Force save
UnityEditor.AssetDatabase.SaveAssets();
}
}
this worked
hi guys
i am working with scriptableobject
an i wanna set icon for scriptableobject's instance
tried using SetIconforObject, but it doesnt work as aspect
Hey, did anyone encounter problem when making editor for generic class in unity 6.0? It doesnt work for me like it used to..
public abstract class TestGeneric<T> : MonoBehaviour
{
public T value;
}
public class TestGenericInt : TestGeneric<int>
{
}
[CustomEditor(typeof(TestGeneric<>), true)]
public class TestGenericEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.LabelField("Testing field", EditorStyles.boldLabel);
DrawDefaultInspector();
serializedObject.ApplyModifiedProperties();
}
}
If I make empty class e.g TestGenericBase it will work, but I'm not the biggest fun of empty class just for the sake of editor :/
How do I prevent change callbacks being triggered on a property fields in custom editor when the inspector is opened?
When I select an object with a script that has custom inspector and setup a callback in the CreateInspectorGUI like below, the message is logged whenever I select the object and inspector opens
propertyField.RegisterValueChangeCallback(_ => Debug.Log($"property field '{propertyField}' changed"));
The binding used in the inspector is... less than ideal... but long story short, you can't. If it is a issue, you should change your logic.
Oh no :(
Can you propose an alternative solution in that case?
I have custom inspector base class that collects certain annotated properties from the component, and depending on the type of annotation notifies the component of the changed value.
For example I have a "Variant" property that is annotated such that when it's value is changed in the inspector it updates the component data, and the component emits C# event that other components currently on the scene are subscribed to.
The problem is that reacting to the event in the component triggers some calculations, so I want to avoid doing them each time I select another object and new inspector is opened.
I use it to generate shader asset files, and some property fields perform a simple uniform update on the material, while some other properties change the shader soruce code itself, and I just can't afford to regenerate the shader each time I simply change selection
for example here I have a prefab that generates a raymarching shader from the scene hierarchy:
and changing the Variant in the Sdf Torus Controller in the inspector is intended to regenerate the whole shader with alternative function for the torus
while some other properties like Main Radius don't regenerate the shader, they just update the uniforms
My idea is to just... write a custom inspector for each kind of component and live without property fields
Hmm, you could use the Bind event and keep a bool for whether it has been bound or not maybe?
Can you point me to the right docs? I am a novice when it comes to UITK
specifically to the Bind event because I can't find it
Oh... right... it is an internal event... 😬
You can use the TrackSerializedProperty extension method I guess instead of the ValueChange event
Or the TrackSerializedObjectValue extension method for I think when any value on a SerializedObject changes.
first experiments show promising behavior
yup, thank you very much, this is enough for now
how do you keep the values of editor tool settings ? it keeps resetting every time i close the editor window or recompile my code
its incredibly annoying
in my case my inspectors are just "views" of the data that is stored and serialized in components
mine isn't. for example i set a grid size for placing things, this is just solely for the editor tool
every time i close it and reopen its back to 0
so I bind to serialized properties of components to get updates when data changes and register handlers to update the component data when controls change
thats fine if the data relates to objects
hmm, I am not sure in this case, I am still learning editor tools. I had the privilage of designing my tool around prefabs, custom inspectors and components, so the data is just there, stored on game objects directly.
is this some kind of "preset"?
yeah its easy enough when the data relates to game data
its just a placement tool for level editing i want to place things snapped to grid sizes
or should it be a persistent tool setting
i have a bunch of other settings too id like to keep persistent
my only other option is tie to a scriptable object
maybe PlayerPrefs?
but then why bother have an editor window when i might aswell make it a part of the scriptable object editor
these are the settings i want to persist when i close the editor tool
I haven't used PlayerPrefs myself, but this sounds like something that could help you in that case
hm maybe
I've used it for a bunch of tooling 👍
can it be used for binding ?
It's a persistent SO, so just make a SerializedObject from it and should be the same from there to get the bindings. But I rarely ever use bindings, so I can't confirm much about that side.
slider.BindProperty(_instance.FindProperty("_bounds"));```
it works \o/
ok i dont understand gui styles i put this as my style:
style = new GUIStyle()
{
normal = new GUIStyleState() { textColor = Color.white, background = Texture2D.blackTexture },
fontSize = 15,
alignment = TextAnchor.MiddleCenter,
stretchWidth = true,
stretchHeight = true,
fixedWidth = 100,
};
yet no background comes up behind the font
i just have font white but i thought the background would show
this is how it looks which is fine until its over an object that is white
then its unreadable so was trying to put a black texture behind it
I'd just draw a DrawRect manually before it
but then what is this api for https://docs.unity3d.com/ScriptReference/GUIStyleState.html ?
textColor works fine
I don't know if every control uses all of GUIStyle. I forget, haven't done IMGUI stuff in years
thats fair though ui toolkit doesnt yet support world space tracking
so i dont have much choice
I generally also don't build GUIStyles from nothing, and use the constructor that takes another GUIStyle
EditorStyles already has so many good starting points
well i did try EditorStyles.label but the font is super faint and hard to see if infront of bright objects
if there was a white cube in that scene it be unreadable lol
My internet has dropped, my point is that you don't need to use the empty constructor, you can pass in another GUIStyle to duplicate it and only modify one part of it
Doesn't help the issue, just gives me peace of mind I've set everything up at a basic level 😄
yeah i wonder .normal isn't the default state of the label
Perhaps not
they have .normal and .onNormal
bit confusing
really hope they prioritise some scene visual elements for ui toolkit -_-
Ah, I see why my API was using DrawRect, it's because I support a background color as well as a foreground
it would be silly to make lots of GUIStyles 😄
it seems this did the trick:
var style = EditorStyles.helpBox;
style.normal.textColor = Color.black;
style.normal.background = EditorGUIUtility.whiteTexture;
Could also be that imagePosition is set to TextOnly somehow
using white texture from utility works but not black texture static reference
ill just stick to white with black font as long as its working im happy 😄
Gets a small Texture with all black pixels.
Unity sets all pixels of this Texture to transparent black (0,0,0,0).
well, there's your problem
does serialized objects not work with finding properties that are lists?
i keep getting null when it should find it
Context?
ive since re-written editor so no longer relevant but it was a list in an scriptable object with serialized field but find property didn't work on the serialised object of that scriptable object
it worked for fields that were floats though
¯_(ツ)_/¯
I mean we understood that much, but you gave no context on the structure of your data nor how you were doing FindProperty (i.e. what path were you using on whcih member etc)
anyone knows how to emit events to ui-toolkit ?
We have a #🧰┃ui-toolkit channel. Though this is the answer: https://docs.unity3d.com/Manual/UIE-Events-Synthesizing.html
ye i seen that channel , had a quick peek - its just under "artist tools" and no one is answering any code related questions
You can script everything in Unity, the groups only help you find channels
Is the only way to use custom generic editor window to use some abstract base class? Can't we just use something like this? (it doesnt work of course, but maybe I missed something)
[CustomEditor(typeof(TestGeneric<>), true)]
public class TestGenericEditor : Editor
{
private TestGeneric<BaseType> testGeneric;
protected override void OnEnable()
{
base.OnEnable();
testGeneric = (TestGeneric<BaseType>)target;
// code
}
public override void OnInspectorGUI()
{
// code
}
}
am i misunderstanding how tracking property values work? i want my button to hide when a value is true so i have:
var btn = root.Q<Button>("edit-button");
btn.TrackPropertyValue(settings.FindProperty("_editMode"), (prop) =>
{
//this should get called since the value changed to true
Debug.Log(settings.FindProperty("_editMode").boolValue);
btn.visible = !prop.boolValue;
btn.SetEnabled(btn.visible);
});
btn.clicked += () =>
{
//set to edit mode
settings.FindProperty("_editMode").boolValue = true;
settings.ApplyModifiedPropertiesWithoutUndo();
settings.Update();
};
for some reason the TrackPropertyValue never gets called when it should since i changed the value to true in the click
If you are still struggling with this. This will only work once. So once it is clicked it will set _editMode to true, and the TrackProperty callback will be raised. But not again, and not when first opening the editor.
Also, calling Update after Apply does nothing
help guys
Don't have the background transparent. You have to cover up the text that is drawn there by default
If I don't do that, I don't see the text with the name duplicate just one color
I am not following what you are saying or what exactly you are wanting I guess.
Isn't that what you want..?
That is what you want, right?
Right... that is how colors work. If you have light text on a light background, the light text is going to be hard to see
Also I noticed if I start playmod or exit unity it all goes away how do I save it?
Well, two things, first Unity can't serialize dictionaries. And Unity also can't serialize static fields. So you would need to make it a list (or serialize it to a list) so it can be saved, and store it in a class derived from ScriptableSingleton
However, you have other issues. What happens when you change scenes, or close and reopen Unity? The instance ids may be different. And you will also need to manage when gameObjects are deleted in the editor so you can remove them from the dictionary
can you elaborate?
Oh what part?
conservation
Pardon?
color preservation
The long and short of it is that I would recommend one of these options:
- 'store' the color in the name of the game object, like
UI __#8634eb. And then parse the naming by finding the__#and anything before that is the actual name and anything after that is the color.- Downside is that it would show in the title field in the inspector when the object is selected.
- Add a component to the object to store the color.
- You can make it invisible using
hideFlags(google). - Downside is you have to manage adding/removing the component as the user sets/clears the color.
- If the asset/plugin is removed, you will have "Missing Script" warnings.
- You can make it invisible using
- Have a component that you add to the scene that stores the references and the colors.
- Downside is it can get tricky if multiple scenes are loaded at once, and you have to manage adding/removing the objects from the list on the component
Is there an easy script that does all this?
I thought I could do something similar, but without the extra elements.
When opening an scene by code, how can I avoid this popup? Basically, if the scene can't be opened I would like to skip it rather than get this popup.
If you just want the hierarchy 'headers' there are a lot on github and on the asset store that do just that
yes
can I see it?
Just google like Unity hierarchy header or unity hierarchy enhanced and you can also add github to the end of the search to find stuff on github. Or on the asset store just search for hierarchy. There are a bunch, like 25+
People I did a UI like that using UI toolkit and filling the table at runtime using a cs script. Now I would like to be able to rename the nodes... do you know how can I achieve that by code?
So I'm trying to use this https://docs.unity3d.com/ScriptReference/Undo.RegisterFullObjectHierarchyUndo.html as registering individual objects causes a stack overflow for when I'm spawning stuff on my terrain. But the problem is that I get this warning, even though it does undo it all correctly: https://i.imgur.com/ltC5pmc.png
All of these it's warning about should be part of the hierachy, so no clue why it's saying it's not registered
I guess the problem is that it doesnt take into account of object created after storing the state
im not sure if that's a problem though?
registering individual objects
With this, do you mean Undo.RegisterCreatedObjectUndo, which the warning suggests?
Yeah, I hit a stackoverflow if I register like 10k trees
the terrain tool does undo operations fine if I populate it from that instead
but I need to populate stuff that isn't supported by the tree tool
I guess technically you can't interact with the terrain trees so there's a lot of information that doesn't need to be undo from them and basically just undos the state
which is kinda what I want too as I don't care about reference bindings, so if I can just suppress that warning from spamming 10k times that would be great
Any tips on how to properly draw a property field for [SerializeReference]<Interface> field? I just want only accept monobehaviour components that implement this interface. Preferably generic solution for interfaces but I can settle on creating property drawer for each interface my self.
Just wanna know if there is any thing I could look in to or read about it. And preferably using ui toolkit rather than MGUI
SerializeReference does not allow you to reference Unity objects like MonoBehaviour or ScriptableObject.
Hello, does anyone knows if it's possible to define scripting symbols that activate only when running specific (or at least any) Unity PlayMode tests? I.e is there a way to have #if PLAYTEST_1 and activate it only when running the first test? If not, is there at least something like #if UNITY_PLAYTEST?
hi , can anyone help solve this issue
Hi all, bit of an odd issue I've run into
I'm creating a PropertyDrawer that shows an extra field when one of the Enum values is selected
Hiding and showing this Vector2 field according to the Enum works fine, however I cannot edit the values of the Vector2 field
Any ideas?
The field is being created as below:
EditorGUI.PropertyField(customOffsetPos, property.FindPropertyRelative("customCursorOffset"));
Figured it out, I forgot to submit an increased GetPropertyHeight() value for when the additional field was shown
is there some sort of type, attribute, drawer or black magic so that if I have [SerializeField] GameObject thingy I can specify if that thingy is supposed to be something from the scene or a prefab asset? 🤔
odin inspector has it 🥲
ObjectField has a parameter allowSceneObjects at least
hi - can someone help me with test setup lifecycles? I have a set of EditorMode tests that run together, and a few fail, if I run them again they work and it makes me thing maybe the [Setup] method isn't called once per test, but once per set of tests, or the state handoff between tests is not what i think
If i select and run five tests, does Setup get called five times or once?
ah actually i think our issue is StartCoroutine() being called at some point in our code under test
that was a problem, as is the fact i didn't realise that behind these tests is some scene getting objcets spawned, so if [Setup] creates two objects, next tese there's two more, now total 4
yay okay, so now i'm back ot jsut the startcoroutine() getting call in teh code under test breaking the tests
How can I unset a property on a material variant?
I can see Material.SetColor but not UnsetColor or UnsetProperty etc
oh nvm it's RevertPropertyOverride!
How can I modify this field on an existing model via code?
ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(...);
modelImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(Material), "RGB"), AssetDatabase.LoadAssetAtPath<Material>("Assets/Path/To/Your/Mat.mat"));
modelImporter.SaveAndReimport();
Awesome. Damn that was obscure.
How to make my SerializableObjects from my embedded package be detected by Unity?
I added a scriptable object asset to my package's Editor directory, but when I tried selecting it in a component, the dropdown didn't suggest it
I found "hideInEditor": false, that I could add to package.json, but SOs are still not recognized
Should I always use GetPropertyHeight in property drawers when drawing properties?
Or is using singleLineHeight + standardVerticalSpacing ok practice?
Both work, kinda depends. But I guess thinking about it, it would be better to use GetPropertyHeight (I use both).
But if you can, I for sure recommend using UIToolkit instead. Much easier.
You can use UI toolkit to make property drawers?
Heck yeah, at least in 2022
I think 2021 as well but not too sure
I tried making an editor once but gave up because I couldn’t figure out how to reference the actual doc i made in the UI toolkit without a hardcoded path
Yeah... that is cause you gotta use a hardcoded path. One way (which I use) is to get the current folder dynamically, and use that as the starting point so that it is safe if a user moves the folder.
An alternative is if you make a VisualTreeAsset or StyleSheet (or any other UnityEngine.Object) a serializable field, you can assign a default value to it in the inspector when you click on the script. I tend to not like it as much since it is hard to tell from code where the value is coming from.
See that’s why i kinda stay away from it unless for editor windows. I use the default serialized fields when I make an editor window, but they don’t exist for editors and property drawers. To get around this in the past I’ve used a scriptable object class that has the editor/property drawer class declared inside of it so i can use its default references that way, but i dont think my job would like that level of jank…
@gloomy chasm do you use AssetDatabase.GetAssetPath for getting it dynamically?
Yeah, what I do is have this class in the root Editor folder, and then have a wrapper utility class with methods like LoadVisualAsset(string documentName) that uses the GetFolderPath() method from this class, and then adds the path to wherever I store all of the UI files (uxml, uss, png, etc.)
internal class EditorAssetsFolderLocator : ScriptableObject
{
/// <summary>
/// Reterns the project reletive path to the "Editor" folder in the assets folder.
/// </summary>
public static string GetFolderPath()
{
var locator = CreateInstance<EditorAssetsFolderLocator>();
var script = MonoScript.FromScriptableObject(locator);
string path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(script));
if (Path.DirectorySeparatorChar != '/')
path = path.Replace(Path.DirectorySeparatorChar, '/');
DestroyImmediate(locator);
return path;
}
}
Hmm im pretty sure AssetDatabase.GetAssetPath would break in a package tho
even ones added through a repo?
You mean github repo?
Not github but yea basically
I dont remember specifically what problem but i’ve had issues with it before with some stuff not working correctly
Hmm.. pretty sure (like 98%)
hmm okay. I’ll ask a senior dev about it, thanks!
You mean this?
I'm working on a small tool that uses Physics to place stuff in a level in the editor.
Currently I'm in a bit of a bind so maybe this is just a rubber 🦆 moment. I want to make it so that you select stuff in the level, press "Add" and everything with a Rigidbody gets noted down using my SimulatedBody struct to note the Rigidbody, the position before simulation and the rotation before simulation so that I can reset both if you don't like how things ended up.
The problem for me is figuring out when noting down the original position and rotation is a good idea.
Do you select stuff in the level, press "add" and then press Simulate?
And if so, how would I handle deletion of objects, adding objects, etc...a lot of work right?
Do you just select bodies in the level you wish to simulate and then press Simulate?
What if you accidentally lose the selection for whatever reason? How do I handle the potentially misaligned storage of pre-simulation stage?
is there something like IProcessSceneWithReport but for prefabs? 🤔
