#↕️┃editor-extensions
1 messages · Page 87 of 1
ha
i could honestly get rid of it, i don't depend on odin except for my serializedscriptableobjects because its way easier for me at least that way
Yeah... Unity needs to at least get their internal teams onboard...
They also need to make the default editor UIT instead of IMGUI... :/
hey yall a great group here i wanna say, i've learned more just now than all my prior googling on this stuff combined, so, whats UIT
this channel is pretty active, full of good people
Isn't it already?
i imagine editor extensions and development is still enough of a niche its not so saturated as game dev is where everyone thinks there game code is some kind of novel trade secret and won't share any knowledge
Nope... unless that has changed since 2020.3
I do feel it is a niche, not too narrow, but not to vast too
I feel like this channel is just the perfect amount of active.
What do you mean default UIT for Editor?
Inspector wraps them in UIT container
Oh, sorry. I mean that when a component or SO doesn't have a custom editor, it uses IMGUI still instead of UIT.
the final step of UI is either drawn through IMGUIContainer or pure UIT
yeah the migration is gonna take a while
I would think it would be pretty easy tbh. I guess I am missing something.
a while of about 10 years easily 😄
To do what? Fully switch the whole Unity editor over?
It's a pretty big work to convert everything to UIT, and that's just counting Unity side
Forget about public scripts
And Asset Store stuff
i wish the inspector, well at least for the 99 percent of it being ascii chars, it feels like a lot of work to update some fields, i mean i could update more text than that with vb6 and not lag
but taht doesnt cover the fancy stuff
can you change the frequency it polls everything for new values
Using GUI or UIT?
yes
which is?
oh
i may not be asking the right question even here
i just saw you talking about UIT, i know about imgui, but not UIT
well its good it pushes instead of polls at least thats good to know
event like mouse moving, clicking, releasing
thats a lot of pushing
not really
It's the nature of things, the fundamental
how many time can you click on the screen?
10, 20 per sec?
It makes 40 events at max, which is not that much
i think i still have a macro that can challenge that but yea, but you said on mouse move?
Unity calls Update about a 100 times/s when focused. Around 10 when unfocused
GUI can update roughly dozen time
Might have to confirm this last number
But it does not matter
Update is not an issue if you are careful with your code
yea, i feel it my duty to find and remove any and all alloc in update loops, i mean, im' newish to unity, c sharp was easy to pickup but man, i'm used to doing embedded stuff and lower level and i've seen some bad update loop things, i still think its amazing that unity can churn out a game that works with that many scripts that allhave update, fixed/late update calls (i know it wrangles these but still)
thelast time i had any experience with a game creator was a bunch of random c++ header files that didn't compile, and then later some bitblt
i had no idea unity existed until like 2, 2.5 years ago
The inspector will not draw (user defined) UITK property drawers unless the entire element is already drawn as UITK
it's a weird decision
seeing as half of the default UITK drawers are incomplete I understand why they did it
Really? Most of them seem pretty solid to me.
New reorderable arrays by default in 2020? LOL no UITK support
Yeah... that really annoys me...
In a property drawer, I am trying to find a way to keep track of a certain set of properties in a array property. Any ideas?
(Specifically, I am trying to check if a value is a duplicate, and keep track of it instead of check every frame)
Not really other than the obvious static fields/session state
I literally can't get this object to serialize despite being able to see it has changed
var it = so.GetIterator();
it.Next(true);
while (it.NextVisible(true))
{
Debug.Log(it.displayName + it.intValue);
it.serializedObject.ApplyModifiedProperties();
it.serializedObject.Update();
}
I can see the update values in the Debug.Log's but it doesn't actually write the serialized values to disk, so when I open unity back up it reverts to the old values
How can I flush the changes to disk?
I tried just randomly throwing an armada at it, but nothing seems to work. https://gdl.space/sozivezila.cs
The code snippet should work. That bit in the link there won't because calling so.Update() at the top will get rid of any changed to the serializedObject.
Also, why are you calling ApplyModifiedProperties in a loop like that. After the first call it will be doing nothing.
How can I draw one of these? I am not finding the API
If you mean the lines. I think that uses the Handles.DrawLine/DrawBezier API. If you mean the whole thing with the range and numbers and everything, you need to do that yourself.
Oh, I found a dirty trick to draw that exact curve which is what I need 😏
https://forum.unity.com/threads/replicate-audiosource-inspector.537341/#post-5740822
There's also animationcurve that is similar
I am very sad to learn than UIT doesn't have the performance to support resizing a mid sized grid of elements like in the ProjectBrowser. Going to have to use IMGUI for it 😦
wondering if it's made worse by resizing on every event callback - may want to buffer and only execute after a second or something. Most resizing isn't constant.
Well what I did was set the Width and Height of each item, and put them in row containers. Then on GeometryChanged, I calculate the number of items that can be shown horizontally, and add/remove the number of items from each row.
not sure about your exact situation but in terms of strategies to deal with this - creating/removing elements is expensive so ideally you want to create elements up-front and re-use them. Ideally some kind of virtualised grid but you could go half-way by creating e.g. the largest number of columns you need up-front perhaps.
i.e. use the display = none on hidden columns
Yeah, my plan was to do the vertualised grid (originally I was using ListView, but that had even worse performance).
I thought about doing display = none, i will try it and see how it goes. The most important thing for me is being able to resize the elements performantly with like a slider (like you do in the Project Browser).
when virtualised, what's the most number of elements you expect? I have a feeling no matter what you do you may run into issues if you want to support fullscreen at 4k with the smallest tile setting
I think that IMGUI would struggle with that as well. I think I would think most you would normally have is like 17 x 8, so 136?
sounds reasonable 👍
Do you happen to have any idea why once I display =none one column of elements, all of the others start acting like they can flex even though I set their widths...
If that’s not what you want, try setting the position to absolute?
But I have the width set on all of them, so it should flex them right...?
well the interaction between all these things is a little messy. maybe check their flexgrow & flexshrink are set to 0 to be sure. Also, you may want to set their width via .transform instead of .style (I think it's more performant)
AH, setting the flexshrink and flexgrow to 0 did the trick. Thank you. How would you go about setting the width/height via .transform?
nice. Er I can't remember off the top of my head. It might be .layout.width or worldBounds or something instead. Wouldn't worry about it too much - probably not much gains unless setting the position.
Yeah, there are a lot of ways to set the position and width/height. Will worry about it later.
@split bridge Well thanks for your help. Changing the number of elements is silky smooth. Sadly updating the size of the elements starts lagging pretty quickly. I assume that is because having to changing the style of all of the items.
Potentially, yea. Some things are more expensive than others. Flattening the hierarchy where possible and avoiding word wrap can help.
oh also it's worth trying to set the usage hint for the root of your elements. If I'm not mistaken I think that will move some part of the process to the gpu. https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.UsageHints.html
Oh, cool. Doesn't seem to make too much of a difference. I think because I already have the elements in a ScrollView, which I think already has a usageHint.
I'm not sure what to do now. I have it to the point where it is pretty good up to a point. But then it lags hard. On the other hand IMGUI has better performance, the only downside is that it is IMGUI :/
New vid?
hmm yea it could be worth setting all the elements to position:absolute and just calculating their transform positions
I normally wouldn't mind too much about the performance. But I need it for an asset, and it would just make it feel low quality.
Hmm, guess I will try setting their positions that way. Do you know if there is a performance difference using style.top/style.left vs .transform?
yea pretty sure I saw quite a big perf improvement from using .transform
Alright, cool. I will give it a try and see how it goes. Do you happen to know if getting rid of the row containers would make a different for manually setting the pos?
Like just set each item pos vs setting the row y and the item x.
wouldn't expect much difference from losing the extra container... though it's also probably not doing anything for you either?
The reason for the row containers right now is because later on I want to have
vertical scrolling like the ListVew.
Where it reuses the elements as it scrolls.
Sure - makes sense - though I don't think you need the row elements to do so
Thought it might have better performance.
It might make it more convenient to hide a row I guess but you'll likely end up with only num rows + 2 in order to scroll and I'd probably just leave all the rows visible all the time.
im creating a property drawer for a custom struct, but i want to make it run a function whenever a value is changed, but im new to editor scripts, any help is appreciated
EditorGUI.Begin/EndChangeCheck
https://docs.unity3d.com/ScriptReference/EditorGUI.BeginChangeCheck.html
thanks, ill try it out
ok, im having trouble seeing how to use it
i have a custom Vec4 struct, and then a Tetrahedron struct that contains 4 Vec4s
i need to update a variable of Tetrahedron whenever the 4th variable, "w", is changed on any of the 4 vec4s
i want to set Span.x to be the minimum W value, and Span.y to be the maximum W across A,B,C,D
You do a BeginChangeCheck, then put all of your controls/fields, then do an EndChangeCheck, if it returns true, then you set the pan value as you want.
i guess what i dont know how to do is get all 4 W fields
property.FindReletiveProperty("a.w").floatValue
a should be the name of the field you want, the period acts like a slash does in file paths.
alright
Hey all,
I'm creating a 3D tilemap tool to create terrain that best represents what Old-School Runescapes tiles look like.
However, while editing the terrain is an easy 60FPS, spawning/instantiating the simple 2-triangle meshes is not. See the WebM attached.
Code for the simple render() function: https://gist.github.com/nox7/b7c353ee21c68f0ff7c75e47db07620d
The Editor profiler shows that the "Event Loop" and GFx.WaitForCommand is taking up the time. Commenting out the "render" function makes the lag go away. Why would spawning 4 meshes cause such an FPS drop in the editor? Additionally, commenting out the MeshCollider & MeshFilter (so the mesh doesn't actually render in the scene) does not cause the lag to go away.
Sorry, please ignore that. I benchmarked the function and realized that isn't what's causing it
SceneVisibilityManager.instance.DisableAllPicking();
Calling this every mouse movement was causing the Editor to lag
does anyone know if its possible to customize the states in an animator? we'd like to have icon badges, if there are certain SMB behaviors or custom components on an state
If it's been rewritten to UITK then yeah otherwise not easily
you mean if its using the UI toolkit as package?
If it's using UITK to render then you can just find the nodes and add things
nice, thanks
Thought I would give you an update. Doing the abs position, and manually positioning them did have a good bit better performance. It is to the point where I think I could use it and it would cover the most common use cases without lagging. But when it gets bigger with smaller items (I guess that just means more items) the performance starts dropping off pretty fast.
So now I am really not sure which to use...
I really like UITK, and it would be nice to be consistent. But the performance is so good with more items using IMGUI.
My experience of performance of imgui has definitely not been as positive as yours by the sounds of it! It's fine until you need to support any interaction like rollovers and then it kinda falls over in my experience. Are the performance issues you're concerned about related to resizing a window? I'd be more concerned with the more common interactions myself.
I have just been comparing the performance with that of the Project Browser (I open it up and set the items scale and count to be about the same).
No, resizing the window is very smooth because of just setting the display state and reusing items. Yeah, perhaps the performance is good enough since you won't be resizing the elements that often.
I plan to, but that doesn't help with large windows like this one.
What I am trying to do is basically recreate the Project Browser. The problem comes when the window is large, and the items are on the smaller side, so like 28 columns and 13 rows. And then trying to resize all the items with the slider.
It will be virtualized if it is.
No, that is not the problem I am talking about. I am talking about when you simply have a lot of items on the screen at one time.
For the purpose of this test, that is correct.
I hope you are using GUI instead of GUILayout
UITk
I have a big window, lets say full screen. And the items are small, like 35px/35px. That is about 30 x 14 or about 412 items. And now I want to change their size. It lags when changing their size.
Here is a test script. https://paste.mod.gg/aporaruqig.cs
The only purpose of this script is to see how performant updating the position, width, and height, of a large number of elements is.
One thing to keep in mind is your fps & slider callback rate - you may want to rate limit it as a first measure. Then further check that e.g. the change of size is actually a change.
I could maybe. But it is an SliderInt, and it only calls when the value does change.
I don't think I am...
just put a debug in there to double check that?
@split bridge @severe python Okay, so it seems like using transform.scale works quite well. The only downside really is that borders scale so are no longer consistent (1px border no longer stays 1px). But I think at least for my use that should be okay since I don't think I need any borders.
It is the regeneration of the mesh that is causing the performance problem
Here is the profiler when resizing if you are interested
Time to go back to IMGUI
That gives significantly worse performance than using transform.position
I have 3 options, have not great performance with large numbers of elements, use scale, or use IMGUI.
Honestly I think I may. The performance is just so much better. I would be mixing IMGUI and UITK though which is a bit icky.
That's very sad to hear
That I am using UITK and not just IMGUI?
no, that performance is not there with UIT
Ah, yeah.
The trouble really is just that it is having to regenerate the meshes.
That doesn't matter. All the elements are using Abs position, they are not being touched by the layout.
I asked on the forums if you are interested, trying to explain the problem is rather difficult it seems. https://forum.unity.com/threads/how-to-make-a-performant-gridview.1104193/
Fellas, I have a weird issue. DragPerformEvent is not working on MacOS, but it does work on other OS...
Why could this be???
graphView.RegisterCallback<DragPerformEvent>(evt => Debug.Log("DragPerformEvent"));
This wont work on MacOS
That's a lot of tesselations going on there - do you have rounded corner borders?
I do, I got rid of them and it does help. But not enough to fix the performance problem.
Welp, looks like I'm going to IMGUI for the grid. At least for now. Scaling doesn't work when using text (since the text gets larger as well of course), and I added text to the buttons in my test and the performance just tanked again.
If they add some sort of batching, or ability to copy mesh data instead of generate a new one, then this would work great. But until then, it is a no go for large grids.
Yeah, they really need a grid element. I suppose they would have run in to this problem as well if they tried.
Why is that?
The bottleneck is the regeneration of the meshes (Even without the borders it is still slow).
hey just wanted to thank ya guys for the editor help, asset is submitted...and rejected...but because its too similar to existing assets, yet, there aren't any, so i asked them to send me a link of one... 😦 its like he didnt even look at it or read me wonderful RTF documentaiton
welcome aboard
I didn't know that was a thing they did.
Not that uncommon
yea thats what i heard when i asked someone i knew who has a few assets, said he got rejected, its just at least he didn't meet some requirement... i mean i only made this asset to help people get started out with netcode stuff, and the main thing is like lobby/room management, i can't find a single one thre used to be one i had heard of but its gone
wack
Just because I think it is interesting, and want to share. I found this QuickSearch repo on github from 5 years ago which I am pretty sure Unity used as the base for their QuickSearch, at least originally. https://github.com/appetizermonster/Unity3D-QuickSearch
Seems like you're not alone: https://forum.unity.com/threads/how-to-use-draganddrop-with-visualelements-and-manipulators.684382/
Very little about this though
Anyway, I had to think of an alternative way to create the nodes in my graph, because I cannot trust macos :/
Contextual menu is the fallback, I guess
Do you know if it worked in the past?
I have no idea
I am making a system with GraphView API, and I was testing dropping stuff from the blackboard to the GraphView
It was working alright, and then today I tested in in MacOS and... surprise 😛
It's... a long shot, but since it sounds like events aren't firing at all.. If they're implemented in a way that involves AppleEvents then MAYBE they need to be allowed in Accessibility security. As in, try adding Unity (and the Hub?) here?
Worst it can do is not help 🙂
Ah, ok. That's "special"
Even if that is the case, I cannot expect people buying my Asset to change that configuration settings, that is so hidden
I need to offer them a clear an usable solution
Well, if it's selective and they're not ENTIRELY broken then it's unlikely the cause anyway, it sounds like Unity's bug.
Probably
Not that it helps you either way =\
By the way, this is it, if you want to take a look (its 30 secs video)
Demo of the Conversa dialogue system for Unity
oh sorry.. 🙂
No problem.
can you suggest any good youtube channels or websites were I can learn basics of writing editor extensions?
oh yeah this one is good http://codingsensei.com/
cant access this
Sure! There is the manual:
Custom inspectors > https://docs.unity3d.com/Manual/editor-CustomEditors.html
Custom Windows > https://docs.unity3d.com/Manual/editor-EditorWindows.html
And there is a Unity Learn tutorial on it
https://learn.unity.com/tutorial/editor-scripting#
Those should get you started well.
thanks
Is their any way to compile a specific file or assembly? (From script) I'm generating some code and I don't see any reason unity needs to compile the entire project
So far this seems to be all I can find CompilationPipeline.RequestScriptCompilation(RequestScriptCompilationOptions.None);
No there is not, and if there was I'm sure Unity would be using it for general recompiling.
afaik unity doesn't recompile the entire project however it has to reload all assemblies and that oftentimes takes more time than the compilation
it recompiles the set of assemblies that depend on the assembly that changed
@civic river ^
Yes, you use a compiler 🙂
Nothing easy, but you must learn how a .csproj works to compile things correctly
Meaning files, dependencies, references, defines, etc.
@civic river btw maybe you could specify why you need to trigger script recompilation? it'd be easier to understand what the context is and what problem is it solving
there is a non-public Unity API that allows to patch already compiled DLL's in memory using mono cecil, before they get stored to disk, which is extremely useful for some project-wide things
hoping someone can help, i have a list of strings that correlate to a number of .asset files. I need to check if those .asset files contain a certain class. any ideas of the better way to go about this?
A better way to do what exactly?
somewhat esoteric/advanced question but does anyone know if there's a way to force the inspector to change its target from code WITHOUT changing the actual Selection? Even with reflection is fine. I assume it has something to do with the ActiveEditorTracker but not really sure how to work with those.
Only if the inspector is locked. Then you can use the internal methods
void SetObjectsLocked(List<Object> objs) and void GetObjectsLocked(List<Object> objs)
(Using the set method will also set the inspector to be locked)
Hmm ok thanks, might have to mess with that to see if I can get it to do what I want. Basically all I'm trying to do is get it to show the selected folder in the inspector when you choose the folder in the two column layout. The problem is that if I set that folder as selected using Selection, then the two-column layout automatically then changes the folder to the parent folder instead (since it always selects the parent folder of the current selection).
Specifically when you choose the folder on the left side of the two-column layout, not the right side (which works fine, just like the one-column layout does)
If you figure that out let me know 😛
Figure what out?
The problem is that if I set that folder as selected using Selection, then the two-column layout automatically then changes the folder to the parent folder instead (since it always selects the parent folder of the current selection).
This without changing the selection nor locking the inspector
If you want to see what I'm doing, I wrote a simple little one-file tool to let you add notes to any folder: https://gist.github.com/MattRix/c66de4ffe222ccf67462baddfb01e302
so it would be nice to be able to click on folders in the left column of the two-column layout and have them show up in the inspector as well
it's easy enough to detect which folders are selected, but I can't make them show up in the inspector without using Selection, which as I mentioned above, will then select their parent folder instead.
Idk exactly how the project browser is handling it, but you could try locking the project browser, set the selection then unlock the project browser again.
yup! That's what I'm going to try next, we'll see...
Here you go. There is a tiny bit of a utility class just to get the Project Browser type, but that is trivial to replace https://paste.mod.gg/zehuqeqami.cs
You just use that like you would Selection.
Great, thanks! Yeah I have my own Reflection helper class so that shouldn't be a problem to swap out.
It's a code generator that reduces dictionaries to flat indexed arrays with static lookups and does some compile-type type shuffling to avoid extra runtime overhead. So the files end up looking like this https://gdl.space/asazorifez.cs It's not generated as a compilation side effect, rather it's compiling an asset into a code representation.
Ideally I'd just patch the symbol table
I don't know if cecil can do that or not
yeah, so this new codegen functionality can do that, but it's not a public API - though it's used by Burst package so it's probably here to stay
but that's kind of maybe overkill
so whenever you change the asset it triggers a recompile and i guess it's annoying that it takes so long?
Have you done any perf tests out of curiosity? Dictionaries are incredibly fast and don't generate gc when fetching (I mention as your linked code has 'AntiAllocationWrapper' in it and old Unity used to generate garbage).
The idea of the allocation wrapper was to avoid having new objects created when boxing new values on set. (It's just a persistent box, basically)
In terms of perf, you can see the difference yourself in the user API VS what the code gen gets to do
https://gdl.space/dojomamisa.cs
Yeah, the asset saves in 20ms and it takes unity 10-15s to compile so it's pretty clear where my time would be better spent making a better user experience
lol
At any rate I'll see if I can get something stable put together from cecil, patching symbols shouldn't be too difficult... Hopefully lol.
Cheers
Idk what you'er doing but you can also just do expressions
hello, Im currently building a tiny editor for viewing my scriptable objects; I currently have a button for each scriptable object, however when I click on it im only able to show the sciptable object as a field (from serialized property) - how can I display this specific scriptable objects values ?
The serialized property has a objectReferenceValue field which if the SerializedProperty is for a field that is of type UnityEngine.Object, it will contain the reference to the object. In your case, the ScriptableObject. Then you can use Editor.CreateEditor to create an editor for the SO, and draw it.
thanks! worked great!
aight, I have one more question: how can I convert a scriptable object into a serialized property ?
SerializedObject
For UIElements / UI Toolkit: Is there a way to detect the deepest VisualElement which an event has occurred? Alternately, just knowing the deepest element at a certain position?
My situation is: I want to register a context menu event handler at the rootmost VisualElement but only handle the event if it happened on certain specific VisualElements, and I don't want to have to register the event on every single VisualElement class that I care about.
It’s not pretty but one way would be to set the userData of every VE that’s valid (eg userData = true) - then in the callback cast the target to a VE and check the userData.
@split bridge @severe python I lost some hair from it, but I got it working! I still gotta do selection but that will be pretty easy (especially compared to getting the rest of it to work)
I would like to be able to make it so the item at the top left stays the same even when resizing, but not sure how to do that exactly...
But still! It works!
https://streamable.com/eo0uu9
But not the deepest target. So if I have a root VisualElement containing all other VisualElements, "target" will be the root VisualElement, not the specific VisualElement that I clicked on.
But I think I solved it, I was approaching it wrong. What I thought I wanted wasn't actually what I wanted; I don't want "Label" etc. to be valid options, so it turns out I do have to register the event handler on each VisualElement that I care about.
100% UITk!
Basically, just not having rounded corners, ended up having good enough performance. Wish there was a better answer.
No, in the end it was basically "Just scale the stuff". Said that I could position the text my self (Like I do now with the whole cell), and use a callback to manually draw the border if I needed one.
Yeah... It works just fine without them though.
I asked about adding some sort of batching system and they said they had talked about internally for stuff like ShaderGraph.
It is really annoying that making custom controls is not really a 'supported' feature... you can't save data and you cant change the pseudo states :/
Actually... that is not the case. I think that you need to use the Checked state if you want to be able to have a lost focus color, I'm not sure tbh though. I can't find any way to have one so I just assume that is the case. (for example clicking on a list item and then clicking on another control will make the list item be grey instead of blue. I want that...)
That isn't what the ListView does.
Oh wait I know what they are doing
My bad I get it now. They are using multiple pseudo state selectors at once.
Yeah. I would prefer if they just made them public. It isn't even like you can do that much damage with them...
I think the worse offender though is the stupid ViewData. Not allowing you to serialize your own view data is stupid. I assume they don't want people to just go saving all sorts of data and mixing View with Data. But like, come one I am going to have to make a State class and a GetState and ApplyState methods, and pass that up to the EditorWindow.
It is so ugly and convoluted compared to what they can do internally...
@severe python Hot dang, they originally had it public in 2018, but then made it internal after 2019.1!
Hey all. I was wondering if you all know of a tool or a way to select multiple GameObjects in a scene and convert that selection to all the lightmaps that those objects are using, so that I can quickly change their parameters without having to select the Game Objects individually and click on their lightmap thumbnail for each one.
Anyone know of a good snapping tool
For environments. Grid snap is horrible for mod kits
Hey @severe python about what we were talking about, do you happen to know if there is a way to look at the default USS Unity file? I am trying to get the 'selected' and 'selected focused' color for the items in the ListView.
What do you mean? What sort of snapping are you wanting?
Well darn.
I don’t know either but have you tried via the uitk debugger? Should be able to see class and specific overrides using it
Yeah, and that works for most things. The problem in this case is that I want the "selected-focused" color, so as soon as I click on anything else the color changes...
So I can't like color pick or open the menu to see the color or anything.
Yea it’s super fiddly - may not be possible but think I’ve managed similar things before through some careful picking and maximising the debug window. May not be possible - will give it a try tmrw when I’m in front of Unity
I mean... the other obvious way if you just want the colour is to screen grab it but yea.. I know 🙂
You can't even do that. You have to take a screenshot and then color pick that 😛
That’s what I was suggesting 👍
Ah got it. 👌
On a VisualElement, you can set the property delegatesFocus, if you do that it gives you an error InvalidOperationException: delegatesFocus should only be set on composite roots.
So naturally you go to set isCompositeRoot, only thing is it is internal so it can't be set, which means delegatesFocus will always error... meaning it is completely useless...
I'm trying very hard to make Handles.FreeMoveHandle above an object in scene view to give it some custom dragging behaviour. I am very close to what I want to achieve, the problem is, that no matter where I click in the scene, the dragging begins. Even if it's completely outside of this FreeMoveHandle. I tried using
int id = HandleUtility.nearestControl;
and checking if id is equal to the controlID I got, but then dragging doesn't seem to work at all.
Show code
I think it's hard-coded somewhere as I can't see a class that the style comes from but it seems to be the Focus state and here's the colour from the inspector (for dark skin anyway - not sure if light is different)
I think this is only really valid for something like a TextField (not sure what else) - I haven't seen almost any docs around this attribute (that explained anything) but I think it e.g. helps to select inside the actual text field when you call .Focus on a TextField - I wouldn't expect setting isCompositeRoot to do something useful even if it worked but I could be wrong.
Honestly, I'm not sure what it does. I just know that the ListView uses it so I was going to use it. I think it is silly that there is an exposed property that 'can't' be set.
So I put a label and a text area into my inspector with IMGUI, and for some reason, when you click on the text box, it puts a cursor and turns the box border blue.... except for the top line of the border. That stays black, and I'm not sure why. Any ideas?
Nope sorry, not without seeing the code. A screenshot of the area in the inspector in question wouldn't hurt either.
The cursor for the box is also missing until something is typed in...
bool isExpanded = true;
readonly float singleLineHeight = EditorGUIUtility.singleLineHeight + 6;
string expression;
float currentVPosition = 0;
float middleMargin = 6;
public void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
currentVPosition = position.y;
isExpanded = EditorGUI.BeginFoldoutHeaderGroup(new Rect(position) { height = singleLineHeight }, isExpanded, new GUIContent("Expression Testing Tool"));
currentVPosition += singleLineHeight;
// TODO: Needs Implementation
if (isExpanded)
{
Rect labelRect = new Rect(position) { y = currentVPosition + 2, height = EditorGUIUtility.singleLineHeight };
GUI.Label(labelRect, new GUIContent("Composition Expression"));
Rect clientRect = new Rect(labelRect) { y = labelRect.y + singleLineHeight + 2, height = (EditorGUIUtility.singleLineHeight * 3), width = labelRect.width - 1 };
expression = GUI.TextArea(clientRect, expression, new GUIStyle(GUI.skin.textArea) { padding = new RectOffset(0,0,0,0) });
}
EditorGUI.EndFoldoutHeaderGroup();
}
public float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float heightTotal = 0f;
float height = 0f;
if (isExpanded)
{
height += (EditorGUIUtility.singleLineHeight * 4) + 6;
}
heightTotal += singleLineHeight;
heightTotal += height;
return heightTotal;
}
Hmm, it could be the padding for the GUI style maybe?
Try it without setting a custom style.
That makes the cursor appear, but the line is still missing
using the default padding but increasing the top padding does not fix it either
Rect labelRect = new Rect(position) { y = currentVPosition + 2, height = EditorGUIUtility.singleLineHeight };
GUI.Label(labelRect, new GUIContent("Composition Expression"));
Rect clientRect = new Rect(labelRect) { y = labelRect.y + singleLineHeight + 2, height = (EditorGUIUtility.singleLineHeight * 3), width = labelRect.width - 1 };
RectOffset offset = new RectOffset();
offset.left = GUI.skin.textArea.border.left;
offset.right = GUI.skin.textArea.border.right;
offset.bottom = GUI.skin.textArea.border.bottom;
offset.top = 3;
var textAreaStyle = new GUIStyle(GUI.skin.textArea) { border = offset, padding = offset };
expression = GUI.TextArea(clientRect, expression, textAreaStyle);
Changed to this and still doesn't work.
How do you display a GameObject on an editor? Im using EditorGUILayout.ObjectField, which is obsolete, is that fine?
There is a different overload that is not obsolete.
what is that overload? I've had a hard time finding it online
string, value, type, bool
Hi! I'm making an editor script where I can select a certain AI agent and when I press 'train agent' it trains the data of that agent. I have a helper box that says the agent is training or not. But it never says it is training because it keeps saying that the bool is false.
Even though the AI agent scripts debug as true. Is it because the editor extension can't acces the monobehaviour script of that object?
the bool 'aiagent.istraining' is a public bool on a monobehaviour
There's a target variable that you need to use
Or use serializedproperties, which is the recommended way
@waxen sandal like this?
because that doesn't work for me
you mean this when talking about target variable?
Thanks, I'll look into it!
There's no way to exclude certain directories in an ObjectField right?
No builtin way. Can of course do it your self with a change check and get asset path.
I meant with filtering in the objectfield view
Removing hte reference without feedback is a bad idea
This might be the wrong area, sorry if so.
I added NavMeshComponents, and my Visual Studios tells me this 'error'
Error CS1069 The type name 'NavMeshData' could not be found in the namespace 'UnityEngine.AI'. This type has been forwarded to assembly 'UnityEngine.AIModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' Consider adding a reference to that assembly.
The program builds and runs just fine, but I'd like to fix this Visual Studio error notification. Any idea how I would do that?
@severe python After all that work to make a grid view with UIT, having text truncated labels proves to be too much for it and makes it lag, even just resizing the window... I wanna cry... it took me a week to do and in the end I will have to use IMGUI... which also means more time...
I deep profiled when resizing and the problem is the truncation. There is no styling on it beyond setting the width and height.
truncation as in ellipses? I wouldn't expect just setting the overflow to hidden to take much time
Correct. It isn't setting the overflow to hidden. It has to measure the actual string text and then use a binary search test for the best ellipses spot in the string.
yea ok, that doesn't sound cheap
Yeah... I had to implement my own truncation for the label because the label doesn't have it in 2019.3 (it is basically the same as what unity does though). But I don't have any need for that now either... more wasted time, in the end it is like 2+ weeks of work that won't be used now.
I mean I did, but like I would prefer to have my 2 weeks back 😛
then you wouldn't know that is was going to be a waste 😄
Yeah, the good old catch 22 sort of thing.
how come you're throwing it away?
Doesnt fit his expectations 🙂
I mean, I am going to keep the code for sure. But the performance isn't there, especially when compared to a grid view made with IMGUI.
I worry that you'll get further with imgui and have different performance concerns. If UITK is fast while you're not resizing a window I wouldn't be too quick to abandon it. Just something to consider.
complex imgui has a lot of overhead in my exp - esp per frame
no no no, IMGUI is beautiful!
Stockholm syndrome 😄
I thought about about that too, but the project browser gets good performance even with a lot of items on screen at once. So I am just kind of assuming that I can get the same result 😛
UITK is also a bit slow when scrolling quickly.
if you've looked at the deep profiler while e.g. mousing over and interacting with the project browser window and you're happy with it and you don't find much advantage the UITK workflow then go for it I guess
Does it have bad performance with mouse over...?
Oh I do find advantage with UITK! If it was just for me I would still be using it for the grid view. But this is for an asset, and the lag makes it feel sloppy and unprofessional to me. So I can't justify using a 'backend' that I like even when it is worse for the end user.
I've always found mouse over states, progress bars etc a pain to get working at a decent refresh rate without repainting the entire window. UITK is expensive to build but pretty decent once built in my exp. I prefer that trade-off - esp so when factoring in the workflow. I think getting a snappy & reponsive ui in both paradigms is totally possible. Fwiw if I paid for an asset and it didn't redraw until I finished resizing the window - so long as it was then very responsive, I wouldn't think anything of it. That said - I don't have a horse in this race haha - go for imgui if you feel more comfortable about the perf.
Oh, you know I didn't think about repainting... I bet if I did that it would tank the performance hu...
Just my opinion/experience. Mikilo can likely help with good imgui techniques if you hit perf issues 😄 and I'm guessing they may well disagree with me that it's a big deal/perf concern.
Yeah I agree. (I also just spent the past 45 minutes deep profiling to see if I could fix the performance at least for scrolling, and I can't. It is just a mater of number of elements basically)
What annoys me is the tone Unity seems to take with people who try to do more advanced things with UITK.
It is kind of a "Ehh, I guess you could try doing this or that, but... eh"
Instead of "Oh, how can we make this better for your use case" or "How can we fix this."
they are not publishers
they are employees 🙂
They lack of passion
And i'm gonna break it in half to you guys, I got rejected from Unity (HAHAHA XD)
Well, I don't mean it that passionately, I just mean their general stance.
Like, they are not really interested in people making their own controls.
Are you saying you applied and got rejected?
Oh I think it is a great framework! But it still has limitations, some of which are imposed by Unity for seemingly no reason (Why view data and pseudo state internal...).
Yes.
Twice actually XD
But it's a pretty big (insane) story
I agree there are plenty of performance issues with UITK. But imo there are with imgui too. Just depends what tradeoffs you want. I’m sure they’ll improve it and even if perf issues persist (as they probably will) at least the team are really responsive on the forums (unlike almost every other team). I have many quibbles with many parts of uitk and there are lots or things that should work but are unusable. That said, so far I’ve been able to make pretty complex UI with decent perf, both runtime and editor.
Seeing as it's aiming to replace UGUI I imagine that will help motivate them to head towards a more performant outcome, at least more that then editor side
Is there a way to remove the text from a toggle. I already have a custom label ahead of the toggle and it pushes the toggle to the wrong place
The white square is the "rect" that the toggle is rendered in, I'm trying to either push it to the right side of that boundary or expand it so it fills the rect.
n/m I fixed it I guess
Here goes our chance of fixing a bunch of the crap in the editor
Is there a way to detect if a ContextualMenu (UI Elements/Toolkit) is closed without selecting any menu item? I essentially just want to be notified when the menu opens, and when it closes (for whatever reason).
Not for closing, but there is the ContextClickEvent when clicking the right mouse button, and there is ContextualMenuPopulateEvent for when a context menu requires menu items.
Full list of events https://docs.unity3d.com/Manual/UIE-Events-Reference.html
Is there a way to open a certain editorwindow upon opening Unity? I tried calling the button click function in the awake but it doesn't get called
You can use the [InitializeOnLoad] attribute to call a static constructor when unity loads (This includes like when enter/exit play mode and recompile scripts)
That's what I was afraid of, thanks though.
Do you just want to know when it was closed. Or specifically if nothing was selected?
My use case is: I want to highlight the element that has the context menu active, and remove the highlight when the context menu is no longer active.
I may be able to just assume that any click after a context menu is opened counts as the context menu closes, but I worry there may be edge cases there.
You could try something with the Focus events...
Hmm yeah there might be some clever way to accomplish this.
How do you repaint a control in IMGUI? I am trying to get hover style to work. I looked at the source but as far as I can tell I am doing the same thing...
Repaint()
Is there a nice way to do it within a class? Also, it doesn't look like GUI.Button calls repaint.
To do hover effect in IMGUI, you must enable EditorWindow.wantsMouseMove
Then call Repaint when the mouse enter your button area
I know a lot of things changed since the new UI and 2019.4
But it is basically how it was done before
But the default button doesn't require that stuff to work. Is it just not possible to recreate it without doing this stuff?
Also to repaint, does that mean I have to pass my class a reference to the editor window?
Yes, Repaint is called from an EditorWindow, somehow you need one
Or you can call RepaintAllViews() if you don't care
Well that sucks. Why unity always gotta make it so hard to mimic built-in controls :/
And you can't trigger a repaint by setting the event type I assume?
What would be useful is to have access to the current drawing EditorWindow
Hopefully Unity will release a new and improved Editor UI system soon. 
Here you go @gloomy chasm
static class Utility
{
private static bool initializeCurrentEditorWindowMetadata;
private static PropertyInfo current;
private static Type HostViewType;
private static FieldInfo m_ActualView;
public static EditorWindow GetCurrentEditorWindow()
{
if (Utility.initializeCurrentEditorWindowMetadata == false)
{
Utility.initializeCurrentEditorWindowMetadata = true;
Utility.LazyInitializeCurrentEditorWindowMetadata();
}
if (Utility.current == null)
return null;
object guiView = Utility.current.GetValue(null, null);
if (guiView != null && Utility.HostViewType.IsAssignableFrom(guiView.GetType()) == true)
return Utility.m_ActualView.GetValue(guiView) as EditorWindow;
return null;
}
private static void LazyInitializeCurrentEditorWindowMetadata()
{
Type GUIViewType = AssemblyVerifier.TryGetType(typeof(Editor).Assembly, "UnityEditor.GUIView");
if (GUIViewType != null)
{
Utility.current = AssemblyVerifier.TryGetProperty(GUIViewType, "current", BindingFlags.Public | BindingFlags.Static);
Utility.HostViewType = AssemblyVerifier.TryGetType(typeof(Editor).Assembly, "UnityEditor.HostView");
if (Utility.HostViewType != null)
Utility.m_ActualView = AssemblyVerifier.TryGetField(Utility.HostViewType, "m_ActualView", BindingFlags.NonPublic | BindingFlags.Instance);
if (Utility.m_ActualView == null)
Utility.current = null;
}
}
}
Just replace AssemblyVerifier with Reflection stuff and you're good to go
He was drowning in there before, let him breeze a little 😄
So I am drawing nodes inside an editor window as areas. However if 2 nodes overlap and I click somewhere on the upper (last drawn) node where there is no inputfield or button but the node below has one at that spot, Unity interact with the node below and select the field or clicks the button
Is there a way for an area to block any interaction for what might be "below" it?
Hi. I created a small custom struct with 2 floats, like so
public struct PolarVector
{
public float Angle;
public float Magnitude;
}```
and I created a class with an array of these. They show up in the Inspector like this:
but I'd like them to show up in a table view like Vector2 and Vector3
In my research, a lot of people are talking about creating a custom inspector. I have no experience with that and none of the guides or examples I'm finding are for a table view like this.
Honestly I just want to locate Unity's default Vector2 inspector code and copy it, but I can't find that either.
@spiral wasp What you want is called a PropertyDrawer https://docs.unity3d.com/ScriptReference/PropertyDrawer.html
@gloomy chasm after basically copying those first two blocks of code, I'm now getting this
I'm trying to read the full article but it's full of terms I'm not familiar with
So the first one uses Unity's new UIToolkit UI system. At the moment it doesn't work with PropertyDrawers unless the inspector they are in also use UIToolkit.
You are going to want to scroll down and use the one that overrides OnGUI
Yeah, I see now copying the third block does make the example work.
I was hoping it would be just a few lines of changing some attributes instead of telling it how to draw the entire inspector view, but if it works it works. I think I can modify it from here. Thanks again!
@spiral wasp This should get you close 🙂 Please look at the docs to help understand what some of the things are.
EditorGUI.BeginProperty(position, label, property); // This makes it so that things like the blue lines for prefabs showup properly and it handles overrides.
Rect valuesRect = EditorGUI.PrefixLabel(postion, label); // Makes label without any field and moves the rect over to the end.
valuesRect.width /= 2;
EditorGUIUtility.labelWidth = 35; // Unity has spacing between a label and a field, this sets what that space is. I just guessed on the size.
EditorGUI.PropertyField(valuesRect, property.FindReletiveProperty("Angle"));
EditorGUIUtility.labelWidth = 45;
// Move over to draw the next field.
valuesRect.x += valuesRect.width;
EditorGUI.PropertyField(valuesRect, property.FindReletiveProperty("Magnitude"));
EditorGUIUtility.labelWidth = 0; // Setting to 0 resets it to the default value.
EditorGUI.EndProperty();
You will also need to override the GetPropertyHeight method since it tells the editor how much height is needed in order to draw the property.
You can return EditorGUIUtility.standardLineHeight Which is the standard height for a single field line.
(Btw that is untested free hand discord code, so it may not work perfectly)
yeah, it had a couple typos, easy fix. Result is much better than I had gotten so far!
After a bit of tweaking, got it looking pretty good
valuesRect.width = 75;
EditorGUIUtility.labelWidth = 10;
EditorGUI.PropertyField(valuesRect, property.FindPropertyRelative("Angle"), new GUIContent("A"));
EditorGUIUtility.labelWidth = 12;
valuesRect.x += valuesRect.width + 3;
EditorGUI.PropertyField(valuesRect, property.FindPropertyRelative("Magnitude"), new GUIContent("M"));
EditorGUIUtility.labelWidth = 0;```
Why is the last labelWidth set to 0?
Per Mech's comment in his code:
// Setting to 0 resets it to the default value.
oh ok
I guess you should cache it then reset the cached value.
@gloomy chasm Labels are missing when it's inside of another struct
I really wish I could just look at the Vector2 GUI code and copy it...
OH, I just remembered something that would be handy! https://docs.unity3d.com/ScriptReference/EditorGUI.MultiFloatField.html
Nice! I'll try it in a bit
Certainly easier than using this guy's custom property drawer https://gamedev.stackexchange.com/a/151625
You will need to use EditorGUI.Begin/EndChangeCheck(), and set the serialized properties in the if for the endChangeCheck.
(There is also a scoped(?) ChangeCheck if you prefer that)
About doing a grid with IMGUI. When calculating the number of columns, how do I account for the vertical scrollbar? Right now it will overlap a bit before adjusting the column count, which looks ugly.
(Also, I got a got it basically done start to finish in one day and with half the the lines of code...)
Would anyone be able to point me in the right direction to making a scrollable editor window extension?
I need to make an editor window that mimics the infinite scrollable space of the scene window
That's pretty vague
Well, essentially I have a series of scriptable objects that link to one another
I am trying to create an editor window that will visually represent this chain of scriptable objects for me
since this chain of scriptable objects could be extremely large I would need a window that can be scrolled around in
something like this
You could look into GraphView, the same thing shader graph and VFX graph use
there's a tutorial pinned to this channel that goes over some basics
I will take a look, thanks
@visual stag this is precisely what I was looking for, many thanks
I want to copy a GUI.skin into my own style, do I have to initialize the style every time in OnGUI. I placed buttonStyle = new GUIStyle(GUI.skin.button); in OnEnable(), but I get the error; You can only call GUI functions from inside OnGUI.
make a property
that would still get called each time OnGUI is called when it draws the button
Sure, but you embed a null check in it so it's not initialising every time
ah, i see, ta
is it usual to just initialize the styles at the top of OnGUI?
I just use properties and use them where they're usually used
I have a button with image and text using the following code
greenLight = Resources.Load<Texture2D>("GreenLight");
sceneGreenButton = new GUIContent();
sceneGreenButton.image = greenLight;
sceneGreenButton.text = "Scene Configuration";
buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.wordWrap = true;
GUILayout.Button(sceneGreenButton, ButtonStyle, GUILayout.Width(150)))```
This makes a button with the image on the left, text on right, how can I make the text appear on the left of the image instead?
I'm not convinced this is possible
You can't using GUIContent. You would need to position and draw the image yourself.
I have a project which draws gizmos on scene models, in one version Gizmos.DrawLine() draws the lines on top of the model, however I recreated the app to refactor it and now the gizmos are drawn underneath the model. any ideas perhaps?
I know handles have a draw order/depth sorting thing
But no clue if that influences gizmos
I fixed it by replacing Gizmos.DrawLine with Handles.DrawLine, but i'd still prefer to know the reason
How to resize labels ?
GUILayout.Label("Settings", EditorStyles.boldLabel);
I want to make the text big
Working Thanks
Thanks! I actually remembered there is EditorWindow.mouseOverWindow which works perfectly for updating hover repainting! 😄
Be careful of mouseOverWindow, it can be null
Yeah, but I don't think it can be if I only access it to repaint on hover events. But will do a null check just in case.
Everytime I close and reopen unity my custom editor for my scriptable object loses all of its data.. any ideas? https://pastebin.com/m8Djby3Z
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.
Oh wait - is this not just because multidimensional arrays are not serializable?
don't combine set dirty and serializedObject
also multi-dimensional arrays are not serializable, yes
Okay I just removed serializedObject calls
That is depressing.. any way around it?
I need to serialize them
Lmao I have to write a multidimensional array serializer?
It's not that complex
Of course
An alternative would be to break your data structure up into multiple serializable objects that contain other serializable objects
you just need to move the data into 1 dimensional arrays
Just feel like thats a fairly common datatype
e.g. a single dimensional array of objects which each contain a single dimensional array of objects which each contain a single dimensional array of objects < to get a 3D array 🙂
That sounds like a decent way to serialize it, but working with that data format would give me a headache
Is there a way to edit the metadata for all of the sprites in a sheet? I can get the Texture2D and the sprites contained in it easily enough, but how do I write the changes I make back into the meta file?
Any idea why key up/down events would be being eaten by my IMGUIContainer and not sent from IMGUI to UITK? I made sure I am not Use()ing them, and there are no controls or anything that could eat them...
yo yo. dipping my toes back into reflection-ville and could use a hand.
Here is the field I want, hidden in Unity's code:
namespace UnityEditor.Modules
{
internal static class ModuleManager
{
[NonSerialized]
private static Dictionary<string, IPlatformSupportModule> s_PlatformModules;
...
Here's how far I've gotten
[InitializeOnLoadMethod]
static void GenerateModuleDefines()
{
// Get all the types in the editor
var editorTypes = Assembly.GetAssembly(typeof(Editor)).GetTypes();
// Find the internal static ModuleManager class
var moduleManager = editorTypes.FirstOrDefault(t => t.Name == "ModuleManager");
// and get its s_PlatformModules field
var modules = moduleManager.GetField("s_PlatformModules", BindingFlags.Static | BindingFlags.NonPublic);
// Get the dictionary object
object obj = modules.GetValue(null);
...
So I've got the dictionary as an object but can't figure out how to cast it to something usable.
I don't know how to cast it to Dictionary<string, IPlatformSupportModule> because IPlatformSupportModule is an internal interface.
Casting to Dictionary<string, object> is invalid so that's a no-go as well.
Any pointers would be appreciated! 💙
Could cast it to the none generic IDictionary. Might be able to cast to Dictionary<string, object> but I don't remember how casting works with collections exactly, I don't think it would work though,
ah sweet, ya the non-generic interface seems to be the ticket. i did not know about it, thanks! 😃
Reduce it to :
typeof(Editor).Assembly.GetType("UnityEditor.Modules.ModuleManager")
And yeah, MechWarrior is right, just cast it to IDictionary.
I never use LinQ in Unity, ever.
Why is that?
Dont have time for suboptimal code and GC garbages
I tried adding deleting of items to my tool, and it lagged bad, so I looked at the profiler... and uh... I think something may not be doing what I want it to... LOL
lol 24k calls
xD
I have some ideas what may be happening, but I wish that it game some more details about what is calling it.
Ooh, I managed to get it up to 35k calls!
Oh cool... it is Undo.RecordObject()....
Anyone have any tips for getting started? Trying to make a tool for a Game of mine, It would using Nodes
Do first, and come back with problems 😄
Can someone explain the performance difference between Undo.RecordObject and Undo.RegisterCompleteObjectUndo? Because right now Undo.RecordObject is still creating a lot of GC calls, and lagging, which Register doesn't.
I'd imagine register would do so too
Nope, register doesn't have the same GC lag problem.
I know Record makes a diff at the end of the frame. But I'm not sure what exactly it does thus not sure what to change to optimize for it.
My concern with Register is that overtime it would bloat the memory maybe.
hey all, im having a weird issue where im trying to get something like a label as a timer in my editor window to update constantly, and its not working. i have the timer drawn in OnGui and then i call Repaint() in Update but for some reason, while Update itself is working (spammed console with debug to test), the Repaint portion isn't and the timer label only updates whenever the window is moved. sorry for the novice question, but any help is appreciated!
How often are you calling it that you're noticing performance issues??
Just call it when changes occur
Just once...
You can scroll up a bit and see the screenshot of the profiler with a single call. I did some refactoring and got it down to ~10k calls.
Hello, so I'm making a "portal" editor window for a team project. The team requested that I make an editor window that lists important links and reminders. This window has to be booted when the project opens up and not on compilation loading (or else it will load every time unity recompiles). How do I do that?
SessionState
I don't understand why this code isn't working
ScreenCapture.CaptureScreenshot doesn't create any files
[MenuItem("Tweaks/Screenshot", priority = 2)]
public static void Screenshot()
{
Debug.Log("Screenshot written to screenshot.png");
ScreenCapture.CaptureScreenshot("screenshot.png");
}
I used a
GUIStyle myStyle = new GUIStyle(){ wordWrap = true, };
on my GUILayout.Label, and now the text also turns black (it used to be white. I have dark theme on)
Is there a thing to detect a theme's default color for text for example?
hi guys, i wand to build an editor extension (delivered via package manager) which talks to and external service and has some editor ui. do you have any tutorials you could recomment me so i can get started faster that digging through docs? I think i'm mostly interested in linking a managed dll to the editor ui?
The problem is that what you are doing is creating a completely new 'unstyled' style. There is EditorStyles.label, which is the default style for labels. You can make a copy of the style by using it as a parameter in the GUIStyle consturctor. Lucky for you there is EditorStyles.wordWrapLabel! (It isn't called that exactly but that will get you close)
Which part are you not sure how to do, I assume you mean making custom editors in general? Just googling "unity editor scripting" will come up with a bunch of resources for getting started. Including an official unity learn guide, and the docs for "Editor" which contains an example of how to get started.
Hmmm, I tried looking how to use SessionState and EditorPrefs, but I cannot seem to get anywhere. Do you know how it works in this case?
SessionState is like EditorPrefs, but only for the lifetime of the process
EditorPrefs is persistent
yes, I expect some editor scripting, but is that it? just have a class that wraps the dll and integrates with the editor UI?
So I assume I can use SessionState to get a boolean on whether the project has booted up or not?
I don't really understand what you are asking. But I think so?
Exactly
yeah, I don't know which questions to ask yet. never did editor stuff before
Yo Mikilo, do you know any downside to using Undo.Register instead of Undo.Record?
I guess just start, and then ask questions once you run in to problems (Don't forget to google though!).
no idea
@gloomy chasm the use case is that if your object is so big that a diff would take a long time but not sure why it's not allocating memory
Is there a way to just replace a gameobject with another, but keep all of it's properties and children? Like when you have a capsule that can move but you want to change the capsule to a character model. Thanks
Uh... just change the mesh/render/filter and animator?
you can do that?
This is not the right channel for this conversation. I would also recommend reading the docs https://docs.unity3d.com/Manual/class-Mesh.html
(There is also the mesh filter and mesh render pages on the side, I would read those as well.)
ok thanks
Does anyone know a simple LUA plugin which isnt xlua or moonsharp (since m# is basically discontinued)
Hey so update. I looked over the documentation for SessionState and I am unable to find how the key works for the startup option. Should this also be done on awake? I am not sure how to tackle this
It works the same as EditorPrefs.
You set a key on any startup (OnEnable, InitializeOnLoad, etc) and prevent from executing a 2nd time if it exists
Should a PropertyDrawer GetPropertyHeight include a standaredVerticalSpacing?
Only between the properties you're rendering iirc
back with some questions. I have an sdk client library (api client) with target framework : .net standard 2.0, which I've imported into unity (copied the dll into Assets/plugins folder). Now unity throws a bunch of errors that it cannot load references, even though i also copied the referenced dlls into the same folder.
Assembly 'Assets/plugins/System.IdentityModel.Tokens.Jwt.dll' will not be loaded due to errors:
Unable to resolve reference 'Microsoft.IdentityModel.JsonWebTokens'. Is the assembly missing or incompatible with the current platform?
Microsoft.IdentityModel.JsonWebTokens is also copied into the same folder.
Is there another approach here I'm not aware of?
Chances are that Microsoft.IdentityModel.JsonWebTokens is failign to load because of some other error
yeah, I resolved most, but i've reached the end of the chain:
Assembly 'Assets/plugins/Microsoft.Extensions.Http.dll' will not be loaded due to errors:
Reference has errors 'Microsoft.Extensions.Logging'.
Microsoft.Extensions.Logging is the correct version (according to nuget) and this is the last error I get related to it.
ah, scratch that
ok, solved all of them. some were caused by an incorrect dll version which broke referencing upchain
I would still appreciate some help with a remaining error:
Failed to extract MyDll.ErrorDetailsConverter class of base type Newtonsoft.Json.JsonConverter`1<System.Collections.Generic.List`1<MyDll.Details>> when inspecting Assets/plugins/MyDll.dll
UnityEditor.AssemblyHelper:ExtractAllClassesThatAreUserExtendedScripts (string,string[]&,string[]&,string[]&)
Can't find anything relevant on the webs
where MyDll.ErrorDetailsConverter is a JsonConverter:
public class ErrorDetailsConverter : JsonConverter<List<Details>>
{
// ...
}
and is being used in an attribute on a the Details property:
[JsonConverter(typeof(ErrorDetailsConverter))]
So i found SceneView.pivot to change the pivot of the rotation in scene view, thru code
But changing this also moves my scene's camera to center to that object/position
Is there a way to change only the rotation pivot without changing the camera whatsoever?
There's a field on the Tools class iirc but not sure if it has a setter
Hmm i dont think Tools is what im looking for
It's the rotation pivot when u do alt + LMB + drag in scene view
@gloomy chasm in case it’s of interest I stumbled across this: https://forum.unity.com/threads/share-your-ui-toolkit-projects.980061/#post-6660406
Well dang it... Thanks! I will try out what he does and see how the performance really compares. He also needed it for a tool that is the exact same idea as what I'm doing... cooooolll.....
how can you enable/disable IL2CPP builds in scriptable build pipeline?
Looks like he is just drawing textures, you are dealing with texts, much heavier no?
That is what I thought at first as well, but I looked at it a bit (Tiny bit) and it looks like he has text as well.
Opinion please. How is this for a Stack<> property drawer?
You can edit the other elements, they are just grayed out.
I'm not sure if that is best though.
Right now the remove button removes the selected element, I'm thinking I should change it to remove the latest element though?
And I'm not sure about the spacing, it looks a little silly when selecting the last element since it lights it up, and makes the space more obvious.
Visualizing a stack as a stack makes not much sense in this case, you probably want to treat it as a normal list while making sure it's clear that it's a stack and the order in which items are being popped
So, just have it act and look like a normal list in the inspector except for some sort of indication of what the top item is?
That's pretty much what I'd do
There's no reason to not allow things like reordering and removing items from the middle since it's not runtime
I guess so
Any recommendations on differentiating the top item?
"Top"
That is a good idea, I feel like a bit more would be good as well though (maybe just me).
?
Well you asked for UX suggestion
Yes and I appreciate it, but I don't understand where you mean to put an arrow(s).
"Top" is good and should be enough, but a stack can be visualy directional, put an arrow 😄
Put them everywhere
We dont use them enough to my taste
@serene spear #↕️┃editor-extensions message
my thing is an enum
Keep in mind that variables in a custom editor script (regular class variables) are reset when you open the window/type again. Should be using values from the object you are giving a custom editor to instead.
Yes. All of these get reset when you reopen the editor for the type
Oh
You should be using the values from your object
editors do not have any persistence once closed
Which is why vertx linked you the message
that part you're doing fine though, the values you're drawing from your SO should be saved
so if I had this in the above NPCDialogueData, it would be fine?
just the ones in your editor will not
The Editor also provides the serializedObject (a property of the same name) for the object its inspecting, so you shouldn't need to create one yourself
You creating one yourself may actually not be compatible with that, though I'd have to test to see
you should just use the property regardless
alright I fixed it by putting it in the data class instead
I am having some issues with installing this library in unity. https://github.com/Unity-Technologies/2d-extras
I am using unity 2020.3.8f1 and I have tried using all of the branches on the GitHub for different versions of unity. The error I keep getting is:
Library/PackageCache/com.unity.2d.tilemap.extras@da71076aeb/Editor/Tiles/RuleTile/RuleTileEditor.cs(297,82): error CS1061: 'ReorderableList' does not contain a definition for 'IsSelected' and no accessible extension method 'IsSelected' accepting a first argument of type 'ReorderableList' could be found (are you missing a using directive or an assembly reference?)
It produces 3 errors all identical, but they list different line / column numbers in the error.
Wrong channel but it's likely not supported in the unity version you're using
Oh, sorry! is there a better channel for this post?
Probably #🖼️┃2d-tools or #archived-code-general
Or open an issue on the repo
It's already there
oh
is there a way to take what the length of a string would be if printed in an editor popup window and have the windows width auto adjust based off that?
GUIStyle.CalcSize
ty
yo! what is this channel about?
do you happen to know what other considerations should be used when using GUIStyle.CalcSize? It keeps falling short just a little bit
do you even use the correct style?
Doing cool stuff
so first I did GUI.skin.everyOption.CalcSize(new GUIContent(example); where everyOption was everything I could find between label, button, etc... example is my string. Once that didn't work I actually tried replicating the unity scripting api page for GUIStyle.Calcsize, except new GUIContent("text) being my string again.
as an example of falling short
what do you use to draw "Do you..."?
it's not drawing, it's opening a popup
is my popwindow stuff currently
oh okay. I'll look up drawing
boldLabel
probably
okay, thanks. Sorry I missed that, let me try it out
thanks again. Works better than I thought even
How do you store a reference to a subasset without loading it? You have GUIDs for main assets. But from what I know, subassets don't have GUIDs.
They have a sub id
GUID is for the asset file.
Each sub-asset has a FileId:
I have this little utility in NG Tools
Ah, is that the localIdentifier I have seen referenced before?
Yes
Like GUID
They have some flaws, but I guess if you dont go too far it should work out of the box
Like what?
Int64 overflow
Since when?
Some internals in older version were providing Int32 FileID
Pretty sure mine don't do that 🤔
They implemented Int64 recently (meaning few years only)
2018 if I recall correctly
I gotta check my code then
Because of that, the method might probably work in older versions, but it's not 100% guarantee, if you are unlucky the 32 first bits are matching, but not the 33rd
let me drop you the internals
Unity serializes long... right...?
I think so
That's slightly worrisome
No clue, you probably have more luck in #💻┃unity-talk or the forums
InstanceIds don't survive editor sessions right...?
it does
How the heck does LazyLoadReference work then...
All it saves is the instanceID https://github.com/Unity-Technologies/UnityCsReference/blob/2019.4/Runtime/Export/Scripting/LazyLoadReference.cs
Only thing I can think of is the ForceLoadFromInstanceID, but not sure how it would know what to load still...
Isn't instanceId bound to the lifetime of the object and doesn't guarantee that when it's recreated that it has the same one?
The only guarantee afaik is that it's unique and thus good for comparing whether objects are the same and passing to the cpp layer
I am just trying to figure out a good way to reference lots of assets without having to load them. I was going to do my own thing with just GUIDs and local identifiers. But if lazyLoadReference works, then that is great.
However I don't really like the idea of using it since I can't figure out how it is working.
You are partly right.
Runtime Object created in a scene will see its ID gone forever.
But existing Object in the Editor will survive a domain Reload.
But not unity restarts?
It's been a while since I messed with this so good to get a refresher 😉
This one looks interesting Object.ForceLoadFromInstanceID
From what I read, it just remembers Object from their InstanceID, which makes it non-persistent
persistent as in "can survive DR, and Unity Editor restart"
You running after FileID means you want real persistency, LazyLoad does not provide that from what I understand
But just give it a try, if you want to make sure
Well the whole point of the lazyload is that it is persistent.
So I just did a test, and it seems like the instance ids are persistent between editor sessions...
Close the unity editor and then open it up again.
Just because they can be doesn't mean they always are
Navi is right. It might be pure luck.
IIRC it's just an incrementing number + a bit of magic for different things
If nothing in your project changes then iirc it'll often be the same or similar
Nowhere in the code of LazyLoad I see a persisting ID or meta or anything that can hold something between processes
That is what is confusing to me
different things
IIRC assetdatabase objects are negative and runtime objects are negative
Read the docs. The whole point is that it does save.
https://docs.unity3d.com/ScriptReference/LazyLoadReference_1.html
That is why I am confused since as far as I know, you are completely right about the instanceIDs persisting/not persisting.
Yet this thing seems to indicate otherwise.
They're doing if (!Object.IsPersistent(value)) which makes me think that perhaps something changed
This is editor namespace though right? Don't you want runtime save/load?
It is yeah
Afaik the only way to do properly persistent id's is to just do it yourself
I will for now yeah. But I am going to ask on the forums and see if I can get someone from Unity to explain it...
The doc is not even clear
I mean
Look for 'm_DefaultMaterial'
Do you see one single assignemnt?
I don't get the point of this example
I assume it is assigned in the inspector.
It's generic, that doesn't serialize in 2019
It isn't serializing a generic though.
My guess is, it specifically targets this ScriptImporter flow
Actually there's a drawer for it, does Unity serialize generics as long as you don't have a field of that type?
//----------------------------------------------------------------------------------------------------------------------
// What is this : Custom drawer for fields of type LazyLoadReference<T> that filters presented candidate list to assets of type 'T'.
// Motivation(s): default object field drawer is not aware that the generic argument of LazyLoadReference<> should be used
// to filter the list of candidate assets.
//----------------------------------------------------------------------------------------------------------------------
[CustomPropertyDrawer(typeof(LazyLoadReference<>))]
internal sealed class LazyLoadedReferenceField : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
System.Type fieldType;
ScriptAttributeUtility.GetFieldInfoFromProperty(property, out fieldType);
EditorGUI.BeginChangeCheck();
var value = property.objectReferenceValue;
position = EditorGUI.PrefixLabel(position, label);
value = EditorGUI.ObjectField(position, value, fieldType.GetGenericArguments()[0], false);
if (EditorGUI.EndChangeCheck())
property.objectReferenceValue = value;
}
}```
It can serialize classes that take generics, but it could not serialize generic fields.
Field as in public T value
Cool
Well, Unity apparently also doesn't know what to do with it
/// <summary>
/// Implicit conversion from asset instance ID to <see cref="LazyLoadReference{T}"/>.
/// Calling this never triggers a load.
/// </summary>
/// <param name="instanceID">The asset instance ID.</param>
public static implicit operator LazyLoadReference<T>(int instanceID)
{
return new LazyLoadReference<T> { instanceID = instanceID };
}```
This hurts though
Why does it hurt?
Because that implicit conversion has no guarantees and is not safe
What do you mean?
You can pass any number into it and it'll magically be a LazyLoadreference that points to something that might not even exist
But you can already do that since you have access to the InstanceID...
isBroken only works when it is loaded
The thing is, a constructor accepting a instance Id is okay because you can clearly see that it's being created. Compared to you passing a random number to a method that is magically converted to a LazyLoadReference
I think it should work whether it is loaded or not. It just checks if it exists, doesn't load it I think.
Is there a good way to load a sub subasset... :/
I don't care if the main one is loaded really, I get that that is unavoidable. But getting a sub-asset seems to be a pain, having to get and then compare localIDs (Not actually tested this yet)
I mean it isn't the worst. But like, this feels really inefficient.
public static Object LoadAssetFromReference(AssetReference reference)
{
var assets = AssetDatabase.LoadAllAssetsAtPath(reference.Path);
foreach (var asset in assets)
{
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out _, out long localId))
{
if (reference.LocalId == localId)
return asset;
}
}
return null;
}
Looks beautiful to me
🙂
Anyway, InstanceId would not work for your case
Fyi there is the LoadAllAssetReferences (or some similar name) which is only subassets
hi all, a bit new to editor extensions and all that, but would any of you know if its possible to have an inspector field display a different type of input menu depend on the type of something? like for example if the type of an object is float, then itll give the float input field. but if its a bool, it will give a checkmark
im not sure if i phrased that correctly
but hopefully youll understand
Uh... maybe you didn't explain it well. But from what I understand of what you described, that is exactly how it works. There is no 'inspector field', there is just a series of float, int, string, Object, enum, and toggle fields.
(You can make your own drawers('fields') for different C# types, but that is beside the point)
lol i suppose i didnt explain it well
so like
lets say i have
object f;
wait actually i dont even understand my problem
nevermind lol
hi. how do I make an ObjectField (UI tookit) accept any asset type?
I'm trying to draw some text in the scene, however this isn't working cs GUIStyle dstyle = new GUIStyle(); dstyle.fontSize = 50; Handles.Label(Vector3.zero, "Some Text", dstyle);
what's the context to this code
an editor window
i placed it in OnGUI
and a handles scope?
i don't know
you will also need to do it from the scene view gui
which is OnSceneGUI in an Editor. I think EditorWindows will need to register to SceneView.duringSceneGUI or something similar
is there an easier way to just draw some text to the scene view
Sorry, I don't think you actually need the scope, that's just if you want to draw a normal GUI label. You just need to call your function from the scene view's GUI
i'm not sure what you mean by from the scene views' GUI
I found a different way to do it, thank you for your assist in any case.
I mean by calling Handles.Label in https://docs.unity3d.com/ScriptReference/SceneView-duringSceneGui.html
anyone know how to register a method with params for a button click in ui toolkit?
Do you mean like this new Button(() => MyMethodWithParams(25, false));?
similar
or I guess myButton.onClick += () => MyMethodWithParams(25, false);
Does that answer your question?
downloadBtn.clickable.clicked += () => { MyMethodWithParams(25, false); };
i went this route
thanks @gloomy chasm
Uh, that is quite redundant.
onClick is obsolete
They changed it to clicked my bad.
Internally btn.clicked += MyMethod; just does btn.clicked.clickable.clicked += MyMethod;
It is just extra steps. (I mean it does exactly that)
i just folowed the docs
Well yes, if you do you clickable that is how you would use it. But using clicked is faster.
https://github.com/Unity-Technologies/UnityCsReference/blob/master/External/MirroredPackageSources/com.unity.ui/Core/Controls/Button.cs#L81
Any clue how i can fix this clipping issue
its already at 0.01
this is in-editor btw
Make the clipping smaller if you can. Otherwise I would recommend reconsidering your design, generally you don't need things to be that small. Further discussion would be best in another channel since this channel is for extending and adding more/new features to the editor.
Only asked here because it's editor related (SceneView camera). Where would you continue the conversation?
I understand, that is a common reason people ask here. Since it really doesn't have anything to do with programming (unless you are wanting to try making an extension that manually sets the clip distance). #💻┃unity-talk would be best I think.
Thanks.
How do I get a Reference of an Object when Clicking on it in the Scene Viewer?
how can I check what input system is being used right now? (in code)
is it possible to make reorderable lists support adding elements with multiple object selected without the list values being reset?
Is this your own code or the new default ones?
If I don't set the onAddCallback and let the default behavior run I get this warning
but if I try and implement it myself I don't get the popup, but different values are still lost
list.onAddCallback = list =>
{
list.serializedProperty.InsertArrayElementAtIndex(list.count);
};
I think the problem is that they all use the same editor they are all using the same instance of the ReorderableList.
Could try getting the serialized property from the editor instead of from the RL
@gloomy chasm Ok, tried a couple more things but no luck. Are either of these attempts lookin close to what you're thinking?
list.onAddCallback = list =>
{
// 1. throws exception: InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)
foreach (var t in targets)
{
SerializedObject so = new SerializedObject(t);
so.FindProperty("swatches").InsertArrayElementAtIndex(list.count);
so.ApplyModifiedProperties();
so.Dispose();
}
// 2. loses unique values
serializedObject.FindProperty("swatches").InsertArrayElementAtIndex(list.count);
// 3. also loses unique values
list.serializedProperty.InsertArrayElementAtIndex(list.count);
};
looks like this works?
list.onAddCallback = list =>
{
Undo.RecordObjects(targets, "Add Palette Element");
foreach (var t in targets)
{
if (t is Palette palette)
{
palette.AddDefault();
}
}
serializedObject.SetIsDifferentCacheDirty();
serializedObject.Update();
};
Well done 🙂
Hello everyone, was wondering something I tried to google but to no avail. I'm trying to create a Mask attribute for my string[], so that I can select multiple options from a determined array. I think I can learn my way to create the mask part but the issue is that attributes affect the children and not the array itself. Is there some way I can achieve this? I believe I could create a wrapper class and make a property drawer for that, but I'd REALLY rather not...
Does anyone have a nice serializer/property drawer for dictionaries? i tried googling it but i couldnt find anything
oh i mightve just done found it https://forum.unity.com/threads/finally-a-serializable-dictionary-for-unity-extracted-from-system-collections-generic.335797/?_ga=2.117506506.234555679.1621481763-941283105.1594593299
Sadly Unity does not support drawer attributes for collections. It applies the attribute to the item's in the collection.
using an editor window, are there conditions where an Update() will stop executing mid flow? I have the following code cs void Update() { if (!EditorApplication.isPlaying) { string text = ""; if (Time.realtimeSinceStartup - lastInvokeTime > interval) { lastInvokeTime = Time.realtimeSinceStartup; if (CheckForChange()) { text = "changed"; lastChangeTime = lastInvokeTime; } UpdateGeometry(); } if (hasChanged) { text += " hasChanged"; if (Time.realtimeSinceStartup - lastChangeTime > maxInterval) { text += " doUndoRed:[" + !doUndoRedo + "]"; if (!doUndoRedo) { Debug.Log("DoSomething"); DoSomething(); } ...
However, in console, doUndoRedo is set to false (!doUndoRedo == true) and DoSomething is never called
Attach a debugger?
Also if text is logged with doUndoRed:[" + false + "]"; then !doUndoRedo won't be true
I get no debug message for DoSomething, even though it should be reached. I've tried that, and also tried putting a try/catch in there
if doUndoRedo = false, then if(!doUndoRedo) will return true
console message: hasChanged doUndoRed:[True] and DoSomething was not called
No if your log is false then doUndoRedo is true
You're logging the inverse
I misread nevermind
I'm completely stumped why the code within the if statement isn't being called, despite the condition returning true
There should be no reason, if you attach a debugger and step over it does it just disappear? where does it go?
it's an rare case, I've tried hundreds of times to catch the issue, but it's very sporadic
ah, never mind, this isn't the issue
i had forgotten that I was outputting at the end of the fn, so the code is being called.
Hey people! I'm creating an editor tool that has both OnInspectorGUI and OnSceneGUI. I'm moving some handles in OnSceneGUI that set a property directly in target. Now in OnInspectorGUI I'm accessing that property with serialized property, however it does not seem to update, unless I deselect the object, reopen the inspector or change some values directly in the inspector... Any clues?
Why does it not detect that the original property value is changed?
Are you applying your SO?
Ummm... I've tried to apply it, but I get a bunch of errors, that I can't do it in OnSceneGUI.
0.o
Well, you probably have to repaint your inspector as otherwise it won't redraw and thus the fields won't update
Oh, okay. I'll give it a try. Thanks.
Nope.
Actually, I think the inspector is not the problem.
Gotta see some code then
for some reason neither hastebin nor hatebin work for me xD
Hastebin doesn't work anymore. https://paste.mod.gg/
Huh. What happened?
No idea, this is third hand knowledge from me 😛
@waxen sandal actually the problem was with something else. 😅
The monobehaviour that the property is in was not updating.
Still is not...
event though it's execute in editor and has update. Gotta check when it's called...
I'm using
public int typeReferenceIndex = 0;
public int objectListReferenceIndex = 0;
public Dictionary<int, System.Type> typeReferenceDictionary = new Dictionary<int, System.Type>();
public Dictionary<System.Type, List<Object>> objectListReferenceDictionary = new Dictionary<System.Type, List<Object>>();
eith enabled popup
typeReferenceIndex = EditorGUILayout.Popup(typeReferenceIndex, typeReferenceList.ConvertAll(i => i.ToString()).ToArray());
objectListReferenceIndex = EditorGUILayout.Popup(objectListReferenceIndex, objectListReferenceDictionary[typeReferenceDictionary[typeReferenceIndex]].ConvertAll(i => i.ToString()).ToArray());
is there a smoother way of writing this out?
I can't tell exactly what you are doing. But Trying using lists and .IndexOf() instead of dictionary.
okay, ty! I'm just trying to create some extensions for developers to be able to create items essentially with our own spice on things. The above works, but, was thinking it might be sloppy if others looked at it?
I can confirm that it is quite hard to read and figure out what is going on (Of course I have no context for what it is doing, but still).
If I am reading it properly, the first typeReferenceDictionary should really be a List/Array, doing otherwise is just complicating things imo.
And for that last popup I would at least separate it out in to one or two local variables to help improve readability.
Idk how you have it setup, but it could be a good idea to just store the object strings instead of the objects (No clue if this makes sense for how you are using it though since I don't know the full context)
I appreciate the advice! Going to fix it up to be nicer
When I call animator for my custom editor, should I call Animator or RuntimeAnimationController?
Animator doesn't allow me to use the Animator from my project, but RuntimeAnimationController does
I'm editing a ScriptableObject directly at design-time and have a class that implements the ISerializationCallbackReceiver interface. However, when I set a nonserialized field, OnBeforeSerialize is not called, but After is. Is there some way to tell unity I want it to serialize the asset right now?
Hi, i'm currently making my own level editor, and wanted to change a level prefab's background from the editor. I have done the integration but i cannot get the background to save in the game, it's showing in the prefab edit scene, but not in the game
here's my current code
but editorscenemanager.getactivescene() returns the scene where the prefab is placed, not the prefab scene itself
so far, nothing works, and i've been struggling for days
So are you trying to edit an instance of a prefab, or the prefab asset itself?
Then you want to do this
// Load/get the GameObject of the prefab.
GameObject prefabRoot = PrefabUtility.LoadPrefabContents(assetPath);
// edit prefabRoot here...
// Save the GameObject back to the prefab.
PrefabUtility.SaveAsPrefabAsset(prefabRoot, assetPath);
PrefabUtility.UnloadPrefabContents(prefabRoot);
okay let me try
There is a handy scope struct for doing it https://docs.unity3d.com/ScriptReference/PrefabUtility.EditPrefabContentsScope.html
my unity crashes after doing this XD
probably because i'm putting it in awake and executing it in edit mode
Yeah, that is most likely it.... Why are you doing this in a Component anyway...
so what i do is i try to do something like this
when i click on a background, it will save the path of the background that i'm choosing on a temp script
then when i hit save, it will load the sprite from the path to the saved temp script
and then from the component, i'm running it in edit mode to change the background
here's the code for saving on temp script
selectedBackground = GUILayout.SelectionGrid(selectedBackground, backgroundImages, 1, GUILayout.Width(position.width/11.1f), GUILayout.Height(position.height*backgroundImages.Length/9.5f));
UnsavedEditorData.selectedBackgroundPath = backgroundPathList[selectedBackground];
Why are you using a component to do that? Why not just do it from that editor window?
how would i do that ?
Get the prefab?
I am having a hard time following what you are trying to do, so it is a bit hard to give advice.
okay, i will try this method first, and if it doesn't work i'll come back here again
thanks
I've solved it with your method, thank you very much @gloomy chasm sorry for tagging
is there a way to automatically format the numbers in input fields?
ie to always show a certain number of decimal places
because even if you type 1.5000 it will shorten it to 1.5
hello, would it be possible to use a NaughtyAttributes Scene property in an EditorWindow?
to produce a dropdown from which to select a scene
there's not much information online about using NaughtyAttributes stuff in EditorWindows
hmm yes, I think it is: https://dbrizov.github.io/na-docs/attributes/drawer_attributes/index.html
sorry I'm not very clued up on editor scripting, I'm still a bit lost : /
EditorGUI.PropertyField() takes a SerializedProperty - how do I define this property to be a naughtyattributes Scene one?
So you have a field with a scene attribute on your editor window?
Can you give some more context to what you're doing?
Sure, I just want an editor window that has a dropdown with the available scenes
I see that NaughtyAttributes has ScenePropertyDrawer: https://github.com/dbrizov/NaughtyAttributes/blob/master/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/ScenePropertyDrawer.cs
What code you have atm?
private void OnEnable()
{
var obj = new SerializedObject(this);
mainStationProperty = obj.FindProperty(nameof(mainStationScene));
}
#region Quick Build Tab
[SerializeField, Scene]
private string mainStationScene = "TestStation";
private SerializedProperty mainStationProperty;
private void ShowQuickBuildTab()
{
NaughtyEditorGUI.PropertyField_Layout(mainStationProperty, false);
}
#endregion
This is in a class inheriting from EditorWindow right?
yep
In that case you want to make a SerializedObject field in your class and assign it in OnEnable with new SerializedObject(this)
Then you can call FindProperty("stationScene2") to find the SerializedProperty
awesome, thank you kindly!
I've updated the code and posted a screenshot if you or anyone else is curious
Might want to call Apply on the SerializedObject if there has been a change to the propertyfield
Look up (Begin|End)ChangeCheck
great, thank you
Best to check the source
how do i make my editorwindow aspect ratio stays ?
Change to size to match the aspect ratio when it diverges (aka the user changes it)
where exactly ?, sorry if this is a noob question
OnGUI should be called when the size changes
So you can just check whether it matches your aspect ratio
lets say the user resizes the width, do i change the height ? and vice versa ?
how do i know when the user change the width tho ?
Depends on the behaviour you want
just check whether the size is different from last frame or doesn't match your aspect ratio
I wouldn't recommend this behaviour though since it's a pretty shitty user experience
i wanted it to be resizeable, but not freely
Hi everyone, does anyone know the answer to this question
https://answers.unity.com/questions/1434594/guilayout-selection-grid-colour.html
Unity is the ultimate game development platform. Use Unity to build high-quality 3D and 2D games, deploy them across mobile, desktop, VR/AR, consoles or the Web, and connect with loyal and enthusiastic players and customers.
i wanted to make the selection in guilayout.selectiongrid more pronounced
Does anyone know if it's possible to save changes to the uv's in the meshfilter.sharedmesh so it does not revert back after closing and reopening Unity editor?
The meshes are fbx files imported into Unity and used in prefabs.
@livid tinsel you'll need to save a copy of the mesh elsewhere. You cannot persistently modify mesh data that is a subasset of an FBX for example because the AssetImporter will just blow it away when it checks for changes.
Also worth noting that there's nothing wrong with saving Mesh data to a prefab
Thanks a ton I will have a look at using that method. I was trying to combine textures into an atlas then using a new material on all of the meshes. They currently have one material per mesh, probably because of a unique texture that belongs with each mesh.
fo sho. Also I suggest you make good use of https://docs.unity3d.com/ScriptReference/EditorGUIUtility.PingObject.html to figure out wtf asset you're pointing at heh
Cool I'll have a look.
I'm hoping to get rid of 99% of the materials in my models.
a worthy goal 😛
Just ran in to another hard to reproduce bug with [SerializeReference] in the editor 👌
It is such a nice idea, but it is just too unpredictable to use for anything but the most basic use-cases 😦
If you can report it with a repro it'll get us closer to that goal :)
I gave up on it and just use odin again, almost any time I use it in practice it breaks
I have 6 bug reports open on it
=x
Yeah, that is the paint though. All the bugs are ones that are either hard to reproduce, or require complex setups. I will see about reporting it though.
Their warning about prefabs maybe not being supported scared me off of it tbh 😛
Every time I try to make a complex tool with it it generates loads of bug reports for me and then I put the tool on hold
It is what it is, I'm glad it exists even if it's buggy. They seem to care about the reports more than other areas of the engine I've had issues with
Personally never had an issue using odin but yeah you always run that risk using any 3P tool. Stability wise it's leaps and bounds ahead of unity's serialization though
yeah, it's a really good idea it's just not really in a usable state
even graph foundation API has to use serialization workarounds internally =x
Ah.. I see... perhaps I should see about doing some optimization...
Haha really? Not surprising I guess. Does it even use SerializeReference? Or just json?
it uses [SerializeReference] but also has to use ISerializationCallbackReceiver to hack around some particular issue
I only stumbled on it because of a serialization bug I was trying to solve 🤣
LOL, nice.
Hmm.. 3.4 million GC.Alloc calls when I delete a collection of items... I think I may be doing something wrong...
Looks like it was Undo.RecordObject... yep still no idea how it works or what it does...
many times you dont need to explicitly use Undo calls, do you have some context?
also, I do not recommend [SerializeReference] unless you know exactly why it's useful - the applications are surprisingly narrow.
In this case it is needed. I am adding/removing items (references to assets to be specific) to a ScriptableObject asset. Undo.RegisterCompleteObjectUndo doesn't have the same problem, so I just use that.
Yeah, I know how, when, and what to use it for. The problem is that it is unstable 😛
For example, having a tree structure with 3 levels will break on a prefab variant.
And it doesn't seem to play nice with Undo under some conditions (Didn't test enough to know which conditions though)
How are you modifying the SO?
generally you can just ApplyModifiedProperties and its done
I am modifying the instance directly (not using SerializedObject). It is for the editor only and would be far more work, and much less convenient if I used SerializedObject instead.
using SerializedObject in the editor is way easier
That is the case most of the time. But that is not the case here. I have a tree data structure which is the only thing I interact with. And I store references to assets in the nodes of the tree in HashSets. So a lot of it is either not serialized or would require multiple steps to get the same info, also would have much worse performance.
The only upside of using SerializedObject in this case would be the built-in Undo support.
These scriptableobject values don't persist when I restart Unity, they keep setting themselves back to true
Are you setting them there in the inspector or through script?
I display these fields through script, then set them in the inspector
Are you using SerializedProperties? And if so are you making sure to ApplySerializedProperties()
it seems like only this one object is having this problem, all the rest are fine, here's the script where they're being set
ApplySerializedProperties()?
there are a lot of these Apply things I don't know about
I see, you don't want to use SerializedProperty and also directly set values. The best thing to do is to only set values using SerializedProperty
I use ApplyModifiedProperties()
I'll be honest I don't know what Update does
I'm still new to editor scripting stuff
Good, that is what I meant to say. I just slipped and set the wrong thing.
so this is right?
Yes but no. Editors already have a serializedObject property you can use, no need to make your own.
Correct
And you only want to set values using SerializedPropertys. So don't do things like npcDialogueData.hasInteraction = EditorGUILayout.Togggel(.....);
I thought that was how you were supposed to set bool values like value = EditorGUILayout.Toggle() I always thought it was very dumb
Instead you would do.
SerializedProperty hasInteractionProperty = serializedObject.FindProperty("_hasInteraction");
EditorGUILayout.PropertyField(hasInteractionProperty);
(_hasInteraction should be the name of whatever your serialized field is called)
does EditorGUILayout.Toggle support serialized properties, everything I've seen of it only supports bools, is that why you would make it a var?
You can also do hasInteractionProperty.boolValue if you want to set or get the value that way.
That makes more sense