#↕️┃editor-extensions
1 messages · Page 11 of 1
I just uh realised that's actually pretty bad too
because it overlaps with the name selector constructor for SimpleSelector
so I've got to figure that out.
just changed it to .USSName() instead
I'll take a look into UIToolkit. As for manually positioning things, it's really just the entire thing that has to be manually positioned as it can be dragged around. GUILayout.Group doesn't appear to be a thing, GUI.Group is though?
I was already using that for the box itself, and from my limited knowledge you cannot nest them, unless there's another thing I can use to apply a background image?
is there a way i can add my own type filters to the filter search in the project files?
Nope
You just need a background image? You can use GUI for that or any of the vertical/horizontal groups as a background.
I don't really get what you are doing so it is a bit hard to suggest things
is there a way to automatically insert a search term into the search bar instead then?
Depends, how do you feel about reflection? 😛
i try to avoid it if possible but if its the only option then 
Yep, I figured that out just by trying it anyway. I added it to a VerticalScope. How I do the background though is affecting the next bit. Instead of trying to style it out myself, I did an image, and the box has a glow effect when selected which is... just another image. Which means, to account for the glow, there's a fat border and that's pushing my butons away. much sigh
Yeah reflection is the only way
I don't really understand what your setup is or what you are seeing. Sorry
is there any documentation on it?
I will have pity on you and give you a hand
You get the project browser, and then set this method it looks like
https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/ProjectBrowser.cs#L534
You can use that to find the last active project browser
So not too bad really! Just two quick reflection calls!
Sorry man but it does not help at all. I meant exactly that. Collapsing multiple changes into one group make it easy to undo everything at once, but then when you want to redo it it does not work unfortunatelly :/ If I put let's say adding created object to a list and object creation itself into one group, I will undo both, but then redo only creates object but doesn't add it to the list, like it can handle only single operation.
Unless there is something I do t understand and I don't know about it...
Creating multiple groups mean multiple undo operations, right? If I make a group, add some undo operation, collapse it, then create another group, those will be 2 separate undos? Or making multiple groups in one go is still only one ctrl + z?
Uhh, I am having a hard time following, are you able to show some code for it and use that to explain what it is/isn't doing?
Forgive me pls but this one will be huge XD
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
it is a partial class of a graph view
and basically whenever there are some changes i apply them and record them into a single group
so lets say deleting one node will destroy one SO associated with it, delete its reference in another SO, deletion will cascade on every edge connected to this node, and with every edge another SO associated with it will be deleted. Overall a lot is going on there
Oh gosh, okay... So the issue is that redo is not working, but undo is?
but when i delete a node, undo it, and then REDO it, then some operations are being ignored or smth... anyway references to this SO are being deleted but SO itself is not
i just dealt with something similar just an hour ago. but it was something with how i had written a setter method which ofc was not being called when redo happened. not sure if its something similar you are running into
Honestly, there are so many things going on, and the undo system can be a little confusing sometimes. I am going to say it would be best to recreate the very basic setup of the undo system and try different things to learn about it. Like start with just creating objects and undoing and redoing it.
Something that might be going on, it looks like you are deleting assets and undoing the destruction. Unity doesn't like you undoing asset database modification.
Beyond that, I would really recommend reconsidering how you are structuring this. Using SOs like this is really not a great way to go about it.
is there a way to set the sprite of a gameobject seen in the scene view (in editor) based on a bool inside of a script?
for instance lets say the bool was called active and the two sprites were called sprite_active and sprite_inactive
i guess some pseudocode for it would be like
if (active){
spriteInEditor = sprite_active;
}
else
{
spriteInEditor = sprite_inactive;
}
You mean set the SpriteRenderer component .sprite property?
yeah, although for usage in the editor as it'd make it much easier to setup levels (i have blocks that can be in one of two states on the loading of a level, and it'd be easier to visualise if i can see which state they are in the editor)
I solved it, but it may be ugly. I'll give more context, I'm doing a basic-ish node editor. The visual appearance of the node is handled by two images, one when the node is selected (has an outer glow) and one that isn't. In order for the image to "scale" properly with the glow, there has to be a fat border. This pushes the buttons away by 9px, understandably, so I used additional areas to line the buttons up properly.
So while that works, clean or not, there's one more issue of the missing connection beziers. The connection beziers rely on the rect of the button, but there is no rect anymore. Not sure what to do about that?
This is more or less the entirety of what I have thus far, minus the drawing of the connections: https://gist.github.com/Tencryn/52c2c31eef7b3e97166498c48e788c7c
to give an example
left is scene view currently, right is in-game view
note that only the bottom row of blocks is actually set to the active state, but this isn't visible in the editor
Well... until Unity team wont improve its native serialization in editor im forced to stick to SO, as abstract SO can still be serialized, but native C# class can not :/
ideally i'd want to be able to see in the editor which blocks are active or not at a glance rather than having to look into the inspector for it
What version are you on? There is [SerializeReference] which does support polymorphic serialization
HOLY MOLY since when?! 😮 I just switched to new LTS (2021) like a month ago
Since 2020.2. But stable in 2021
Easiest way would be to use the Gizmos API
I recommend reading the docs though, there are some caveats.
This may be a stupid question but:
another thing I would need that SO allows me to do is having a dedicated inspector for this sort of data container. If it wasn't a SO but pure C# class, can I make an inspector for it? Ofc it would be opened only programmatically then, but that is the goal
If I recall, I was trying something like that before but failed, but honestly I dont remember how i tried to do it and what failed in particular
What does "dedicated inspector" mean for you? Do you mean "A way to show properties either in my window or another window" or do you mean "Show the properties in the inspector window"?
properties in the inspector window
Example:
What im working on is a state machine creator. Each edge in a graph view have associated SO to it, and it stores all the information about a transition (just like in a mecanim). When I select the edge i can just simply open inspector for that SO
but how would I achieve that with storing all that information about a transition in a C# class?
that is not a SO*
hm, i see
is there a way to actually change the actual sprite of the gameobject rather than drawing a gizmo overlaid ontop?
i mean i managed to get this from that
There are two ways you could handle it. One is to have a dumby SO, and have its editor just draw the PropertyField of the selected node/transition in the last focused instance of your window. The other option is to make the SO asset's inspector change to show the PropertyField of the selected node/transition. I would probably opt for the first one.
I don't know what it is currently drawing where. Like, are you talking about the sprite that is being rendered with the SpriteRenderer component?
Just as I thought. So my plan B wasnt that stupid after all XD
Nvm, I will handle it somehow and when the time comes I will make some V2 with a better solution.
@gloomy chasm I admire your multithreading man XD
Suit yourself! xD
LOL, idk how good I am really doing but I try. Hindsight, should have created threads. Oh well
yeah
so by default i have the sprite set to the active one in the sprite renderer
and then it just animates during gameplay so automatically changes to the correct sprite while playing
ofcourse one thing i could do is just manually set the sprite through the inspector, but that'd be slow
Ahh, so the right way to do that would probably be to create a custom editor for your component. And check when the bool value changes, and when it does. You get the SpriteRenderer component, and set the sprite of it.
ok so im not too sure where the file i need to reflect is located. ive been looking for a .dll file in the unity version folder but i have not been able to find anything
No no, you just get the type. Since the ProjectBrowser is an internal type, we can't get it directly. So to get it, we need to get the assembly that it is in, which is just the Editor assembly. We can get that from any type that we know is in that assembly var editorAssembly = typeof(EditorWindow).Assembly;. Then we get the Project Window type System.Type projectBrowserType = editorAssembly.GetType("UnityEditor.ProjectBrowser");
oh yeah, that makes a lot more sense
After that you just do normal reflection on the type. Like projectBrowserType.GetMethod("SetSearch"); (might need to use the binding flag for nonPublic, I don't remember)
i managed to get it working just by doing this
void OnDrawGizmos()
{
spriteRenderer = GetComponent<SpriteRenderer>();
if (!tileActive)
{
spriteRenderer.sprite = pinkBlockInactive;
}
else
{
spriteRenderer.sprite = pinkBlockActive;
}
}
You can do that on OnValidate so that it only does it when you change a value.
ah that works better
there was a slight delay when i was using OnDrawGizmos()
(between toggling the active state and the sprite toggling)
void OnValidate()
{
#if UNITY_EDITOR
spriteRenderer = GetComponent<SpriteRenderer>();
spriteRenderer.sprite = tileActive ? pinkBlockActive : pinkBlockInactive;
UnityEditor.EditorUtility.SetDirty(spriteRenderer); // We do this so that the sprite will stay set after the scene is changed or the editor is closed.
#endif
}
i'll likely have to change the condition at some point as i'll be implementing other interactables with their own sprites in future, but that works perfectly now
i haven't come across that #if #endif before, is that actually vital to the code working or is it just a preference thing
It is called a preprocessor directive. It lets you either compile or not compile code depending on the condition. So in this case, you cannot have editor code in a build (EditorUtility.SetDirty()). So we surround it in the directive so that it only will compile that code if it is in the editor. Without it, it will throw errors when trying to create a build.
What could cause a Handles.Button to not be interacted with?
Vector3 pos = (rect.center + connector.rect.center) * 0.5f;
if (Handles.Button(pos, Quaternion.identity, 4, 8, Handles.RectangleHandleCap))
{
Debug.Log("click");
}
i got it. it ended up like this
// Get type
var editorAssembly = typeof(EditorWindow).Assembly;
System.Type projectBrowserType = editorAssembly.GetType("UnityEditor.ProjectBrowser");
// Get window instance
var WindowInstanceInfo = projectBrowserType.GetField("s_LastInteractedProjectBrowser");
// Call method
MethodInfo setSearchInfo = projectBrowserType.GetMethod("SetSearch", new [] {typeof(string)});
setSearchInfo.Invoke(WindowInstanceInfo.GetValue(projectBrowserType), new object[]{"t:TestClass"});
Nice! That all looks right to me! 😄
@gloomy chasm Do you know how to bind values of a UI VisualElement to a C# object (e.g. Textfield value to a string)?
There's got to be documentation somewhere but RegisterCallback is uh- not well documented in a way
There is binding but that's for Serialized Objects / Serialized Properties.
I would also love to know this
It's partly here
but what in the sam hill
it is a really weirdly documented page in the sense that it's clear what we need to do is here but is mixed in with SerializedObject/SerializedProperty
so I'm guessing for some reason you must serialize a primitive type and then use that in the bind
might just be better off with IMGUI container because this is
this is something else
They are in the process of completely rewriting the binding to support any kind of object
currently binding is only really covering serialized properties
Ah, thanks
Do I just go the IMGUI route then?
I'm stuck on Unity Engine 2021.3.6f1 due to university restrictions and I won't have access to that
you can register change events and do it that way, is there any reason you're not using serialized property though?
I'm using GraphView to have nodes with data attached that gets updated based on the values within the extension container.
I could try serialize the node itself and have it modify itself from that which sounds not too good of an option
I'd personally prefer doing it with UI Elements because of the design benefits
How would I register change events
Thank you
That just really helps with what I'm wanting to do and it's nice to know I just missed something
it's just a pity it doesn't help with the opposite direction, so unless you're really smart about it you probably have to redraw the whole graph if the serialized representation changes
oh that sucks
I'm doing it so I can do Unreal-like blueprints for my plugin framework (the graphview window is just a general editor window template I'm creating, which I plan to use to make visually-scriptable plugins with)
just the value thing is a bit of a pain now and again
I've just started exploring the inner workings of node (esp. custom EdgeConnectorListeners), it's really cool seeing some of how it all works.
Using Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); with a custom editor extension. I wish to raycast against a prefab in prefab edit mode, but I do not get any collision with the prefab. It works fine if I drop the prefab into a regular scene. Any thoughts here?
Got it for anyone wondering. Didn't know anything about the PhysicsScene until a min ago. Now it works great if I use it like this:
if (physicsScene.Raycast(ray.origin, ray.direction, out hit, 1000f))
{```
i dont know if this is the right place to ask
in vs 2019 there is an option to do ctrl + shift + m to add a function you want it opens a dialog box like this how do i do this in vsc
Hey everyone,
would you recommend a 50% discount on launch for 1 week or 2 weeks?
when i edit a variable in a scriptable object, github dont always detect the change until i press ctrl + s. But on some variables it doesnt detect the change after i do that. I assume the reason is because im not using serializedproperties when changing those certain values as they are being changed from a method. how can i then register a change that should be saved?
I am already registering and handling undo's correctly on those variables so i dont know what else i could do
Anyone know of a way to check if the active game view is "Game" or "Simulator"?
do you mean the scene and game view?
No, I am using the device simulator. It is like the game view but runs as a mobile device.
Window > General > Device Simulator
oh, well im not equiped to answer that so someone else would need to
Kind of did a hacky thing, I check the active window type against the game view type. It works
i thought that id make a quick tool for generating LUT textures within unity as i didnt find any already. but im having this issue where its only updating the render texture on recompile. even after i press the render button which should just create the file right away. the render method here is only called once i press a button within the window and never any other times. But i am reloading the asset from the assets in OnEnable so i guess that might have something to do with it?
void Render(bool GeneratePNG)
{
Graphics.Blit(defaultWhite, renderTexture, ShaderMaterial);
// * RenderTexture to Texture2D
Texture2D tex = new Texture2D(512, 512, TextureFormat.RGB24, false);
// ReadPixels looks at the active RenderTexture.
RenderTexture.active = renderTexture;
tex.ReadPixels(new Rect(0, 0, Resolution, Resolution), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
string fileName = "";
if(GeneratePNG)
fileName = textureName();
else
fileName = "Assets/LUTGenerator/Textures/Default_LUT_Preview.png";
System.IO.File.WriteAllBytes(fileName, bytes);
if(!GeneratePNG)
{
previewTexture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/LUTGenerator/Textures/Default_LUT_Preview.png");
Debug.Log("Preview Render Done");
}
else
Debug.Log("Texture Generated");
}
thing is it doesnt update within my assets either until i recompile
i tried calling EditorUtility.RequestScriptReload() after rendering, and that does not seem to do it either. so i think it has something to do with validating the asset files
or if anyone knows a different way i could render a texture in a editor window with a shader applied that would be perfect
The way you are doing it you need to call AssetDatabase.Reload(); after wirting the bytes. But there is a better way. Simply do AssetDatabase.CreateAsset(filePath, tex);
No need to convert to bytes, you can just save the Texture2D as an asset (unless I am remembering something wrong)
thank you that worked nicely
Hi everyone, I'm starting to look into handles with the preview render utility class, I can render the handles correctly to the screen with the following code. However I can't seem to get any interaction from them.
The button I am adding apeares in the center of the cube, however there is no effect or console output when clicking it. I know with defualt scene based handles these functions are meant to sit on OnSceneRender() however I am unaware of whether preview render utility has something like this, or if that would be the reason that the inputs are not being recognised.
There really doesn't seem to be much information on these classes online, and the stuff out their doesn't seem to describe the two of them interacting all that much (I have found a few places online however mainly these are people asking a the handles rendering correctly and not them apearing correctly)
Any help on this would be apreciated.
#region Behaviour
// - - -
private PreviewRenderUtility _previewRenderUtility;
private Camera _camera;
private GameObject _renderTarget;
private Transform _renderTransform;
// - - -
#endregion
protected override void OnInspectorRender()
{
InitialisePreviewRenderUtility();
DrawPreviewRenderUtility();
Button("Debug Button", true, () => Debug.Log("Output"));
}
private void OnDisable()
{
_previewRenderUtility?.Cleanup();
if (_renderTarget) DestroyImmediate(_renderTarget);
}
private void InitialisePreviewRenderUtility()
{
_previewRenderUtility?.Cleanup();
_previewRenderUtility = new PreviewRenderUtility();
InitialisePreviewRenderUtilityCamera();
InitialisePreviewRenderUtilityRenderTarget();
_previewRenderUtility.AddSingleGO(_renderTarget);
}
private void InitialisePreviewRenderUtilityCamera()
{
_camera = _previewRenderUtility.camera;
_camera.fieldOfView = 60f;
_camera.farClipPlane = 100f;
_camera.nearClipPlane = 0.1f;
_camera.cameraType = CameraType.SceneView;
_camera.clearFlags = CameraClearFlags.Skybox;
Vector3 position = new Vector3()
{
x = Mathf.Sin(Mathf.Deg2Rad * -30) * Mathf.Cos(Mathf.Deg2Rad * 15),
y = Mathf.Sin(Mathf.Deg2Rad * 15),
z = Mathf.Cos(Mathf.Deg2Rad * -30) * Mathf.Cos(Mathf.Deg2Rad * 15)
} * 3f;
Quaternion rotation = Quaternion.LookRotation(Vector3.Normalize(-position));
_camera.transform.SetPositionAndRotation(position, rotation);
}
private void InitialisePreviewRenderUtilityRenderTarget()
{
_renderTarget = GameObject.CreatePrimitive(PrimitiveType.Cube);
_renderTransform = _renderTarget.transform;
}
private void DrawPreviewRenderUtility()
{
Rect guiRect = EditorGUILayout.GetControlRect();
Rect rect = new Rect(10, 10, (guiRect.width + guiRect.x - 20), (200 - 20));
if (rect.width > 0 && rect.height > 0)
{
_previewRenderUtility.BeginPreview(rect, GUIStyle.none);
_previewRenderUtility.Render();
RenderHandles();
_previewRenderUtility.EndAndDrawPreview(rect);
}
GUILayout.Space(rect.height);
}
private void RenderHandles()
{
using(new Handles.DrawingScope())
{
Handles.SetCamera(_camera);
Handles.color = Color.green;
Handles.DrawWireCube(Vector3.zero, Vector3.one);
float size = HandleUtility.GetHandleSize(Vector3.zero);
Handles.color = Color.white;
if (Handles.Button(Vector3.zero, Quaternion.identity, size * 0.1f, size * 0.05f, Handles.DotHandleCap))
{
Debug.Log("Clicked");
Repaint();
}
}
}
Is there a way to draw the Enable checkbox of a MB (like in Physics Body) from a custom inspector? (Basically I would like to make the Balancer Authoring script be disabled/enabled from the inspector without the drawback of it not being Updated... But store the enable state in a custom bool variable)
any idea why stopImmediatePropagation won't work?
it's a parent with single child, clicking the child would trrigger the parent as well even with stopImmediatePropagation
This is a custom foldout with a toggle, so when the toggle clicked, the foldout would get triggered as well
this is bizzare. is EditorGUILayout.GradientField(_gradient); supposed to automatically set the gradient by itself? cuz it does. most other cases it would be _gradient = EditorGUILayout.GradientField(_gradient);
not really sure where to put this but is it possible to increase the scale of the UI in the editor? mine is super tiny
I can't say for sure. But I can at least say you should definitely not be recreate the PreviewRenderUtility each draw. Just make it once in OnEnable.
No, there is not. And even if there was, it sounds like you are trying to do something in a very unintended way.
Check this out https://forum.unity.com/threads/is-it-possible-to-increase-the-font-size-in-the-editor.661336/
Maybe this is outdated. It's from 2019.
All I could say is to read the docs for the event propagation. From what I remember it is pretty well written. Sorry I can't be be of more help.
That is because all the others are structs (value types) but Gradient is a class (reference type).
Isee
Thank you, I'll have a look at doing that and seeing if that solves it.
Hello, I created an empty GameObject (no script, only a transform) that is just supposed to contain 2 other GameObjects, like that:
My problem is that when I try to drag it somewhere else, it only selects one part (Head in this example) and what I'd like to do is to select the whole group (Human) with my mouse, but the UI doesn't allow me to drag and drop it to modify the position easily
What I've been doing until now is change the position with the transform component inside Human, but that's very tedious with many copies...
How to get the object value from a PropertyDrawer for the list?
In my class I have
[SerializeReference] public List<string> StingsList = new();
In my custom property drawer I'm trying to get this field value (to add something to the list, for example) like this:
var stringsList = property.FindPropertyRelative("StingsList").managedReferenceValue;
I'm getting "InvalidOperationException: managedReferenceValue is only available on fields with the [SerializeReference] attribute", but the field has SerializeReference.
Btw, I need not the string value, but the full list.
The List doesn't exist in the the serialized representation. Array and List are serialized the same way. There's no method to automatically convert a serialized array property to List<T> or Array. You will have to do it manually.
how do i set the start size of a scriptablewizard window? it doesnt seem to work by setting the position rect at awake
i just increased the min size instead 
For some reason, any attempt to get the width and height of a visual element results in NaN in 2021.3.6f1 (including via VisualElement.style or VisualElement.contentRect or any variation thereof)
and resolved style doesn't work either oddly
Okay so the UIToolkit Debugger can see the width and height of an element. Clear as day, it can. That means that somehow, some way you can get the Visual Element. I'm not even remotely sure how it's going to NaN under the hood though.
When/where are you getting it?
An unset .style is NaN iirc, and .resolvedStyle is not resolved at the time of some actions.
I found out how thankfully
That is really weird behaviour to have in some respects to just after a node is created and added to a graph element.
I think generally it is better to use the transform, or localBounds, or one of those ones instead of the style directly.
yeah, I used style as a last resort test before I found GCE
I can only imagine the other behaviour being that it throws an exception if it's not been calculated yet
but that seems difficult to maintain
throwing an exception or using GeometryChangedEvent?
I mean that something like contentRect is either going to be a value that indicates that it is unset, NaN, or it's gonna throw an exception
ah - I used it just as a test and thankfully I don't have to use it. I don't know what Content Rect is useful for specifically
It's not that specifically, I mean any of the parameters. The only reason GeometryChangedEvent works is because that runs after layout has occurred, and the values have actually been set to something at that point
after you add something to the hierarchy it's just in a collection, with the UI dirtied ready to do layout when it's drawn
you can even have entire UI structures sitting in memory that have no layout ever occur on them because they're not in a panel, so all their dimensions will be NaN
style is the style that has been directly set on the element via C#, and resolvedStyle is whatever the combo of Uss and style is once it's needed to be resolved for layout
yeah, those thankfully were explained in the Intellisense documentation
I just kept trying things till eventually something worked but I can see why they'd be NaN when they weren't being drawn.
I was trying to get the behaviour working afterwards, which probably wasn't working as intended
Thankfully I don't think there'll be any other reason to get the information again in the way I was trying to
I just needed to center the node on the cursor along the X axis after it was created and drawn so that it could properly appear similar to other blueprinting systems
Hi everyone, sorry to bring this up again but I am still stuck on getting Handles to interact with the mouse within the inspector using the Preview Render Utility.
Right now I have a cube and a button, all I want to do is see if clicking the button will call a debug log. However the Handle.Button doesn't seem to register any inputs.
https://forum.unity.com/threads/previewrenderutility-and-handles.859168/
I have found this thread on the forums, where someone mentions the fix for this being to add the offset from the corner of the window to the left of the preview, to the current events mouse position. However they don't elaborate any further then that. I do not know what they mean by left corder of the preview area / window. And also do not know what adding this offset to the mouse position will do.
So far I have tried doing this code below to:
Rect previewRendererRect = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.MinHeight(200));
Rect editorWindow = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
Event.current.mousePosition += previewRendererRect.min - editorWindow.min;
Whereas the previewRendererRect is the rect used inside
_previewRenderUtility.BeginPreview(previewRect, GUIStyle.none);
However this did absolutely nothing on its own. Am I meant to manually reimplement program interaction logic by doing some sort of ray cast to the editor UI using this mouse position? And if so, how would I actually go about doing this? Elsewise what is the actual correct way of doing this sort of things.
This is my full script: https://pastebin.com/yVD1yuhn.
created a custom mask map creator. If anyone is in need of one DM me.
setting the pickingMode resolved this 
Is there an editor callback for when asset is double clicked?
Similiar to how Animator/UIBuilder and similiar stuff works?
never personally used it
you proly need to see what's in UnityEditor.Callbacks
Guys i wanted to make a custom editor that serialize an array of parent class, and the designers could instantiate the child classes inside the editor and this instance will serialize based on the child properties, any tips on how i could achieve that ? Im trying to use [SerializeReference] but it is not working
You can try my drawer https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
what is the element called where you have a slider with the option to also set a low and high value on said slider? Googling has not given any good results
Ty
Hey folks, I'm trying to build out a custom editor for jump physics and I want to visualize it. Is there any way to set up a mini scene that renders live when showing the editor and has the player character just constantly jumping? Or is there at least a way to manually draw a simple box with a circle moving up and down according to either an animation curve or just manually calculating the position each frame?
MinMax Slider
Thanks!
Is still posible to use WebView in EditorWindow?
yes, sorta... https://github.com/gree/unity-webview
pretty sure the webview class still exists, better check that 1st than the linked above
dang I'm on windows which isn't supported
I'll look for the webview though
doesn't seem to exist in the docs
Its not exist....
I wanted to create a new window and load an iframe there with a color generator, google search..... ChatGPT 😛
Small brain here, I just had to press W
have a nice day
Hey, I'm creating a editor using UIElements, which has a grid of ObjectField's. I've created callbacks for when the value changes, but I can't figure out which element was the one that received the event so I can get the proper grid position. Any ideas?
Hi. I was wondering, how can I make it so the variables are shown like this? Like, when I create a public bool it just creates one bool, not a grid-like thing like in here
the event has a .target property which is the VIsualElement which recived the event.
Yeah I realized, just weird that the type is an IEventHandler when the docs specify it's VisualElement 😅
Just need to cast it to VisualElement
Guys i created a property drawer for a class on a monobehaviour script and it world perfectly
but when i use it on a struct inside a dictonary it send me error because of the EditorGuiLayout, só i used the editor gui but the elements did not scale properly
I wanted to make the same layout i had without the dictonary
Is it because im trying to use the dictonary editor at the same time i use the property drawer?
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty iter = new SerializedObject(property.objectReferenceValue).GetIterator();
float height = EditorGUI.GetPropertyHeight(property, label);
while (iter.NextVisible(true))
height += EditorGUI.GetPropertyHeight(iter) + EditorGUIUtility.standardVerticalSpacing;
return height;
}
I'm trying to make a CustomPropertyDrawer and I've been searching on how to set the height... the only thing I could find is this, but it gives me some errors (type is not a supported pptr value, object at index 0 is null).
I'm using this within a class which derives from PropertyDrawer and make all my other CustomPropertyDrawers derive from this, so I want to make it as universal as possible.
Any ideas how to make this work?
Nwm, I can just set the height within OnGui with height = lastRect.y - position.y + lastRect.height and return it in GetPropertyHeight
The only thing I don't understand is when I have an array and every element in the array has the height of the last element instead of having their own height...
Any ideas why this happens and how to fix this?
You don't make an iterator, you just get a copy of the property via SerializedProperty propertyCopy = property.Copy() and then
do propertyCopy.NextVisible(true) instead of the iter.NextVisible(true)
But you also need to get the end property, otherwise it will just keep going.
Also also, EditorGUI.GetPropertyHeight returns the height of the property including any child properties. So if memory serves, you can just do return EditorGUI.GetPropertyHeight(property);
Idk, it broke when I changed it to return EditorGUI.GetPropertyHeight(property);
I'll try the first one
Ok, I might be dumb, how do I do it with the end property?
public class PropertyDrawerCustomDefault : PropertyDrawer
{
protected float _height;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty copy = property.Copy();
SerializedProperty end = copy.GetEndProperty();
_height = EditorGUI.GetPropertyHeight(copy);
while (copy.NextVisible(true) && copy != end)
_height += EditorGUI.GetPropertyHeight(copy);
return _height;
}
}
That's how I did it
You do copy.EndProeprty and do SerializedProperty.Equal(end, copy)
ooh, ok
It is EqualsContents that you want
public class PropertyDrawerCustomDefault : PropertyDrawer
{
protected float _height;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty copy = property.Copy();
SerializedProperty end = copy.GetEndProperty();
_height = EditorGUI.GetPropertyHeight(copy);
while (copy.NextVisible(true) && SerializedProperty.EqualContents(copy, end))
_height += EditorGUI.GetPropertyHeight(copy);
return _height;
}
}
That's how it is now
but now It's cursed
Both are the same and should have the same size, yet have very weird heights
Custom Property Drawers will make me go insane
Ahh, @ornate oriole try just returning EditorGUI.GetPropertyHeight(property, true);
I did that but it doesn't work
Also, careful about cashing the height like that. PropertyDrawer instances are reused between different properties of the same type.
What happened?
oh.
As it looks from my perspective, the PropertyDrawer is just constantly resetting the height of properties of the same type to the height of property in encountered last (basically loops through and does stuff like: allPropertiesOfThisType.height = encounteredProperty.height and at the end of the loop it sets the height to the height of the last one in the array). Except for properties which are declared separately:
public SomePropertyWithCustomDrawer imOk;
public SomePropertyWithCustomDrawer[] imAllTheSame;
For now I'll just try some other nasty thing instead.
You are misunderstanding I think what is going on.
The way it works is that when Unity goes to draw a property, it checks to see if there is a property drawer for that type. If there is, it will create a single instance of that property drawer.
Then for every property of the type that it encounters, it simply gets the instance of the drawer and passes the the property to the GetPropertyHeight and OnGUI methods.
I see, I understand the concept here, but the thing that still confuses me is the height it sets to these properties.
With a single property the height is correct.
With an array of properties there is only one height (equal to the height of the last element in array)
The single property is unaffected by the heights in the array, so there seems to be a problem with the properties being in an array only
Right now it's declared like this:
[Serializable] struct AttackSet { public Attack[] someAttackArray; }
public Attack someSeparateAttack;
public AttackSets[] someAttackSets;
Seems like in my case the Attack[] array breaks, so I'll try to do this instead:
[Serializable] struct NastyContainer { public Attack attack; }
[Serializable] struct AttackSet { public NastyContainer[] someAttackArray; }
public Attack someSeparateAttack;
public AttackSets[] someAttackSets;
Which would basically 'separate' the attacks (not make a direct array of attacks)
If that works then I'll be happy enough.
Can you share the code for your property drawer, that is where the issue is.
Sure, I'll chuck it into a pastebin
Would be better to use one in #854851968446365696 as they have syntax highlighting
You can ignore the _height += stuff, I set the height directly at the end of the scripts
just didn't delete it yet
And it might be a mess since I've been experimenting and didn't clean it just yet 🙏
But it should be readable enough
Also, what's the order of execution of these methods, especially in an array?
Does it first go through each OnGUI method and then it draws the whole array? If that is the case then it would make sense why the height was the same everywhere
oh my f** god
@gloomy chasm It's ok, I think I solved the problem
Oh what was it?
I don't really know (probably due to the order of the method execution so my _height was being reset several times and only after that the height was being set)
I just chugged my problem into ChatGPT and it surprisingly gave me a correct solution
I thought you were not using _height any more thought...
I wasn't, I was just addressing the previous errors I had (but the other solutions worked even worse so whatever..)
additional field in base class:
protected Dictionary<int, float> _heightDictionary = new Dictionary<int, float>();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
_heightDictionary.TryGetValue(property.propertyPath.GetHashCode(), out float height);
return height;
}
within OnGUI:
_heightDictionary[property.propertyPath.GetHashCode()] = _height;
basically making a dictionary and read the height later from it, instead from the _height field directly
it's kind of a workaround since I need to play around with it in the OnGUI but it works so I'm happy
Is this what you are doing now? If so, no, don't do that that is going to break so much stuff xD
Do NOT cache the height, at all, no, bad
oh.
GetPropertyHeight is called before OnGUI. Also things like EditorGUI.GetPropertyHeight call the GetPropertyHeight of the property drawer
Ooh, I see..
But I checked it out and it seems to be working for now without any issues
How exactly can it break?
Firstly, if anything else ever calls EditorGUI.GetPropertyHeight and a property using this method is present. It will give incorrect results.
Even if it calls GetPropertyHeight first, the height returned from the dictionary will just have the default value of 0, then OnGUI gets called and updates the dictionary, and whenever another GetPropertyHeight gets called it already has the height there
Idk how exactly does the instantiation of the custom PropertyDrawer instance works, when it's deleted, how exactly and how often does it update the inspector, but for now it looks good, idk, maybe it has to be a specific scenario when it actually does break, or I'm lucky that it didn't break just yet
OnGUI does not always get called after GetPropertyHeight
Again, just don't cache the height. Why are you caching it?
Because all the other solutions didn't work so I tried this instead
Like I get the main idea that it could break, but for now I just don't see where and when exactly it could break, what would have to happen to make it break
Both the solutions with iteration and simple EditorGUI.GetPropertyHeight(property) didn't work and the height was nowhere close to what it was supposed to be for some reason
oh wait, I'll check something
Yeah, I checked it once again with EditorGUI.GetPropertyHeight(property, true) since I had EditorGUI.GetPropertyHeight(property, label) earlier, but it still doesn't work
Hi. Is there a way to redraw only some fields with property drawers and leave the others the same?
I can find fields with FindPropertyRelative and redraw them, and I can draw default fields with PropertyField.
But how I draw default all except fields I specify (and redraw), without actually drawing all of them (so if a new field would be added I won't need to update custom drawer)
are you asking how to use the property field for everything except the ones you want to be different?
Yes. I want to use the default drawer for all fields except the one with specified type.
And my property is an element of a list.
Hmmm I'm pretty new to the editor stuff, but I'm messing around with it a bit. Is there a reason you can't just use another field type and tweak the data going in and out?
I have a list of class instances, which I create through editor to configure stuff.
I think I find a solution (for my problem at least).
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var lines = 1;
EditorGUI.BeginProperty(position, label, property);
foreach (var field in property.managedReferenceValue.GetType().GetFields())
{
var fieldType = field.FieldType;
if ("type I don't want to redraw")
{
var rectType = new Rect(position.min.x,
position.min.y + lines++ * EditorGUIUtility.singleLineHeight,
position.size.x, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(rectType, property.FindPropertyRelative(field.Name)); //draw default
}
}
// custom redraw for needed elements5
EditorGUI.EndProperty();
}
Use a PropertyAttribute and have your drawer target that, then only the fields with the attribute applied will draw with the property drawer that targets that
Thanks. Actually I came up with something like this in the end.
When I create game object in edit time. How can I make it so scene becomes dirty and does not instantly saves assets?
I create object like this
var go = new GameObject(type.Name, type);
go.transform.SetParent(transform);
and for some reason scene is instantly saved
No, you never dirty the scene, it's not saved.
Undo.RegisterCreatedObjectUndo (go, "Created go");
but it is for me
so hold on
var go = new GameObject(type.Name, type);
Undo.RegisterCreatedObjectUndo(go, "Instantiated node");
go.transform.SetParent(transform);
is this how it's meant to be?
what about modification of serialized data?
Undo.RegisterCompleteObjectUndo(this, "Added connection");
connections.Add(connection);
and destroying of game objects
DestroyImmediate(node.gameObject);
Undo.RecordObject
Undo.DestroyObjectImmediate
what about callback when Undo happened (so I can rebuild view)
I tried this, but no luck
private void Awake()
{
Undo.undoRedoPerformed += OnUndo;
}
private void OnDestroy()
{
Undo.undoRedoPerformed -= OnUndo;
}
That's it, if no luck it sounds like you've done something wrong
Anyone knows if its possible to create an animation preview VisualElement with UIToolkit? I'm building an editor and would like the following behaviour:
- User selects and animation with an object picker
- The selected animations preview is displayed in a visual element next to the object picker
- The user can scroll the animation and see the time for a given frame.
Basically, can I create an instance of the preview window (bottom of inspector) and place it in my custom editor?
This window. It's displayed when selecting an animation (fbx) in the inspector
I've managed to get the animation window to show in various ways with GetWindow<AnimationWindow> but I dont need the whole window, just the preview module.
callback is not called though
I register in EditorWindow class
Does Editor window have an awake that's relevant? I don't use awake in them
what would be appropriate callback then?
OnEnable iirc? Just test it's called and registered
yep, that was it
damn
this is much more complex
I found out I store elements in a list as well
which makes deletion through Undo leak
Is there a way to register some callback along with Undo?
Or maybe register undo as action alltogether?
or I guess I better not rely on lists...
i'm trying to add c# extention to my VS code editor but it doesn't exist
all youtube tutorials show it having a green logo and a verification from microsoft
does it not exist anymore ?
It exists, but you might be better off using visual studio 2022. There seems to be a lot of issues with vs code integrating with unity in general
@gloomy chasm I've been getting more and more used to using UIToolkit now - I'm able to do a majority of what I could in IMGUI and then some (e.g. extra stylized functionality).
That is great to hear! Are you using USS properly?
Also, cool too see a BP implementation. From a UX and UI POV, it hurts a bit to look at. But still cool non the less!
YAY! 🎉
and I'll be releasing the exportsheet & exportselector attributes soon
USSOM is the only reason I'm able to do this reliably
They grow up so fast 🥹
I'm essentially creating and exporting the sheet whilst storing const/static variables in the class that the sheet and the object uses.
is it always great? no
but the reason I do it is mostly for color variables
that way I can just tweak on the go
You know uss supports variables right?
yeah and var() is missing from USSOM rn
but I'm using C# so I need the variables in C#
meaning I can use the same variables for C# and have them translate in USSOM. (C255 allows me to create UnityEngine.Color objects with RGB-255 values)
Kind of defeating the point of USS still.... I take back half of what I said!
well
I can use USS properly
and I know how to
I just have those in case I want to do quick changes
so I just scroll up to a script instead of opening a style sheet and making a change
You just chose to use it poorly. I don't think that is the glowing defense you think it is 😛
it depends on what I'm doing
there are things I can do in USSOM that would require some extra step(s) in USS
such as using UnityEngine.Color objects for values
What do you mean...?
I'm passing in a Unity Engine color value directly to the USS Object Model and it translates the value for me into rgb/rgba USS functions.
You can do element.style.backgroundColor = Color.white;
No, why would you need to have the values both in uss and C#
having them in C# (as the const/static variables) is so I can quickly change them for the USS exporter and have it appear when I load up unity.
having them in USS is the primary thing
So.... you have them in C# to basically 'fix a problem' that you created for your self...
Color32 exists you know 😛
yeah, I also plan to add it in as well
I found out a few days ago
and just have it on the things to do
I also don't really understand the need for the C# version of USS, is it just because you like having strict compilation?
not even that
I just didn't want to write native USS
so I could have everything in C# and work from one language alone.
but in the end, I learnt USS, some UXML and a lot of web-dev related stuff in the process
don't regret it though - I got a lot more out of it than I expected and learnt a lot more in the process
Still a terrible idea that will just add confusion for anyone else that ever looks at your project, and bloats the project more. But likewise you can still do you 😛
USSOM isn't even like mandatory to the project, it can be wholesale stripped out and removed
the USS style sheets being generated are important for the styles of the editor window
it's just a tool I made for preference of C#, nothing more and nothing less.
So you could almost.. idk... not use it. Or what if you just added a visual interface for it to do it in the editor!? Ooh some kind of builder, for UI!
because I could do that
but there's less educational value in it for me.
I don't learn if I just use everything that came from the factory (there are exceptions and what not)
I do it not because I think my way's better
I just do it because I want a challenge and I want to learn.
Fair enough, cool that you learned a bunch! But also, having the colors in the code still defeats the point of USS, also, no light theme support 😢
I'll add in stuff for light theme, for sure.
genuinely out of pure interest for what that would entail technically.
I don't think I'll be keeping them in the code though honestly
it's not even a permanent solution, I just have them there so I don't have to scroll to the bottom of the script
the only reason XML is there is because I've built in a habit of doing XML on anything and everything I create now.
Well, with uss it is super easy! At least the way I do it is just have all theme specific things in their own uss files. Basically just the color values. Then in C# I load the light or dark file depending on the current theme.
There might be a better way now to do it within the UXML, idk.
probably yeah
I need to explore UXML more
also I will add too
the only reason I'm doing BP is to do a visual scripter for IMGUI using UITK
out of just the genuine interests of
A) USS
B) Visual Scripting Logic and how you'd roughly create a visual scripting system for any game engine
C) How to execute a visual script
Wait wait, so you are writing a tool in UITK to write code for IMGUI? 😂
It'll already be not as performant unlike just native IMGUI or UITK
pretty much, yeah
and what I'm doing is
I'm making two tools at once.
a basic UE-Like graph toolkit
and then the Plugin creator on top of that as a separate class inheriting from it
it's funny in many ways and it's just a case of "can it be done, if so how cursed?"
Ahhh, now you are speaking my language. But my cursed is probably different than yours... But still!
yeah
I think some people will be under the assumption I don't know or care how bad this is (or could be) both from technical, logical and performance reasons.
Ehh, honestly, as long as you know what and why you are doing. It is all good!
true
I am fully aware of what I'm doing and why it's bad at least
had to research that beforehand.
All good then!
but I still wanted to do it because it's fun to learn both practically and theoretically
still the rabbit-hole of imgui-vs-rmgui will never cease to end
in terms of overall, it's case-dependent
in terms of unity, UITK (RMGUI) is preferred over IMGUI - except in the case of very simple controls
Indeed, I do stuff like that all of the time! Dove deep in to the internal View system to make sidebars! Just to see if I could.
Made a way to search bound IMGUI fields in any editor window. That one was cursed!
noice
plus the stuff we learn is transferrable to actual solutions for actual problems (overall, not saying that yours isn't an actual problem dw - just mine)
Ehh, sometimes less so than others xD
yep
USSOM i learnt more of the technical constraints of language translation / exporting, UI Design and the web-dev languages.
is it a better system than what Unity has, no.
I'd be dumb to think that. It's just a curio of sorts from curiosity and persistence.
I wonder if you've had any sort of tool project like that yourself, Mech
Where I made a system just for learning basically that had no practical benefit?
yeah
No, interest or motivation for me mostly comes from a use-case. If there is no use-case I have little interest/motivation to work on something
that's fair. I'm only lucky to have the chance to do these less-practical projects because I'm a student still
Just as long as you don't get too attached to those projects and realise that without a usecase you are procrastinating, that's totally fine
This is not what this channel is for, but you need to properly configure the !ide you use
If your IDE is not autocompleting code
or underlining errors, please configure it:
• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)
• VS Code*
• JetBrains Rider
• Other/None
*VS Code's debugger plugin is unsupported.
We recommend using VS or Rider instead.
If errors are underlined in red, it's working
is UItk's pixel size calculated based on screen aspect ratio already or not?
e.g vis.style.width = new Length(200);
I'm doing this manually currently myScreenRatio * 200 or should I not care about it? also this is for editor extension
Make sure it's generating csproj files for them in Unity's external tools preferences
When dealing with a custom property drawer that's inside a list, when I interact with an enum popup field, it thinks I want to reorder the list. What would be causing that?
Can you share the code? (Partially asking because I'm learning and would like to see an example of a custom drawer haha)
I wouldn't use my code as a foundation for your learning, I'm guessing everything myself 
Everything is an opportunity for learning
Hmmm what is the role of BeginProperty?
Isn't the field itself representative of the property?
Also, if I understand correctly I believe EditirGUI.PropertyField tries to automatically figure out what to do. Maybe they're related?
Yeah, it figures out what the property field is. I think the idea behind BeginProperty is if you want to group property fields, but I honestly have no idea on that. All I know is, what I have, causes major visual issues lol
Think of BeginProperty like this. If you have a prefab, everything within a Begin/EndProperty is treated like a single field, so it will all be overridden if you change one value.
Normally you use this for inline fields. Like Vector3 style field would use this.
This is just an item in a list that shows different fields depending on the type selected. How do I stop selecting an enum triggering the drag of the list item? It messes up everything.
Lowkey losing my cool, cannot find the answer anywhere and I'm unable to progress. Selecting an enum shouldn't initiate drag, furthermore, dragging list elements shouldn't cause them to forget everything.
It really seems like a unity bug when something like this happens all because of selecting an enum field
Hi, I am trying to switch mesh of my walls, it works but when I select multiple walls and press the update walls button it only changes one wall
`[CustomEditor(typeof(WallSwitcher)), CanEditMultipleObjects]
[ExecuteInEditMode]
public class WallSwitchEditor : Editor
{
WallSwitcher wall;
private void Awake()
{
wall = (WallSwitcher)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Update Walls"))
{
wall.SwitchWallMesh();
}
if (GUI.changed)
{
EditorUtility.SetDirty(wall);
}
}
}`
Try simplifying the setup. Just the field on its own, just the field in a single list, etc.
Because target is only the first select target. targets is what you want. Or you can just use SerializedObject and not have to worry about it at all since it supports it natively 🙂
ohh got it THANK YOU!
@gloomy chasm I simplified it more, it doesn't look as buggy due to less height mess but it is still the case where I click on the enum, and it's trying to drag despite not holding down click. Dragging, with the default behaviour and no custom stuff, is buggy in itself where elements will hide behind other elements so that's expected, it's just... I need it to not drag when I'm selecting a type.
This is the entire code:
public enum ConditionType { Variable, Quest };
public class ConditionalObject : ScriptableObject
{
public ConditionGroup[] conditionGroups;
[System.Serializable]
public class ConditionGroup
{
public ConditionType type;
}
[CustomPropertyDrawer(typeof(ConditionalNodeObject.ConditionGroup))]
public class ConditionGroupDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
Rect typeRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(typeRect, property.FindPropertyRelative("type"));
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
}
}
can you get rid of the begin and end property stuff
I don't think it's relevant in property drawers afaik
I have tried removing it, makes zero difference to the end result in my experience
What version are you on? It sounds like it might be a bug
2022.2.14f1, tried it in 2023.1.0b11 with the same result. The issue does not occur with 2021.3.22f1, unrelated stuffs have issues but the property drawer works flawlessly
Update: Doesn't occur with 2022.1.24f1 and 2023.2.0a9 so I guess either it was fixed unintentionally for the latter, or intentionally but wasnt applied to 2022.2 or 2023.1. I did submit a bug report just in case detailing this.
does anyone know any way of getting path to "Unity Editor" and not the "Project"
I need this to generate a .gitconfig file with a path to "Editor\Data\Tools\UnityYAMLMerge.exe"
Is that unity's git merge conflict resolving tool?
Ah. I would assume you can just use the full path
Are you unsure of where it's located in your file system?
no no no I know where it is and i have setup my github to use it
[mergetool "unityyamlmerge"]
trustExitCode = false
keepBackup = false
# Replace path with path to your Unity version!
cmd = 'E:/Unity Editors/2021.3.16f1/Editor/Data/Tools/UnityYAMLMerge.exe' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"
problem being this path is absolute
so every person on my team that wants to use my repo needs to change the path
I was thinking about making an editor script that changes the path automatically
Ohhhh and you want to know how to reference it through PATH so you can just say "unitymerge.exe" or whatever it is, yes?
Or at least to avoid having to specify things like version number?
what I am thinking about is having a static editor class that changes the ".gitconfig" file that is in the root of my repo and unity project with "InitializeOnLoadMethod" attribute
that is simple C# stuff
problem is one of the things that I need to set in the file is the path to the Unity Editor tool
"UnityEditor.AssetDatabase" and other classes like that seem to only be able to get info for the current project
and not the actual Editor itself
@green current
So are you trying to set it up so that every unity project works this way? Every project on your system? Or just this one project?
my project is on gogs (self hosted git) and I want everyone who downloads the project to have the stuff set up for them automatically
So... I have custom window that relies on selected game object in scene.
When I start PlayMode that object instance seems to be destroyed and my custom window breaks.
So the question is how can I get new instance of that object in playmode?
I tried hooking into EditorApplication.playModeStateChanged and reading Selection.activeObject from here. But it seems like it's still pointing to dead reference
thus I get errors about accessing destroyed gameObject property on monob
Possibly a stupid question but:
https://docs.unity3d.com/ScriptReference/SerializedObject.Update.html
Does this:
- copy the serialized data from the actual object into the SerializedObject wrapper?
or - copy the serialized data from the SerializedObject wrapper into the actual object?
How would I make a custom button show underneath the "Add Component" button? Image for reference, I want it to be like the "Generate Component" button
Hook in to Selection.onSelectionChanged. Should do.
Updates the SerializedObject's data to match the UnityEngine.Object's data. ApplyModifiedProperties goes the other way, updating the UnityEngine.Object's data to match the SerializedObject's data.
Update = Object data -> Serialized data
Apply = Serialized data -> Object data.
You basically will want to get all inspector windows. Get when the target(s) of each window changes, when that happens, you query the VisualElement that contains the Add Component button element, and add your own button there.
Overall, it is a bit of a pain, requires a bit of reflection, and some knowledge of UIToolkit.
thank you!
thank you
- I struggle to find any article on how to make clickable scene areas. For example, the tilemap grid that allows you to place tiles in it, without either gizmos or selectable objects on them. Is there any article, manual etc. on how to achieve anything similar to this?
Not quite sure I understand what you are wanting. But if it isn't done with Handles, then probably just using IMGUI in the draw scene callback
- Idk whether it's handles or not tbh. Should i go with my specific context maybe to make it clearer?
Is it possible to edit tilemaps somehow in a scriptable object? Trying to make templates I can paste onto my tile map
I'm creating a object field with EditorGUILayout.ObjectField(). How can I determine which object field is currently focused in the inspector so I can draw additional gui depending on that selection
How can I check if a Prefab is currently open in the Prefab editor view?
@gloomy chasm how can we use DropDownMenu on runtime (uitk)? and sorry for the ping 😃
I'm looking for an easy way to make nested menus like in DropDownMenu
Runtime? #🧰┃ui-toolkit
Also https://docs.unity3d.com/ScriptReference/UIElements.DropdownMenu.html
idk what you are asking haha
it is, but how can I use it? I'm using it with ToolbarMenu all this time, but don't know how to use it WITHOUT toolbarmenu due to it editor only
also dropdownmenu is not visualElement so can't just use it as is, by that I mean we can't just add it as a child of visualelement
Taking a look at the source code. All it is is literally just a list basically. Looks like EnumField uses GenericDropdownMenu. Doesn't even use DropDownMenu.
So basically. At runtime, you use GenericDropdownMenu
Aight, looking into it now 👍 .. thanks!
@gloomy chasm also found this just now 😂 -> https://github.com/fabSchneider/fab.uitk-runtime-dropdown
it uses DropDownMenu
That is old. Use GenericDropdownMenu it does literally that.
At least somewhat
aight, doing it now 👍
@gloomy chasm just fyi 🤣 https://forum.unity.com/threads/ui-toolkit-accumulating-extra-millions-of-extra-vertices-to-render-when-objects-made-hidden-visible.1273028/
in my case moving a visualelement will make vertices count jump to 120k... what an insane bug
You use StartNameEditingIfProjectBrowserExists.
You can look at the implementation of something lie creating a folder to see how to use it https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/ProjectWindow/ProjectWindowUtil.cs#L309
any of you know how to use Experimental.GraphView.Resizer?
It doesn't seem there's any documentation on Resizer - just it's members?
looks like you aren't even supposed to use it - just found that adding a resizableelement works and modify that with UnityStyleSheets instead
doing some hacky behaviour (for better or worse) allowed me to forcibly do group resizing with Resizable element without it breaking everything.
Nice theme!
What are your guys' opinion on having custom editors in separate files vs having them in the same file as the component they are attaching to?
Same file bloats the project and can sometimes make it hard to find the custom editor, which is prevented by placing it in the same file but then you have to add a bunch of pre-processor directives..
someone asked about polymorphic SerializeReference in another chat and was directed to bring it up here
there are several tools that can help with this
I use Animancer, and it comes with a little polymorphic drawer of its own https://kybernetik.com.au/animancer/docs/manual/other/polymorphic/
Guys i used a property drawer on a collection and when i change an element all the others elements keeps the same modification, is there a way to fix this ?
Don't have them in the same file.
Your project won't compile if you do.
you'll be splicing run-time code with editor-only code and it'll cause numerous errors in the console
learnt the hard way last year, just before my first team's project cause I did that mistake with my first plugin :)
That's what the pre-processor directives are for ;)
you have to keep them in separate scripts
and that's what you call a dumb idea
keep them separate anyway
#if UNITY_EDITOR
[CustomEditor(typeof(ShrinkingPlayableAreaManager))]
public class ShrinkingPlayableAreaManagerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var manager = (ShrinkingPlayableAreaManager)target;
if (GUILayout.Button("Initialize"))
{
manager.Initialize();
}
}
}
#endif
}
Main reason is legibility
other reason is so you can modify both easily without having to scroll forever based on scale
That's true
also if you do IMGUI you should really get used to structuring your editors too
so many people complained about it in the circles I knew
turns out they just do one or two scripts
not proper panel/context-based structures
can you elaborate?
The way I do IMGUI editors is
you have the initial opening panel that contains the editor window creation and opening process, with the main OnGUI call
then you have "Panels" which have their own structures, all with one exactly the same "PanelName.Draw()"
ahh, okay, I see
that way you're splitting context apart and you're making it easier to edit the sections you're working on
oh yeah, I wound up doing exactly that for one game
because I realized I couldn't get the different panels to play nice with each other if they weren't all drawn in one big go
you don't do it in all one big go really
you only draw the panel you need
and you track the state of the overall editor
I am not making very fancy editors though as you can see x) It's just a button which calls a function that would normally be triggered by an event
which is a pain to test bugs with sometimes if you're constantly changing the scripts because of editor window refreshing
still, probably better to get it separated anyway
all you really need to do is create a folder called Editor in the location of the main script
and create a new script in that
that way it doesn't compile nor will have any chance to.
Editor folders littered everywhere
that's why I generally just stick to one main one in the assets personally
and have sub folders in that for each plugin I'm working on
more specifically
it's Editor/Plugins/pluginNameHere
that way I keep the editors in one place and everyone on my team projects knows "oh okay this is neopolitan's work, best not mess with it"
so even if they mess up the main object classes, they can't mess up the editors anywhere near as easily without my approval first
there'll always be others who prefer it another way
or would tell you to do UIToolkit
preprocessor directives is a solution to the problem but even if it shouldn't compile, I wouldn't take that chance.
Unity pretty much tells us that anything in a folder labelled Editor isn't being packaged with the main game files
Gotcha
I wish you luck though
oh right, i should add that this was just an OnGUI() thing lol
i mixed that up with IMGUI
even though it is an immediate-mode GUI
just not that immediate-mode GUI
Hey, specific help here with custom editors. How can I access the drawing method for drawing these fields in this array? Basically I want to hide one of the fields when the enum is set to something specific. Where should I create a custom editor?
You create a PropertyDrawer for veryLittleThing, you will have to manually draw each of the fields.
Alright I'll research property drawers thanks :)
Oh this actually works this is so cool, SerializedProperty.enumValueIndex is really useful for checking what the enum is
thank so much!
actually one thing, this is looking pretty scuffed, I just made the rect for the other variable have lower y position, but it's not changing the bounds of the array, how to fix?
less confusing, it looks like this with 1 element
Hello. What is the proper way to update something during edit mode
currently I use ondrawgizmos for updating everything
If you need an Editor Update loop you can subscribe to EditorApplication.update. I would also suggest to use custom editors instead of doing editor only stuff in a MonoBehaviour. It really depends on the context of the things you want to update.
I tried that but the issue was that it does only Update when I move the mouse/interact
EditorApplication.update will always fire. It is not bound to any interaction, maybe you are confusing it with OnSceneGUI?
tried it now it seems to work fine now. Weird I could remember that I had this issue times ago.
does anyone know why the element doesn't change height to match the fields? (making a property drawer)
I think involving EditorGUI.GetPropertyHeight() might do the trick for you, read up on the usage here: https://forum.unity.com/threads/custom-property-drawer-height-and-width-solved.469692/ . However, I'm not entirely sure if this is correctly respected in ReorderableLists.
Hi everyone, I was wondering how do we get the exact rect of the inspector / custom editor class? I've seen online for EditorWindows people can use "position" however I can't seem to find anything that difinativly gives me exactly the editors bounds all the time.
The best I have found is doing this:
Rect editorRect = GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
However this does give me what I assume is the correct bounds, it also for some reason gives me a rect of (0, 0, 1, 1), alternating between a correct and incorrect value.
Is there a better way to do this?
I also was wondering as a second question whether or not IMGUI would be useable with assets for the asset store, I am trying to rewrite the editor for some scriptable objects so that they are more userfriendly and I keep coming across people using IMGUI instead of just the base inspector. Right now I don't know another about IMGUI to be able to tell if its worth looking into as a solution to all my issues with this, however I figure it would be worth knowing at the start if I can even package this with the asset (both functionally and legally since its someone else's code).
Here is a sneaky way to do it 
public override void OnInspectorGUI() {
EditorGUILayout.BeginVertical();
base.OnInspectorGUI();
EditorGUILayout.EndVertical();
Rect editorRect = GUILayoutUtility.GetLastRect();
// make sure we don't operate on any other events then actual drawing if we want to retrieve the rect size
if (Event.current.type == EventType.Repaint) {
Debug.Log(editorRect);
}
}
Brilliant thank you, with the event.repaint does OnInspectorGUI get called from other events? If so if I am trying to do somethign that will register button clicks do I need to make sure to only check handles on an EventType of mouse down? or does that not matter?
OnInspectorGUI is called consecutively with multiple event types AFAIK. So yes, for special kinds of operations where you want to listen to mouse clicks you can use EventType.MouseDown in that method. However, finding out which elements were clicked is far more sophisticated. This article might help you out to gain a deeper understanding of what is happening in the IMGUI draw methods: https://blog.unity.com/technology/going-deep-with-imgui-and-editor-customization
(Of course for simple button interaction you can use GUILayout.Button and be done with it immediately, but I guess you are after more complex stuff :D)
I'm wanting to look into handles right now, and have gotten it to the point where I am rendering them ontop of a PreviewRenderUtility, though I can't get any interaction from them. So currently trying to debug that at the moment, Dx
The only thing online I have found said that I'd need to add an offset ot the mouses position based on the whole inspectors rects lower left edge, to the previews rects left edge. Not sure if that would work but thats why I was asking about the rect xD
Thank you though ^-^
idk where to ask this but my rigidbodys information isnt showing up
i remember it used to tell u the velocity and stuff
If you want to see the extra info you need to set you inspector to Debug mode
You can do that at do that by pressing the 3 dots at the top, next to the padlock of the inspector
that doesnt show me the velocity
idk what made it disappear i was able to see it a couple of days ago
i can see it on another project
wait i think its got to do with the editor version
Ah, hmm. Maybe then. I didn't know there was a difference between versions. Is upgrading fine for you?
If not you can always write as script that just outputs the velocity as a field.
its downgrading actually
i use the 2022 version but it wasnt showing up so i tried 2020 and it worked
So im trying to write my custom editor script.
but when using EditorGUILayout.BeginFoldoutHeaderGroup() im not getting any arrow to the left of it in the inspector.
public override void OnInspectorGUI()
{
serializedObject.Update();
physicalFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(physicalFoldout, "Physical Properties", EditorStyles.boldLabel);
if (physicalFoldout)
{
hitBoxRadiusProp.floatValue = EditorGUILayout.Slider("Hitbox radius", hitBoxRadiusProp.floatValue, 1f, 20f);
attackRangeProp.floatValue = EditorGUILayout.Slider("Attack range", attackRangeProp.floatValue, 1f, 20f);
}
EditorGUILayout.EndFoldoutHeaderGroup();
statsFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(statsFoldout, "Stats", EditorStyles.boldLabel);
if(statsFoldout)
{
factionProp.enumValueIndex = (int)(Unit.Faction)EditorGUILayout.EnumPopup("Faction", (Unit.Faction)factionProp.enumValueIndex);
roleProp.enumValueIndex = (int)(Unit.Role)EditorGUILayout.EnumPopup("Role", (Unit.Role)roleProp.enumValueIndex);
EditorGUILayout.PropertyField(maxHitPointsProp);
EditorGUILayout.PropertyField(attackDamageProp);
attackSpeedProp.floatValue = EditorGUILayout.Slider("Attack Speed", attackSpeedProp.floatValue, 1f, 10f);
threatMultiplierProp.floatValue = EditorGUILayout.Slider("Threat Multiplier", threatMultiplierProp.floatValue, 1f, 10f);
}
EditorGUILayout.EndFoldoutHeaderGroup();
EditorGUILayout.PropertyField(spellBookProp);
}
message was too long, so i had to remove the first foldoutgroup, but theres no change to the code
also, my sliders dont seem to work during runtime
I have a question regarding the updating of a property drawer. I have a group box and want to update the contents of it based on a bool. I have a callback on the toggle, which seems to be getting called. The issue I have is with how to redo the the contents.
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var root = new VisualElement();
var label = new Label(property.name);
root.Add(label);
DrawGroupBox();
root.Add(new Label("after box"));
return root;
void DrawGroupBox()
{
//_groupBox.Clear();
var constantBoolProp = property.FindPropertyRelative("useConstant");
var constantBoolField = new PropertyField(constantBoolProp);
constantBoolField.RegisterCallback<ChangeEvent<bool>>(evt => DrawGroupBox());
_groupBox.Add(constantBoolField);
if (constantBoolProp.boolValue)
{
var constantVal = new PropertyField(property.FindPropertyRelative("constantValue"));
_groupBox.Add(constantVal);
}
else
{
_groupBox.Add(new PropertyField(property.FindPropertyRelative("variable")));
}
root.Add(_groupBox);
}
}```
The following is happening: the commented groupBox.Clear(), if I uncomment it, it never shows anything. Not quite sure why if I add stuff after the clear.
If commented, it *does* show, but still doesn't update properly. if the bool goes from false to true, it seems to do something, but not the correct thing: now shows the groupbox after the second label ("after box"). if it goes from true to false, nothing seems to be happening
I'm sure it's something basic I'm missing here
Ah one of the issues was a mistake on my part, the root.add(groupbox) shouldn't be inside the method. Now it just doesn't do anything, although the event gets called 100%
Nvm I switched to hiding it by changing the style.display
Hey ppl, I have a PropertyDrawer for a tag list (array of strings) but I want the UI to allow the user to insert the tags as comma separated values and save/parse when they FocusOut of the text area. I've made functions to convert the csv to array and the other way around and they work perfectly. But I need to keep the state of the text areas and the current focus control name.
If I keep them on the PropertyDrawer as class variables it works exactly as I want for one object, but of course, Unity reuses the instance of the drawer for all other objects.
I don't want to store the values of the text area or the control name on my actual object.
What could I do?
I even thought of creating a dictionary and use the hash of the object as a key to store the values for all objects.... but seems silly.....
or maybe not...
You just need it stored until you press enter or lose focus, yes?
yep
I tried the Dictionaries.... they work perfectly... it still feels a bit wrong for some reason.
What do you think @gloomy chasm?
Just use a delay field then?
And if that wasn't a thing. All you do is have a string field, before drawing the TextField, you would check if it is null, if so you set it to be the property string value. You give the TextField this string field. Then on Enter or lost focus, you set the property string value to the string field, and set the string field to null.
Thank you so much @gloomy chasm
You're very welcome! 😄
Let me know if I ever have a chance of hiring you 😉
has anyone been able to drive the "Font Asset Creation Tool" all from scripting
You have to use reflection
as long as it works that is fine
more or less wanting to rebuild font atlases based on custom character sets derived from the loc system
helps keep atlas size down for asian languages since a lot of glyps are often not used
Now, this is just from residual memory, so idk how helpful it will be. But I feel I remember you had to use the FontImporter, and maybe even have to get a pointer to the c++ object to access some of the fields that are not even exposed to C#.
But I would start by looking at the source for the FontImporter
yeah it looks fairly exposed since TMP stuff is all just in a package and a asmdef
gross the part that does the work is not even its own function
its just inline with the other ongui stuff
though looks like i can easily get it to popup the window and edit all the fields to be correct
who donst live a good thousand line long function that mixes ui drawing code with functionality
atleast got it auto populating all the fields of it as needed
Oh that is gross...
like i think i am one of the few people that does not mind imgui, but i also never put in piles of logic to do the work just in the condition for drawing a button
LOL, I don't hate IMGUI. And for doing small or quick things, it is still really great! The real trouble comes when you want to do more complex layouts, or styling. The difficulty and complexity goes up real fast then.
I have a serializeable class that has a MyBaseClass property, and this base class have two child classes (all serializeable). In a custom editor script I'm attempting to use PropertyField or ObjectField to get this property to display correctly, but I get the error: type is not a supported pptr value
Anyone know what I'm doing wrong?
Sounds like there's something about the type that makes it not serializable. Can't really know what it is without seeing it.
It's pretty simple so I'm not sure. The base class have no content. Each child class has one field, the type of which is derived from ScriptableObject. SerializeField is used for the fields.
It sounds like you want the base class to serialize the child classes? If that's the case, you don't need to nest them in the base class. You just need fields for the types.
You can nest them, but it doesn't affect serialization.
I had an idea to be able to select a child class from the editor
Then you need SerializeReference and a custom editor to choose the type.
SerializeReference lets you define a field of a base type and assign derived types to it.
Thanks, I'll look into that!
What do you mean inspector attributes?
when setting an object field to "None", it still shows the last selected object until the inspector refreshes. Do I need a callback and refresh it manually?
You want to override what draws for the Range attribute?
Sounds like you’ll have to parse the file then if(attribute) draw a slider
I don’t know enough about that kind of stuff though so i may be wrong
Ohh. EditorGUILayour.Slider or EditorGUI.Slider
There’s a bunch of different methods
I think one of them
is you might have to use reflection to create attributes that add inspector elements like that
I use a translator to Common Intermediate Language for C# that allows me to tell when methods are called on startup that are internal-use only.
one thing I'm finding issue with right now is data persistence with UI Elements
I've gotten IMGUI technically working with UIE blueprinting but it's not supposed to work and I can already tell it won't work later down the line with global variables and port-to-port pass through.
for one frame, the Execute function in the first node successfully gets the "true" value from the boolean port
but after that, it won't update the condition because the data held in the port is null.
how would I keep the state of each port/visual element persistent for IMGUI without it resetting after one read? (it won't visually reset because the condition in the main execute port doesn't reset if the object value in the data port is null)
I did manage to find a work around for that for now, by "resolving" the port's value based on whether or not it has a connection as the first step during a node's execution. If it doesn't then it'll stick to whatever's there (based on the entry field), if it does - it'll get the value.
and it worked at least
What do you mean data persistence? You shouldn't be trying to persist data of the elements...?
well I need to have a bool output port link to a bool input port and pass the data through (and similar for any data type output to input)
I found a way to do it though
No you don't. You need a output port bound to a bool value and a input port bound to another bool value 😛
that's how it works
I just need the bool value to be transferred or to work with a global variable.
Each node only runs through an Execute() function
no pass-in params, resolves the values and operates off of them.
What I mean is, UITK should not be handling the transfer. That should all be done on your model/viewmodel
ah, I thought the model was part of UITK because it was UITK-based.
Yeah exactly
the only weird persistence issue I have is
if an input port has a field assigned to it, although that field is assigned to the Execute() func will never be able to read it more than once
and it'll read as null for every subsequent read, unless it has a connection to another port
the way I get around that is just never resetting the value of the node's condition (in case of the branch node) and having it operate on the last known value - it updates whenever that value changes but reading the input port's value again* will be null every subsequent read
mb though @ thinking the model was part of the UITK
Idk what your setup is @earnest talon . Only thinking about it briefly, but the way I would approach a BP like visual scripting thing is like this.
Have a base node with an void Execute() method, and two lists of a custom NodeProperty class, one for inputs and one for outputs. More on that later.
For things like branch nodes, for loop nodes, etc. You inherit from the base node, and implement the logic in the Execute. Adding things to the two lists as needed.
For other types of nodes, you use reflection to get the methods, and invoke them in the Execute method, you populate the two lists from the params of the methodinfo.
About NodeProperty, that would also be a base class with two-ish implementations. One for manual setup where it stores the value, and one for reflection where it gets/sets the value.
The base class would contain things like linked nodes/properties, maybe parent node, etc.
For UITK, you can basically just have a single node class. For each node in the graph, you would create a UITK node. You populate the ports by getting the values of the two lists. And thats it.
Again this is only thinking about it for a couple of minutes, so there are probably things I didn't think of or better ways to do it. But, that is the basic idea.
That is pretty similar to how I do it
the only difference being the properties and reflection
the only things extra I'm tracking are the execute ports*
that way execute goes to the next method afterward, if there is a connection to the port.
I've been doing some testing with what I've gotten so far and i knew it would be inefficient compared to IMGUI done raw
but I'm surprised at how efficient IMGUI already was aside from the visual scripting gimmick thing I'm doing
RAW IMGUI LOW - 126 ticks / 12,600 nanoseconds / 0.0126 miliseconds
RAW IMGUI HIGH - 1927 ticks / 192,700 nanoseconds / 0.1927 miliseconds
VIS IMGUI LOW - 3896 ticks / 389,600 nanoseconds / 0.3896 miliseconds
VIS IMGUI HIGH - 10249 ticks / 1,024,900 nanoseconds / 1.0249 miliseconds```
those are just the low/high values I found in a brief window
the lowest so far has been 67 on RAW IMGUI
3896 still on VIS IMGUI
a lot of that processing power is probably going towards resolving the port connections
out of curiosity, how much overhead should a visual scripting system generate on top of the raw methods?
I need something as a baseline to at least aim for efficiency-wise.
I understand what those numbers are. Do you mean for drawing the graph UI? Or...?
for the overall OnGUI method itself
meaning resolving each port connection per node
and executing it
Oh right, this is a IMGUI creator thing
getting info from ports
setting info to ports
and yea
a lot of the overhead is generated from the per-node port connection iterations.
the ports themselves have data passed in and out of them
oh wait
that's not execute
the first one isn't really necessary, I can remove that
is there a reason that is not just if (p is Dataport port)?
oh I didn't know about that
thank you
those two changes immediately took the overhead down
(removing direction is not direction.input, as that's only called if the node is an input node & if p is dataport port)
9736 was the highest recorded for Vis IMGUI but that was the very first frame which was odd itself
but it's now at
RAW IMGUI HIGH - 1729 ticks / 172900 nanoseconds / 0.1729 miliseconds
RAW IMGUI FIRST-FRAME - 122 ticks / 12200 nanoseconds / 0.0122 miliseconds
VIS IMGUI LOW - 114 ticks / 11400 nanoseconds / 0.0114 miliseconds
VIS IMGUI HIGH - 1617 ticks / 161700 nanoseconds / 0.1617 miliseconds
VIS IMGUI FIRST-FRAME - 9736 ticks / 973600 nanoseconds / 0.9736 miliseconds
still a fair lot worse overhead
but a lot less than it was
it's averaging around 200-900 ticks / 20000 ns -> 90000 ns / 0.02 ms -> 0.09ms
imgui's averaging around 80-1600 ticks - which is weird
they're pretty much neck and neck though (when all options are ticked/highlighted) but I'll need to test it on more systems
I'll have to snoop around and see what other issues I've got
I'm trying to make a property field that's linked to value inside a scriptable object, is that possible?
This is what I have and it's currently not working
var variableRef = new SerializedObject(variable.objectReferenceValue); // references scriptable object
var variableRefProp = variableRef.FindPropertyOrFail("value");
Debug.Log(variableRefProp.floatValue); // shows correct value
var variableFieldValue = new PropertyField(variableRefProp, "Value"); // doesn't work/show```
You will still have to call
Bind()on thePropertyFieldafterwards.
You have to bind theSerializedObjectto the field
Oh thanks, now it works perfectly 👍
i must be missing something. _Chance.floatValue = EditorGUI.Slider(chance_Rect, new GUIContent("Chance"), _Chance.floatValue, 0, 100); does not let me change the actual value of the slider. anyone knows why?
could it be an issue that im trying to make a propertydrawer for a struct and that is causing it to not be editable?
This looks fine. Where is this used?
this is the script. and its type is a struct
Well, you choice in naming convention aside. Instead of passing in the value and getting it back, try just pass it the property.
yeah im aware my naming isnt great, just trying to get it to work 
EditorGUI.Slider(chancePosition, _Chance, 0, 100, "Chance");
that didnt really change anything
Also, is the issue that it simply won't slide at all? Also, are you looking at it in a custom inspector? If so, make a new component that just has a single field of LootPoolRarity so you can check there with knowledge that there is no chance of anything else affecting the value
yeah, i cant grab the slider or open the window to select an object for the field. im looking at it in the inspector through another script like this
public class LootPool_ScriptableObject : ScriptableObject
{
public LootPoolRarity Rarities;
}
Does it have a custom editor?
no it does not, should it?
I was just checking if you might have other code that is affecting it.
ooh
I know
ya gotta override the GetPropertyHeight method
right, that is true, i completely forgot that was a thing
it defaults to just a single line height. So that is why the first field works and can receive input, but non of the others can.
thank you, now it works just fine 
hey i want to work on a project with a friend, and basically share the files between our computers. Saw that unity collaborators was depricated. and the new version you gotta pay for, which are not my intentions. Github is not possible either since the files ar eover 100mb. Anyone ideas on other free(!!!) solutions?
There is no free way to host a large repo.
we worked it out (it was a missing .gitignore (also, this was the wrong chat))
I want to display all child properties of of my object reference in editor, but despite there should be one int and one string, there is nothing.
// Create a VisualElement for each behaviour
for (int i = 0; i < _behavioursProperty.arraySize; i++)
{
var behaviour = new SerializedObject(_behavioursProperty.GetArrayElementAtIndex(i).objectReferenceValue);
var childProperty = behaviour.GetIterator();
var behaviourElement = new VisualElement();
while (childProperty.NextVisible(true))
{
var p = new PropertyField(childProperty);
behaviourElement.Add(p);
}
root.Add(behaviourElement);
}
_behaviours is a list of abstract type, maybe that is the problem idk... I have done this already with IMGUI and it being abstract wasnt an issue, but maybe this new UI doesnt like polimorphism as much? Anyone knows something about this?
You need to call Bind to get property fields to build in UIToolkit
It's called by default in some scenarios, but if you're using your own SerializedObject I think that's not going to be the case
oh really? I thought it is used only to... well... Bind a property, not display it
ill check that!
oh wait... but this way I dont know how to get paths for these properties...
I dont know them in advance.
_behaviours holds an abstract type not without a reason
I don't think you need to use paths, you just call Bind() on your behaviourElement with your behaviour SO
RIGHT! I totally forgot it is an option... Im still very new to UI Toolkit. Thanks, that solved the problem
var foldCont = new PropertyField(childProperty);
foldSpace.Add(foldCont);
foldCont.BindProperty(childProperty);
var x = foldSpace.Q(className: "unity-object-field-display");
Debug.Log(x);
Now i have something I cant find explanation for. Instead off adding whole property visual element I want only to add this object display nested somewhere inside, but no matter what way I try to access it, its always null.
I tried everything that came to my mind, but its always null. I tried even add this property element and then query its parent to get to this object display, but the same happens
Bind does not build things immediately, it's complicated
you would have to register events to try to detect when it's created
ohhhhhh great... it is so unintuitive XD
omg that ui toolkit drives me crazy XD
now uss is messing with me
.transition{
margin-top: 30px;
}
.transition > .unity-object-field__selector{
display: none;
}
.transition > Image{
display: none;
}
.transition > .unity-base-field__input{
border-width: 0px;
background-color: var(--unity-colors-window-background);
}
.transition are property fields, and this top one works, but everything below it does not
i cant modify anything nested in this visual element -,-
Hi everyone... I'm trying to create and store a ScriptableObject with some bools and floats when my custom editor detects that there is no available configuration file. For that I wrote this constructor, and added the attributes required to the class:
static ConfigEditor()
{
int count = AdvancedBuildSettings.GetSettingsFiles(out List<string> results);
if (count == 0) {
Debug.LogWarning("ADVANCEDBUILDSETTINGS: Did not find a configuration, adding a new one for you in the Assets/ folder...");
/* Line 21 */ AssetDatabase.CreateAsset(CreateInstance<Config>(), "Assets/AdvancedBuildConfig.asset");
AssetDatabase.SaveAssets();
} else if (count > 1) {
Debug.LogWarning("ADVANCEDBUILDSETTINGS: Multiple Configurations found, this can lead to unexpected behaviour. Please remove them. A list follows:");
foreach(string result in results) {
Debug.LogWarning("ADVANCEDBUILDSETTINGS: " + result);
}
}
}
When I now create a .unitypackage and drag it into another project I get this error, but the file above (hardcoded for testing) gets created. After restarting the Editor, the asset is usable just fine.
Unable to import newly created asset : Assets/AdvancedBuildConfig.asset
UnityEngine.StackTraceUtility:ExtractStackTrace ()
ConfigEditor:.cctor () (at ConfigEditor.cs:21)
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes (System.Type[])
UnityEngine.UnityException: Creating asset at path Assets/AdvancedBuildConfig.asset failed.
at (wrapper managed-to-native) UnityEditor.AssetDatabase.CreateAsset(UnityEngine.Object,string)
at ConfigEditor..cctor () [0x0001f] in ConfigEditor.cs:21
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadAttributes (System.Type[]) (at /home/bokken/build/output/unity/unity/Editor/Mono/EditorAssemblies.cs:149)
I have no clue what I'm missing here, and tried a couple of different approaches.
My guess would be that it is doing that because it is trying to create an asset while it is still finishing importing assets. And really, it is pretty bad practice to always force create an asset like you are doing. It is better to do it either when the user asks to, or once something actually requires it.
Well, it's filled with information about the build configuration that's required in the next step, so I'm kinda stuck with that. I was hoping to get some portability into different projects with it (set up once, use often), and save myself tinkering with jsons.
But thanks for the feedback, maybe I'll go through a setup screen of sorts.
Is it only used when/right before building?
Are the settings only used in the editor? If so and you only need one. Then you could use a ScriptableSingleton.
It basically stores the original build information here, allowing you to configure different settings for different Host OS and Build Targets. (i.e. When on Windows Host, build IL2CPP for Windows Targets, when on Linux Host regenereate .sln file and build IL2CPP).
It allows you to configure a set of build options for different buildservers, basically. But I have to "reset" to the original ones after building in batchmode locally.
It's really targeted towards CI Pipelines with Gitlab and sorts.
Oh, yeah then a ScriptableSingleton should work great for you!
thanks, I'll check the docs 😉
I'm more of the backend guy, so I don't do a lot with editor and scriptables 😉
Somewhat related. This might be of interest to you as well if you want to show the settings in the Project Settings window. https://docs.unity3d.com/ScriptReference/SettingsProvider.html
Well, it is mostly backend, so you should be fine. All it is is a singleton that saves it state in the editor without having to be an asset.
well, that made quick work of it. thanks for helping out.
Okay, did have to revert back to not using singletons, as there actually is a valid use case for storing multiple configurations. Aside from that: This little tool just out 5 of our unity projects through our gitlab pipelines, and instead of them being mono builds, they are all il2cpp builds for win/mac/linux respectively, and also pipe their data into sonarqube from build server instead of the developers server. All while the devs can continue to use the mono target while developing if they so choose to.
Now to polish and put it in the asset store for the probably 5 people in the world that need this 😉
I have a problem for which i found also a thread on a forum, but unfortunatelly without an answer, tho it is I would say a very basic problem...
https://forum.unity.com/threads/repaint-a-whole-inpector-windows.740576/
Overall its about repainting editor window for inspected element in a custom editor while using UI toolkit. Repaint() just doesnt work, and MarkDirtyRepaint() also doesnt fit into this scenerio :/
Why do you need to repaint it? If you are using binding fields it should automatically update.
then it is logical to assume that I dont
the problem is when I add or remove behaviour from my SO
So you add a behaviour, and..? What do you expect to happen and what does happen and where?
var dropdownMenu = new GenericDropdownMenu();
var types = System.AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => typeof(FSMCBehaviour).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface);
foreach (var type in types)
{
dropdownMenu.AddItem(type.Name, false, () => AddBehaviourOfType(type));
}
var addButton = new Button(()=>dropdownMenu.DropDown(root.worldBound, root, true)) { text = "Add Behaviour" };
root.Add(addButton);
private void AddBehaviourOfType(System.Type type)
{
var behaviour = ScriptableObject.CreateInstance(type) as FSMCBehaviour;
behaviour.hideFlags = HideFlags.HideInHierarchy;
AssetDatabase.AddObjectToAsset(behaviour, serializedObject.targetObject);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(behaviour));
_behavioursProperty.arraySize++;
_behavioursProperty.GetArrayElementAtIndex(_behavioursProperty.arraySize - 1).objectReferenceValue = behaviour;
serializedObject.ApplyModifiedProperties();
}
instance of some SO is created and added to a list of behaviours
but every behaviour is simply a foldout with some additional logic and then iterating through all of its properties, which are binded to SO fields
but SO (behaviour) itslef isnt binded to anything
Ahh, but then you don't see it in the inspector for your FSMC State, correct? I assume you are manually creating each of the elements for the behaviours in the OnCreateInspector method.
correct
i finally found some workaround. Basically i dont put everything in root visual element, but i make aother container in it, and then put everything in it. When I need to repaint inspector I just call root.Clear() and populate with newly generated container. It makes the job done, but let's say that you can see in the editor that Clear() was called XD
repaint sorta useless in uitk
Right-o, that is expected. What you need to do is to create a element that inherits from BindableElement, and bind it to the list. When the value changes, you can then add/remove the behaviour elements
you can force it to reconstruct the whole hierarchy
private void TryForceRefresh(VisualElement container)
{
container.schedule.Execute(() =>
{
var fakeOldRect = Rect.zero;
var fakeNewRect = container.layout;
using var evt = GeometryChangedEvent.GetPooled(fakeOldRect, fakeNewRect);
evt.target = container;
container.SendEvent(evt);
});
}
Yeah i thought about that and propably in a long run i will do so. Just needed a fast solution for now
No, don't do that. That is not the way you are meant to handle this sort of thing 😟
agreed, avoid it if you can 😂
naaaah... im using MarkDirtyRepaint() all the time, it is usefull 😄
"No, don't do that. That is not the way you are meant to handle" things in UITk 😧
depends what you are using UI Toolkit for 😄
That is just a graph view. Cool, but does not make it an exception 😛
those arrows are not native to edges in graph view
Yeah, I know.
Doesn't change anything about using Repaint in UITk
(Not that you should never use it. Just the vast majority of the time it is the wrong answer)
well in this case the geometry changes everytime edge moves, so this arrow needs to be re-rendered every time user drags the edge
How are you drawing the arrow?
ofc, repainting like every frame would be stupid for sure XD
but yeah, there are cases when UIT related stuff need to be repainted from time to time
here it is
Oh nice nice! Yeah I was going to ask if you were doing it nicely with MeshGen 👍
it is a very awful flashback tbh couse I remember that for a long time i was trying to achieve it without MeshGen as google was meesing with me haaaard XD
for hours I googlde stuff like "generating mesh in unity editor" but I never came across MeshGen while searching until someone here on Unity discord told me about it... my blood was boiling man
Haha, well glad you got it figured out!
- Can someone share a link of custom tools (not windows nor inspectors) guide articles/series? All i find out there is related to anything but the in-scene custom editor thing except unity documentation, which is not really helpful for me
What do you mean "custom tools"?
- What lets you modify game objects in the scene directly by dragging, clicking on them etc.. I believe that "custom tool" is an official term for this, isn't it?
I see, and you already read this documentation and example? https://docs.unity3d.com/ScriptReference/EditorTools.EditorTool.html
- Yes, i did. I based my test tool off that, and now i'm lost. Reading anything else in the docs but this example passes through my kettle brain without making any effect, and any non-official article tells me about windows and inspectors, but not tools
Yeah there isn't really anything else on the subject as it is a bit niche. Is there something specifically you are having trouble figuring out?
- A lot actually. What i try do create now is a grid tool that allows me to expand/contract the grid, as well as select specific cells by clicking on them, which opens up their editor window or inspector. And the problem is, i have no clue how, nor what should i search up to learn this
- There are much more problems other than this, but hopefully i'll find a solution myself eventually. I really don't like to bother people much 😄
Well assuming you want the cells to be just visually drawn in the scene view (apposed to GameObjects), then you will want to look in to the Handles API. Not sure how comfortable you are with it, but you can also look at the source code to see how handles is used.
- I'm familiar with the concept, and i already tried using scaling slider handle for the resizing purpose. However not only it's inconvenient to use, it acts unpredictably, so seems like it's not an option here. As for the grid, currently it's just a bunch of draw line calls. But this is just a visualisation without any interaction in it for sure, and googling it didn't give anything even slightly related to the topic.
I made this tool for editing a list of Vector3 points. You click on a point to be able to get a transform handle for it. Not sure if it would be helpful for you to learn something from it or not https://gdl.space/metecaduni.cpp
- Will look into it, thank you
If grid isn't huuuuge, nor is created or modified at runtime, i would consider writing something that will actually instantiate a game object for each cell, then if you want some generic inspector for a grid cell then it is simple as making a MonoBehaviour for such cell and writing a basic custom inspector for it.
In case that grid is huge or individual cells will be created at runtime, instantiating game objects will be performance heavy, so then I assume you gonna need a lot of math for it. You could make then a single game object containing information about the grid, but still you will need some cords to track 3D space occupied by each cells, and then do a raycast from mouse position with some math (which I even dont want to try think about) to determine if ray intersects with a cell, as there is no game object with physical geometry so you cant just receive raycast hit.
I dont know the context so it is still hard to say. If this grid is gameplay related and not only some data visualizer or smth, then definitely a game object for each cell would be a way to go
For expanding and contracting a grid i believe it would be as easy as creating 4 empty game objects in a scene which transforms are forced to be on a single plane, and then some script to dynamically adjust grids metrics based on positions of these 4 game objects. Simply dragging one of these game objects will result in expanding/contracting a whole grid.
I would really never recommend using GOs as handles/gizmos. That has so many side-effects. Saving with the scene (or making sure they don't as the case may be), dirtying the scene (in this case making sure they don't), bad performance for resizing the grid quickly, bad performance when switching out of the tool, bad performance for... anything really. And you have to manage the lifetime of the GameObjects
As an aside about the raycasting thing. The Handles class has a number of methods for getting a sceneview raycasy from a point. And you can use the Plane class to get the intersection point on a cell 🙂
The more you know! Never made a scene-based tools so havent used this classes at all, but i believe the premise is not far off
Yeah, you could do that, or you could just do this to get 4 handles instead.
No need to fuss with GOs or anything
List<Vector3> positions = new ();
private void OnSceneGUI()
{
for(int i = 0; i < positions.Count; i++)
{
positions[i] = Handles.PositionHandle(positions[i], Quaterion.identity);
positions[i] = new Vector3(positions[i].x, 0, positions[i].z); // Contstrain to 0 on the y.
}
}
never touched hanles in my life before so didnt know they dont need any physical attachement in a scene XD
Haha, yeah, it is pretty neat!
yesterday i was just looking if anyone had made a property drawer for making quick buttons to trigger methods for debugging. i did find this (https://github.com/madsbangh/EasyButtons/tree/master) but my VS code didnt want to recognize the namespace so it worked in engine but vs code was complainging and i dont know how to fix that. anyone that could help with that?
or knows another package that just works straight away?
- Well, it depends on what would you consider huge. I guess 11x11 at average, but making 121 game objects still sounds like the most inefficient approach. The grid is not visual btw, in the game it's completely invisible. Beneath that i plan to load a mesh, on top of which i will position the grid so that i can build there
- So, it's that grid thing again. In the docs on tool context there's a comment saying that it can be used for custom selecting logic. Which is actually what i want. Rn the grid still remains a bunch of lines, and the only way to select it is through the hierarchy which is annoying. But as usual, the internet is completely silent about this custom selection logic. Here's what i'm talking about
- And also it's mentioned that tool context is used to " implement specialized versions of the built-in transform tools", which includes the rect tool. And the thing is, i badly want to be able to resize my grid with this kind of tool, i.e. drag any point at the border. As always, i founf no articles on this. Does somebody here have any, or at the very least could point me in the right direction? I would be very grateful
The Splines package does this. I can't look atm to see the specific implementation. But you could take a look at the source code for it to give you some idea.
(I mean it has its own implementation for the transform tools when editing a spline. Not the rect too specifically)
- Will check that out. Is it a built-in package, or must i search it up on github/asset store?
It is in the package manager in 2022
Is there something special I'm missing? I want this box to have a background color of #3C3C3C but instead it's displaying as #2A2A2A. What's causing that?
This is inside my EditorWindow, and I can confirm it should be #3C3C3C with ColorUtility.ToHtmlStringRGB:
void OnGUI() {
GUI.backgroundColor = new Color(0.235f, 0.235f, 0.235f, 1f);
GUI.Box(new Rect(0, 0, position.width, 32), GUIContent.none);
GUI.backgroundColor = Color.white;
}
It acts as a multiplier on the GUIStyle.
Please help guys i am trying to use CreatePropertyGUI to create custom attributes with VisualElements and I know unity 2022.2 and later CreatePropertyGUI should work and earlier than that it should just say "NO GUI Implemeneted" because the older unity version still use the imGUI system... That's what you would expect at least, however i am having the inverse affect where i have tried a CreatePropertyGUI in unity 2022.2.4 and even 2023 and it still says "NO GUI Implemented" but OnGUI still works fine. The image shows the code and the output and this is in unity 2023, where VisualElements should definitely work
Is there a way to nest an inspector for a ScriptableObject inside of a ReorderableList or ListView for a custom inspector?
I think it is because it is for a PropertyAttribute, iirc UITK does not really support them yet fully.
i believe you are missing to override the GUI function that defines what it should look like, unless createPropertyGUI is the correct one
Alright thanks, I'll experiment a bit more
I can't get intellisense to work on vs 2022
And External Script Editor just lists the exe for visual studio (devenv) rather than the actual Visual Studio version
If your IDE is not underlining errors in red or autocompleting code,
please configure it using the link below:
• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)
The steps above are the only ones there are. Have you added the workload to VS?
oh, sorry. I ended up getting it working by updating vs and switching to a version of 2020 because I had accidentally used 2019
If I use
public class SpriteCustom {
public string key;
public Texture2D texture;
public SpriteCustom(string key, Texture2D texture) {
this.key = key;
this.texture = texture;
}
}
public List<SpriteCustom> customs = new List<SpriteCustom>();```
I get a decent enough inspector editor for what I need to do
However, if I try to add a custom list like so:
public class SpriteCustomTest<T> : List<T> where T : SpriteCustom {}
public SpriteCustomList<SpriteCustom> customs = new SpriteCustomList<SpriteCustom>();```
it is no longer compatible with the inspector.
Is there a way to get the same compatibility without writing a whole custom process?
I want to make a property drawer that draws all of the properties in a row. I have lots of structs that contain two fields, where the second one is a number, so I figure I can just write this thing once
my first thought was to write a drawer that just iterates over all of the properties. However, in a list, this malfunctions:
(this is after calling Reset on the property at the end)
as you can see, it's running through all of the properties in the entire list...
while (property.Next(false))
{
// ...
}
if I don't Reset, then it throws an error after drawing all of the properties in a single row
the motivation is to avoid having to know the exact name of the two properties to be drawn
I think I'm fundamentally misunderstanding how to use the serialized property
I switched to passing true for that "enter children" argument, and now...
the number on the right appears to be the ID of the SO on the left; changing it turns the reference into a Missing
I switched to calling Next(true) once, then calling Next(false) repeatedly, and that appears to be working right
curiously, this also meant that the last list in the inspector had its last entry go missing, along with an error complaining that the operation was not possible when moved past all properties
just the last list, though. I guess that's because the whole thing gets serialized into one long sequence?
calling Reset() makes it happy again. But, again...definitely unclear on the specifics here 🙃
Get a copy of the property before iterating it with var copy = property.Copy();
Also you can get the end property (last sub property) var end = copy.EndProperty();
And in the while you can use SerializedProperty.EqualContents(copy, end)
Got it!
like an end iterator
so when I do property.Next(true);, that steps into the struct and gives me the ScriptableObject on the left in that image
and then if I did it a second time, it was wandering into the ScriptableObject reference, I guess.
Note, it is the reference, not the actual data of the ScriptableObject.
Right.
Just some internal part of the reference, I guess
since changing those numbers was changing the references
Yeah, you can use property.NextVisible(true) to not get the internal serialized fields
Fields with the [HideInInspector] attribute will also be skipped with NextVisible(..)
gotcha
ack, mucked it up again
int count = 2;
var prop = property.Copy();
prop.Next(true);
while (count > 0)
{
var child = new PropertyField(property, "");
child.style.flexBasis = first ? 0 : 100;
child.style.flexGrow = first ? 1 : 0;
elem.Add(child);
first = false;
--count;
prop.NextVisible(true);
}
perhaps .Copy also rewinds the property?
"Returns a copy of the SerializedProperty iterator in its current state." suggests it doesn't, though...
it behaves correctly if I just do var prop = property;
(and then Reset at the end)
anyone knows how to convert anon object to json ? i tried the following
var data = new { roomLink = roomLink, roomName = roomName, secret = secret };
Debug.Log( data );
// output : { roomLink = localhost:8338, roomName = new room name, secret = password35 }
var json = JsonUtility.ToJson( data );
Debug.Log("JSON = " + json.ToString() );
// output : JSON = {}
Debug.Log("JSON = " + UnityEditor.EditorJsonUtility.ToJson( json ).ToString() );
// output : JSON = {}
what is the object look like?
anonymous object new { key = value , key2= value2 }
All the same unity serialization rules apply when using JasonUtility
Would need to use Newtonsoft.json
heh, no other way ?
You might be able to serialize an array of system.object... maybe...?
I don't think so though
hmmm
sounds like an idea
System.Web.Script.Serialization.JavaScriptSerializer , System.Text.Json seems like it is an option
ref : https://stackoverflow.com/questions/331976/how-do-i-serialize-a-c-sharp-anonymous-type-to-a-json-string
but its not part of the editor dll's lol
What are you trying to do?
Why are you trying to do that I mean. I am getting the feeling it is not something you should not be doing 😛
lol probably not
but it should be possible lol
i mean it logs out the first line pretty well
then the json logs are empty :<
Why are you trying to serialize something random to json... I feel like there is a lot better way probably...
i mean i can just declare a class and fill in the values ... but it would be much more convenient to send post data with inline anonymous object
instead of creating 100's of these classes
public static void Post( string uri, string json, Action<Result> callback ) {
var req = UnityWebRequest.Post( uri , json, "application/json" );
req.SetRequestHeader("Content-Type", "application/json");
...
Why would you create 100's of the classes...?
making a rest api , and i need to quickly test bunch of json file structures
also the inputs / outputs are not always consistent - sometimes keys will be missing for what the api should return
used this one https://github.com/Bunny83/SimpleJSON to convert string to a JsonNode object which works great
Hey guys !
Are we able to somehow make TextAreas within the editor window scroll-able?
I'm running into the issues where the text is becoming so much that I can't see my buttons at the bottom haha
I've been able to make the entire window scroll-able, but that's not quite what Im after
using ( var scope = GUILayout.ScrollViewScope( scroll , /* optional */ GUILayout.Height( 100 ) ) )
{
// .. your text area gui here
scroll = scope.scrollPosition
}```
yes
Sweet! Thank you 😄
yw
Hey @tough cairn I seem to be getting an error using the ViewScope;
Not sure if there is something I'm missing, but it doens't like being invoked as a method
notice how i wrapped it inside a "using"
if u don't want to use this wrapper u can use these methods instead :
scroll = GUILayout.BeginScrollView( scroll );
// .. your text area gui here
GUILayout.EndScrollView();
public static string AnonObjToJSON(object input)
{
//dynamic result = new ExpandoObject();
//var dict = ( IDictionary<string, object> ) result ;
var dict = new Dictionary<string, object>();
foreach (PropertyInfo propertyInfo in input.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
dict[propertyInfo.Name] = propertyInfo.GetValue(input, null);
var output = "";
foreach (var kv in dict) output += $"{kv.Key}:" + ( kv.Value is string ? $"\"{kv.Value}\"" : kv.Value ) + ",";
return "{" + output + "}";
}
hehe
i might use it recursively for more complex stuff , for now seems to do the trick
Hey @tough cairn
One last question in regards to formatting
Do you know if we can use hyperlinks or any kind of other rich text like we normally would with TMP?
try this
var style = new GUIStyle( GUI.skin.textArea );
style.richText = true;
GUILayout.TextArea( "<b>text..</b>" , style );
Can this be applied to labels as well? 🤓
Looks like iot
😄
Woooo! Man you're a top tier lad
It works!
What the fu...
Are the keys strings by chance?
ahaha i knew u gonna love it
var data = new { roomLink = "val1", roomName = "val2", secret = "val3", connected: true };```
So like... maybe a list of strings would work?
yeah
I'm trying to update multiple packages from a script
but it seems sometimes the process gets interrupted after one package
maybe the package installation causes a appdomain reload, cancelling my async routine?
I also noticed if you don't wait until one package has installed, any subsequent requests get just ignored
I know that you couldn't multi-select packages to install/remove all at once until recently
maybe there's a relation there
maybe I could modify Packages/manifest.json and use Resolve instead?
or Packages/packages-lock.json
public static PackageManager.Requests.AddAndRemoveRequest AddAndRemove(string[] packagesToAdd, string[] packagesToRemove);
oh
Oh yeah, we just edited the text file
Not sure if this is the right place to ask, but I'm working on tooling (hand pose relative to object)
Ideally this would be configured by opening a "fake" prefab scene and doing the configuration in isolation. However, this component can be added to any object, including non-prefab ones, so AssetDatabase.OpenAsset(whateverObjectToConfigure); won't work. Any suggestions, or even ideas as to where to look further?
working on tooling in an EditorWindow... trying to make a selectable list of images that can be clicked on (and selected) or drag-and-dropped into the scene. right now I got to the stage of having a scrollview pane with the images, but not sure how to tackle the next two parts of this
- Is it possible to show a helpbox from within a property drawer without implementing a custom editor just for this purpose?
I'm looking for a way to "gray out" or remove menu items from the "Create Asset" menu. The [MenuItem] attribute has a validation feature, but [CreateAssetMenu] does not. I want to show or enable my menu item inside the Create menu only when a prefab is selected. Some of Unity's menu items do that (eg "Prefab Variant" or "Create Template from Scene") but I could not find a code example for this. Anyone got an idea to make this work?
context: right-click in the Project view, not in the scene hierarchy
Look in to scene stages
https://docs.unity3d.com/2020.1/Documentation/ScriptReference/SceneManagement.Stage.html
Highly recommend using UIToolkit for this. It is a pain to do in IMGUI. You will have to use the Event.current.type and also the rect of the images.
Yeah, of course. Just increase the height of the property and draw the help box
You already said the answer yourself. You use [MenuItem]. You can use this along with the undocumented API that is linked there to create the asset nicely like [CreateAssetMenu] does. Will probably want to look at the source code for learning how to use it.
https://docs.unity3d.com/2020.1/Documentation/ScriptReference/ProjectWindowCallback.EndNameEditAction.Action.html
- How much should i increase the height? Is it a magic number, or is there an utility to calculate that?