#↕️┃editor-extensions
1 messages · Page 24 of 1
Thought of that, but feels a bit dirty. What if user saves in-between these steps? Or some other weird thing happens.
It is an option though, perhaps I should explore it more, but it does feel like it has a large room for issues to be discovered later. 🤔
I think there was a way to set things as "don't show in inspector" and "don't save" with some flags, though I'm not sure whether they work nowadays - last I checked they had issues. But if they do work, it might be a pretty decent option to add some marker component with some ID, just like I need it. 🤔 Thanks @tender olive, will explore! And let me know if you have alternative ideas. 🙂
Today I found out that [InitializeOnEnterPlayMode] is much earlier than playModeStateChanged, good to know. That is very important to know
Np. Curious what your end goal is here - might help inform implementation decisions. Like why do you need to identify the object and only once in play mode?
Making a debugger helper of sorts where you can right click an object and say "I wanna debug this guy", and then in code you can add a conditional breakpoint that only breaks on the selected objects.
This works, but I'm storing the objects by ID or instance, either way, that doesn't quite work when exiting entering play mode, which may be a bit annoying because you can't select some object to debug and carry that over multiple sessions.
Not sure it's that big of a deal. It helps me anyway and is just a few clicks, but am planning to put the code on some public repo for people to use, so I thought I'd look into making some improvements that I can think of. 🙂
I wonder if making a static resetter package would be worth a hassle 🤔 , so the idea is to disable the domain-reload in the editor and just crawling all statics via their namespace and set their default values (for value types) and null for (for classes)
I'm trying to create a tool to automagically write a cs class containing the structure of an ui prefab... so far I've got it working but whenever I try to add the feature to include nested prefabs into the generated class, the info I need from the asset yaml doesn't seem to be present... Unity doesnt seem to add the stripped part of the prefab pointing to the monobehaviour/prefab =(... does anyone know some api that could help me here?
How are you doing this in the first place?
Hey there, I am facing FileIOPermission present both System.Security.Permissions and mscorlib problem, anyone knows the solution?
Get permissions
Doesn't using 'default' keyword do that already for class types, or can it be overridden to return something besides null?
default for classes is "null"
Yeah that's what I mean...
You said default for value types and null for classes... but to generalize you could just use default for both value and classes, right?
Does someone know if it's possible to have shared library built for a unity game ?
I have a .csproj outside of unity game folder and i want to buiild it to use it inside of the game.
I tried MSBuildForUnity but it didn't work
Hi,
anybody else having the Problem, that the Rider Editor Plugin of Unity is not compatible with Riders flatpak?
specificly both are installed through Flathub.
I first thought that It might be a problem with flatpak isolation, but that cant really be it, because Vscodium is seen just right. so its prolly just that the editor extension does not support the flatpak for rider?
(and no, I cant use the toolbox, because im running an immutable distro (Kinoite) & the rider plugin wont allow me to run that one inside one of fedoras toolboxes)
I found a Workaround, which lets bot h Flatpaks Connect, and tells me that the Editorplugin for Untiy is the Problem:
Ive just Installed Rider through toolbox and flatpak, so I can select it.
and if I manually open the flatpakversion (the one that actully works under immutable systems) It is ablle to connect to unity.
So the Problem has to lie in the way that the Unity Editor Extension discovery.
Does anyone know how to access the settings asset field there (at top)? I need to for a niche case, but even after looking at the editor on github I can't find that field. Plus I don't know what this panel is Resources-wise so I can load it up in the first place 
try {
var graphicsSettingsAsset = AssetDatabase.LoadAssetAtPath<Object>("ProjectSettings/GraphicsSettings.asset");
serializedObject = new SerializedObject(graphicsSettingsAsset);
var iterator = serializedObject.GetIterator();
iterator.Next(true);
while (iterator.Next(true)) {
if (iterator.propertyPath == "m_SRPDefaultSettings.Array.data[0].second") {
iterator.objectReferenceValue = hdrpSettings;
serializedObject.ApplyModifiedProperties();
break;
}
}
} catch (Exception e) {
Debug.LogError($"Failed to set m_SRPDefaultSettings to {hdrpSettingsPath}: {e}");
}
I figured it out 👍
Hello, I want to write a rightclick menu that converts all the materials on a gameobject in my scene (or prefab!) and converts them into another type of material suitable for the current SRP. I'm struggling with a couple of concepts around this though - specifically if I just replace the sharedMaterial nothing happens, and if I replace material in the renderer, unity tells me I've made a mistake. Whats the correct process for something like this?
some thoughts: should I be making assets out of these upgraded materials? If so, is there a way to trace back where a material in a scene came from asset wise?
so I can plonk it next to it?
Is it possible to draw a selection outline without using a GameObject? The only options I am using are Handles.DrawOutline that takes either GameObjects or MeshRenderers, but I am drawing a mesh with the Graphics API.
Doesn't look like it.
Yeah... didn't think so... I guess I will see if I can make an outline for disabled GOs or renderers haha. Thanks for the sanity check.
I don't quite get the question
Is it an outline in the scene?
You know in the scene view when you select a GameObject, you see an orange outline around it? I wanna do that, but without having a GameObject.
Only method though looks to require one sadly
You probably should be making assets, yes... you can find the path using AssetDatabase.GetPath or something in that class, I believe. As for your other question... I wanna say that .sharedMaterial should work just fine (once you have these assets), but I can't say for sure.
The answer to my question was if you're in the editor, you have to grab the entire array of .sharedMaterial, make changes, and assign it back at the end.
if anyone else ever runs into it
//This works
Material[] materials = rend.sharedMaterials;
for (int i = 0; i < materials.Length; i++)
{
materials[i] = someReplacementMaterial;
}
rend.sharedMaterials = materials;```
but
rend.sharedMaterials[i] = someReplacementMaterial;
Has anyone ever managed to use UIElements.PropertyField and built a derived class selector? It seems that PropertyField is quite limited for this kind of thing and requires a dummy ScriptableObject with T Value instance in order to work.
Oh, that makes sense. Pretty much all array properties in Unity return a copy, so modifying said copy has no effect (unless you set it back to the property)
yeah, I thought setting the element directly would be okay, so that caught me off guard
What? What are you trying to do?
For clarifications in-case you were not sure why. It is because sharedMaterials is actually returning a copy of an array from C++. So rend.sharedMaterials[i] = someMat is just setting it on the array copy.
[CustomPropertyDrawer(typeof(AnimCommand))]
public class AnimCommand_Drawer : PropertyDrawer {
float totalHeight;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return totalHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
EditorGUI.BeginProperty(position, label, property);
...
Rect startRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight * 4);
property.isExpanded = EditorGUI.Foldout(startRect, property.isExpanded, new GUIContent("Animation"));
totalHeight += startRect.height;
if(property.isExpanded) {
...
EditorGUI.PropertyField(...);
totalHeight += pos1.height;
}
EditorGUI.EndProperty();
}
}
This is code and I left out code that is not needed
Basically, in list, every instance of the AnimCommand takes 'totalHeight' value from the last element in the list
it works fine outside list.
Anyone have idea what might cause this? So far chatgpt and google didnt give me answer, might be that iam not asking right keywords
Basically i calculate totalHeight in onGUI, based on selections and save it
then get height just returns that value
this is just simple prototype but it will have lots more options
you're kinda not supposed to do that... getHeight is called first and should calculate the height and then that height is passed to OnGUI
but, my assumption would be that here it calls all of them through the same prop drawer (not sure if it does it otherwise), so of course the height is based on the last thing that was drawn
@native geode
The PropertyDrawer is reused for every item in a list. And GetPropertyHeight is also called before OnGUI is called. So you need to implement the height calculation logic fully selfcontained
So, exactly what Pulni said haha.
so basically i need to do that calculation twice?
because when drawing i need to calculate it on the go
No, you already will have the total height, it is the position.height of the OnGUI
generally that's what you're supposed to do, yes... if it makes you too unhappy, you could try storing them in a dictionary by serialized property, but that's kind of a hack
even more unhappy 😦
not sure how that's even more unhappy 😄
Yeah, but I will need to calculate position of some element in the middle again based on selection of item above
What? Do you mean based on other items in the list?
But I plan to override display of List. Just asking for opinion before i start it.
I thought I would make new class that stores only list and create drawer for the new class
- would that problem persist in that case also?
- Is that proper way to override display of the list?
There is option A that displays label below it if turned on.
based on selection in A, selection B will be lower or higher
Can't make drawers for lists. So would need to make a custom list class for it.
For UI, I would look at using UIToolkit instead of IMGUI, you would probably like it more and find it easier to work with.
UIToolkit is not really compatible or has problems with older versions of Unity right?
Depends. It works great for 2021 and newer. 2020 has a few limitations.
Yeah, iam creating Asset store, asset and would like it to work on older versions
Ahh, 2020 is not widely used now. And 'no' new projects are being started with it. it is also almost out of LTS support. The assetstore recommends 2021 as the min version and I would also recommend that. But up to you.
Have you seen Jason Weinmann’s video on creating concrete objects that derived from abstract classes and interfaces using a GitHub package?
I’m testing how UIToolkit handles setting managed reference properties and the issue that I’m seeing is that when you change a property of this type is that it will multiply the choice field because it already exists in the previously drawn property drawer
I achieved a successful result but I had to use an unsaved scriptable object instance with a generic class type and use their serialized properties to build a proper Property Field
Multiplayer Mastery Course - https://game.courses/mp/
Lunar Bundle - https://assetstore.unity.com/mega-bundles/lunar-new-year-2024?aid=1011lkXUB
Dragon Sale - https://assetstore.unity.com/?on_sale=true&orderBy=1&rows=96&aid=1011lkXUB
00:00 Introduction - Remember to Like :)
00:30 Ability Demo - PreCode
02:54 How it Works - Code
03:52 Ability...
anyone know what could cause this error?
Cannot create Settings Provider for: CreateSettingsProvider
UnityEditor.SettingsService:OpenProjectSettings (string)
TerraPunk.Editor.PathDataBuilder:OpenSettings () (at Assets/Content/UnitManagement/Scripts/PathData/Editor/PathDataBuilder.cs:661)
I was changing the settings provider after it has been working for almost a month and it seems to have stopped working. I renamed some stuff, moved some stuff around... but even if I just comment everything out so it just returns a blank settings provider i still get the same error. :/
what I mean by that is:
[SettingsProvider]
public static SettingsProvider CreateSettingsProvider()
{
return new SettingsProvider("Project/Path Data Settings", SettingsScope.Project);
}
ah, there was an exception occurring in the class, but outside that method, that was not being logged.
Is there a way to override how these are rendered? I would like to change the text ideally, but if that's not possible, whatever is possible (color/shading)
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
[InitializeOnLoad]
public static class UnityHierarchyScenes
{
static UnityHierarchyScenes()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemOnGUI;
}
private static void OnHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
{
for (var i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
if (scene.GetHashCode() == instanceID)
{
if (scene.isLoaded)
{
var content = new GUIContent("S");
var color = new Color(0.5f, 0.5f, 0.5f, 1f);
var backgroundRect = selectionRect;
backgroundRect.width = 18.5f;
EditorGUI.DrawRect(backgroundRect, color);
EditorGUI.LabelField(selectionRect, content);
}
}
}
}
}```
This will draw something. What you need to do after is match the background color, match the font weight, size and position and draw over it.
Perfect thanks! I didn't know GetHashCode is equivalent to the instance id from the callback
Take a look at this code example from the UnityEngine.Object class. Notice what the GetHashCode returns.
FYI, a Scene is a struct, but just wanted to showcase this
private static void OnAttach(AttachToPanelEvent evt)
{
evt.destinationPanel.visualTree.RegisterCallback<DragPerformEvent>(Dragged, TrickleDown.TrickleDown);
}
private static void OnDetach(DetachFromPanelEvent evt)
{
evt.originPanel.visualTree.UnregisterCallback<DragPerformEvent>(Dragged, TrickleDown.TrickleDown);
}
private static void Dragged(EventBase evt)
{
Debug.Log("Drag performed");
}```
I'm having trouble using this `DragPerformEvent`. It never triggers on drop/release
OnAttach and OnDetach work fine
Cause the visual tree is never dragged...
But it can be a drop target
m_DropArea.RegisterCallback<DragPerformEvent>(OnDragPerformEvent);``` this is a unity example. It registers the `DragPerformEvent` on the drop target
Need more context, got a link to the full example?
What I mean is you are registering it to a thing that never receives the input. The panel.visualTree is this top element. You don't want that one, you want the child of it, the "#rootVisualContainer". That is the rootVisualElement of a Window
I see the example, but they have changed the input system and the drag and drop system a couple of times now, so the examples are probably no longer up to date. Assuming you copy pasted the entire class 1 to 1 and it isn't working.
private static void OnAttach(AttachToPanelEvent evt)
{
_dropArea.RegisterCallback<DragPerformEvent>(Dragged);
_dropArea.RegisterCallback<DragExitedEvent>(DragExited);
_dropArea.RegisterCallback<DragLeaveEvent>(DragExited);
}
private static void OnDetach(DetachFromPanelEvent evt)
{
_dropArea.UnregisterCallback<AttachToPanelEvent>(OnAttach);
_dropArea.UnregisterCallback<DetachFromPanelEvent>(OnDetach);
_dropArea.UnregisterCallback<DragPerformEvent>(Dragged);
_dropArea.UnregisterCallback<DragExitedEvent>(DragExited);
_dropArea.UnregisterCallback<DragLeaveEvent>(DragLeft);
_dropArea = null;
}``` Changed the target. PickingMode is set to Position. DragExited works. DragPerformed, nope
So in order to DragPerformedEvent to fire, DragAndDrop needs to be updated. Solved.
So various things update when you re-focus the editor (like modifying the manifest, or resolving packages), so is there a way to force a "re-focus" so I don't have to click out and back in of the editor?
UIElements?
Not sure what that has to do with this
Found EditorUtility.RequestScriptReload(); so I'm using that for now (reloads scripts, but doesn't recompile them).
I misread
any idea on how to calculate IMGUIContainer from UI Toolkit layout correctly to match underlying inspector size?
var imgui = new IMGUIContainer(() => { inspectorElement.editor.OnInspectorGUI(); });
I basically have this where editor is UnityEditor.Editor
but layout auto resolves to just default 22f
which is incorrect
and looks like this
things just overlap each other
It's just my own helper
private class InspectorElement : VisualElement, IDisposable
{
public UnityEditor.Editor editor;
public IMGUIContainer container;
public void Dispose()
{
if (container != null)
{
container.Dispose();
container = null;
}
if (editor != null)
{
Destroy(editor);
editor = null;
}
}
}
to properly dispose things
That’s why you aren’t using Unity’s InspectorElement?
new InspectorElement(asset);
it appears to have same problem
What’s the code like now?
_root = new ListView
{
makeItem = () => new VisualElement(),
bindItem = (element, i) =>
{
var comp = _components[i];
element.Add(new UnityEditor.UIElements.InspectorElement(comp));
},
unbindItem = (element, _) => { element.Clear(); },
itemsSource = _components
};
where's your imguicontainer?
//var NormalInspector = new IMGUIContainer(() => { getEditorGui.DoDrawCustomIMGUIInspector(component); });
InspectorElement uieNormalInspector = new InspectorElement();
uieNormalInspector.Bind(new SerializedObject(component));
thats from the source example
can you give a link to it?
Is the Editor you are trying to draw your own or is it default?
I don't know which would it be
I just want to draw whatever normally gets drawn
for game objects for example
it may be IMGUI one (Odin Inspector) or VisualElements one
The list elements you are drawing, is it a custom editor or a default editor?
what list elements?
private void CreateGUI()
{
_root = new ListView
{
makeItem = () => new VisualElement(),
bindItem = (element, i) =>
{
var comp = _components[i];
element.Add(new InspectorElement(comp));
},
unbindItem = (element, _) => { element.Clear(); },
itemsSource = _components
};
FillData(typeof(Transform));
rootVisualElement.Add(_root);
}
private ListView _root;
private readonly List<Component> _components = new();
private void FillData(Type type)
{
_components.Clear();
foreach (var guid in AssetDatabase.FindAssets($"t:{nameof(GameObject)}"))
{
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
var asset = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
if (asset.TryGetComponent(type, out var comp))
{
if (comp.GetType() == type)
{
_components.Add(comp);
}
}
}
_root.Rebuild();
}
You are using list view, are you not?
So the list has visual elements that populate the list view
I took it from mine, but basically it's the same from source example
I have my own property drawer and it uses foldout.
I want so that when I hover on the header of fouldout to glow whiter, to signal to the user that he can interact with the foldout
How would I do that
This is current state
public class MicroBarAnimation_Drawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
EditorGUIUtility.AddCursorRect(headerRectWithArrow, MouseCursor.Link);
if(headerRectWithArrow.Contains(Event.current.mousePosition) ||
property.isExpanded)
{
Microlight_DrawUtility.DrawHoverGlow(headerRectWithArrow);
Microlight_DrawUtility.DrawHeaderBottomOutline(headerRectWithArrow);
}
}
}
It works and glows but with huge delay, basically when OnGui is called
Calling OnGui every frame is bad so what i thought I would do is have property Hovering
which when changes state from true or false, calls OnGUI, on top of regular OnGUI
anyone know how maybe default implementation is done? like button or list hover?
mind showing more code?
so same like your case
Why go through that when InspectorElement can be used?
I forget honestly, its basically the same like Unity's source example
You want the height to fix the overlapping right?
But maybe try to figure out why it overlaps first?
oh it's due to this, thus I wrapped it with imguicontainer
Where’s the source to that?
because item height is 22f
while it's clearly more than that
question is, how to figure actual item height
and how to apply it
from the staff themself
The link I mean😂
I'll test it. But still, this post is very old
yeah my snippet is very ancient too
might mess up with the copy paste
you can basically apply your own guistyle for the imgui part
according to your code
your IMGUI part is never called
you only use inspector element
proly, there was issue with propfields, the inspectorElement one was to workaround it iirc
I mean
I'm fine either way
but either way I don't have proper size
for inspector
oh! you meant the commented imguicontainer, yeah, but it was working fine other than the quirks with propsfield
it's basically copy/pasted from the old uitollit source
it was commented bcos I changed the custom editor for the component to uitoolkit iirc
it's whatever, I just need proper size of that thing 
I think they removed the old examples apparently https://github.com/Unity-Technologies/ui-toolkit-manual-code-examples/tree/215b134e8c8f736e7de90a13bceb891a154ac790
check how your list view gets created
there may be a mention of item height somewhere
I mean you can apply your own gui style with imguicontainer, no?
huh?
it's shown in the snippet file
I don't get how that affects anything or returns me content height
their new example for showing default inspector is like nothing much to see in there https://github.com/Unity-Technologies/ui-toolkit-manual-code-examples/blob/215b134e8c8f736e7de90a13bceb891a154ac790/create-a-binding-inspector/Editor/SimpleBindingExampleInspectorElement.cs#L7
lmao the old one is much more complete than that
I bet they just added imgui support to that inspector element
proly yeah
Oh I misunderstood then, thought you wanted to adjust it so it could fit to whatever container
I know so little about unity's imguis that I don't even care 😂
bump
Also
public class AnimCommand_Drawer : PropertyDrawer {
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return totalHeight;
}
}
This is custom drawer for my AnimCommand class
MicroBarAnimation_Drawer has list of the AnimCommand classes
how to access height of AnimCommand_Drawer from the MicroBarAnimation_Drawer which has list of AnimCommands?
Could use an 'empty' guistyle that is only visible when hovering and use GUI.Label
I usually have a similiar hover check to yours but then then inspector needs to be constantly updated (requiresConstantRepaint) so there are probably better ways lol
Iam not following but ill google it
Hmm actually that might block you from interacting with the foldout
I'm on my phone and have read through this fairly quickly but, you are aware of the virtualisation method and list height settings, yeah? https://docs.unity3d.com/ScriptReference/UIElements.BaseVerticalCollectionView-virtualizationMethod.html
https://docs.unity3d.com/ScriptReference/UIElements.BaseVerticalCollectionView-fixedItemHeight.html
I did fallback to manual slider for item height, but without it I couldn't figure how to get imgui content size anyway
To have auto size
I wanted to add the red button to my custom Property Drawer and that seems as really hard task but I have seen it everywhere like Odin Serializer.
I don't think they are using UI toolkit since that is not a new tool.
How would I create button of custom color?
Not sure how much info you are needing. But if you just want to know how to color a button, you can set the GUI.backgroundColor = Color.red; before drawing the button.
(Might be GUI.contentColor it has been a while so I don't remember exactly which)
I think i have been trying that and it didnt work, but I will try it again soon after iam done with cooking.
I was trying to paint it white, white is default color 🤦♂️
i have been trying to use other colors. but on labels and didnt work
It is because it multiplies the color of the texture
thanks, that was good find, will help in other areas too
Btw, exactly of changing the color of a button https://docs.unity3d.com/ScriptReference/GUI-backgroundColor.html
You can also change the backgroundtexture to be put white if you just want a white square, https://docs.unity3d.com/ScriptReference/Texture2D-whiteTexture.html
Or you can provide a more neutral white button
Can I override or augment the behaviour of an existing asset importer?
More specifically, can I write my own importer that runs after an importer in a UPM package, or disable the importer from that package and use my own fork or subclassed package?
What kind of existing asset importer?
this one specifically
I want to fork it
Ideally just disalbe the one in the package and rewrite that importer
But obviously I can fork the whole package.
I wonder if they ever implemented registering a scriptedimporter with an existing extension
It's been a complaint for years
I have never really used importers before
But this one has a wontfix limitation
And replacing it seems to be the easiest way forward for my particular situation
@waxen sandal you know what... Most of the API I'd need is private anyway so I think I'll just fork the whole project.
Yeah that's usually how it turns out :/
I found this script to create a text file on the current folder I'm in and it works great.
https://pastebin.com/XrufxuYj
Is it possible to modify it so that, when I create a new text file, I instantly go to edit it's name? Just like when creating a C# Script.
Try ProjectWindowUtil.CreateAssetWithContent(
ProjectWindowUtil.CreateAssetWithContent(filePath, contentAsString, texture2DOptional);
``` If oyu need a unique path
How do I unlink a project from the version control?
I want it to then link to a fresh new repo
This channel is about creating editor extensions, not about how to use Unity products
No, I mean like. Do you know how when you create a new C# Script you already can edit the name of the file?
Yes?
Is it possible to mimic that?
Doesn't CreateAssetWithContent also do that?
Oh it does? Oh ok
I think it does
There's an api that also lets you do that manually but I forgot what it's called
ProjectWindowUtil.StartNameEditingIfProjectWindowExists
But that's a lot more complicated
thanks
Does anyone knows how to create that message created with IMGUI but with unity UI Toolkit?
HelpBox, you either have to add it from C# or in the UXML, it doesn't show up in the library of the UIBuilder.
I am working on a git package, which means the contents are imported in the Packages folder.
I still need to change the material (or shader) of a renderer in a prefab when a different render pipeline is detected.
Is this allowed? I am not sure if the packages are editable when imported
You are not allowed. You will have to do it to the instance, or have a version of the object copied to Assets somewhere
I am making android apk update pop up using google play in app update plugin, where user gets a pop in app when there is new update available for the app, but in 'AppUpdateInfoOperation' this is giving app not owned anyone know whats the reason
is there a details explore view in unity editor ?
Is there a way for me to create a custom open behavior for a custom asset type in the editor? Like for example, when you double-click on a C# file, it opens it in your IDE, or when you double-click on a prefab, it opens it in an isolated scene. I'm trying to make an asset type that automatically creates a C# file of the same name, and double-clicking it will open the C# file in the IDE.
there any known pitfalls with UI Toolkit TreeView in an editor window that would cause it to always automatically expand all nodes on a domain reload? I have Auto Expand disabled, and even when manually calling treeView.CollapseAll(); it still ends up fully expanded after each domain reload.
I think you could probably do that with the [OnOpenAsset] attribute
https://docs.unity3d.com/2020.1/Documentation/ScriptReference/Callbacks.OnOpenAssetAttribute.html
just create your own static method and use the attribute on it
Thank you, that looks perfect! Is there a way to make it only run if trying to open an asset of a specific extension, or would I just have to get the file extension and use an if statement?
I think there might be a way to do that
I have used it mostly for opening custom editor windows, so I needed to know the type
i think you can use Selection.activeObject and just check the type of the object that way
can't remember if we are meant to post screenshots of code but just as an example:
It doesn't seem like that would work for me, since I would need to check the file extension rather than the type. I'm trying to make a custom asset that's basically a json file with a special extension, and only want to run the OnOpenAsset for that extension. Is there a way for me to get the file extension from the object or the instance id? I don't really see anything that includes the file path.
I think it is possible
The docs page hints that you can use external tools to open it but doesn't give an example
You can get the relative file path via AssetDatabase.GetAssetPath and I imagine then just check the path to see if it contains the extension?
Alternatively, you could use Path.Join() and get the full path if you need that instead
I'll post what I've got in a sec
Also turns out previous me didn't realise you can just use the instanceID instead of messing around with Selection.ActiveObject
public class TempCommandTest
{
[OnOpenAsset]
public static bool MyOpenAssetMethod(int instanceID, int line)
{
Object obj = EditorUtility.InstanceIDToObject(instanceID);
string relativePath = AssetDatabase.GetAssetPath(obj); // in my case this returns: 'Assets/New Custom File.myextension`
return true;
}
}
if you need the fully qualified path i think there would be a bit of fiddling around involved because both AssetDatabase.GetAssetPath() and Application.dataPath contain the Assets/ portion of the path
Thanks, this works great! I'll just use string.EndsWith to check for the extension.
nice, glad to help
i find the custom editor stuff very confusing sometimes lol
using UnityEditor; //add into c# code for AssetDatabase.GetAssetPath()
relativePath+=AssetDatabase.dataPath; //Contains the path to the game data folder on the target device (Read Only) and it includes: projectPath/Assets
thanks for the input, realise I could have included the using UnityEditor; tag but I notice that a lot of people in here don't bother
the person who asked the question just wanted to find the file extension, however just thought I'd clarify:
the issue with just appending the strings as I think you suggested (or even using Path.Join()) is that both AssetDatabase.GetAssetPath() and AssetDatabase.dataPath() include the Assets\ folder, meaning that path would be incorrect, as below:
D:\Unity\Projects\MyGame\Assets\Assets\MyFile.json
there might be an existing or alternative way of getting the full path for an asset, but if you decide to use those two strings you would need to truncate Assets\ from one of them
and wich was it's uxml code?
It is in the editor namespace, the name is the same a well, HelpBox
so how could i add inside this scrollview? ```html
<ui:ScrollView scroll-deceleration-rate="0,135" elasticity="0,1" mode="VerticalAndHorizontal" name="TemplateListScrollView" style="left: auto; width: 100%; margin-right: 0; padding-top: 15px; padding-right: 3px; padding-left: 3px; background-color: rgba(0, 0, 0, 0); margin-left: 0; flex-grow: 1; padding-bottom: 3px;" />
Right now the ScrollView is closed, you need to add a open tag
done
i think
Yeah
and then...?
<eu:HelpBox/> or maybe it is ue...?
lemme try :>
Ahh it is uie
No, there is a message property I think
nice!
And do you happen to know any website with usable icons for the Unity editor or icons in general... no? Because I want to add a trash can icon to this button, and I don't really know what resolution the icon should be or anything... I just know that the color it should have is one that in hexadecimal is like this #eeeeee (I can quickly change it in Photoshop).
This goes over a bit how to make them .
The style of icon is called Material Design. Google has a bunch of icons. But the issue with them is that they are 24x24 pixels where as the Unity ones need to be 16x16. So what I tend to do is to find one on google icons that works for what I need, and then recreate it (ish) but staying on a 16x16 grid.
https://www.foundations.unity.com/fundamentals/iconography
Here are two places to get icons in the same style as Unity's. Again though, these icons are 24x24 and we need 16x16 for Unity, so they don't really work as is.
https://pictogrammers.com/library/mdi/
https://fonts.google.com/icons
Just incredible 💪
Thank you so muchh
You're welcome 🙂
look the result of Unity Debug Window its correct with Asset , but without cut-cat, solved have c# of DoubleOnProjectToOpenAsset.png
DoubleOnProjectToOpenAssetFullPathOnDblClick.png //on double open in project, it selects file in explorer, than choose the favorite editor for great purpose (diffrent meshes/names have been in same model file, also prevent open in slow big app)
theoretically this would set this element to have a height of 50 pixels with no max height, right? What instead happens is that the height gets set to 50 pixes and stays at 50 pixels no matter how tall the window is. :/ am I missing something?
in fact thats what looks to happen in the preview, yet in the editor window it does not.
Does both the parent and the child have flex-grow set to 1?
If not, they won't grow to fill the space that contains them
yes the parent has flex-grow set to 1. The parent of that is the root visual element.
Have a play around with the UITK debugger and see what seems to be clamping the height or not expanding
It looks like this "Template Container" is what's doing it?
Yeah, you'll need to either only add the children of the template container to the hierarchy, or style it
how do I style it? As in, how do I add my style sheet to this element, not how do I write a style sheet.
TemplateContainer can be targeted in USS, or you can style it inline via code
what does it need in package manager to be included to support webp, similar but (not .psd), here is a example file that works in browser, but unity editor needs smth? file:// gstatic1_webp.webp
Hey vertx, what is the proper way to do this? Right now I basically have a few UXML docs and instantiate them in the script and add them to the root in the CreateGUI method of an editor window. If I style the template container, it's applied to all template containers as my uss is applied to all the UXML docs. I don't think I should have to create a new style sheet right? Is there some way to add a style class to the template contianer?
SmallFonts
instance.AddToClassList("my-class")
Were you saying it to me?
hello guys! I need help!
I am creating a editor extension for slicing sprites and create animations.
Everything is working, except one thing.I want to organize states in my state machine so it doesn't look like this.
controller is my AnimatorController and I used controller.layers[0].stateMachine.states[i].position bud didn't work.
My code:
void StatePosition()
{
for (int i=0; i < controller.layers[0].stateMachine.states.Length; i++)
{
controller.layers[0].stateMachine.states[i].position = new(3 * i, 0, 0);
}
AssetDatabase.SaveAssets();
}```
And sorry my poor English and feel free to correct me, both in code and in English.
does anyone know how I can sample a 3D animation given a frame on a gameobject in a preview window?
Am I using the AssetDatabase stuff correctly? I was following the advice of someone here https://discordapp.com/channels/489222168727519232/763495187787677697/1216172017301061703
Nevermind, I tested it, and it works perfectly! Thank you very much @bright carbon , this issue was driving me up the wall!
I would use the generic version of LoadAssetAtPath instead of this casting and typeof stuff
otherwise, looks fine 👍
Though you may find your changes are not saved if you're not dirtying anything you modify: #↕️┃editor-extensions message
Hey guys. Hope it is correct section for the question 🙂
Does anyone know how to add Sprite field here? ( see picture ).
Trying to learn this stuff. Code should be something like nodeContainer.mainContainer.Add(sprite).
But I get an impossible conversion. Object that is passed to method should be of type UIElements.VisualElement
Yeah, this is the right place to ask. But not really clear what you are asking. Can you explain it a bit more?
Actually already found info on some random video. Had to to:
var sprite = ObjectType()
{
type = typeof(Sprite)
}
I wanted field to appear on node editor panel, so that I can assign sprite
Oh yeah, you just add a ObjectField VisualElement.
Was trying to google it for 5h😀😃
Oof, that's rough
using (new Handles.DrawingScope(color))
Handles.Label((gridSystem.GridLayout.GetCellCenterWorld(path.first) + gridSystem.GridLayout.GetCellCenterWorld(path.last)) / 2f, new GUIContent($"{path.first} : {path.last} | {path.target}"));
```What I do wrong? Why isn't it colored? (Color should be the same as the path line)
Have to use a GUIStyle to color it https://forum.unity.com/threads/how-to-change-the-colour-of-handles-label.1192570/
Hello, I am trying to run the editor in batchmode to make an android build. I use -builtTarget Android and the logs say it switches successfully. Later in our build pipeline we check EditorUserBuildSettings.activeBuildTarget however it always seems to return Windows instead of the actual active platform. I don't see anything else in our code that changes the build target.
Is this expected behaviour? If so, how do I get the actual build target? From command line?
I'm using 2021.3.31f1
Nvm, I think the build agent is using a different unity install that's missing the android module
Anyone knows why sometimes I have to do cs propertyField = new PropertyField(property); propertyField.Bind(property.serializedObject); // <======= THIS LINEin order for the property to draw?
Because otherwise it won't be bound to a serialized object...
Yeah but doesn't this line in the source code deal with that? Doing just the propertyField = new PropertyField(property); is usually enough for it to work.
public PropertyField(SerializedProperty property, string label)
{
this.AddToClassList(PropertyField.ussClassName);
this.label = label;
this.RegisterCallback<AttachToPanelEvent>(new EventCallback<AttachToPanelEvent>(this.OnAttachToPanel));
this.RegisterCallback<DetachFromPanelEvent>(new EventCallback<DetachFromPanelEvent>(this.OnDetachFromPanelEvent));
if (property == null)
return;
this.bindingPath = property.propertyPath; // this line
}```
No, all that it is doing is setting the binding path. Aka, the path of the property to get a value from relative to the source object.
The thing is, where is that property? It has a path, but where should it use that path?
There is where .Bind(serializedObject); comes in. It is setting the source of where the path should be used from.
The reason why you only 'sometimes' need to do it is because custom Editor automatically do call the .Bind() method, and you don't need to for custom PropertyDrawer because it is propagated down from further up.
You do need to do it for EditorWindow because where should it get that value from otherwise?
Do you know where can I read about this? Thanks 🙂
About binding, or specifically when you do and don't need to call it?
because custom Editor automatically do call the .Bind() method this part
Oh, not really anything to expand on. They just do?
Somebody save me please!
I'm not sure exactly what the problem is, sorry. Is the issue with sprite slicing or state machines?
If the issue is that your changes to the state positions is not persisting you may need to mark the asset as dirty before saving assets
I tried using EditorUtility.SetDirty(controller) but don't work.
So just to confirm, is the issue that the changes your code makes to the position are not saved?
yes!
my script is already serving its purpose, but I want it to result in an organized state machine
Try setting the AnimatorStateMachine dirty. I think that's where the states are actually serialized
don't work.I think the problem is not when saving. See this code. In my debug log it is showing the position without my change that I made in the previous line, that is, it does not even change the position of the states.
void StatePosition()
{
/*o objetivo desse método é organizar a posição dos states na state machine,
mas não está funcionando*/
for (int i = 0; i < controller.layers[0].stateMachine.states.Length; i++)
{
controller.layers[0].stateMachine.states[i].position=new(300*i,0);
Debug.Log(controller.layers[0].stateMachine.states[i].position);
}
EditorUtility.SetDirty(controller.layers[0].stateMachine);
AssetDatabase.SaveAssets();
}```
I tried set dirt before and after the loop "for"
Ah. Looks like ChildAnimatorState is a struct so when you index into states[i] you're getting a copy of the state, not a reference. Try doing something like this
// Get copy of state
var state = controller.layers[0].stateMachine.states[i];
// Change position
state.position = new(300*i,0);
// Reassign state to array
controller.layers[0].stateMachine.states[i] = state;
I did a Debug.Log(State.position) and showed the right values, but in my state machine graph on animator continued in the wrong positions 😖
Hi ! I have a question about EditorApplication.delayCall : in the documentation, it is said that each function is only called once. Do I still have to make the handler unsubscribe from it afterward or is it handled automatically ?
You don't have to
Nice. Thanks !
Hey people. Trying to write some custom property drawers, but implementing it with ui toolkit approach(CreatePropertyGUI) causes a No GUI Implementation error in the inspector. I'm using unity 2022.3 and Use IMGUI Default Inspector is turned off. I thought the inspector is supposed to be rendered by ui tookit in this situation, but it doesn't..? the inspector is not any custom editor. Just a serialized MonoBehaviour.
And the code is something like this:
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
var owner = property.FindPropertyRelative("Owner");
var size = property.FindPropertyRelative("Size");
container.Add(new PropertyField(owner));
container.Add(new PropertyField(size));
var slots = property.FindPropertyRelative("ItemSlots");
for (int i = 0; i < slots.arraySize; i++)
{
var slot = slots.GetArrayElementAtIndex(i);
var slotContainer = new VisualElement();
slotContainer.Add(new PropertyField(slot.FindPropertyRelative("Item")));
slotContainer.Add(new PropertyField(slot.FindPropertyRelative("Amount")));
container.Add(slotContainer);
}
return container;
}
Is there an issue with the code maybe?🤔
Can you show the whole class?
Just this:
[CustomPropertyDrawer(typeof(Inventory), true)]
public class InventoryDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
var owner = property.FindPropertyRelative("Owner");
var size = property.FindPropertyRelative("Size");
container.Add(new PropertyField(owner));
container.Add(new PropertyField(size));
var slots = property.FindPropertyRelative("ItemSlots");
for (int i = 0; i < slots.arraySize; i++)
{
var slot = slots.GetArrayElementAtIndex(i);
var slotContainer = new VisualElement();
slotContainer.Add(new PropertyField(slot.FindPropertyRelative("Item")));
slotContainer.Add(new PropertyField(slot.FindPropertyRelative("Amount")));
container.Add(slotContainer);
}
return container;
}
}
Could it be that NaughtyAttributes package somehow forces the IMGUI mode?
I see it in the stacktrace when trying the OnGUI version
Also, one thing I'd like a confirmation for: custom properties are basically a nice way to display data that unity can serialize anyway, right? It's not like I can access the object instance and draw fields for whatever of it's members that I want, even those that can't be serialized?
Basically, if I want to create a property drawer for an inventory containing array of slots that contain abstract-generic type item instances, I'm fecked?
[Serializable]
public abstract class ItemInstanceBase
{
[SerializeField]
private Item definition;
public Item Definition { get => definition; protected set => definition = value; }
public ItemSlot Slot { get; internal set; }
public ItemInstanceBase(Item definition)
{
Definition = definition;
}
//public abstract bool CompareDefinition(ItemInstanceBase otherItem);
//public abstract bool CompareDefinition(Item otherItem);
}
public class ItemInstance<TItemDef> : ItemInstanceBase where TItemDef : Item
{
new public TItemDef Definition => (TItemDef)base.Definition;
//public event Action ItemDataChanged;
public ItemInstance(TItemDef definition) : base(definition)
{
//base.Definition = definition;
}
}
//There are different generic type instantiations, like
ItemInstance<ConsumableItem>
I just want to see a list of item definitions, that are SOs, so no problem to serialize them, but I can't seem to get to them via serialized properties.🥲
Is a custom editor window with some reflection my only option?
Normally this is cause there is some custom editor that is for ScriptableObject or MonoBehaviour. Things like Odin that use attributes to make custom editors tend to do this.
Yeah, it appears to be NaughtyAttributes. It seems to implement a custom editor for unity Object.
Not sure I follow
in the code above there's the private Item definition; field. I just want to draw a list of those in the inspector. The problem is that it's a class field of a non serializable abstract ItemInstanceBase and/or generic classes that extend it.
So... why would you want to draw it if it isn't serialized?
For debugging purposes mainly
Ahh
You have two options. You could serialize them ([SerializeReference]) or you could get the value of the parent class that is serialized using boxedValue (PLEASE read the docs page on it though!!)
How would I access the SerializeReferenced field? With just FindPropertyRelative?
It would be same as how you access with SerializeField
Aight. I'll give it a try. Thanks for the insights!
Sure thing!
Hi there 👋
I have a custom editor that is on a Prefab. Is there a way to detect when Prefab is instantiated / drag'n'drop into the Scene (not in runtime) ?
I tried to use OnEnable on my customeditor but I need to select the GO containing my customeditor to trigger OnEnable
I'd like to catch an event as soon as my custom editor is added to the scene
You can on the component itself if you add the [ExecuteAlways] attribute and use the Awake method. Not really a way from within a Editor class. A clunkier option is to use the ObjectChangeEvents class which has a way of getting events when 'stuff' happens. You would have to check for a component on the object or something to see if it is the prefab you want.
Hey 👋
Indeed, ExecuteAlways may be the way but it involves some refacto since a lot of my code was not planned to run in edit mode... But I finally can detect my GO, thanks
It's the reason I never use that package. People recommend it all the time, but it makes the inspector unusable 🤷
thats why i aim to move my package to UI toolkit
Yeah, I have my own UITK package that I use
do you by any chance have dynamic labels in yours?
What do you mean? Like [Label]?
like for example, i have an attribute that add a title to the inspector, you can either set a constant string to that title or a dynamic one that uses reflection to grab the string value of something and set the title text to that
with ImGUI the inspector always updates based on GUI events, but with UI toolkit the inspector only updates when needed, i need it to basically always refresh and cant figure out how to do that
I don't really know what the purpose of such a label would be lol
its cool to have, you can have it display the date and time
or maby a debug value
you can basically have it update dynamically based on whatever you want
here is the docs page to it: https://editorattributesdocs.readthedocs.io/en/latest/Attributes/DecorativeAttributes/title.html
What would you say the advantage of ui toolkit in the context of editor extensions like property drawers? From what I've seen so far it's functionally the same as OnGUI.
you dont have to deal with manually calculating rects
You aren't living in the dark age
you can also use the UI builder window to not have to code the layouts
You can easily draw an entire inspector for an object without doing some disgusting stuff
You can easily draw vector shapes
In a few Unity versions your extensions will still work
you mean mine?
Using IMGUI means that your work is on a timer and will be incompatible in the future
No comment on when that will happen, but it will
Hmm... But it's all about presentation, right? It's not like it changes the way you access the data, right?
IMGUI repaints constantly, UITK repaints when things change
so yes, it's got different data access
More:
- Amazing debugging tools
is there a way to make UI toolkit repaint constantly?
🤷 schedule an event and mark your element as dirty
Wait, how? From what I've seen so far, you use the serialized property to bind the object to the ui. What's the other way that ui toolkit adds?
You bind it, and then it checks for changes and does not update the UI unless there are any
so if the data isn't changing, the cost of the UI is 0
Okay, but that doesn't change how you access the data. Or rather, you're still limited to the serialized data. Unless you use reflection.
the SerializedProperty and Object stuff remain the same
Well, UITK can be used to draw non-serialized properties easily
How?
It requires the properties package which for some reason isn't yet integrated, but you can find it in the entities package and in my ECS project I use it to draw some non-serialized data without actually iterating it myself
it's a similar setup to the 2023 runtime data binding
Interesting. I'll have a look. Thanks.
I think the entities team must have taken the properties stuff and ran with it while the UITK team focused on runtime binding and we have a bit of an SRP situation where these things may get merged back together in a unified way in a few years time ):
https://docs.unity3d.com/Packages/com.unity.properties.ui@2.1/manual/index.html
It's been torn apart and used as the core of how the Inspector for Entities works
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var root = new VisualElement();
var label = new Label(GetNewName(property));
var propertyField = DrawProperty(property, label);
root.Add(propertyField);
propertyField.RegisterCallback((ChangeEvent<string> changeEvent) => Debug.Log("sadsadsd"));
return root;
}
ok i rly dont understand this, the RegisterCallback should run every time the property field is changed, right? why doesnt it do that, im modifying the value in the propertyField and nothing
Use the RegisterValueChangeCallback or RegisterCallback<SerializedPropertyChangeEvent>
ok that works, but for some reason if i try to change the label text it doesnt
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var root = new VisualElement();
var label = new Label(GetNewName(property));
var propertyField = DrawProperty(property, label);
propertyField.RegisterCallback<SerializedPropertyChangeEvent>((changeEvent) =>
{
label.text = GetNewName(property);
Debug.Log("sadsadas");
});
root.Add(propertyField);
return root;
}
isnt there an event that always updates?
Is there any way to hook into the "Save" or "Save project" command specifically (and not run callback on creation of new assets etc)
I'm making a snapping script to snap the centroid of some game objects to our grid. For some reason, the transform.position of the selected gameobject is not outputting what the transform.position reads in the inspector
for (int i = 0; i < Selection.gameObjects.Length; i++)
{
Undo.RecordObject(Selection.gameObjects[i].transform, "Snap Objects");
Debug.Log(Selection.gameObjects[i].transform.position);
centroid += Selection.gameObjects[i].transform.position;
oldParents[i] = Selection.gameObjects[i].transform.parent;
Selection.gameObjects[i].transform.SetParent(falseSnapper.transform, true);
}
the Debug.Log line there outputs this:
but the selected object is this:
and it doesn't have a parent :(
I doubt it's wrong, you must be looking at the wrong object
i started getting a bunch of errors in unity and i restarted it and i was fine
is this a bug? when I maximize a view in the editor, left click stops working. 2022.3.20f1
and it's LTS...
hopefully there's a hacky fix?
seems as if the maximized window never has focus. even when I select all , they won't turn blue
2024-03-12T15:06:25.5532] @firebase/database: FIREBASE WARNING: Provided authentication credentials for the app named "[DEFAULT]" are invalid. This usually indicates your app was n initialized correctly. Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURI." and is from the correct project. How do i fix this?
Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURI."
I've found a serializable dictionary but it kinda carries a problem
it doesn't seem to update it's values in real time
i'm using it to update radius on a gizmo
but it only update when I click play or I save a new code
and I would like it to update everytime the value changes
do you guys have any idea what could be the problem?
Yeah, most Serializable Dictionaries have issues like that, normally due to a poor understanding of the underlying serialization system. That is why I wrote my own. You can rip it out fairly easily if you don't wanna include the whole package https://github.com/MechWarrior99/Bewildered-Core
ohhh, thanks, gonna see if I can learn how it works
Is there a fix for this? It should appear below the EnumField.
hi. How I can play an animation in the insepctor. I set in the onclick listener an object and access to its animator but I don't see any play function. I don't know if this is the channel but I need extremely rapid help.
If the play function does not show it might not have supported parameters. You can create another script and attach it, then reference the animator in it and call your own function instead.
public class AnimatorPlayer : MonoBehaviour {
public Animator Animator;
public void Play() {
Animator.Play(); // Whatever play method you want to run.
}
}
Now you can attach the script, drag the object in the onClick listener, then call your Play method.
@warm ember
WORKED!!! thanks
Hey, I've got an issue I haven't encountered before. When trying to load an icon using Resources.Load from a directory where an Editor Window class is (knowingly, and for that Editor Window), the icon is found but returns as a single pixel.
I've made sure the format is PNG /RGBA8, and that the type of import is for an Editor GUI / Legacy UI. It's set to no compression and no filtering mode. This is a 1024x1024 image being loaded as a Texture2D
using the exact same path for a GUILayout.Label call, however, shows the icon just fine.
okay nevermind, it's just a very long string name that's the issue
All right. Thanks
I am making a small editor script, is there a way to detect which canvas was created last ??
No information of creation time is stored
How do you pin a tab on the editor? Unity Version Control tab always disappears at relaunch
Wrong channel, this is about creating your extensions not about using the editor
How to link IMGUIContainer to EditorWindow method?
<ui:IMGUIContainer onGUIHandler="IMGUIContainerTest" />
And here is my method
void IMGUIContainerTest()
{
EditorGUILayout.TextField("Test");
}
something like this:
public override VisualElement CreateInspectorGUI()
{
var root = new VisualElement();
var imGUIContainer = new IMGUIContainer(YourFunction);
root.Add(imGUIContainer);
return root;
}
So its possible only via C#
yeah
I started using UIElements to help extend functionality better and, honestly, it's going a lot more nicely with a mixed UIE/IMGUI approach than it would've with IMGUI alone in some cases. I've had to do some extra handling but the C# UI Elements toolkit is helpful
how do I add lines to this sub menu as I have in the first menu? I tried setting the "second prioirty" of the menu item to really small/large numbers but it doesn't seem to do anything.
the issue is if I set one of those sub menu items to a low priority, it changes the location of "Path Data" on the main menu dropdown.
How to get a specific property value from ui element?
Can't you just use the serializedproperty/object that you bound to?
It is not bound to any object. I have radiobuttons with respected type. So the type is a property of a radiobutton node. Then I want to read and parse this value to enum.
The value of radiobutton is a boolean
Yeah?
It's a toggle?
https://docs.unity3d.com/ScriptReference/UIElements.RadioButtonGroup.html is this what you're using?
GroupBox and Radiobuttons inside of it
I've found View Data Key.
I've been working with jquery for a half of a year. It was so easy to acess user defind properties. Like <button custom-prop="someValue"/>. and then acess it using one of jquery method.
I think the solution is to use RadioButtonGroup instead
I don't think GroupBox is how you should be doing this
With RadioButtonGroup you get the index of the active element
You don't understand the question
I have the following UXML code
<VisualElement custom-property="value"/>
Then in C# code i want to access the custom-property attribute to get a value from
Things i can access are style, text, value. But i cannot access the custom-property
That isn't supported as far as I know.
I see a way to handle this.
Create an extension method that
- Receives an UI Elelement and attribute name as a string
- Fetches the XML markup of it
- Parses it and finds needed atribute
You could I guess... but that is going to be slow and really not how UITK is meant to be used. Additionally, you couldn't use the UIBuilder with it. The intended workflow would be create a custom VisualElement that has the needed fields.
Ok, thanks
Editor.CreateCachedEditor(property.objectReferenceValue,
null, ref editor);
IMGUIContainer imguiContainer = new IMGUIContainer(() =>
{
EditorGUI.indentLevel++;
EditorGUILayout.BeginVertical(GUI.skin.box);
if (editor.serializedObject != null)
{
editor.OnInspectorGUI();
}
EditorGUILayout.EndVertical();
EditorGUI.indentLevel--;
});
I'm using this code to expose values of a variable that isn't attached to a script, but when I destroy the attached GameObject I get SerializedObject target has been destroyed. error. Anyone know how to fix this?
You can use a InspectorElement to do the same thing without having to mess with creating and drawing the inspector yourself.
Man... I'm really fighting the urge to make a OdinInspector/NaughtyAttributes 'replacement' using UIToolkit that actually follows the editor styling guidelines and look. And have some sort of 'bake' ability so you could ship editors you make with it.
But also, I have other projects I can work on and do we really need another "Make custom editors using attributes" package...? 🤔
I have tried that before and it only gave me the main object the variable is attached too
What do you mean?
Hold on this is gonna take a bit of explaining 😅
var inspector = new InspectorElement(property.objectReferenceValue);
This works...? Important to not do property.serializedObject.target my mistake.
So I have something like this
OH damn message to long 😅
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
ExpandableAttribute att = attribute as ExpandableAttribute;
VisualElement container = new VisualElement();
PropertyField field = new PropertyField(property);
field.SetEnabled(att.Editable);
field.RegisterValueChangeCallback(
evt =>
{
if (att.Should_Expand)
{
Foldout foldout = root.Query<Foldout>("PropertyFoldout");
foldout.style.display = evt.changedProperty.objectReferenceValue != null ?
DisplayStyle.Flex : DisplayStyle.None;
foldout.SetValueWithoutNotify(evt.changedProperty.isExpanded);
}
});
container.Add(field);
Foldout child_foldout = new Foldout();
child_foldout.name = "PropertyFoldout";
child_foldout.text = "Property Data";
child_foldout.style.display = property.objectReferenceValue != null ?
DisplayStyle.Flex : DisplayStyle.None;
📃 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.
Yeah this is going to break for sures if you ever have to draw two at once
InspectorElement should do exactly what you want
The left is the correct way with the code I shwoed you
The right is the wrong output with what you told me to use
For some reason it is giving me the base class even though that isn't what I asked for.
Just for testing, try setting the height of the InspectorElement to something like 250
How do I do that I'm not seeing a SetHeight like with other visual elements
Infact doesn't this just add the element without exposing the visual element variable that is created?
I mean set the style.height of it
Yeah I know but I can't do that since I don't have access the visualelement that was created with InspectorElement.FillDefaultInspector
It returns a void
Ok that works
What I did try was before doing the change you just suggested I created an empty visualelement and did the last thing you suggested and I still got the wrong output but with just a style height change
So there must thing with InspectorElement.FillDefaultInspector only drawing the main serializedobject instead of the variable that should be exposed.
Also I didn't know you could call new on InspectorElement. I alwasy thought you had to call the static function FillInspector. But now I know 😅
FillDefaultInspector actually just loops through the properties and adds a PropertyField for it. It doesn't draw any custom editor. Basically it draws it how a default inspector is drawn
Funny thing is the way I was doing it before was perfectly fine. There was an underlying issue where I was removing something from a list while destroying the serialized object at the same time. And Unity was looking for an object that was destroyed.
Because I was still getting an error with the code you suggested. Had to use an Editor Coroutine to give the editor time to delete the objects before updating the inspector.
var addComponent = gameObject.AddComponent(type);
var serializedObject = new SerializedObject(addComponent);
var serializedProperty = serializedObject.FindProperty("m_Script");
I need to get fileID and guid from m_Script: {fileID: 11500000, guid: bd3bdbcd6702bc0bdabd531c0e4243d9, type: 3} How to do that?
Thanks it works
Is it possible to get guid from type? not from addcomponent?
Find the asset instead
So I'm using grid snapping and rotation increment snapping to build levels in Unity but it seems that it snaps to unrounded values a lot of the time. For example instead of snapping exactly to 1, it moves the asset to 1.002 or the rotation to -.06. This can make my assets not connect properly. How would I go about making this a perfectly rounded value?
In this case, when you use your grid increment tool, are you worried about some potential z-fighting in that area of imprecision?
Hi!
I've been trying to make a node editor, and found a quirky thing. There's this attribute from NaughtyAttributes, AllowNesting that makes my parameters look nice.
with allow nesting attribute
Without AllowNesting
So i looked into what the attribute actually does, and it's only this
[CustomPropertyDrawer(typeof(AllowNestingAttribute))]
public class AllowNestingPropertyDrawer : PropertyDrawerBase
{
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(rect, label, property);
EditorGUI.PropertyField(rect, property, label, true);
EditorGUI.EndProperty();
}
}
So since I need it for all the fields on all the nodes, and I already have a custom editor for the node, I was thinking of hardcoding those lines. However i'm not sure how to translate it for UI Toolkit
Basically, this is the method I call to generate each field
VisualElement CreateVisualElement(SerializedObject bj, FieldInfo field){
if(field.GetCustomAttribute<HideInInspector>() != null || field.GetCustomAttribute<InputAttribute>() != null)
return null;
PropertyField propertyField = new PropertyField(){
label = field.Name,
bindingPath = field.Name
};
propertyField.Bind(bj);
return propertyField;
}
and works with the attribute and without, that visual element gets added to the nodeview. So i need to add those kinda lines there, but im not sure how or what I could use?
I checked, and the PropertDrawerBase doesn't do anything else. So basically, those three lines make it so all attributes work as expected. What I want to do is, when Im creating those properties by code, have a way to also add those three lines so that they are taken into account by default
If it was normal editor code it would be trivial, but im not sure how to translate it with UI Toolkit
I have a BaseEditor that has an EnumPopup edit mode selection.
I also have ChildEditorA and ChildEditorB. How to render a specific editor based on selected mode value?
I'm not 100% sure either, tbh. It seems that UIE Property field uses EditorGUILayout in the background inside of a imgui container. Potentially you can replace that imgui container with your own, copying code from Property field where necessary?
It's a bit scuffed but can't really think of other solutions rn 
Mmmm, do you know where I can find the source code for it? the decompiled version of property field is around 1000 lines
I just looked on GitHub, search for EditorGUILayout in the file and you should find it relatively quick
But isn't that the normal PropertyField? not the UIElements one
Ui elements Property field yes
Is using an imgui container and editorgui.propertyfield in the background afaik
Uff, I see now the code
Maybe you can query the imgui container and simply rebind it's onguihandler
I didn't understand half of that, im too new with UI Builder, how do I rebind a onguihandler?
How to get window from custom inspector. I want to open Tile Palette window from custom inspector
Imgui container works similar to a regular IMGUI method. To know what to draw every frame, you pass in a function that handles the imgui drawing
So the Imgui container instance should have a property called OnGUIHandler
Which just points to a function to draw IMGUI controls
And just to avoid any confusion, an IMGUI container is just another visual element.
The same way as normal EditorWindow.GetWindow
I mean this
just have those in different functions and call them OnInspectorGUI depending on which value is in the enum
It creates a mess in a code
But I will go with this. Thanks
Editor.CreateCached > call OnInspectorGUI on the child
Some editors could have not only the OnInspectorGUI method.
What does that mean
OnSceneGUI for example or OnEnable
Then call those as well?
Thanks
Is it possible to store data in the PropertyDrawer?
I have a Resource Database Scriptable Object, and, on the instances where i need to select a Resource, i want to Select the Resource Database, and then select a Resource from it...
I have a ObjectField to select the Resource Database, and then a Dropdown to select the Resource, but the value of the Resource Database isn't stored once i exit the window and go back....
and Adding the ResourceDatabase to the Resource seems quite redundant... Specially since i made the Resources to be very small (byte wise) and efficient
No, it's just that my modular pieces don't connect perfectly. So if I have two walls side by side, there will be a gap between them sometimes so I have to manually go in and round out the values.
On another note...
Can i not set a value of a property with RegisterValueChangedCallback?
var selector = CreateResourceSelector(ToDropdownChoice(SelectedResource));
selector.RegisterValueChangedCallback(evt =>
{
var resource = Database[FromDropdownChoice(evt.newValue)];
property.boxedValue = resource.ID;
});
selector is just a DropdownField with all the Resources on a Database...
Debugging i can see that the resource is getting set, but when i refresh the Inspector it resets to default
property being the SerializedProperty coming from CreatePropertyGUI(
can't seem to find anything about it on the docs/forum
My hunch is this is a precision problem. Could be wrong tho :/
||is there a lore reason|| why my Move function isn't listed in the Event Trigger component?
note, i have the gameobject selected and not the script
@visual stag ah... that makes sense... thanks for the response. my paremeter is not supported by Event Trigger... the reason im trying to even do this is to get my controller working for mobile. I'm using the built in On-ScreenButton script to simulate keyboard input and it works perfect in the editor, but in the build its very unresponsive and just doesnet function properly. been trying to find workarounds
Is there a way to rotate icons drawn with Gizmos.DrawIcon()? I can get the icon to follow the objects position but not its rotation.
Tried that but only the position changes
I'm starting to think its a bug or DrawIcon just isn't allowed to be rotated
Ahh, is the icon drawn in screenspace or world space, I can't remember.
I'm honestly thinking screen space
All other Gizmos will rotate when changing Gizmos.Matrix
hey guys. can smb help me out? visual studio doesnt recognize unity code for some reason. although i have unity extension installed for the ide. and as always, theres no info on how to config it.can smb help me out? thx
Try Edit-> Open C# Project
try retarting your pc
try restarting unity and vs
check your ide preference in Preferences -> External tools or something like that
Can I check if Unity can serialize a type? I wrote some code to look for references I forgot to assign, but I noticed that it’s incorrectly flagging fields that hold types Unity cannot serialize.
It doesn’t look like I can just check if the type has the System.Serializable attribute
Oh! I was looking at FieldAttributes instead of TypeAttributes
Let’s have a look at that..
I don't know if there's a good answer, but there is a class in the source called UnitySerializationLogic that has the entire logic (WillUnitySerialize) in a very readable flow
There's even a fun lil dictionary called TypesThatShouldHaveHadSerializableAttribute (unrelated)
ah yeah, Type.IsSerializable alone is not helpful. It says most of this stuff isn’t serializable
I’ll have a look at that.
sneaking in to Unity HQ to make it just return true every time
bit of a weird question but i'm editing a scriptableobject via code in an editor tool and using AssetDatabase.FindAssets at the start of the function i have for some data i need to reference but theres this weird inconsistent issue where it seems like if the request is too much/too long the changes i do to the so after the findassets code just don't apply?
the code still runs, i get debug logs and all that, no errors either
its like it hits this mystery request threshold and just refuses to actually do what im telling it to do
Are you correctly dirtying the scriptable object?
bet ok ill do that. was going to post code/more context but figured it would be something where someone is like "oh it's probably x thing" haha
out of curiosity, what is this inconsistent behavior im getting?
I have absolutely no idea what you're seeing, the description is too unclear, but if you don't dirty an object then changes won't persist
I see that I’m not allowed to just copy paste the CS reference, so I will simply be inspired by the code instead 😉
I am not copy pasting, I am simply applying the keystrokes ctrl-c and ctrl-v in an order that duplicates
I also might just mark these unused fields with NonSerialized
to make sure Unity isn’t trying anything funny
I had to do a ugly workaround for this, tho it will fail if SerializedReferences are used
var attr = obj.GetAttributes();
// then do check if contains serializeField
attr.AttributeClass.Name == "SerializeField")
//Unity supports a very small amount of types to be serialized so this is ok-ish approach ig.
var types = new List<string> { "dec" , "string", "int" };
bool valid = !types.Contains(obj.Type.Name));
I already check for SerializeField, yeah
This is only a problem in a few places where I use a public field
But my public fields are usually non-serialized anyway
Heya!
In 2021 this code works flawlessly. The button is focused then clicked.
But in 2022 the button is only focused and no click even goes through.
Anyone else had this issue? Or how am I supposed to send click events to UI-toolkit? I've tried different keys, capturing and sending mouse events, and this follows the documentation provided.
public static void Click(this Button btn)
{
var clickEvent = new Event()
{
keyCode = KeyCode.KeypadEnter,
type = EventType.KeyDown,
};
btn.Focus();
using KeyDownEvent keyDownEvent = KeyDownEvent.GetPooled(clickEvent);
btn.SendEvent(keyDownEvent);
}
I'm trying to make a property drawer for an array based on a generic enum argument. The idea is that it displays specific enum values for specific indices of an array (where specific position is tied to an enum). This works fine until I have a class with a generic TEnum argument. Any workarounds?
I basically need to know the Enum type in my generic class, EnumerableArray<TEnum, TStored> so that my TStored[] internalArray can use this property drawer
how do I update materials/shaders properly, so that my renderers don't use fallback shader?
So I added the option of having groups into my node editor
Is there any wayt to make them collapsable?
Im using UI Toolkit and GraphView
The group or the nodes? @elder wasp
How to remove last undo operation from Undo stack?
quick quesiton, does the assemblyreloadevent still be triggered even when we turned off the domain reload from project settings?
If your script change is seen then it should yeah.
Would test though
Actually both, I'm not sure why my nodes are not collapsible either, even when calling RefreshExpandedState
@elder wasp what does your code look like?
public NodeView(InfiniteLandsNode node){
this.node = node;
CustomNodeAttribute attribute = GetAttribute(node.GetType());
AddToClassList(attribute.type);
this.title = attribute.name;
this.viewDataKey = node.guid;
style.left = node.position.x;
style.top = node.position.y;
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/sapra.InfiniteLands.Visual/UIBuilder/NodeView.uss"));
SetPosition(new Rect(node.position, Vector3.zero));
CreateOutputs();
CreateInputs();
DrawParameters();
RefreshPorts();
RefreshExpandedState();
}
this is the constructor of NodeView (that inherits from Node)
and here the responsible to generate the parameters
protected void DrawParameters(){
VisualElement element = new VisualElement();
FieldInfo[] fields = node.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
SerializedObject bj = new SerializedObject(node);
foreach(FieldInfo field in fields){
VisualElement fieldElement = CreateVisualElement(bj,field);
if(fieldElement != null)
element.Add(fieldElement);
}
if(element != null)
extensionContainer.Add(element);
}
It's intersting, I can collapse the nodes if one of the inputs/outputs is empty, but as soon as they are all connected I can't
Similar to this issue https://forum.unity.com/threads/graphview-node-not-being-collapsible-when-ports-are-filled.1428303/
With the workaround
public NodeView(InfiniteLandsNode node){
.... stuff fro before
SetPosition(new Rect(node.position, Vector3.zero));
CreateOutputs();
CreateInputs();
//WORKAROUND for uncollapsable nodes
Port hiddenPort = InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(int));
hiddenPort.style.display = DisplayStyle.None;
if(inputContainer.childCount > 0)
inputContainer.Add(hiddenPort);
else
outputContainer.Add(hiddenPort);
//End of workaround
DrawParameters();
RefreshPorts();
RefreshExpandedState();
}
@elder wasp are you setting Node.expanded anywhere in your code too?
Nop
Have you tried setting that and then refreshing expanded state?
Im actually trying that, and Im getting weird behaviour
Where ToggleCollapse makes it look nice, but changing expanded state makes it look weird, incoming pictures
usual collapsed
changing expanded to false
Opening and closing fixes it
This is using the workaround, without it I cant open neither close
Withut the workaround, and expanded set to false
Right
That's so bueno
My guess is that internally the node doesn't collapse of it detects all its ports are connected
that's a weird funcionalioty
It makes sense, cuz ports that are connected should not be collapsed, no?
So if all ports are connected, don't bother collapsing anything.
the thing is that collapse shouldn't collapse ports, only the expandedContainer
I mean, setting the ToggleCollapse it shows as expected, ports are shown, but the expanded container is hidden
like here
Doesn't collapse also hide non-connected ports like in Shader Graph?
I can't remember, been a long time since i used shader graph
But then more reason even, if the port are connected, it should be shown
Me neither haha, I just remember seeing something like that
but here once all ports are connected i can't collapse anything
For reference, this is the expanded state
Ok so the issue is that if all ports are connected, expandedContainer is no longer collapsed properly?
So if all ports are connected, I can't manually click on the collapse button
It's greyed out
Ah
Expected look
Oki, sorry I misunderstood the problem
Actual look
its okay hahaha
Ok so I think I found it still, I believe the issue is what I described earlier accidentally lmao
One second, trying to copy the code on phone :pain:
private void OnPortConnectAction(Port port)
{
bool canCollapse = false;
var updatedInputs = inputContainer.Query<Port>().ToList();
var updatedOutputs = outputContainer.Query<Port>().ToList();
foreach (Port input in updatedInputs)
{
if (!input.connected)
{
canCollapse = true;
break;
}
}
if (!canCollapse)
{
foreach (Port output in updatedOutputs)
{
if (!output.connected)
{
canCollapse = true;
break;
}
}
}
if (m_CollapseButton != null)
{
if (canCollapse)
m_CollapseButton.pseudoStates &= ~PseudoStates.Disabled;
else
m_CollapseButton.pseudoStates |= PseudoStates.Disabled;
}
}
This sits in the Node class
this is weirder
As you can see, whenever a port is connected it will:
-
Loop through all input ports, of any of them have no connection, "canCollapse = true"
-
If all inputs are connected, check all outputs to see if any of them have no connections.
-
If all ports are connected, disable collapse button
Idk why this would be a thing tho
Why does this exiiiist, doesn't make any sense! :((
I really hope a Unity Dev explains why this is necessary
Maybe on the node you can get the collapse button by querying node.Q(name: "collapse-button");
The above method is bound to port.onconnect
Which happens on RefreshPorts
So maybe create a custom method that wraps RefreshPorts and then subscribes another action to the port.onconnect callback that hard-code insets the disabled state
In simpler terms?
On my phone rn, can I get back to you first thing in the morning with some (pseudo) code?
Hey does anyone know of an editor extension that lets you organise prefabs that you can use to build your scenes?
I have a lot of stuff in my game at the moment, but it's a pain in the ass to find anything spesific
Kinda just want a dropdown or something that lets me only search materials/prefabs/etc
Kinda also don't want to bother coding it myself XD
It depends on what you want exactly. The Unity Search window has a way to save a search, so you can quickly search for the same assets again. Could be a way to for example find all prefabs at the path x with y in their name.
There is a paid asset called SmartLibrary that lets you create collections of assets either by dragging and dropping them in to a collection, or using rules to find them, kind of like the Save Search feature in Unity Search.
https://assetstore.unity.com/packages/tools/utilities/smart-library-asset-manager-200724
(Full disclosure, I made the asset.)
There are not really any free options that do this sort of thing.
If you want a menu that replaces Unity's Object Selection window (the one that opens when you click the circle next to a object field), there is no option as far as I know.
Here is the docs for search window and saving a search https://docs.unity3d.com/Manual/search-usage.html
Thanks a lot. The asset looks like a major time-saver. To be honest, I'm wondering if a full level editor pack might help. I'll have to think. But I've saved the assert for later
Thanks for your help, and the search window link
Sure thing! 🙂
Is this the only entry point we have into customizing the hiearchy window?
https://docs.unity3d.com/ScriptReference/EditorApplication-hierarchyWindowItemOnGUI.html
Or are there others?
yeah
Boooo
What are you wanting to do?
Ideally add a custom "scene" that isn't a real scene
Ahh
my ideas right now are:
- Actually do load an extra scene and do some shenanigans to make it work
- Use a separate floating editor window at the bottom of the hierarchy window, sort of like the Preview window in the inspector
hmmm... I remember there being a HierarchyProperty struct, you might be able to use that with the hierarchy window to do something... maybe not though
any documentation on that you can find would be appreciated
Reflection, but I will take a quick look
Well, if you are going to go that far you might as well just use UIToolkit and add a element to the hierarchy window
Well I would if I could. Is that possible? Can i get a reference to the main VisualElement in the Hierarchy window somehow?
If I can do that I feel I can do what I want
'Just' get the editor window for the hierarchy and then you can access the rootVisualElement and the .panel and stuff
oooh... is it that easy? 🤔
What would be my entrypoint though?
I'd need to do it whenever the hierarchy window loads right?
Resources.FindAllOfType(hierarchyType)
Yeah, that is the only icky part, the only way I know to do it is to check each frame if the number of windows has changed
There is no "Window Opened" type of event sadly 😦
oof
Ahh, might be able to just hook in to the TreeView of the hierarchy window https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/SceneHierarchy.cs#L230
This is what Unity Entities uses to draw subscenes in the hierarchy.
https://github.com/Unity-Technologies/UnityCsReference/blob/6a26bc151b158aa1bba01019d97d932710fd8d6e/Editor/Mono/SceneHierarchyHooks.cs
But it's not entirely fake it seems. There's some underlying scene.
Ahhhvery interesting, thank you
Thank you this helps! I'm hoping to avoid reflection if possible but good to know this is here
Avoid reflection, hahahahahaha
Good luck 😛
Not exactly related, but found this which is interesting https://forum.unity.com/threads/what-is-unity-hierarchy-for.1478325/#post-9374987
@elder wasp could you check if any of the following code overrides the disabled state
Alright, will check it
Just checked and nope
Would've been kinda surprised if it did but would have been the easiest solution, I'll try and think of other work arounds
No problem, and thanks!
Now I have another problem. Im trying to make a dropdown field to select other scriptable objects. But I need two things
1- The label text updates in relation to the selected scriptableObject name
2- When clicking on the dropdown field, it shows an updated list of the available scriptables objects
I created the dropdown field, and managed to get the list of scriptable objects, plus being able to assign it, so i have a variable always holding a reference
Now the problem is how can I bind it properly? I tried with the RegisterValueChangeCallback, to change the value and assign the new reference, the problem is that when I try to rebind i get stack overflow
DropdownField dropdown = new DropdownField();
dropdown.RegisterValueChangedCallback((ChangeEvent<string> ev) => ReselectOutput(dropdown, ev));
and then
void ReselectOutput(DropdownField dropdown, ChangeEvent<string> changeEvent){
LocalInputNode nd = node as LocalInputNode;
string parentAsset = AssetDatabase.GetAssetPath(this.node);
object[] asset = AssetDatabase.LoadAllAssetsAtPath(parentAsset);
foreach(object st in asset){
if(st is LocalOutputNode newNode){
if(newNode.OutputName.Equals(changeEvent.newValue)){
nd.output = newNode;
dropdown.bindingPath = nameof(newNode.OutputName);
SerializedObject bj = new SerializedObject(newNode);
dropdown.Bind(bj);
}
}
}
}
but this breaks
Where does it throw the overflow exactly?
i cant check because the UI breaks completly. Im guessin that after rebinding, it calls the register value changed callback and starts breaking
Ok so why is the serializedobject getting bound to a dropdown?
So that if there are any changes on the object, the label changes live too
Right, so if the SO gets renamed it also updates on the graph automatically?
yup
Its not the SO name perse, but a variable called OutputName, but it has the same purpose
So the SO has a variable on it that can change, and is displayed in a dropdown?
yup
Is that variable gonna change while the dropdown is visible?
Nope
Then maybe just rebuild the dropdown values in something akin to a OnEnable?
ah no sorry, yes, the value will change when the dropdown is visible. I thought you meant the dropdown select window
Cuz what really needs to happen is for the dropdown content ( a list of strings) to be updated when your variable changes
Basically you can see this. If I modify dsd text field, i want to get the dropdown to update too
Ok so the variable name can be found on the graph also?
Yup, I got that handled, and I got a method to find those variables in the node
So when you update the text in the local output, you want the dropdown on local input to update?
exactly
Aight, so what if your local output OnChangeEvent is broadcasted for local input nodes to listen to, which triggers the dropdown to refresh?
But also, the dropdown field should show all the updated texts of all local outputs, meaning that switching to another should change the label to that one and update when the new one changes
Also what's the reason you can't just use an object reference to that output node?
Instead of using strings
my idea was to find a way with binding, because I managed to get this working
I wanted to have it all controlled on the node editor itself. Having a reference and manualy putting it can be hard to do with the inspector because you might end up with maaaany nodes.
Label field = new Label{
text = nd.output != null ? nd.output.OutputName : "None",
};
if(nd.output != null){
field.bindingPath = nameof(nd.output.OutputName);
SerializedObject bj = new SerializedObject(nd.output);
field.Bind(bj);
}
so i wanted to change that to a dropdown field
Yeah but the issue is that the dropdown value changing doesn't trigger a dropdown content rebuils
I see
For the rebuild I was hoping to register into an onclick event of some sorts, to reupdate the list
and then on select/change value rebind the text
I guess you could register a OnMouseDown callback on the dropdown that also just rebuilds the dropdown contents
Okay found a simpler solution with a button and a generic menu
So im doing this
Button btn = new Button(){
text = nd.output != null ? nd.output.OutputName : "None",
};
btn.clicked += () => CreateMenu(btn);
btn.style.minWidth = 80;
var label = output.contentContainer.Q<Label>("type");
output.contentContainer.Remove(label);
output.contentContainer.Add(btn);
and then
void CreateMenu(Button btn){
GenericMenu menu = new GenericMenu();
string parentAsset = AssetDatabase.GetAssetPath(this.node);
object[] asset = AssetDatabase.LoadAllAssetsAtPath(parentAsset);
LocalInputNode nd = node as LocalInputNode;
foreach(object st in asset){
if(st is LocalOutputNode newNode){
menu.AddItem(new GUIContent(newNode.OutputName), newNode.Equals(nd.output), () => {
nd.output = newNode;
btn.bindingPath = nameof(newNode.OutputName);
SerializedObject bj = new SerializedObject(newNode);
btn.Bind(bj);
});
}
}
menu.ShowAsContext();
}
my issue now is that removing label from the port makes it impossible to click on the port
Alright, this fixes it
btn.clicked += () => CreateMenu(btn);
btn.style.minWidth = 80;
btn.style.marginTop = 0;
btn.style.marginBottom = 0;
var label = output.contentContainer.Q<Label>("type");
label.style.color = new StyleColor(new Color(0,0,0,0));
label.style.marginLeft = 0;
label.style.marginRight = 0;
label.Add(btn);
xD
is there any trick to bind a min value to floatA while max value to floatB with a minmax slider in uitoolkit?
Nope, it aint supported. Might be in Unity 6 with the new Binding system, not sure how it plays with the SerializedProperty binding.
For before then. You can look at the source/visual tree to see if there are elements that you can bind to. Otherwise you would need to either use the schedualer or TrackProperty to check if the properties have changed and update the slider.
guess I have to resort to registervaluechanged, yeah no undo/redo for me 😅
What I normally do is this:
minMaxSlider.RegisterValueChangeCallack(evt => {
minProperty.floatValue = evt.newValue.x;
maxProperty.floatValue = evt.newValue.y;
minProperty.serializedObject.ApplyModifiedProperties();
};
minMaxSlider.schedular.Execute(() => {
if (minProperty.floatValue != minMaxSlider.minValue)
minMaxSlider.minValue = minProperty.floatValue;
if (maxProperty.floatValue != maMaxSlider.minValue)
minMaxSlider.maxValue = maxProperty.floatValue;
}).Every(100);
Or something like that. Could also store the contentHash of the min and max SerializedProperty and check if it has changed. Probably more reliable then checking if the float values are different.
now we're talking! Will do just that, thanks, Mech!
Sure thing!
I'm losing my mind trying to set a SecondaryTexture via an asset importerer for a sprite. When a normal map is imported in a specific folder, the AssetImporter "OnPostProcessTexture" method finds the original texture importer (for the other texture, not the normal map), sets the secondary texture on the original texture importer to the OnPostProcessTexture, and calls "save and reimport" on the original texture importer
However, in practice, this is resulting in the secondary texture being created and given a name, but set to null. Is this because the OnPostProcessTexture Texture2D is temporary?
this hack is actually clever why I've never thought about wrapping a serializedobject in it 😄
will it cause issues if I'm not unsubbing the callback @gloomy chasm ?
Nope. All good.
nice 
Hi, I don't know if anybody has here has experience with this, but I am trying to check out files on perforce with this command:
https://docs.unity3d.com/ScriptReference/VersionControl.Provider.Checkout.html
I am not giving it a cl number because I am trying to create a new changelist with a given description. So I am using ChangeSet changeset = new ChangeSet(description: "Some description!"); which seems fine, I am getting no errors from this.
How can I create a new cl with a description?
I'm thinking maybe it needs a cl number, but I don't have it yet. So is there a seperate command to create a new cl?
In UIElements' Foldout, is there a way to animate expand/collapse?
nope
it sets the display style property by code, so uss can't override it.
I'm doing some inverted-hull outline stuff and would like to automate the baking of smooth normals into some other part of the mesh data like vertex colors. I can figure out most of this, but I'm curious if the normal recalculation used by Unity's model importer is exposed anywhere so I can more easily generate smooth normals with a more advanced algorithm. Mesh.RecalculateNormals won't really cut it since split vertices always have hard edges
Weird question but does anyone know the best way to clear an assetbundle tag from an asset?
i could be doing it wrong but just setting them to string empty via assetimporter seems to be assignining them like string empty assetbundle, instead of actually not having one
what unity version are you using/targeting btw?
is there any way to support intellisense in Rider inside the Temp/ directory?
Add it to your csproj
how to do it though?
for example when I click a "view generated shader" in the shadergraph asset inspector
I was thinking more like there should be some setting in rider, maybe?
I'm trying to automate setup of a component that has a custom inspector from another script, but its inspector has a bunch of fields and code ... so I'm wondering, can I somehow use the actual inspector instance from code?
specifically, say that I do this in my own editor script ```csharp
Foo foo = obj.AddComponent<Foo>();
// ... call/assign something on an associated FooInspector?
if it helps, the custom inspector is made using UI Toolkit
is there a quick way to get a string search result of all the game objects in the scene similar to how the search bar in hirarchy works ?
found this https://docs.unity3d.com/ScriptReference/Search.SearchService.GetItems.html gonna try
so basically :
public static void Select( string search = "" ) {
if( string.IsNullOrWhiteSpace( search ) || string.IsNullOrEmpty( search ) ) {
Selection.objects = null;
return; }
var scene_search = SearchService.CreateContext( "scene", search );
SearchService.Request(scene_search, ( context,list) => {
var selection = new List<GameObject>();
foreach( var item in list ) {
var obj = item.ToObject();
if( obj is GameObject ) selection.Add(obj as GameObject);
}
Selection.objects = selection.ToArray();
} );
}
Im tyring to change the borer color of a port created with UI Elements
But it doesn't matter what I set that it automatically becomes the default
How can I override this kind of changes?
You can see what I mean here
Color never changes, but border-color gets reseted every time I hover
/* PORT */
.port.node-view-port {
--port-color: var(--node-port-color);
}```It's a special cookie. `.node-view-port` is my USS class, but `.port` is used in the native code.
The property is used in the Port element (this TvPortView is a custom element I made derived from Port)
Native code
public class Port : GraphElement
{
private static CustomStyleProperty<Color> s_PortColorProperty = new CustomStyleProperty<Color>("--port-color");
private static CustomStyleProperty<Color> s_DisabledPortColorProperty = new CustomStyleProperty<Color>("--disabled-port-color");
(...)
}```
Ooooh,I will try it tomorrow ,thanks!
So is that absolutely needed to achieve that or can you do it without the extra class? Not for amy reason in particular just to understand it better
I don’t remember. It’s a been a long time tbh.
You could try setting those in a global stylesheet and load that onto your root element
Wouldn't scale well but might work fine in a one off situation
Revisited the code. I had a feeling that it was because of something weird happening.
What ends up happening is that any combination I tried that was not css TvPortView.port, .port.node-view-port { --port-color: var(--node-port-color); } does not work. I tried .port, TvPortView, etc...
Note: Maybe Port.port { works, but since I'm rocking a custom Port derived element, it doesn't.
.port.optional{
--port-color: #FF0000;
}
this just worked for me!
optional is a class I have on the port
Oooh, and this happens! NEAT
where can I find all the icons that Unity has in the editor to use them on my custom editors¿?
You can find them here, or install the package to get them in editor (I recommend using the package, much easier) https://github.com/ErnSur/unity-editor-icons
It's for a package Im making and I want to keep it with as less dependencies as posible
Are the icons on that package the same unity uses? aka the file id is the same?
Im trying to set it on the uss file, as background image, but no luck
Why don't you inspect the package and see how they got them?
It would not be a dependency. It would just be for you to view them in editor.
Open the files in GitHub
All the pacakge is doing is showing you the icons that are in Unity that you could use. Clicking on one will show you the icon resource path of the icon. You just copy that path and load the icon in your own editor
You can do background-texture: resource('console.warnicon'); if you are using uss
Yeah, bit hard to find and not really documented. I don't even remember how I found it haha 😅
i cant belive that I cannot find the icon I need
There's this two icons on the animator window
the eye open and closed
And there are some variations in that package, but none that match style and color
I guess it's animationvisibilitytoggleon, but the color is not the same?
I need some translation
NullReferenceException: Object reference not set to an instance of an object.
UnityEngine.Bindings.ThrowHelper.ThrowNullReferenceException (System.Object obj) (at <579f6a25593149bdb5b2b685692d23ea>:0)
UnityEditor.SerializedObject.get_objectVersion () (at <adf0e73faa2b4739bc17dcc108877e1a>:0)
UnityEditor.UIElements.Bindings.SerializedObjectBindingBase.GetViewHashCode () (at <2050825fd3274799a79980c703b0ce2d>:0)
UnityEngine.UIElements.VisualTreeDataBindingsUpdater.GetDataSourceVersion (System.Object source) (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEngine.UIElements.VisualTreeDataBindingsUpdater.Update () (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEngine.UIElements.VisualTreeUpdater.UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase phase) (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEngine.UIElements.Panel.UpdateDataBinding () (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.UpdateSchedulers () (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEngine.UIElements.UIEventRegistration.UpdateSchedulers () (at <1478f14db9ca4624bdcc87040fae8937>:0)
UnityEditor.RetainedMode.UpdateSchedulers () (at <2050825fd3274799a79980c703b0ce2d>:0)```
I opened the IMGUI debugger window to see what it's called. Have you tried D_animationvisibilitytoggleon?
Np. Yea the UI Elements and IMGUI debugger windows are super helpful for this 👍
A SerializedObject is null that is being bound or was bound to
I'm trying to understand where the binding even happened. I'm not directly Binding any SerializedObjects
Well... I don't know where or when you are seeing that exception so I am not sure what to tell ya
I was getting to that.
I'm making a quite complex POCO PropertyDrawer. That POCO is currently shown in a MonoBehaviour.
Where the error (sometimes) shows is when I add or remove any other component object in the same GameObject
Ah, it is probably a issue with binding a SerializedProperty then
Do you add remove any dynamically in the PropertyDrawer? (like adding to a list, or changing a managedReference)
Hey all. I am trying to make a context menu that lets me add sets of assembly references to an assembly definition. I am having an issue setting the new array of assemblies once I have it.
assemblyDefinition.assemblyReferences = assemblyDefinition.assemblyReferences.Append(GetAssemblyWithName("Unity.Logging")).ToArray();
The assemblyReferences set() is internal. Is there a proper place to set this?
How can you get the current color from the editor style (ie, setting a background color but respecting the user's editor preference settings)?
edit: nvm, can use this
https://docs.unity3d.com/ScriptReference/EditorGUIUtility.GetBuiltinSkin.html
So in the area of things that don't matter, but just set off my OCD. How can I get the spacing to draw like the standard ones?
Here is my current OnGUI drawer for that element.
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
var typeIdProperty = property.FindPropertyRelative("assemblyQualifiedName");
Initialize();
if (displayName.IsEmpty() && !typeIdProperty.stringValue.IsEmpty()) {
var currentIndex = Array.IndexOf(typeFullNames, typeIdProperty.stringValue);
if(currentIndex >= 0 && currentIndex < typeNames.Length) {
displayName = typeNames[currentIndex];
}
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(label, GUILayout.Width(EditorGUIUtility.currentViewWidth * .4f), GUILayout.MinWidth(120f));
if (GUILayout.Button(displayName, EditorStyles.popup)) {
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(Event.current.mousePosition.Add(y: 30, x: 10))),
new StringListSerachProvider("Type List", typeNames, x => {
displayName = x;
var currentIndex = Array.IndexOf(typeNames, x);
if (currentIndex >= 0 && currentIndex < typeFullNames.Length) {
typeIdProperty.stringValue = typeFullNames[currentIndex];
property.serializedObject.ApplyModifiedProperties();
}
}));
}
EditorGUILayout.EndHorizontal();
}
Also it's a button that opens a search window, which I don't think there is a default one by unity.
GUILayout is not meant to be used in a PropertyDrawer, it starts breaking pretty quickly as you do slightly more complex stuff.
To answer your question, you just add a bit of margin (4?) to the left of the button (just move the rect over a bit, and shrink the width)
Thanks for both answers. Is there an editor utility for margin?
I tried this but it still does grow at the same rate.
float margin = position.width * .4f;
EditorGUI.LabelField(position.With(width: margin), label);
if(EditorGUI.DropdownButton(position.With(x: margin).Add(width: -margin), new GUIContent(displayName), FocusType.Keyboard)){
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(Event.current.mousePosition.Add(y: 30, x: 10))),
new StringListSerachProvider("Type List", typeNames, x => {
displayName = x;
var currentIndex = Array.IndexOf(typeNames, x);
if (currentIndex >= 0 && currentIndex < typeFullNames.Length) {
typeIdProperty.stringValue = typeFullNames[currentIndex];
property.serializedObject.ApplyModifiedProperties();
}
}));
}
Use PrefixLabel instead, it returns a rect which is just the 'field' part of it https://docs.unity3d.com/ScriptReference/EditorGUI.PrefixLabel.html
Where to start if I want to get a nice-looking editor script like the post-processing volume ?
Have you made a custom editor before?
Wow. That works magic. Thank you.
Working code:
Rect rect = EditorGUI.PrefixLabel(position, label);
if(EditorGUI.DropdownButton(rect, new GUIContent(displayName), FocusType.Keyboard)){
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(Event.current.mousePosition.Add(y: 30, x: 10))),
new StringListSerachProvider("Type List", typeNames, x => {
displayName = x;
var currentIndex = Array.IndexOf(typeNames, x);
if (currentIndex >= 0 && currentIndex < typeFullNames.Length) {
typeIdProperty.stringValue = typeFullNames[currentIndex];
property.serializedObject.ApplyModifiedProperties();
}
}));
}
Sure thing! 😄
Yes, tons of them
So which part of "how do I make it" are you asking about exactly then?
How do I create a search field that only suggests overrides, and how do I display these overrides that way (with a nice looking dark foldable menu)
Right now I'm adding the overrides through AddComponent, but I'd rather have them as, well, overrides of the main script
They are using the same UI for the render pipeline overrides
Ahh, so what is it is just a list of POCOs on the PostProcessing ScriptableObject which is shown in the inspector of the volume.
For the AddOverride menu, it just is checking the type of each post processing effect in that POCO list, and not showing them in the dropdown
How does the inspector show them is such a clean way ? The dark foldable menu, the on/off checkbox, the three dots at the end for more info, etc
Or rather, what's the function to get a similar looking effect ?
Something like DrawCustomOverride(Override override)
ya gotta make it your self. Do you use UIToolkit or IMGUI?
Ahh, then this is going to be something new for ya a bit! 😄
Here is the code for how Unity draws it https://github.com/Unity-Technologies/Graphics/blob/master/Packages/com.unity.render-pipelines.core/Editor/CoreEditorUtils.cs#L715
Here is the window that is opened https://github.com/Unity-Technologies/Graphics/blob/master/Packages/com.unity.render-pipelines.core/Editor/FilterWindow.cs#L248
I read it all, it feels so incredibly complex
There's no simple way to display a dropdown and add the chosen component to the gameobject ?
Is there a build-in way to do it? No, but for something simple it isn't too hard really.
The code isn't tested because I just wrote it in text editor. But something like this should be it.
https://gdl.space/osurotesul.cs
Waow thanks a lot ! I'll check that out
can somebody please remind me how I can preserve my serialized boolean editor values between my desktop workspace and my laptop workspace when using Unity Version Control? What's kind of weird is that my float values are preserved, but my check boxes for boolean values are not.
...
eh, maybe I unchecked them for some reason and forgot.
There's also AdvancedDropdown which I think is decent https://docs.unity3d.com/ScriptReference/IMGUI.Controls.AdvancedDropdown.html
Got that search bar, folders and a nice look to it
hi, im doing procedural animation stuff and setting up the positions and rotations during play is a real pain in the ass. Is there a way of overriding the OverrideTransform class and adding a record button which records the value of x or something and updates a scriptable object asset? See my image below to clarify.
chatgpt keeps telling me to do target.FindProperty("TPose") but i'd like to know if there was a way to do it without making a child of override transform that stores references to all the pose assets because theres a lot of overridetransforms to set up.
unless i make them static references? but then how does that work with a custom inspector?
It looks pretty indeed ! But the documentation doesn't say anything about how to use the option clicked (no callback, no index returned, etc)
AdvancedDropdown is made in IMGUI. You have to convert it to UIElements using IMGUIContainer
I’ve done it :> it’s fairly easy
You’d have to build your own indexation feature. The system is a basically organized in a tree-like fashion. Each end point would have an index value.
That part I'm familar with (Popup works the same), the issue is getting that index. AdvancedDropdown does not return anything...? That's the reason it must be converted to UIElements, right ?
I'm kinda confused, what is the point of the dropdown existing if it does not return the value / index selected in the dropdown...?
You are meant to inherit from the AdvancedDropdown
Don't remember sorry, you can take a peak at the source to see
Just found it, it's empty
Sort of. I believe you get index of all items, not necessarily the index of an end point
Not sure I follow?
In the example of Root > Folder > Endpoint, doesn’t Folder’s item.id return 1?
Think so yeah
It’s not really representative of endpoint indexation. That’s what I meant
Yeah, you either need to store the actual values in a dictionary or a class derived from the AdvancedDropDownItem
You would want to inherit from AdvancedDropdown and AdvancedDropdownItem and play with that
In my case I made a class that inherits from AdvancedDropdown and acts as a base to all types of dropdowns
Then I made an AdvancedPopupField element that implements INotifyValue<object> that accepts any base CustomAdvancedDropdown I throw at it
At this point you should learn how to raise UIElements events
Hello everyone!
Does anyone knows how could i see where i am giving a min size to this so it doesn't crop that much?
You mean the entire editor window or what part exactly do you wish to have a min size?
I've found the exactly problem i think...
But i don't know how to fixe it
That text should crop itself in more lines when the window is smaller than the text size
its parent?
cuz there's a scroll view going on, indicating that it's parent isnt shrinking either
you mean that one?
no the entire scrollview thing
ill try and reproduce on my end, one sec
Do you want the uxml code?
would save time, yes!
just to be sure, there's no custom elements here?
what do you mean?
that message i've needed to recreate itself entirely by code...
HelpBox is your custom thing, then?
Now I read you all, i'm going to have lunch :>
Btw, Flex Shrink: 1 will tell a VisualElement that it can and should shrink when there isn't enough room for it.
the elements are set to shrink as far as the screenshots show
what elements make up the HelpBox? @indigo condor
Just this:html <ui:HelpBox message-type="Info" text="List is empty! Create new JSON templates to store different data types by clicking 'New JSON Template'." name="EmptyListMessage" style="margin-left: 12px; margin-right: 12px; margin-top: 0; margin-bottom: 0; min-width: auto;" /> I think is just a deffault boxhelp...
Here is the entire code if you need it
Oops, i sent you the wrong uxml code 😅
This is the one that makes reference to the right window
and sorry for the late on answering you... I was having lunch 😦
yeah, that's right, the point is that i don't know why is that not being applied to this code https://paste.ofcode.org/MyPZqQAeUm6hQ9W9JiBGRQ
Helpbox doesnt seem to be in UI builder :pain:
yeah, that's why i made it by code a few days ago
sure!
do you mean that?
sorry, one sec
so what I think is happening is that the Label element of the helpbox doesn't have the correct style settings
as the label grows with the text, but doesn't respect the boundraries or wrapping rules
so... is there any way to fixe that?
It happens that too with another Label that i have
wait, try and set the scrollview's scrollmode to vertical only
that fixe it
And how could i add like an hover text when i pass the mouse over the toggle text?
or just over some buttons
is that made by code editing the uxml or is there any way to make it visually on unity UI toolkit?
What do you mean "hover text"
You can do something like
.my-text {
display: none;
}
.my-text:hover{
display: flex;
}
like that text that appears when the mose is over the text
That is just the tooltip. Or do you want have something else there?
There isn't a good way to do a custom tooltip with other visual elements inside of it. But you can just set the tooltip property on the VisualElements if you just want to set the text
Is that :>
Thanks!
Hey, I need some specific help with something that I really have no idea how to do...
Alright, i need the first boxhelp to have the same height the second one. that's currently working, but the point is that i don't want the first pixel boxhelp to be bigger than the second one
so when that happens i want a verticall scroller to appear...
Did i explain well myself?
In a few words, i need the Add Data boxhelp to always have the first column height, adding a scrollview if it's necessary
Hmm, just setting the height: 100% and have a scroll view in it should do I think... no?
Is not that what i already have?
Can you clarify what you are seeing. Maybe a gif/short video that shows the current behaviour?
I record it with my mobile because the Windows capturer does not detect the window
So sorry for the low quality 😅
What are the settings for the #AddData_BoxHelp element?
that?
Disable flex grow and change height to 100%
Ahh, uhh. remove the flex grow from the scrollview instead
like this?
yeah
the same 😦
I would open up the UIElements debugger and play around with the styles in there. It will be faster to figure out and easy to play with. Sorry, I ma not sure atm what to do to get what ya need
It's fine hehe :>
which editor method auto formats the fields names ? for example from "m_CPMaterial " -- to -- > "CP Material"
nvm i just used disabled group scope *
For future reference it is ObjectNames.NickifyVariableName("m_CPMaterial")
https://docs.unity3d.com/ScriptReference/ObjectNames.NicifyVariableName.html