#↕️┃editor-extensions
1 messages · Page 30 of 1
I've heard about ListViews! But wouldn't I need to manually "build" a ListView by looping through a property and bind it or something?
Or can I declare an already created list as a "ListView"?
If your ListView is in your VisualTree, you can query it and assign a makeItem and/or bindItem in addition to setting the bindingPath yes
You would have to make one your self instead of using the PropertyField.
But as MechWarrior says, if you currently use a PropertyField , you'll have to replace it with a ListView declaration
And in some Unity versions you also have to setup the makeItem and bindItem. But I think in at least 2022 you shouldn't need to, but I can't remember.
Ah yeah, I think that's why I was deciding to go with just hiding it in uss. I remember when I last tried making a ListView it was a lot of added effort for no real gain ahah.
I remember it being a bit confusing on what it wanted when I first tried creating one.
If your ListView is just a default list with no particular look for each element, you can just set the bindingPath of the ListView as you would with a PropertyField
makeItem and bindItem are not mandatory
Hmm, I see! I may try that going forward. But for now I think that particular inspector is working as intended and I don't want to risk needing to work on it any more at the moment haha!
I do appreciate the tip though, I'll almost definitely end up using it later on.
Understandable haha I just wanted to share the info so that you know it exists 😛
Btw, if you didn't already know, this site feels like something you might like/find helpful @golden grove https://www.foundations.unity.com/
Oh, cool! Is it a design reference for inspector layouts?
It is design and style guide for the whole editor 😄
Haha, yeah I guess not limited to inspector.
It includes color codes, and style names, icon guidelines, size, margin, spacing, etc.
When to use what elements
oh that's quite neat!
This gem of a site should be shared more often... I had a hard time finding it after loosing the link
seems quite useful for sure.
1000% agree. it is so good, but feels like Unity doesn't really make it well known. Like the Manual should link to it at the very least
I will say it's layout is definitely a lot more pleasant to look at than the manual haha.
Haha yeah, it is super nice
I have a CustomEditor for my custom type A. This type contains an array of type B. Type B has a CustomPropertyDrawer which contains a button. What options do I have to "listen to" this button being pressed in the context of CustomEditor for A?
This is UITK atm but IMGUI could work too
My initial idea was to somehow try to fetch the CustomPropertyDrawer being used through my SerializedProperty for the array. But it seems like that's not really possible? If I could I would expose an event that could have been listened to.
I'm working on a tool for retargeting animations. And trying to figure out a good way to actually make the mapping (bone A on source skeleton == bone B on target skeleton). And show them.
One idea was to have them side by side, and take inspiration from things like VCS diffing where you can see the connection between bones. But the down side is it crosses on top of the scroll bar, which doesn't look great.
Another idea was to only show the source skeleton, then have the user select bones then hit a key/button to switch to showing target skeleton. And select bones there. Then click a 'map' button or something. Then have a little chip/pill on each bone to show the name of the bone it is mapped to. (sort of like how the UIBuilder shows names).
Any ideas of what might look good and make sense.
Yooo! The new unified graph system is finally coming in the next generation of the editor! This is the evolution of The Graph Tools Foundation system. It took years, but at least we will have it finally! 😄
Oh daamn
Also, looks like in totally-not-Unity-7 we are getting some nice UI updates!
Is there a good way to go about adding custom ui overlays to the game view? I'm looking to build some tools to assist in first person animations/posing, as shown in the screenshots.
I see how to create them for the scene view (https://docs.unity3d.com/2022.1/Documentation/Manual/overlays-custom.html#panel-overlays), but the game view class is internal. I figure I can hack my way to an overlay but wasn't sure if there was a Correct™️ way
Hacking is the correct way, it is what Cinemachine does.
thank you!
Is it coming with Unity 6?
Nope
In the generation after Unity 6
(Unity 7, or whatever they call it)
It is mentioned in this post about the animation update https://discussions.unity.com/t/animation-status-update-q3-2024-unite-announcement/1519289
💀 bummer, so quite far out still
Yeah 😦
From the profiler window I want to be able to copy as text: the call stack starting from a method up to the "root" method, including the duration of each method.
Is it possible to "hook" into this tooltip feature so that i could add the timestamps to the call stack list?
i.e., currently it gives me:
AssetDatabase.V2.RefreshInternal
Application.Reload
MonoCompiler.Tick
Application.Tick
EditorLoop
But I want:
AssetDatabase.V2.RefreshInternal 2500ms
Application.Reload 1000ms
MonoCompiler.Tick 800ms
Application.Tick 400ms
EditorLoop 100ms
is there no way to create a "PropertyDrawer" custom inspector for a monobehaviour class? Or something that works similarly? (Where I can reference properties of the class)
Yeah, Editor is what you want https://docs.unity3d.com/ScriptReference/Editor.html
Am I able to reference "properties" in a Editor class though? I am trying to reuse my other editor pretty much atm haha, where I need to ".Find" a specific variable to know when to draw a button.
Yep, it has a serializedObject property which you can do serializedObject.FindProperty(myPath) to get properties
oh okay perfect! Thanks.
Can someone help me out understand why, when I enter play mode, I get a duplicated gameobject?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class TestCreation : MonoBehaviour
{
GameObject fakeInstance;
void OnEnable()
{
if(fakeInstance == null){
fakeInstance = new GameObject("Test");
fakeInstance.transform.SetParent(this.transform);
fakeInstance.name = Random.Range(0,1000).ToString();
Debug.LogFormat("Created Instance {0}", fakeInstance.name);
}
}
void OnDisable()
{
if(fakeInstance != null){
Debug.LogFormat("Remvoed Instance {0}", fakeInstance.name);
Object.DestroyImmediate(fakeInstance);
fakeInstance = null;
}
}
}
Please note the Execute Always
I can't find a way to actually destroy it
still can't seem to get "Editor" to display with my monobehaviour, is do I possibly need to return something other than a "VisualElement"? it's not even altering my inspector at all unfortunately:
[CustomPropertyDrawer(typeof(Projectile))]
public class ProjectilesEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
var root = new VisualElement();
root.Add(new Label("Test"));
return root;
}
}
Projectile class:
[Serializable]
public class Projectile : Entity
{
[SerializeReference]
public List<ContactEffectComponent> projectileContactEffects;
}
You need to do CustomEditor instead of CustomPropertyDrawer
Ahh I see, let me try that!
Because fakeInstance is not serialized, so will always be null when first created/entering playmode
but when OnDisabled is called from leaving editor mode it should still be serialized and therefore be deleted
Even more, if you actually run the code, the call to destroy (and the log of remove) is done to the right game object
but even with that called, its not deleted
Still nothing, however I am getting a "multi-object editing is not allowed" warning, I've tried using the "CanEditMultipleObjects" to unfortunately no avail.
Select off and then select the object again.
Perfect, thanks guys! I did both and it worked. Not sure which fixed it but I appreciate both of you! (upon further testing it was the selection thing)
It was the selection thing, it happens sometimes when you make a new editor for an object. Just gotta select a different object so it can create a new editor instance for it and get all up to date
Yeah, I just tested by removing the true bool and it still works!
The bool tells the editor if it should work for classes that inherit from the type, so classes that inherit from Projectile
Ah I see, I figured that's what it meant which was what confused me a little haha.
sory, not serialized but referenced
Are you sure it is not deleted? The easiest fix would be to just serialize the field and add the hideInInspector attribute.
im 100% it's not deleted in 2022.3.29
I can't because this is an example on a way bigger piece of code to replicate the same issue. In the actual case the creation is inside a plain c# class inside a certain hirearchy that it wouldn't make sense to make all classes in the chain serializable just to be able to delete one gameobject
Are you aware if there is an easy way to loop through all variables within' the "serializableObject" before I was using the:
var copy = property.Copy();
foreach (SerializedProperty childProperty in copy)
{
if(childProperty.name != "componentName" && childProperty.name != "contactEffects" && !childProperty.propertyPath.Contains("contactEffects"))
{
root.Add(new PropertyField(childProperty, childProperty.displayName));
}
}
loop, however I cannot seem to loop through the "serializableObject" in a similar way. Is there maybe an easier way to add all default variables assigned to "Projectile"?
You can do serializedObject.GetIterator() iirc
don't think this works unfortunately.
Sure! I'll try it, thanks.
var copy = serializedObject.GetIterator();
foreach (SerializedProperty childProperty in copy)
{
if (childProperty.name != "componentName" && childProperty.name != "projectileContactEffects" && !childProperty.propertyPath.Contains("projectileContactEffects"))
{
root.Add(new PropertyField(childProperty, childProperty.displayName));
}
}
This sort of worked (?) I am getting a console error: Invalid iteration - (You need to call Next (true) on the first element to get to the first element)
UnityEditor.SerializedProperty/<GetEnumerator>d__19:MoveNext ()
however, I am also drawing the "Entity" classes properties separately.
Just checked, yeah not sure. Looking at the calls, it seems fine. But really, it is just better to not make GOs dynamically like this in the editor and playmode. I would look at refactoring the code, as most likely there is a nicer way to do whatever you are trying to do (though I could be wrong).
Right, you need to add copy.Next(true) before iterating.
Yeah, I don't think there's a better way, there's a worse way for sure which is moving all this generation and destroying to the main monobehaviour, which would keep track of all of them and destroy them (but I hate this idea)
What are you doing anyway?
this is part of a vegetation system and I was working on an addon to use basic Unity Instancing, just creation and destroying of gameobjects. This would be the parent where the child gameobjects are going to be created in the editor mode
after adding the "copy.Next(true)" it doesn't seem to be drawing any default elements (just the .FindProperty element I add later).
You mean pooling?
also yeah
Instancing is just rendering, normally using a Graphics.RenderMeshInstanced type method. But really, not too sure about why it isn't cleaning up properly
yeah, so Graphics.RenderMeshInstanced is what I use by default. But I want to give the option to users to just instantiate gameObjects if they prefer that (for some cases it might be intersting), and providing that is where all of this falls
Unfortunately I can't seem to get anything working, the only times it draws anything extra at all is when I error it by calling the "copy.Next" in the foreach loop, however this setup:
var copy = serializedObject.GetIterator();
copy.Next(true);
foreach (SerializedProperty childProperty in copy)
{
if (childProperty.name != "componentName" && childProperty.name != "projectileContactEffects" && !childProperty.propertyPath.Contains("projectileContactEffects"))
{
root.Add(new PropertyField(childProperty, childProperty.displayName));
}
}
doesn't seem to work with neither copy.Next(true) or copy.NextVisible(true); (both don't cause errors but also don't draw anything new)
I would debug.log out the path of copy (before foreach and then each one in the foreach as well
Alright, I'll see!
Not really sure what to make of this, but it is only logging the single log presumably outside of the foreach loop.
var copy = serializedObject.GetIterator();
copy.Next(true);
Debug.Log(copy.propertyPath.ToString());
foreach (SerializedProperty childProperty in copy)
{
Debug.Log(childProperty.propertyPath.ToString());
if (childProperty.name != "componentName" && childProperty.name != "projectileContactEffects" && !childProperty.propertyPath.Contains("projectileContactEffects"))
{
root.Add(new PropertyField(childProperty, childProperty.displayName));
}
}
ahh... right...
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
do
{
Debug.Log(iterator.propertyPath.ToString());
if (iterator.name != "componentName" && iterator.name != "projectileContactEffects" && !iterator.propertyPath.Contains("projectileContactEffects"))
{
root.Add(new PropertyField(iterator, iterator.displayName));
}
} while(iterator.NextVisible(false))
I think that should do
Worked perfectly, thanks! You're a lifesaver.
Also, does "do" just "do" if the if statement below is true?
oh nevermind
I didn't even see the while at all.
a do while is like a while but it does one iteration before executing the while statement
I see, I appreciate it! You learn something new everyday haha!
Sure thing, glad I was able to help 😄
What would be a sane approach to emulate the behavior of how the project window allows you to go from list mode to tile mode? Can it somehow be done with just a list view so I don't have to re-create all of the nav/etc stuff it comes with? Or would this require a custom grid element and annoyingly swap between them?
Yeah... 🙃
I actually did it for my Smart Library asset. What I ended up doing is using IMGUI because UIToolkit couldn't get the performance with a large number of entries. And then had a base class, and then two sub-classes, one for list, and one for grid. And swapped between them
With the the IMGUI controls having callbacks for drawing. I don't mind sharing them if you want. But of course, they aren't UIToolkit. And maybe now UIToolkit has better performance. It was originally for Unity 2020
If you could share them that would be sweet to look over. If uitk ends up being a hindrance then I'll swap over to imgui, but I haven't stress tested how much it can do at a time (the list-part seems optimized so far with uitk at least).
Yeah, ListView can do it normally, it was falling apart for me at the grid. I tried a fully custom virtualized grid, using al their recommendations for performance. And the very best I could get was like 300 items I think? And rounded corners would tank the performance.
I'll just share the files directly, I hope it won't inline them and boat this message haha...
Ah damn I'm in the middle of figuring out the virtualized grid stuff too lol, super weird to work with 
I'll take a look at it, thanks 👍
Oh damn didn't realize you made SmartLibrary. Cool asset, I've used it in a few projects.
Oh, thanks, glad ya like it 😄
How do i find out the type of that editor? It should be derived from UnityEditor.Editor, but i'm not finding in in the classes list in the doc.
The implementation of most built in editors are internal
You can find the implementation in the C# source code, which is pinned
In the new Unity Search how can I know what search providers exist? There's a page here https://docs.unity3d.com/Manual/search-providers.html
But the C# docs mention that when using "providerId" I should specify the unique ones "Unique search provider ID string (i.e. asset, scene, find, etc.)" https://docs.unity3d.com/ScriptReference/Search.SearchService.CreateContext.html but the provider page never mentions "asset" specifically
is there a way that when you click the build button that there spawns a editor script asking you which version
The closest provider to "asset" is "Project, p:" which doesn't work to use as a providerId, but "asset" works fine?
im really confused on how to figure out what other "providerIds" exist and how I can use them?
To answer my own question, the easiest way is to create a simple script that iterates over SearchService.Providers and just logs their name + id
Hello, I'm finally getting around to making a simple editor tool for a problem that I've had for a long time in unity. I would like to be able to easily move the pivot for an object and for the most part, I appear to have done exactly except I am struggling to get the script to work with Undo. After reading over the documentation, I got the values to correctly update to their previous state but for some reason, the mesh does not seem to update its position back until I use the tool again. While I'm probably missing something obvious, I haven't worked with the undo system before as I used serialization to handle that in my previous editor tools. Attached is my code, Can someone help me figure out how to handle this issue?
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.
If there are any other external resources apart from the unity documentation on making tools like this as well, please link them so I can get a better understanding of the system
Downloading and importing a manged plugin into an package folder and keep running into this
Failed to check following assemblies for updater configurations:
Packages/com.iambatby.packageinjector/packages/plugins/com.evaisa.lethallib/0.16.1/plugins/LethalLib/LethalLib.dll (ret = 131):
StdErr:
System.InvalidCastException: Specified cast is not valid.
at System.Reflection.Throw.InvalidCast()
at System.Reflection.Metadata.TypeReferenceHandle.op_Explicit(EntityHandle handle)
at AssemblyUpdater.Extensions.SystemReflectionMetadataExtensions.FullTypeName(CustomAttribute self, MetadataReader reader)
at AssemblyUpdater.Application.Program.IsUpgradable(MetadataReader reader, CustomAttribute entry)
at AssemblyUpdater.Application.Program.AssemblyPublishesUpdaterConfigs(IAPIUpdaterListener logger, String assemblyPath)
at AssemblyUpdater.Application.Program.<>c__DisplayClass0_0.<Main>b__2(CheckUpdaterConfigOptions o)
at CommandLine.ParserResultExtensions.WithParsed[T](ParserResult`1 result, Action`1 action)
at AssemblyUpdater.Application.Program.Main(String[] args)
Googling only finds results related to having a space in the path but I don't have one, Any insight?
Hi, I hope this is a good place: I'm working on a game involving hitboxes, and the hitboxes update positions and rotations on a frame-by-frame basis. I've found hitbox editors for fighting games in Unity, but the editors don't seem generic enough to fit the way I've programmed my game. Are there existing editors in Unity where I can periodically play through game logic across frames? Might I have to make something on my own?
You mean like go back and furth along a timeline to see the game logic? Not that I am aware of, might be something on github/asset store. If you just want to go from by frame, you can just pause and advance one frame at a time
is there a decent way of adding a gizmo to everything thing with a certain component when its one i can not override the editor for myself
OnSceneGui and Selection?
guess i could do that on 1 big global object, and just poll for whats selected
You can use the static callback SceneView.duringSceneGui
boom yeah thats what i wanted
sorting is starting to get complicated, so trying to display extra sorting information to make it easier to understand
so as a result, more or less need to draw a extra handle, for all sprites that are not in a sorting group
and sorting groups
would an overlay maybe help too?
overlay for what?
using a handle since i want to be able to adjust it on the go without the inspector
idk, no idea what you are sorting, just throwing it out there haha
its just a isometric scene with a lot of edge cases so just making better tools to see what is going on
ahh
its a big of a nightmare, things were setup while i was on vacation so the grid is not exactly how i would want but too late now
and its a mix of hand drawn art, spine rigs and stuff i rendered out from 3d models and painted over
and also some flat art, that i just did the isometric projections for in shader
actually pretty happy with how the projections worked out, can have decals that are flat and project them onto either of the wall angles or the floor angle
saves a ton of art, and can do the same sort of thing directly to texture coordniates to apply stuff like patterns to walls without changing the actualy sprite that defines the overall shape
Is there an editor method for resetting a UnityEngine.Object, the same way right click > Reset works? Just clearing all serialized data from it. I feel like there must be, but I can't find it.
I found this, but it's unused, internal and sounds like it does something more fancy.
https://github.com/Unity-Technologies/UnityCsReference/blob/a9c165247c85c90cfd8a243c2dabf0820ee0784d/Editor/Mono/ObjectFactory.bindings.cs#L22
Of course there is, it is whatever method that context menu option is calling 😄 . Now where it is is another question...
I tried to find that, but couldn't. IMGUI Debugger shows it as being from native.
Ooh that's right some menu items are populated from native. Dang...
But I do feel like there was a method for it...
you might be able to get the SerializedObject of it, get the iterator from there, then clear all of the Serialized properties under it
Best that gets you is the default value of each type. Not the default set in script 😦
such a weird thing not to expose
would have assumed there would be a way to just destroy the serialized data, which would mean there is nothing to deserialize over the values provided by the initilizers
Yeah, but also, it probably has been rarely touched since it was implemented originally... like 15-20 years ago
yeah only way i found really is to create a new instance get its SerializedObject and copy its data to the other SO
which is not too bad for like a ScriptableObject
but would be a pain for a component since it cant exist just in memory and needs a go to be on
though i feel outside of editor scripting i rarely would have the need for this
and within editor scripting for a one off i would be willing to just use reflection
There's MonoBehaviour.Reset, but It's a shame that it's not a thing for UnityEngine.Object
its not on ScriptableObjects either
also isnt that just the message
dont think it does anything if you call it but you can implement it like you do awake or OnDestroy
SO.Reset is apparently a thing too, but yeah I gotta check on that.
yeah just a message according to docs
not a method you can do anything useful by calling
Yeah you're right, I got confused
i really dislike those messages, though i guess without would need to implement a hell of a lot of interfaces
Easily, just use the DrawGizmoAttribute
I'm trying to use a ListView in a CustomPropertyDrawer. I set it up by fetching and caching the property of my List in CreatePropertyGUI and then binding to the ListView using ListView.BindProperty(). However whenever I add an item to the list it seems the cached property gets out of sync. I have overriden CanCacheInspectorGUI to false as well.
Is this the correct way to bind items in a ListView inside of a CustomPropertyDrawer? The array size seems to stays at 1 here even when I add my 2nd item
private void Bind(VisualElement ve, int i)
{
var propField = (PropertyField)ve;
var elem = _targetList.GetArrayElementAtIndex(i);
propField.BindProperty(elem);
propField.label = elem.displayName;
}```
I don't remember for 100% certainty. But if I do remember correctly, the binding system actually will create a new SerializedObject quite often. And so it just rebinds to that. All BindProperty() really does is set the bindingPath property to the propertyPath of the SerializedObject.
And I don't think CanCacheInspectorGUI is relevant for UITK (could be wrong)
I did some tinkering and I think it might be related to that my List contained classes. I swapped it to be a struct and now it appears to work. I will keep what you said in mind to see if it might be related somehow. The desync seems to be inconsistent and a bit hard to repo, but I have a theory that I might have used some broken data which got fixed when I cleared the list.
Worse case you can call _targetProperty.serializedObject.Update()
Well, apply and then update probably
hello i am trying to import a sprite from aesprite but its acting wierd. This is the same image that i imported once and i want the first version to apply to a sprite, but for some reason it uses the old version instead of the current one. The current one is on the left
when i open it in another program it looks right but when i export into the unity folder it goes back to an old version
Just had the same issue again, even with calling Apply and Update it's still seemingly out of sync. Here I am adding my 4th element
Hmm, weird. How are you adding the item to the serialized array? Just the default ListView + button?
Yeah exactly, the ones shown with showAddRemoveFooter = true
Weird, it should work just fine I think
Yeah that's my thoughts from my experience as well 😅 Might be some bug when doing it in a CustomPropertyDrawer.
What if you put checks in so that it works fine even if it is null? It could be doing two bind updates, one being premature?
Hmm doesn't seem to be the case, early returning just leaves me with an empty element (last 2 entries)
I'm considering just storing the SerializedObject in UserData and then fetching the property from there
Hmm, what if you just set the binding path without using the serialized property at all?
$"{pathToProperty}.Array.data[{i}]"
I would need to supply the entire binding path right? So then I still need to cache the base part in the CustomPropertyDrawer?
You could get it from the ancestor of the element that you are binding
In this case, the list view
I think there is a method like FindAncestorOfType, if not it is trivial to make one
Just setting the bindingPath doesn't seem to be enough. I suppose I'll have to somehow also update the PropertyField?
Is the list nested in another list?
yes
Hmm.. it is possible that could be messing with something
For the deepest list it's even 4x nesting 😅
it is so weird though because it should work just fine
Yeah if I turn off the CustomPropertyDrawer the default implementation works just fine
Do you know if the default drawer is viewable somewhere? Maybe I'm not supposed to get the serialized values like I am since it's an array?
Yeah it is in the source, it isn't a PropertyDrawer, iirc it is baked in to the thing that handles what to draw
using UnityEditor;
[CustomEditor(typeof(Interactable))]
public class InteractableEditor : Editor
{
}```
i need to make an editor script which only allows one of these bools to be true at one time
so i the useSingleInteraction is set to true
and i try to set useOpenInteraction to true
it will set the other one to false
and so on
You make an editor for the parent thing that checks it
Or go up the tree and try to modify another object but no idea if that works
i tried making this editor script which is supposed to turn a bool off if another one gets turned on, and then work backwards as well
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Interactable))]
public class InteractableEditor : Editor
{
public override void OnInspectorGUI()
{
Interactable interactable = (Interactable)target;
DrawDefaultInspector();
if(interactable.useSingleInteraction)
{
interactable.useOpenInteraction = false;
}
if(interactable.useOpenInteraction)
{
interactable.useSingleInteraction = false;
}
}
}```
but it doesn't seem to allow me to turn the bottom bool on
@calm grail what editor script u need help with?
this one
i just wanna see what variables ur accessing via the Editor script
its supposed to block having both of those bools on
by turning off the one that was on
if(interactable.useSingleInteraction)
{
interactable.useOpenInteraction = false;
}
if(interactable.useOpenInteraction)
{
interactable.useSingleInteraction = false;
}
}``` these type of if statements are flawed
think about the logic flow..
u disable the first bool.. then the second if statement runs immediately after
soo.. ofc its gonna flip it back
i think u should use if else instead
I would honestly just change it to either a single bool, or, probably better, a enum. It would make it clearer how it is used and what it does.
yea he knows whats up ^
probably
if (interactable.useSingleInteraction)
{
interactable.useOpenInteraction = false;
}
else if (interactable.useOpenInteraction)
{
interactable.useSingleInteraction = false;
}```
heres a simple fix
but i still just wanna figure it out
#↕️┃editor-extensions message heres the explanation
did u save and let it recompile?
Yeah I don't think this is it. Because it isn't a false check.
yea. enum and a switch statement is probably better
Ahh nvm I see it
yea..
what am i doing wrong
doesnt matter if its a false check.. it still checks it state. which is changed immediately above
it just wont ever work as desired
The issue is that the useSingleInteraction is always checked first
^ yea..
And if it is true, it always sets the second bool (useOpenInteraction) to be false
is there a way to make it work?
both valid methods
I really recommend the enum, especially since it is pretty bad practice to put validation logic like this in the editor only.
still not working
well fudge..
i hate these types of problems.. id have to code in my own editor to wrap my head around it
i know an enum would be better
definately
but i just prefer this
Same, I get it all turned around in my head to easily
I wanna say it isn't really possible
when ur using only if and else statements its pretty easy to get confused
it is.. but its not worth trying to do it with if statements
id 💯 move to enums
Well, the issue is that going in to the statement you don't know what the state of the bools were last check, so you don't know which one you are supposed to flip.
ya, i agree
its best to check every bool.. and perhaps hold a cached version
of what it was last
but that sounds like a if else nested nightmare
at the end of the day this is just an editor script
So ya gotta cache the previous value, or if you draw the fields yourself, you can use a Begin/EndChangeCheck to get when the value changed
boolOnLastValidation;
boolCurrent;
bool previousSingleInteraction;
bool previousOpenInteraction;
public void ValidateInteraction()
{
// Check if there is a change in either boolean
if (interactable.useSingleInteraction != previousSingleInteraction)
{
// If single interaction is enabled, turn off open interaction
interactable.useOpenInteraction = false;
}
else if (interactable.useOpenInteraction != previousOpenInteraction)
{
// If open interaction is enabled, turn off single interaction
interactable.useSingleInteraction = false;
}
// Update the previous state after making changes
previousSingleInteraction = interactable.useSingleInteraction;
previousOpenInteraction = interactable.useOpenInteraction;
}```
maybe?? id really need the script/ editor script to know for sure unfortunately
let me check
holy shit
it works
thanks man
now im just gonna add a debug,log
ur welcome 😉 thank chatgpt.. as long as u understand what to input.. you'll get a half-baked solution that actually works lol
good idea 👍
and thank @gloomy chasm they're the one that actually saw the problem lol
yeah thanks @gloomy chasm
enums would still be better 😈
Haha, no problem. Team effort 🙂
SerializedProperty aProp = property.FindPropertyRelative("_a");
float3 a = aProp.vector3Value;
how come there is no float3Value only vector3Value? How do you get the float3Value? Using Vector3 gives me error return value is junk there does not appear to be a float3 version ?
Manually getting the floats. It's annoying
ah okay, guess ill make an extension method
damn i keep forgetting how to do this but i want to click in scene without losing focus on my current game object how do you do that this is what i tried:
if(Event.current.type == EventType.MouseDown)
{
Event.current.Use();
OnMouseDown(mousePosition);
Selection.activeGameObject = Selection.activeGameObject; //keep focus
}
else if(Event.current.type == EventType.MouseUp)
{
Event.current.Use();
OnMouseUp();
Selection.activeGameObject = Selection.activeGameObject; //keep focus
}
i keep losing focus
Is it possible to make a property drawer for a nested class ? I just want to confirm because I have made one for a nested class, but in the inspector the details of that class is not showing.
It was something like if(layout) HandleUtility.AddDefaultControl(0) at the start of the gui
If that wont work, I can check later when on my pc
Yup
Are there any good external guides on the ScriptableBuildPipeline?
The documentation i've found on the package looks to be extremely basic and not in-depth enough to figure out something i'm trying to do to let the users of my game mod custom materials utilizing my addressable shaders.
Hi everyone, I have a serialized class called EnemySpawnData which contains some fields like Enemy prefab, int maxCount and EnemyPlacementType type. I have created the property drawer for this using UI toolkit (don't know will it work or not), I have an array of EnemySpawnData in another serialized class called EnemiesSpawnData, how can I make array display while making a property drawer for EnemiesSpawnData, with the options like adding and removing element from the array ?
I think I have solved that problem.
Just guessing here, take it with a grain of salt, but i am assuming that the ScriptableBuildPipeline won't exist in the Runtime, because Building already happened. May be totally wrong with that thinking tho
Hello everyone, I just want to ask is it possible to make property drawer using UI toolkit which expands or shrinks based on enum value in Unity ? I have made one property drawer for a serialized class but it is not showing properly, The code is below.
Sorry for long code in advance.
Quick question back on my topic for editorscripts. How do I show a null propertyfield? EditorGUILayout.PropertyField(reflectedClass); throws an error if reflectedclass is null. But I have to assign it first before I can make it not null. Guess I am missing some basic editor script techniques here.
The only way for a value to be null is if it is serialized with [SerializeReference]
If a SerializedProperty is returning null, it means that the path was wrong.
yeah i assume you mean reflectedClass is a serialized property instance pointing to a null field, not actually null? because you definitely can't pass null into PropertyField
I worked around it using a
Object selectedClass;
and then replacing it as soon as the currentClass is != null
selectedClass = currentClass.objectReferenceValue;
And reassigning it before applying modifications
currentClass.objectReferenceValue = selectedClass;
I really don't get what you are doing, but can almost guarantee that there is no need to do that. If ya wanna share the code I can take a look.
public class ClassMethodEditor : Editor
{
int selected = 0;
Object selectedClass;
readonly List<string> allMethods = new();
SerializedProperty currentClass;
SerializedProperty currentMethod;
private void OnEnable()
{
currentClass = serializedObject.FindProperty("currentClass");
currentMethod = serializedObject.FindProperty("currentMethod");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (currentClass != null)
selectedClass = currentClass.objectReferenceValue;
selectedClass = EditorGUILayout.ObjectField(selectedClass, typeof(Object), true);
if (selectedClass != null)
{
allMethods.Clear();
var flags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public;
(selectedClass as MonoScript).GetClass().GetMethods(flags).ToList().ForEach(m => allMethods.Add(m.Name));
string foundMethod = allMethods.Find(m => m == currentMethod.stringValue);
selected = string.IsNullOrEmpty(foundMethod) ? 0 : allMethods.IndexOf(foundMethod);
selected = EditorGUILayout.Popup("Method to be called", selected, allMethods.ToArray());
if (allMethods.Count > 0)
currentMethod.stringValue = allMethods[selected];
currentClass.objectReferenceValue = selectedClass;
}
else
{
Debug.LogWarning("Reflected class is null");
}
serializedObject.ApplyModifiedProperties();
}
}
I can guarantee, I am a total newbie to editor scripts. Barely using them 😄 So feel free to change whatever you like 😉
Might be some typos since I did it without a code editor, but this should be cleaner and a lot more performant https://gdl.space/caguwicelu.cs
EditorGUILayout.PropertyField(currentClass); this will immediately throw a null reference
Shouldn't, if it does then I guess ya need to just move the FindProperty calls from OnEnable to the top of OnInspectorGUI
Was pretty sure that OnEnable was called first, but I could be misremembering
you cant just put a null object in the propertyfield, thats why I am using objectfield with the stored object
Did you read what I just said...? The only reason that currentClass would be null is if either it has not been assigned yet (from the code in OnEnable), or then it was trying to be assigned, the path was wrong so no property could be found.
or if the actual currentClass property is null, which is desired, as you add the component to the inspector and it will be an empty object field, that you can put your asset in
No, A SerializedProperty is just a 'address' or a 'reference' to location on a UnityEngine.Object that can hold data. Basically the same as a FieldInfo from reflection. If the address is null means that there is no house there (in this case, no data container). Not that no one is inside the house.
I just tried it and it works fine. You might need to restart Unity?
Is there a proper way to "cache" values from a PropertyDrawer instance?
I'm doing some addressables finicky loading and i'd like to cache the current value for the property drawer that's drawing the GUI
No, there isn't really a good way to do caching because the drawers are re-used.
i suppose making the drawer use VisualElements would allow me to cache it if i return a custom control, right
You could cache it in the userData property of a VisualElement yeah
Is there a reason why you only create the allmethodarray on change? Guess it should be done everytime, because otherwise it will be empty
Ahh actually it should happen OnEanble as well. But the reason being is that you can't add or remove methods without causing a domain reload. And doing reflection like that is expensive and depending on the class, can cause noticeable slowdowns and a lot of GC if you do it every update.
when it's not serialized?
oh I didn't scroll down lol
I mean, its just for putting the method once. So its nothing that is used like in a mass amount of cases. I select the script I want to reflect, check the method, done. Prefab is created and wont be touched again.
Anytime the inspector is show it will be doing it. It isn't hard to just cache it and leads to getting in the habit of better practices and avoids dieing from a thousend cuts later on. But you can do whatever works for you 🙂
the problem is, that I have to have the popup dropdown anyways in the inspector. Best practice would be to have an additional button to "activate" reassigning of the method I guess.
Thanks for the tips btw, I will def. put the changecheck in
Sure thing
In our build script we set icons depending on platform & what specific build of the game is being built. There's PlayerSettings.SetPlatformIcons which you can feed this info to, but the problem is that on Android there's 1 icon which does not seem to be associated with any of the groups for this function, and that's the Android banner, which is used for Android TV. Anyone knows how the Android banner is set from code? I can't seem to find any info on it.
Did you enable the android banner in playersettings?
Yeah, I can set it from the player settings as well manually, but I want to set it from code.
Ah, it says m_AndroidBanners
Maybe you can access it through that. I am also wondering what you get as output from https://docs.unity3d.com/ScriptReference/PlayerSettings.GetPlatformIcons.html for android. Is it part of adaptive or its own thing then. Maybe worth logging
read along with this: https://docs.unity3d.com/ScriptReference/PlayerSettings.SetPlatformIcons.html
GetPlatformIcons doesn't contain it, it's nowhere in any of the 3 different kinds
But yeah perhaps PlayerSettings.SetPropertyString can get the job done in some undocumented way
In IMGUI is it okay to set property values every frame even if the value is the same, or should I wrap it in a changescope? I.E cs toggleProp.boolValue = EditorGUI.Toggle(toggleRect, toggleProp.boolValue);
is there any built in way of doing the select index bar for a TextElement?
it is okay, thats the standard way
Do you mean TextField? .textSelection has all the functionality
no, i want for TextElement because TextField has it already
It has selection
it has but u can just set the selectIndex, cursorIndex, etc, it doesnt show that bar even thought selection.isSelectable is true
this is my textelement
on the multiple selection it doesnt need to have that bar, but in the first image it needs one because i click on a (bar needs to be on the left of the char)
Not sure, it's late so I can't look into it, but I would stick a breakpoint in TextElement.OnGenerateVisualContent before it calls DrawCaret and debug around that area to see why it's not being called, or if it is, what might be going wrong
i found the solution
ITextEdition textEditor = this;
textEditor.isReadOnly = false;```
thanks :DD
Nice. I figured there were only so many booleans in that area and it'd be one of them 😄
now i get this error when i try to type something when selected, i think its from editingManipulator but its internal and i cant do anything
Inside MonoBehaviour.OnValidate()... should I LogError or Throw? 🤔
I mean, what happens if I throw there? the game refuses to start?
I imagine it's like any exception in a Unity message. It gets consumed and the game continues. At most, it will behave like an exception in Awake, which disables the script.
how to acess system.datetime from the editor?
DataTime.Now...? Or do you mean something else?
no i mean i have a public variable : public DateTime current_date;
and i want to modify this value from the editor however the field does not appear in the editor (as if it' hidden)
Ahh, that is because DataTime is not serializable by Unity.
is there anyway to do something about it?
Basically the only option is to make a wrapper around it that stores the serialized values.
may you explain what this means?
You make a class that has a long or string or something that Unity can serialize. And also has a DateTime field. And implement ISerializationCallbackReciver, in OnBeforeSerialize, you take the value of the DateTime and convert it to whatever type you have as the other field (the long or whatever). And in OnAfterDeserialize you conver it back to DateTime
You will then probably want to make a PropertyDrawer for it so it is easier to edit in the inspector.
i think i understand thank you very much 🥰
Can you make custom editors for serialized classes and structs or is it just for scriptable objects and monobehavoirs?
You can, but they are called PropertyDrawers instead of Editors, and they work a bit different.
I see. Thats why I couldn’t find documentation. Thank you. :)
Is there any way to know if there's a GameView enabled and visible in my Unity or not?
public static bool IsGameViewOpenAndFocused() {
var windows = Resources.FindObjectsOfTypeAll<UnityEditor.EditorWindow>();
foreach (var window in windows) {
if (window.GetType().FullName != "UnityEditor.GameView") {
continue;
}
if (window.hasFocus) {
return true;
}
}
return false;
}
I have a SerializedProperty that I know is a bool, how can I draw it using the minimum size needed to fit it, without a label? This is in a CustomPropertyDrawer
IMGUI I assume? 14px iirc
yeah IMGUI, is there a way to calc that min size? Since in other cases I might wanna use any other EditorStyles.xxx
Hmm I think GUILayoutUtility.GetRect maybe
I tried that, it seems to reserve some extra GUI after the provided Rect. Anyway I think I found it:
EditorStyles.toggle.CalcSize()
So I would just need to know what style it's supposed to draw with in my case
Here is how the GUILayout.Toggle does it https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/IMGUI/GUILayout.cs#L112
I did some more experimenting on this and this is in Unity 6 mind you. I abandoned the UITK drawer and went back to an IMGUI drawer. When tinkering with it I noticed that CanCacheGUI is deprecated. And from my experiments it seems that you can not cache anything in a PropertyDrawer anymore. Overriding and providing false is just straight up ignored, the drawer will be reused anyway. So I assume this also applies to UITK which might be why the ListView was behaving weird, since it would be bound to whatever PropertyDrawer was run last.
Not sure if this is 100% accurate, it's just from my intuition so far 😅
Yeah, caching was never supported for UITK, only IMGUI. But seems they changed some internals as well now. In Unity 6 I really can't recommend IMGUI for editor UI.
Yeah if I could just figure out how to use a ListView in a PropertyDrawer I would not be using IMGUI at all 😄 Might create a Unity ticket just to get a definitive answer on this one
What are you having trouble with? I have spent... too many hours using UITK and property drawers... and specifically the list view hahaha
How to read the property during Bind so I can use GetElementAtIndex(index) and hand it to the PropertyField
You mean in BindItem? There is options:
- You could make it a lambda instead of a method, and just access the property directly. (easiest, even if it may feel a little funny, probably my number 2 recommended way)
- You can set the
userDataof theListViewand access it from the element that is passed to thebindItemmethod. (Not really the way I would recommend, feels a bit dirty to me) - You can simply manually set the binding path. (Probably the way I would recommend)
Number 3 would be something like this:
var list = root.Q<ListView>();
list.bindingPath = "_myList";
list.bindItem = BindItem;
void BindItem(VisualElement element, int i) {
element.Q<PropertyField>().bindingPath = $"_myList.Array.data[{i}]";
}
(with the element returned from makeItem of course having a PropertyField in it)
Thank you! I'll give these a go, not sure if I just missed something, some u6 change, or if there is something odd with nested lists for PropertyDrawers. I'll poke this post in the coming days when I have some time to give it a new test
I've used plenty of UITK for custom editors and property drawers but for some reason ListView in PropertyDrawer seem to complicate it a bit 😅
I had some time to test these 😄 I used a combination of 1 and 3 and it works really well. Getting rid of the old caching I had of the property immediately makes it work as expected.
I bind like:
bindItem = (ve, i) => BindItem(ve, i, prop),
And then in BindItem I do
var elem = prop.GetArrayElementAtIndex(i);
((PropertyField)ve).BindProperty(elem);
Works flawlessly 😁
Some keywords in case someone has a similar problem in the future: ListView PropertyDrawer CustomPropertyDrawer
I may have done an oopsie and have send my help request to the wrong channel, so ill do the liberty of sending it here as well:
Greetings!
I am currently in the midst of updating an property drawer editor tool that uses the ui-toolkit to render an inspector within a parent inspector as seen in the image. I have the base functionality of the tool working but i want to add the ability to have the nested editor persist whenever the user selects a different game object or element to inspect akin to Godot's Resource Inspector.
I have managed to get this working but i have the annoying issue of the ui-toolkit seemingly recursively rendering itself to oblivion, causing Unity to freeze entirely, whenever the user opens 2 nested inspectors in a parent inspector and then swaps focus to a different game object and back.
Here's the current implementation: https://hastebin.skyra.pw/neqerimiga.csharp
If I understand it correctly, ExampleObject can reference another ExampleObject, and shows the editor for it nested inside of itself. Then yes, if 1 references 2, and 2 references 1 it will then be a recursive loop. Not really sure what you are wanting it to do?
The current issue is that 1 references 2 and 2 doesnt reference anything, yet the ui-toolkit keeps rendering 2 multiple times. This happens only when i am attempting to render a list via PropertyField.
For self-reference, i am going to exclude rendering
But UI-toolkit itself keeps self-referencing for some reason
Which part is recursive?
When I am attempting to render 1's list of ExampleObjects. If it is populated with 2 and 3 and the object 2 is open, then 2's editor keeps attempting to draw itself over and over.
I have logged its behavior and have gotten this:
Notice how it keeps repeating itself after it draws the someSubDefaultObjects list.
Worse yet, the object has nothing in its list:
I am currently going to manually render the list instead of using PropertyField and see if i can resolve this issue
I am not sure if this is a Unity bug or something that i created
Especially since i have tested this behaviour with a normal variable and the script functions as expected
It only occurs with lists
Okay well lets see here. Taking a look at the code, the first thing I would say is that I would start with simplifying and cleaning up the code a bit.
A couple of specifics,
- You create a SerializedObject, but never dispose of it.
- You bind each bind each property to the serialized object instead of just binding the a parent element. (this is much worse for performance)
- Not sure how the
FindVisibleChildProperties, but if it returns more than just the top properties, this is most likely the issue. As by defautl PropertyFIeld will already render all children properties - You can just use InspctorElement to show the editor of a object instead of manually drawing the properties.
Good points all around, will check them out
- Entries are never removed from the dictionary, which over time could cause the memory to build up and references to never be GCed
Not sure how the FindVisibleChildProperties, but if it returns more than just the top properties, this is most likely the issue. As by defautl PropertyFIeld will already render all children properties
This is an extension that i have written where it converts the property.GetIterator() into an IEnumerable:
public static IEnumerable<SerializedProperty> FindVisibleChildProperties(this SerializedObject parentObject)
{
var iterator = parentObject.GetIterator();
iterator.NextVisible(true);
do
{
yield return iterator.Copy();
} while (iterator.NextVisible(false));
}
Hmm, should be fine then I think
Irrc, this was based from a couple of forum posts of people creating similar extensions and i have verified that it works.
Yeah, it only does the top level children
As a helpful tip, you can use the DetachFromPanel event on VIsualElements to do cleanup.
So, I used the InspectorElement class where its Bind() determines what to properties to render and it thus far works.
The current issue is that i am getting a bunch of TLS Allocator error due to a lack of clean up
Besides that, it has fixed the underlying issue
And has simplyfied the code dramatically.
One thing i want to ask @gloomy chasm, you mentioned that:
You bind each bind each property to the serialized object instead of just binding the a parent element. (this is much worse for performance)
Yet, for the InspectElement documentation, their given example is as follows:
using UnityEditor.UIElements;
...
var inspectorElement = new InspectorElement();
var serializedObject = new SerializedObject(myObject);
inspectorElement.Bind(serializedObject);
Would this introduce performance issues should the user have multiple objects to render their respective editors?
What I meant was that you are calling Bind on each PropertyField instead of just calling Bind once an a parent BindableElement of all the PropertyFields
Oooh! I understand now.
Cheers for the clarification and overall help ❤️
You're welcome! 😄
Okay, so I am trying to make a custom inspector for fixed point structs from a library that I imported. In the editor, I would like them to display as floats so they are easier to edit, but have them casted as fixed points when storing them. They have an explicit operator that allows them to be casted into floats or vice versa. How do I go about doing this?
Nevermind. I wrote this:
[CustomPropertyDrawer(typeof(fp))]
public class FixedPointEditor : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
property.boxedValue = (fp)EditorGUI.FloatField(position, label, (float)(fp)property.boxedValue);
}
}
I don't know how safe it is but it works for now.
Why does this not work?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
using VoxelTest.Core.Mathematics;
[CustomEditor(typeof(Point3D))][CanEditMultipleObjects]
public class Point3DEditor : Editor
{
private SerializedProperty _x;
private SerializedProperty _y;
private SerializedProperty _z;
void OnEnable()
{
_x = serializedObject.FindProperty("X");
_y = serializedObject.FindProperty("Y");
_z = serializedObject.FindProperty("Z");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(_x);
EditorGUILayout.PropertyField(_y);
EditorGUILayout.PropertyField(_z);
EditorGUILayout.EndHorizontal();
serializedObject.ApplyModifiedProperties();
}
}
This is my Point3D struct besides the operators and few methods it has...
namespace VoxelTest.Core.Mathematics
{
[Serializable]
public struct Point3D : IEquatable<Point3D>
{
[SerializeField]public uint X;
[SerializeField]public uint Y;
[SerializeField]public uint Z;
public Point3D(uint x, uint y, uint z)
{
X = x;
Y = y;
Z = z;
}
You want to use a PropertyDrawer instead of Editor as it is only for objects that inherit from UnityEngine.Object
I tried that it didn't work either
let me put it together again
Can I use EditorGUILayout with drawers?
EditorGUI doesn't seem to have any sort of helpers for horizontal layout
No you cannot, yeah, you have to calculate it on your own.
An alternative is to use UIToolkit, which is what I would recommend
EditorGuiLayout seems to work but idk how to get it to look like the default Vector3 fields
I tried this..
[CustomPropertyDrawer(typeof(Point3D))]
public class Point3DDrawer: PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(label);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("X");
EditorGUILayout.PropertyField(property.FindPropertyRelative("X"), GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Y");
EditorGUILayout.PropertyField(property.FindPropertyRelative("Y"), GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Z");
EditorGUILayout.PropertyField(property.FindPropertyRelative("Z"), GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndHorizontal();
}
}```
This is what it looks like...
I think there is too much spacing between the component label and component field
It works until it doesn't, then you have to rewrite it all using EditorGUI. You can use EditorGUIUtility.labelWidth to adjust the width of the label of the field.
This is the diffrence if I remove the component labels...
ok
Does anyone know what GuiLayout.Vector3Field does under the hood?
looks like it uses internal functionality...
public static Vector3 Vector3Field(Rect position, string label, Vector3 value)
{
return Vector3Field(position, EditorGUIUtility.TempContent(label), value);
}
// Make an X, Y & Z field for entering a [[Vector3]].
public static Vector3 Vector3Field(Rect position, GUIContent label, Vector3 value)
{
int id = GUIUtility.GetControlID(s_FoldoutHash, FocusType.Keyboard, position);
position = MultiFieldPrefixLabel(position, id, label, 3);
position.height = kSingleLineHeight;
return Vector3Field(position, value);
}
// Make an X, Y & Z field for entering a [[Vector3]].
private static Vector3 Vector3Field(Rect position, Vector3 value)
{
s_Vector3Floats[0] = value.x;
s_Vector3Floats[1] = value.y;
s_Vector3Floats[2] = value.z;
position.height = kSingleLineHeight;
BeginChangeCheck();
MultiFloatField(position, s_XYZLabels, s_Vector3Floats);
if (EndChangeCheck())
{
value.x = s_Vector3Floats[0];
value.y = s_Vector3Floats[1];
value.z = s_Vector3Floats[2];
}
return value;
}```
MultiFieldPrefixLabel is internal
I got it I just used the default Vector3Int one and clamped my components to a min of 0
Having a bit of an issue when it comes to assembly definitions and editor scripts. I currently split my asmdefs into Runtime and Editor scripts. The Editor asmdef references the Runtime one.
However, I have a custom property attribute for one of my classes. If I change the Runtime asmdef to reference the Editor asmdef, then I run into a cyclic dependancy issue. And if move the property script to the runtime assembly, it fails to build because it is using UnityEditor. What should I be doing in this case?
The attribute should be in the runtime assembly and the drawer in the editor
Ah yes, that's it. Thank you very much.
Is there a way to deselect the editor play mode window when I press escape on my minecraft style fps controller?
I mean I fixed the cursor not locking at startup my not locking the cursor until I click in the play mode window
I just need to be able to press escape and disable movement again
if i spawn an gameobject how do i add it to the undos?
i thought it was Undo.RecordObject() but that seems to only be for GUI not scene objects?
ah nvm i found it
but then another question, how should i be setting the scene dirty? supposedly according to the documentation i shouldnt be calling EditorUtility.SetDirty() if im using undos. but the scene isnt dirty after im creating the object
oh nvm again, i just didnt see it was being set dirty my bad
Im having a problem where Im assigning a value through managed code bypassing SerializedProperty and thus serialized object does not reserialize itself and does not invoke ISerializationCallbackReceiver methods. Is there any way I could force it to do so or something?
Undo.RecordObject(_property.serializedObject.targetObject, "Paste lambda");
_property.SetObjectValue(paste); //my extension method, efectively the same as EditorUtility.CopySerializedManagedFieldsOnly
serializedObject.ApplyModifiedProperties() doesnt seem to work as I bypassed SerializedProperty, setting object dirty as well
I wanted to avoid that but eventually I ended up calling ISerializationCallbackReceiver methods explicitely. Still, if anyone has any alternative idea i will gladly listen 😄
@wicked niche #1180170818983051344
Is there something akin to IMGUI GetPropertyHeight for UITK? I have a ListView that's complaining that Layout update is struggling to process current layout (consider simplifying to avoid recursive layout): EditorPanelRootElement unity-panel-container6 Most likely because my bound elements are a couple of fields big and I'm using DynamicHeight for the fields in the ListView
Looking at the code it seems that DynamicHeight is recursively going through elements in the list
I'm going to assume there's not so then the follow up question is what I can do to mitigate it, the error is very non-descriptive. No clue what "simplifying" would mean in this context, as I only show the UI I need to.
how come my custom attribute is not being detected by visual studio or unity?? its like it doesnt even exist. i even created an empty test attribute and drawer and thats also not being detected. i have no errors anywhere so i dont know why it doesnt work
here is the example i made thats not working either. so im kinda stumped https://paste.ofcode.org/CeL5kLknWU8VHxahafBXGK
What do you mean 'not detected'?
if i try and type [Test] above any variable or field it just doesnt work, intellisense or anything
Are they in the same assembly definition, or one referenced by the other?
currently i dont have any assembly definitions its just all in the same asset folder somewhere
actually, does #if UNITY_EDITOR affect it in any way?
wait nvm im not using it in the test
though i do have them in the editor folder, but i didnt think that should matter
You need to add a AttributeUsage attribute to your attribute.
The attribute should not be in the editor folder
Only the drawer
i assume the answer is no, but i'll ask anyway. so lets say i for example have an object field. is there a way to limit what is shown in the object field beyond the type? (and can select from scene)
In what way do you want to limit it more?
like lets say its a gameobject, would it be possible to limit it to prefabs with certain components on it?
that case i might as well show an error in the inspector for the feedback
Another option is if you have the advanced object select enabled in the preferences. You might be able to figure out how to open it yourself. And that one can be limited to components
oh, this might be something i can work with
ive been trying to use anything from the UnityEditor.SearchService documentation, where i assume what im looking for is ProjectSearchEngineAttribute but i havent figured out how im supposed to use it
https://docs.unity3d.com/ScriptReference/SearchService.ProjectSearchEngineAttribute.html this page says nothing
Is there a way to refresh an EditorWindow when a selected asset gets reimported?
Yes I did this a few weeks ago give me 1 min I will search it
Use this with a check if it is the right asset
Already tried that. The asset does not appear to be fully imported by that point, and the editor window refresh fails.
Hmm strange
Sorry than I have no idea
Does anyone know of an asset that will allow me to mark a field as [REQUIRED] and will fail compilation or build if that reference is missing?
There are a couple, that do similar things.
- Validator (maxartz15) - github
- Validation (TribandApS) - github
- Better Validation (techno-dwarf-works) - github
- Odin Validator - paid
I haven't used them my self, but they seem decent
i managed to do it with a very nice youtube tutorial: https://www.youtube.com/watch?v=0HHeIUGsuW8
Is there an event for when an asset is open within the editor? for example when I open a scene or when I open a prefab?
I am not sure that there is an event that handles both scenario, but for prefab isolation mode you can use this : https://docs.unity3d.com/ScriptReference/SceneManagement.PrefabStage-prefabStageOpened.html
And for scenes you can use this : https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager-sceneOpened.html
Im actually working on something like that for my package
Which pacakge?
EditorAttributes
That's cool man, we use that in all our projects 🙂
Please add the REQUIRED tag 🙂
glad to hear it, the Required attribute does exist but it only displays a helpbox under the field, it doesn't throw build errors yet
I know, you're half way there 😉
for serialize reference field i can't use attribute right ?
I dont see a reason why you couldn't
so i will probably have to use both or can i just choose 1: attribute/custom editor
you can do both
but I don't know if using both (custom editor, attribute) in a class is more efficient than just using the custom editor
Can you show me
you can use the attributes for the general purpose stuff and a custom editor class for specific stuff
Hey, I was wondering if there is any way to speed up this process?
https://pastebin.com/aeCECTQD
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.
its a simple editor script that does some checks on my assets
checks itself are pretty good, but the asset finding process takes way too long
and I feel like sometimes the whole process pauses for some time?
iterating through and loading every single prefab in the project seems really expensive, do you have the kind of folder organization that would let you pass in a specific search directory/list of directories to narrow down where it needs to search?
nope, not really. I will have to ask my lead dev about that
i can't think of anything that would speed it up more than just searching less assets so if you can convince the rest of the team to put the prefabs in the right place, that'll make everything a lot easier 😄
yeah, I joined the team recently and there is a lot of thing that I would change
also, is this the right way to handle coroutines in editor?
This is the right channel for anything involving editor specific code basically
im asking about my implementation ;p
there's an official editor coroutines package if that helps: https://docs.unity3d.com/Manual/com.unity.editorcoroutines.html
What is procedure.ChecksPassed() doing?
Also, yeah I would recommend just using the built in package. Also also, you can use async and await in the editor 😄
Couple of things you could do to speed it up.
- Switch to the new SearchService API. It is multithreaded, and uses indexing, and if configured to index them, can search for prefabs with a specified component.
- Remove the null check on line 66. You are already only getting GameObjects. And UnityEngine.Object null checks are (comparatively) expensive.
- Unload the asset after loading it (if it was not loaded). This should at least lower memory overhead. And avoid the garbage collector running which could cause lag.
- Use
go.TryGetComponentinstead ofgo.GetComponentto avoid memory allocation when the component doesn't exist.
its not important for now, its not implemented yet
hmm I didnt know that there is new SearchService
Was asking incase there might be a easier or better way to implement which would allow it to go faster. That's fine though.
Yup, pretty nice. Used to be a package called QuickSearch https://docs.unity3d.com/ScriptReference/Search.SearchService.html
basically, each BaseWaveProcedure has a list of AssetChecks and then ChecksPassed goes thru all AssetChecks and does their logic
could you tell me how to use the indexing?
BaseWaveProcedure is an abstract class so im not sure how to make it work
void OnSearchCompleted(SearchContext context, IList<SearchItem> items)
{
foreach (var item in items)
Debug.Log(item);
}
SearchService.Request("t:BaseWaveProcedure", OnSearchCompleted);
You don't 'use' the indexing. Indexing is just the way the engine caches and search the data.
alright, thanks :D
is there a easy way to check that a serialized property has changed?
and while im asking, how can i assign names to the the element gui of lists / arrays?
With IMGUI or UIToolkit ?
uh what?
im not using any package or anything, im doing it by hand
writing all custom editorscripts
I mean, depending of whether your'e using IMGUI or UIToolkit to draw your interface, you won't use the same thing to check if your serialized property has changed
They are not package, it's Unity's solutions for editor scripting ^^'
i have no idea what that means other than its the unity editor
Hmm, do you define a OnGui or a CreateInspectorGUI ?
OnGUI
OK, so that's IMGUI (or immediate mode). Then you can use BeginChangeCheck and EndChangeCheck :
public void OnSceneGUI()
{
var t = (target as LookAtPoint);
EditorGUI.BeginChangeCheck();
Vector3 pos = Handles.PositionHandle(t.lookAtPoint, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Move point");
t.lookAtPoint = pos;
t.Update();
}
}
it's an example from the documentation here : https://docs.unity3d.com/Manual/editor-CustomEditors.html
ah nice. and then for my other question ^
For your other question: the simple answer is having a field named Name or Title iirc. your element name will be the value of this field.
perfect, thank you!
What's your favorite quality-of-life editor extension?
how do I get the target object from that SearchItem?
I tried .ToObject() but that doesnt work
in debug I can see that what i'm looking for sits in .data
i guess just items[i].data as BaseWaveProcedure?
What does it do? What does 'doesn't work' mean?
well, it returns null
Are you searching for components? It might be some other part of the data.
yep, for component
Yeah, not sure, probably just hit a break point and inspect the SearchItem to see where the data is. Might be an instance ID or something
the type of an asset can only ever be GameObject, since that's what prefabs are, so if you're trying to get it by the component type i expect it'd return null
yep, I managed to get it work
now I have another bottleneck ;v
I added first check
public abstract class AssetCheck
{
public abstract bool IsPassed(BaseWaveProcedure procedure);
}
public class VariableNullAssetCheck : AssetCheck
{
public string VariableName;
public VariableNullAssetCheck(string varName)
{
this.VariableName = varName;
}
public override bool IsPassed(BaseWaveProcedure procedure)
{
var field = procedure.GetType().GetField(VariableName);
if (field == null)
return true;
var value = field.GetValue(procedure);
return value != null;
}
}
and in BaseWaveProcedure
[SerializeField]
private List<AssetCheck> assetChecks = new()
{
new VariableNullAssetCheck("Meta"),
new VariableNullAssetCheck("Statistics")
};
public bool ChecksPassed()
{
if (assetChecks == null || assetChecks.Count == 0) return true;
foreach (var check in assetChecks)
{
if (!check.IsPassed(this))
{
Debug.LogError($"[AssetChecker] {name} didn't pass the {check} check!");
return false;
}
}
return true;
}
and its slow, I guess because of this part
var field = procedure.GetType().GetField(VariableName);
var value = field.GetValue(procedure);
No need to guess when you can profile it! 😉
You can cache the result of the GetField and there are ways to speed up the GetValue call (you can google how to make reflection faster, lots of good info).
How do I prevent activeGameObject deselection on certain clicks from an EditorWindow during scene gui? I have an EditorWindow with a SceneView.duringSceneGui that does something like this:
void DuringSceneGUI(SceneView sceneView)
{
Event evt = Event.current;
if (evt.type == EventType.MouseDown && evt.button == 0)
{
Event.current.Use();
}
return;
}
But this doesn't prevent active gameObject from being deselected. Anyone got ideas?
This code does stop actions such as interacting with transform gizmos, but not deselection on click.
Try adding this to the beginning of the method:cs if (Event.current.type == EventType.Layout) { HandleUtility.AddDefaultControl(0); }
Works for me in a Custom Editor's OnSceneGUI at least. See if it works in EditorWindow
It works perfectly, thanks for this. I added it when my raycast hit returns true since I want clicking certain areas to not deselect. But yeah, calling this with Layout does the trick. Thanks again
Is there any way to make an object field for a scriptable object where it can only hold a reference to those that implement a certain interface?
It should only allow drag and drop of Scriptable Objects implementing the interface and if I click on the dot of the object field only reveal those that implement it too
You can try limiting the time on the object field itself, but I don't think so no
Not without rolling a very custom solution
Mmm, i see that https://docs.unity3d.com/ScriptReference/UIElements.ObjectField.html has reference to object type
I'm find with casting in and out of the interface, i will check if that works
im looking at https://github.com/Unity-Technologies/UnityCsReference to try and find what SerializeReference actually does but i cant find it
since i wanted to make an extension of it and just draw the default GUI under a new line im adding
but idk how to do that
was hoping i could inherit the gui, draw my line and then use base.OnGui()
That is because it is used by the serializer which is in C++
You can look at what this repo does https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
what about the inspector propertydrawer?
I don't think it does anything special for it.
yeah, but if i can reuse the code from its property drawer then thats good enough for me
So I see my issue is with the second part, the click and show all the allowed items. It's the class ObjectSelector and this is the line that doesn't let me do what i would like
for (int j = 0; j < requiredTypes.Length; j++)
{
if (requiredTypes[j] != null)
{
m_RequiredTypes[j] = ((typeof(ScriptableObject).IsAssignableFrom(requiredTypes[j]) || typeof(MonoBehaviour).IsAssignableFrom(requiredTypes[j])) ? requiredTypes[j].FullName : requiredTypes[j].Name);
}
}
Do you (or anyone) know of a way to fake a type? Like I know they will be ScriptableObjects that Implement IHoldVegetation
Any way to assign the field of Type with a fake type that fulffills those needs but doesn't actually exist?
Has anyone tried using the Cursor IDE with Unity yet?
no, but i am using copilot which sometimes give functional code but sometimes it just doesnt know that what its doing will cause issues and i try to tell it but it doesnt listen
i dont really use it much other than asking simple stuff i forget about which its usually good at answering. its good at knowing things, but not solving problems
anyway. i currently have this: https://pastebin.com/hBqLueYC
and it works, until its encapsulated by a different class. not really sure what makes that happen other than i checked the property and it only has An object reference (which i assume is the class encapsulating it), and the generic. (which is always there as far as i can tell)
ive run into this problem before but then i found a way around it but this time idk if i know how to
If the property isn't set then you are never drawing it. Also, you can just check the property.propertyType to see if it is a managed reference. No need to get the FieldInfo
but they should be set i think? in the lisst and the test have them set to a default ability which is something other than null that has a serialized bool in it
I don't know where your code is running, butt hat code never enters children, so...
its in a property drawer like FindReferenceBySearch
[System.Serializable]
class SerializsationTest
{
[SerializeReference, FindReferenceBySearch(typeof(AbilityFactory))]
AbilityFactory Ability;
}
the first part is just opening the search window and the button, then its the code i linked
then in the scriptable object where its not working im defining them like this:
// these do not work.
public List<SerializationTest> list = new List<SerializationTest>();
public SerializationTest test;
// but this by itself works
[SerializeReference, FindReferenceBySearch(typeof(AbilityFactory))]
AbilityFactory Ability;
how do i fix that then? or is it even possible?
ah... im dumb. there is a bool i missed on the property field that has "include children" 
CC @visual stag -- I saw a nice repo you have yesterday and saw it could benefit from this too:
ah nvm it's a sealed class..
Is there some plugin or asset in the asset store that allows me to create an XMLDoc from the C# documentation of my assembly def??
sometimes I really hate unity, we are in year 2024 and still we cant serialize dictionaries in editor 😩 . Dear developers in Unity, when you will add this simple feature ?
At last it isn't hard to implement one, but yeah, kinda sad. Here is mine if ya want it
They have said that the reason they haven't added it is because the serialization system is complex, and they want to do it right, not just slap it in.
You can submit the request on the product board
Thanks for reply, I will look your implementation
How do you ensure that your dictionary elements are consistently ordered?
I am in a need of a second opinion on something
Im adding a validation system on my unity package EditorAttributes and you can use attributes like Required and Validate on a field for the validation system to go trough them
you also have the option to make it so when validation fails and you try to build the build will stop
now my question is, would you rather, when a build fails because of a failed validation to spit out the entire validation logs?
or just the validations that stop the build process
as an example you have something like this
[Required(throwBuildError: true)] public GameObject objectField;
if that field is null when you try to build it will stop the process
and throw all the validation errors including the ones that are not marked to stop the build
as it stands now I put an extra label to the ones that stop builds and it looks like this
Hey, anyone know how to get the new search service to find assets in packages? I want to find all assets of a type in assets AND packages but it refuses to find any in packages...
Iirc I store the index with the serialized data. Not the cleanest solution, but also not really any others.
Right, you only use it for ordering in the ui, but it doesn't actually care about maintaining the order down the line. Makes sense
I interpreted it wrong 😄
I think that approach is fine, make the 'Build Killers' an actual Error and use Warnings for the other ones 🙂
I think either is fine, but keep in mind that it is desirable behaviour to find all warnings before killing the validation/build process.
IIRC our system only prints the build errors and then gives you the ability to view all errors/warnings etc somewhere else
its fully customizable, the Required attribute will always give an error by default but the Validate attribute will allow you to specify the severity so you can have warning build killers if you wish, if you only want build killers to be errors you can mark anything else as a warning
for more context, the Required attribute by default only displays an error box in the inspector if something is null, you have the option to mark it if you want it to be part of the validation process and if you do that it will always throw an error, with a separate option to be a build killer
the Validate attribute is for custom validation (ex. check if a string is empty or a number is negative via custom function), you can specify custom messages and the severity (log, warning, error), it will show an error box with that message of the specified severity in the inspector if it fails the validation and will always be included in the validation system and log something based on your parameters
the validate attribute also has an extra optional parameter for it to be a build killer
I didnt really want to create a custom validation console, unity's console works just fine
Yeah if that works then that's great
Just doesn't for us since we are not just bound to Unity but can do the same builds outside of Unity (not game builds but some other things)
cool
Invalid antiAliasingValue Error gettting spammed
so if i have a serialized reference and my drawer here: https://pastebin.com/53uTcWu1 (image for reference). how would i add the possibility to copy the serialized reference to another?
similar to how its possible to copy a reference to another object field, but i want to copy all variables and data thats defined.
is there an easy way to show a vector3 variable as a transform gizmo thingy in the world and move it arround to set it? 🤔
I can try to draw cool stuff in the onGizmo part of my monobehaviour, but I can't draw interactive stuff and there must be something easier than drawing my own 3d gizmo for each vector3 variable I want to show... right? 🥲
I think you can try something like myVector = Handles.PositionHandle(myVector, Quaternion.identity)
I do this in an EditorWindow duringSceneGui, so I'm not sure if it works the same in a monobehaviour (I forget the differences between gizmos and handles). But if it works, there's also a ScaleHandle, RotationHandle, and TransformHandle. And you can use Tools.current to use the same active tool as the sceneview
Not from within a component (and really, you shouldn't). The easiest way to is make a custom editor by inheriting from Editor override the OnSceneGUI method.
If you want to do it the 'right' way, (which is better in the editor, but more work). You can use the Overlays.
not gonna lie, I was hoping for something like [SerializeField, GizmoEdit] but I will look into how to make my own 😅
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor: Editor
{
void OnSceneGUI()
{
var vectorProp = serializedObject.FindProperty("_myVector");
EditorGUI.BeginChangeCheck();
vectorProp.vector3Value = Handles.PositionHandle(vectorProp.vector3Value, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
}
}
Something like that should do it. But yeah, there isn't a attribute or something like that for it.
Somewhat related, what is the typical way of handling quaternion serialized values with these handles? Quaternions are initialized as (0,0,0,0) so their invalid when passing into the handle. Is it best to just perform a check here in the Editor OnSceneGUI?
I would suggest setting them to Quaternion.Identity either as a field intializer on your MonoBehaviour or in the Reset() method
I.e
public Quaternion SomeRotation = Quaternion.Identity;
The thing is, I have a list of points/transforms that are populated dynamically in a ScriptableObject. And I'm not sure how to set initial values of new list items
Then I'd set it whenever you populate that list
If you do it on OnSceneGUI they could still be invalid when something else attempts to access the values
how do i track down what is creating this error? Could not update a managed instance value at property path 'managedReferences[5251334975535972356]', with value 'Assembly-CSharp Interact'
o wait i see, it has a name at the end, then i might be able to find it lol
nvm im not entirely sure what it means, ive been looking online but the only thing i can see is that i have an interface that implements Interact but idk if thats what it means. so i would assume it has something to do with what the manged reference that related to my interaction but idk what it is
It usually means happens when you change name or namespace of a SerializeReference if I am not wrong
ah, that might have happened. if i restart unity might it just go away then?
If you look into your object, you are going to see that the value is now null.
ive tried changing the values that would be related but its still saying it so 
You can revert the prefab change I believe it is the cause ?
oh right, it might be a prefab. i havent checked that
Its trying to change the value from a prefab which does not exists anymore because it broke when you changed a name.
Ever noticed how Unity lacks a built-in way to find specific components in your scene? I built ComponentSearchTool a editor tool to solve that (not sure if something similar already exists). It's open-source, check it out: https://github.com/saurabhchalke/ComponentSearchTool
Nice! I hate to do this to you, but I think Unity already supports what you want to do, both in the hierarchy and in the new search window. Unless you want to just show the contents of the components directly or something.
I am pretty sure it is not possible, but I am going to ask anyway.
Is it possible to delay the activation of the current scene when we change the "PlayModeState" to Play ?
In other words, I would like to be able to have:
- Press Play
- Prevent the current("main") scene activation
- Load Bootstrap Scene additively.
- Wait for Bootstrap to finish (Contains Coroutine and other asynchronous operation)
- Activate the "main" scene
At the moment the solution I have are:
- Make bootstrap non async. (Not everything can be made async/It requires duplication of code only for that.)
- Make every script in the scene wait for the bootstrap to finish. (It can be a pain in the ass to add the check everywhere./This is the best we can in my opinion though)
- Reload the current scene. (It increase the iteration substantially.)
No, but this might be an alternative approach https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager-playModeStartScene.html
I haven't used it my self. But if it works how I assume it does, you could set it to be your bootstrap scene, and then once the bootstrap has finished, have it load the main scene
I believe it would simply replace the current scene ?
Effectively unloading the scene which would potentially cause the scene to reload.
I think it would not cause a seen reload/unload of the scene you are working in
You can also cache a reference to the currently open scene when exiting edit mode, and pass it along to some property that the bootstrap scene uses to load when complete. That way you should be able to play whatever the current scene is I think
Might require saving the current scene I don't know
I will test it, but I fail to see how it could work.
Not exactly sure what the property do, but I'm expecting it to simply replacing the current scene with the one specified then play it.
I want to be able to prevent the scene from reloading, in other words to not have to do a Scene.Load or equivalent.
Wait... so you want to disable a scene from being reloaded when entering playmode?
When you enter playmode, the scene is not effectively reloaded.
What you are wanting to do from what I understand it from your explanation above. When you enter playmode, you want the main scene to not load/do anything until a bootstrap scene has finished initializing/running. Correct?
Exactly
I want to prevent the Awake/Start/OnEnable/Update from the current scene to be called before the bootstrap is finished
Then what I suggest should work (again, with the caveat that I haven't used it before, and so I am assuming it works as I understand it).
The difference is that you set the boostrap as the 'main' scene
What prevent the other scene to be loaded before the bootstrap is finished ?
You load it from teh bootstrap
You set the bootstrap as the enterplay mode scene, and when it has finished running, you load the main scene your self.
Wouldnt do exactly what I am preventing to do ?
A scene releaoad
Or is it different in this case ?
Would do the same I think
But you are trying to have your cake and eat it too
You want to do scene loading, but also not.
The only other option i can think of is if you disabled all game objects in the main scene when/before you enter play mode, and re-enabled them after your bootstrap has finished
That might actually work O.o
(Fun fact, this is what Ori and the Blind Forest does for loading their levels at runtime)
I think I will actually try that.
@gloomy chasm, it seem to work correctly. (deactivate the gameobject)
I have made Readonly drawers before but i dont understand why im getting extra spacing this time. im not adding any space here. the only attributes used is [SerializeField, ReadOnly]
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false;
EditorGUILayout.PropertyField(property, label);
GUI.enabled = true;
}
}
does it have something to do with using both serialize field and readonly?
You can't use EditorGUILayout in a property drawer. You have to use the non-layout GUI methods.
ah isee, thanku
so ive been googling why custom attributes doesnt apply as expected to arrays/lists and i found this:
"the property drawer is applied to each element of the arrays, not the arrays themselves. This is how Unity applies CustomPropertyDrawers to lists/arrays."
so if i want to make a list ReadOnly i have to nest it in a different class and then optionally create a property drawer that hides the nesting? is there no other solutions to this?
I also tried the solution on here by FuzzyLogic: https://discussions.unity.com/t/how-to-make-a-readonly-property-in-inspector/75448/7
with using a begin and end decorator drawer for marking properties read only but im not getting that to work 
If you are on Unity 6 there is now a bool for if it applis to collections
Also, my guess for why it doesn't work anymore is because the default inspector is now drawn with UIToolkit, and the IMGUI fields are each in their own IMGUIContainer.
i dont think we are in unity 6 and i dont think we can upgrade either so
but thanks, now i know
but maybe we are and if so i will do this
The only other option if you want to prevent a list or array from being reordered and having elements added/removed is to make a custom editor for it.
does anyone have any information about tilemaps changing in Unity6?
IShortcutToolContext seems to have been deprecated but i dont see an update to Tilemaps which inherits from it.
I think the all the errors i see are just in the tilemap pallette editor, but I'm not certain
oh interesting... a clean project has no errors, just my upgraded project... guess i have some digging to do 🙂
hey uh, anyone knows how to fix this?
[Package Manager Window] The file [G:\NPC game mechanic\Packages\manifest.json] is not valid JSON:
Unexpected string in JSON at position 1846 while parsing '{
"dependencies": {
"com.unity.ai.'
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
"com.unity.ai.' this ends with .' when it should end with ". Don't know if you manually edited it, or if unity just got something messed up
Hey guys. i'm doing a small game in unity for a sort of game jam here locally, and they're asking us to make it playable on web, on itch.io. is there any limitations to this? Or can I just make any game use the extension and it'll be playable on web?
It's nothing complicated at all, max 10-15 mins in lenght, low poly.
You want #💻┃unity-talk probably. This channel is for making custom editor windows and stuff like that that runs in the editor.
Or actually probably #🌐┃web
Sure, I'll just copy paste the message.
Thanks!
When i create an object from a prefab, the prefabs inside the object become unlinked. how can i fix this?
do i have to go through the inside of the prefab and instantiate the prefabs inside? im confused
this is the template that it creates from
If you do var newPrefab = PrefabUtility.InstantiatePrefab(prefab) it will be the same as if you dragged and dropped prefab in to the scene
but then i can't use gameobject stuff because it turns into an object class.
Just gotta cast it to a GameObject
why is it null?
string prefabPath = folderPath + "/" + characterName + ".prefab";
if (!AssetDatabase.IsValidFolder(folderPath + "/" + characterName))
{
prefabPath = AssetDatabase.CreateFolder(folderPath, characterName);
Debug.Log("Created folder: " + folderPath);
}
Debug.Log(prefabPath);
PrefabUtility.SaveAsPrefabAsset(newPrefab, prefabPath);
when you debug log the prefab path
The docs hold the answer you are looking for 🙂 https://docs.unity3d.com/ScriptReference/AssetDatabase.CreateFolder.html
doesnt mention anything about null values
oh right
nvm
why would it fail, though?
where / how can i edit the editor css file to change the fonts / color ?
It isn't supported, though I think I remember seeing some random github repo where someone managed to do it. (sorry not that helpful I know)
There might be a editor preference for changing the editor font, size, and color?
Hi, does anyone know if you can create a menuitem for each scriptable object asset?
Not natively no. You can if you want to use reflection
Looks like you would want Menu.AddMenuItem. Maybe calling RebuildAllMenues after it. https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Menu.bindings.cs#L68
Not as bad as I thought
How to regenerate csproj files from an editor script?
Or to put it in another words, I have an AssetPostprocessor class with OnGeneratedCSProject(string path, string content) method.
When I import the unitypackage with that class, I want csproj files to be updated with its effects, but right now it's not.
Csproj file are updated when "regenerate project files" button is clicked or when an script is added/removed
So I'm trying to create a new temp scene from a editor script that will have it's own physics scene in order to sim physics on spawned objects. However it seems I can not create a scene with a local physics scen from EditorSceneManager. Any suggestions ?
My other idea is to make all RB's that are already in the scene kinematic
and turn them back on after the sim is done
CompilationPipeline.RequestScriptCompilation should regenerate them
You can specify the local physics mode by passing in a CreateSceneParameters object
EditorSceneManager.CreateScene("MyPhysicsScene", new CreateSceneParameters(LocalPhysicsMode.Physics3D));
No you can’t. Editor scene manager inherits that method and from SceneManager and it does not work at edit time.
Hi ! Would there be any reason a SerializedProperty.NextVisible(true) would return null when I know there is at least 1 sub property ?
I tried using SerializedProperty.FindPropertyRelative() first, but since it was returning null, I tried parsing the content of the property to see if everything was fine and it seems like it is not.
I have 2 fields of the same type, one which works correctly, and the second that have this issue...
2 fields of same type. FindPropertyRelative returns something for the 1st and null for the 2nd.
Is it possible to add components (or just the serialized data) to a custom scriptable object so that I can use this to create gameobjects from a component set? Basically, can I have this GameObject inspector but on a ScriptableObject?
I know I can probably have a GameObject serialized property where I can just drop in a prefab, but I am basically wondering if we have access to these inspectors directly?
Isn't that just Instantiate/Prefab Variant but with extra steps?
So yeah, so I mentioned this could probably be achieved with prefabs. But in this hypothetical use-case, I can create multiple scriptable objects and add a different set of components. But mostly, I was wondering if it's possible to have this "inspector" directly. But even if it's just prefabs / prefabs variant, could you have a inspector for this data, say in a custom EditorWindow?
If it's not possible or is too much to implement then I'll scrap this idea, but was wondering if this is something that already exists
For a custom window on a prefab yeah you can create the inspector manually. You can get all components by GetComponents on the game object, then for each component you create an editor UnityEditor.Editor.CreateEditor. Depending on if you use IMGUI or UITK you just call OnGUI on the editor or CreateInspectorGUI and add it to your custom window.
I don't think you can achieve this on a scriptable object since you need to have an actual instance of the data that you can target with an editor
Okay, yeah this is what I was looking for. This would work perfectly. I could still essentially reference a prefab and use CreateEditor to display /edit that content.
Thanks
It would be possible if prefabs could be subassets. But since they can't it isn't possible. Also you can use InspectorElement to get the default inspector of a object (just as an fyi)
Cool, I'll look into using InspectorElement directly since I am working with UITK. But regarding the prefab subassets, couldn't I still reference the prefab, then load it with AssetDatabase, create a serialized object from it and inspect that?
What's this channel for exactly?
Yeah you can reference the prefab asset and show the inspector for it still
You can take a look at the description of the channel and it tells you mostly. 🙂
Does it also include the sprite editor window, since I want to know something about it
Nope, it is for creating custom windows and the like
You probably want #🖼️┃2d-tools
How can I set a SerializedProperty in a custom PropertyDrawer if the property is of a type that doesn't have a ___value setter? I am trying to create a Dropdown to choose a specific Type, and I have an Attribute on that function, but I don't know how to actually set the value of it.
Actually, I think I might have found it immediately after asking, is it managedReferenceValue? Guess I'll 
Depends on the type you are setting, if it is serialized with [SerializeReference], then yeah, you would set it with managedReferenceValue
It's of type Type, and I have a custom attribute on it, looks like this:
[SubtypePicker(typeof(AbstractGhostPart))]
public Type ghostPartType;
And I'm trying to draw it with a [CustomPropertyDrawer(typeof(SubtypePickerAttribute))]'s CreatePropertyGUI(SerializedProperty property)
Type is not serializable, so you can't use SerializedProperty or related systems with it
I'm trying to make the property serialized, so is there a way I can do that with an attribute?
Ahh the only option is to implement a custom class called like SerializableType and implement ISerializationCallbackReciver
Hm... maybe I should back up and post the original thing I was trying and what went wrong with it. Maybe an attribute wasn't the solution after all
Gimme a second, I need to hand-copy the code over from one computer to another since I can't use Discord on a government machine
Use a paste site?
I suppose, then I could just hand-copy the URL. That might work, hang on
a powerful website for storing and sharing text and code snippets. completely free and open source.
I just went ahead and threw it all in. This looks the part, but the problem is, whenever I enter play mode, those Type properties become null again
Right... cause Type can't be serialized

Maybe I can just make them strings and find a way to go from string to Type in the thing that uses them
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
(Pardon me, gotta get a paste site, old one I used is gone now I guess)
RIP gdl space 
Here is a mostly drop in replacement for Type https://hatebin.com/ntcugqwulk
Doesn't look like I made a drawer for it though
Hopefully it'll work with mine
Your's doesn't work with your's 😛
Correct. But I still think my dropdown is neat I just can't use it for dumb encapsulation reasons which this appears to have solved
Give me like 10 minutes and I will have one a bindable dropdown for you. Been meaning to make one anyway
Okay, it is now showing up, but it says No GUI Implemented even though I've added one. Maybe it's because the PropertyDrawer is on the attribute, not the type itself?
Ah, looks like I need to have a custom editor window after all, the default one doesn't call CreatePropertyGUI:
https://discussions.unity.com/t/createpropertygui-drawer-no-rendering-in-inspector-no-gui-implemented/861931/5
But I have to go now, I have unfortunately run out of time. I'll have to get back at this in the morning. Thank you for the TypeReference class, I think that was my missing sauce, I should be able to get this working tomorrow
Sure, no problem. Still gonna finish the drawer haha
Here you go @simple bloom, you probably want to edit it a bit for your own needs. But a UITK Field and a PropertyDrawer for TypeReference. https://hatebin.com/slqlrepurk
[SubType(typeof(Renderer))]
[SerializeField] private TypeReference _type;
Well was closer to 25 minutes... so a little off on my estimate haha
That is basically exactly what I need. I've forwarded this message to myself so hopefully I remember to check it tomorrow
Haha, well good luck with that
Hopefully hatebin doesn't delete it by then
Well, just @ me again if it does. But should last 24 hours I think
I can't use the formatSelectedValueCallback in TypeReferenceDropdown, since it's internal and my code is in a different assembly.
Commenting that out, it's still giving me the "No GUI Implemented" on the type. I'm guessing this is using some potential newer UI Toolkit features, but I'm stuck on Unity 2021 for this project, so I might have to just go back to using a String and taking the time to get the Type from that
formatSelectedValueCallback maybe it was internal in older version? Not required just nice looking.
The reason you are getting a "No GUI Implemented" is because you have a IMGUIContainer UITK element and are doing editor.DrawDefaultInspector which draws a IMGUI inspector. And I only implemented the property drawer for UITK.
So, I would need to make a UITK editor for the class that uses it and manually add fields for all of the properties?
At least with the code you shared, I don't think you need a custom editor at all.
But no, you can use an InspectorElement which can draw it. Or just loop through the first level of properties and use PropertyFields
I've commented out the custom editor entirely, and it's still giving me that. I don't have any of my custom editor code left
What version are you on?
Hmm. I thought that they made the editor use UITK by default in 2021 but maybe I am misremembering
Maybe it was 2022
You can do
var rootElement = new VisualElement();
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
while (iterator.NextVisible(false))
{
rootElement.Add(new PropertyField(iterator));
}
I think at least. I sometimes forget the exact steps for iterating on properties 😅
Yep, that appears to have done it!
Nice, first try!
Implementing a IMGUI drawer for it is pretty easy too
if (EditorGUI.DropdownButton(rect, property.FindProperty("_typeName").stringValue))
{
var menu = new GenericMenu();
var types = // get types.
foreach(var type in types)
{
menu.AddItem(new GUIContent(type.Name), false, () => {
property.FindProperty("_typeName").stringValue = type.FullName;
}
}
menu.ShowDropdown(rect);
}
Or something like that at least
All right, now as an exercise to myself I'll see if I can find a way to format the text in the dropbox without access to formatSelectedValueCallback
If not, no biggie
Honestly, would just use reflection to grab it haha. Otherwise it is posible, I can tell ya if you want or let you play around and figure it out yourself
Let me try to figure it out my own a bit. I can definitely use reflection, but I'm sure they had a way to do this before making that callback public, I just gotta figure out how
thanks for the tip, but didnt work. had to use reflection to call some methods from com.unity.ide.visualstudio package
also turns out, this also does the trick (regenerates csproj files)
Unity.CodeEditor.CodeEditor.Editor.CurrentCodeEditor.SyncAll();
Is there any means of attaching a description to an enumerated field? I have some enums that are tricky to fully explain with a variable name, so I'd like to have tooltips and such generated for the enums
Nothing built-in. But sure, the basic idea is to make a custom property drawer for either Enum or for a attribute that you add to the enum field. Then show a custom dropdown that has tooltips for them. You would add a Tooltip attribute to each eum value and use reflection to get the attributes.
;)
You want maybe #archived-code-general I think, or maybe #💻┃unity-talk. This channel is for discussing making custom editor windows and stuff like that.
I'm using this amazing code:
var textStyle = new GUIStyle(EditorStyles.label);
textStyle.wordWrap = true;
textStyle.richText = true;
textStyle.fontSize += 3;
EditorGUILayout.SelectableLabel("<a two=\"2\" one=\"1\">test</a>", textStyle);```
and then when I check `HyperLinkClickedEventArgs.hyperLinkData` it only has the first parameter (two = 2 in this case, but if I swap their places, it'll only have the other one)
This was working fine in Unity 2022, but seems broken in Unity 6 (6000.0.18f). Am I missing something? Is it just borked and I should report it? (My quick search didn't find a report about it on the issue tracker)
(And yeah, I can just workaround it by stuffing all my data in one param, it's just a little annoying, also potentially broke someone's plugins / extensions / assets, which is sad)
If it was working in 2022, and not in 6, then it is a bug I assume.
Probably... I guess I'll have to try it on latest version and clean project to be sure and if so - send it Unity's way
is there any extension that hides the Project window with a hokey, the same way Unreal Engine does ?
Not as far as I know but it should not really be hard to make for anyone with coding knowledge.
This would be about 5-10 lines of code if you want to write it yourself
This channel is about writing custom editor windows and inspector and stuff. You probably want #💻┃unity-talk. You can copy paste your message there and then delete it here to avoid double posting.
(I'm pretty sure that would be the correct channel at least)
Is there any decent way to detect when a tag is added, removed, or changed?
I can have an editor update loop that stores previous values, but I'm wondering if there is a better way
Not specifically a tag as far as I know. I would probably use the ObjectChangeEvents to get when an object changes and keep a list of previous values or something. So, only slightly better.
And it breaks when the domain reloads unless you store the previous values
I'm attempting to make a generator that detects tag changes and generates a C# static class that has all of the tags as string constants.
Yeah that is better. Do you know where I can find an example of ObjectChangeEvents, I'm not familiar with those
this might help as a reference to look at https://github.com/AlkimeeGames/TagLayerTypeGenerator
i think there's a few ways to do this, i use an AssetModificationProcessor and just regenerate the file if it sees ProjectSettings/TagManager.asset being modified
Ooh, I thought you meant when a was changed on a GO. There are lots of ways to do that then, you can use the method simonp suggested, or use EditorApplication.projectChanged, or the change event. The docs for the ObjectChangeEvent has pretty good example usage now.
Okay ty! That generator you linked seems to do exactly what I was thinking. I will use it as a reference, because I want the ability to generate it in it's own assembly
Yeah it seems good, though it was Nomnom that linked it not me.
Does anyone know what are the names of the CONTEXT menu elements for every component? Like rectTransform in this case.
If there is a full list somewhere it would be great tho, but for know I only need to know how is the inputMap assets from the inputManager package called.
[MenuItem("CONTEXT/RectTransform/Action", priority = 1)]
It's the type name of any Object. There is no list, that would be ridiculous
InputActionAsset is the type of that asset
I tried using InputActionAsset but no result
Damn
Maybe that specific component cannot have an extra menu entry?
Try InputActionImporter, as the imported object is below. If you right clicked on the header below you would get your context menu iirc
I fear it didnt work :/
I'll look into it when I'm up, but if you use InputActionAsset you should be able to right click the header of the asset below your screenshot where it says Imported Asset
there you mean right? Nothing happens when I right click it
Oh weird there isn't an asset there? I'll have to look when I'm out of bed 
Huh, seems like it doesn't work for custom scripted importers https://discussions.unity.com/t/menuitem-context-does-not-work-for-scripted-override-importers/946848
Also, they've hidden the header and inspector for the asset itself so that's why there's no imported object there
So you'll sadly have to do this some other way unless whatever causes it to not work can be found in the reference source and a workaround is found
Hello there
does anyone know a package or piece of code that can make an enum be drawn as a horizontal button list?
like a switch
I saw a Unity dev working on it, guess it didn't make it in to Unity 6. But should be fairly easy to do, especially using UITK.
There are also a bunch of packages that add a lot of editor attributes, one of them probably has one if you want.
How do I find properties in derived classes?
abstract public class AccessibilityItem : MonoBehaviour
{
[Header("Accessibility Item")]
[SerializeField] protected AccessibilitySettings _accessibilitySettings;
}```
```c
[CustomEditor(typeof(AccessibilityItem), true)]
public class AccessibilityItemEditor : Editor
{
SerializedProperty propAccessibilitySettings;
void OnEnable()
{
propAccessibilitySettings = serializedObject.FindProperty("_accessibilitySettings");
if (propAccessibilitySettings.objectReferenceValue == null)
propAccessibilitySettings.objectReferenceValue = AccessibilitySettingsEditor.GetSettings();
serializedObject.ApplyModifiedPropertiesWithoutUndo();
}
public override void OnInspectorGUI()
{
EditorGUILayout.PropertyField(propAccessibilitySettings);
}
}
[CustomEditor(typeof(DerivedAccessibilityItem))]
public class DerivedAccessibilityItemEditor : AccessibilityItemEditor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
}
}
This approach does not serialize the _accessibilitySettings variable in the editor. Instead it throws a null reference exception, because propAccessibilitySettings is null.
Can you show the full definition for AccessibilitySettings?
(I don't mean the contents of it, just the definition itself)
It's a public scriptableObject if that is what you mean.
I can serialize the field in the derived classes by putting the code in each derived editor.
Just not by inheriting from the base editor, which would be preferable.
wat?
That isn't how serialization works
The editor just shows/accesses the serialized data. It has nothing to do with the serialization itself or in determining what is or is not serialized.
Maybe I am wording it wrong. Since the field _accessiblitySettings is protected I can put propAccessibilitySettings = serializedObject.FindProperty("_accessibilitySettings"); in each derived classes custom editor and it works.
But I'd like to do that once in the custom editor of the base class
Instead of doing it for each derived class with their own custom inspector
Some things to try, put a debug.log right after you get the _accessibilitySettings and log it, to make 100% that is/is not getting found.
Remove/comment out the custom editor for the derived class.
Remove abastract from the AccessibilityItem (this should not be needed!)
I think the abstract class might be the problem
I'll check it and report back 🙂 thanks
The problem was that OnEnable() from the derived editor class hid the OnEnable() from the AccessibilityItem editor class. Unlike in Monobehaviours this was not flagged as a problem. Calling base.OnEnable() solves the problem.
Well yes...
That would have been the first thing I mentioned if it was part of the code you shared 😛
I recommend making OnEnable be virtual in the base editor class
I tried to cut everything not needed to reduce reading time because I'm always so grateful when somebody takes time to fix my issues but seems I was being "too polite" 🥲
Haha, yeah, generally it is better to just share most of it, normally it is pretty easy to skim through. The consideration is appreciated though 🙂
How to open a file selection window, but with the ability to select multiple files?
click edit layers....
where
Okay. I select my ground
now once you click on the layer you will see an add layer... option
and clicking on that will open the tags and layers window
so thats it.
yeah but how do I like hide or lock it
the problem is
this isn't a complete window, it kind of displays from the project settings
because actually if you open your project settings, in there is where this tags and layers actually live
one workaround is
after opening this window, right click on the inspector and lock it
then right click on it again and select add tab>inspector
now one inspector will show the layers and tags and the other will show te object details like normally
Actually another way is to right click on the inspector and select properties,
then the window opens up, you can then put it wherever you want!
I dont get it
Its really hard when I dont have a visual idea of it
And there's like zero tutorial on youtube
1.right click on the inspector while the tags manager is open and select properties
do that first
ok then??
Yeah its in the screenshot
so you can drag and drop it wherever you like
you want it to be open all the time ? right?
i want this function
but while being able to do other stuff?
There's like nothing on newer versions unity. Unless they removed it
?, this is on the layers ?
Nope
There's nothing there
in te scene
I just want to prevent objects from clicking
Mouse over any object in hierarchy and look to the left
FINALLY. THANK YOU
Didn't know what you were looking for!., glad you got it!
Hi everyone, I'm going to ask this here since its related to the editor.
Did someone noticed that the Editor (in UNITY 6.0) throttles its FPS (in the game tab) if the window is not in focus?
This is extremely annoying when testing with ParrelSync (so when having two editors) since the other one is literraly at 0.1 FPS.
Can't seem to find an option to prevent this, even enabling Application.runInBackground does nothing
This channel is for discussion around creating custom editor windows and inspector. And writing other editor code. For general discussion about Unity #💻┃unity-talk would be the correct channel.
anyone?
It isn't supported.
I assume you mean EditorUtility.OpenFilePanel right?
yes
Yeah that isn't supported
is there an alternative?
maybe something like this? https://github.com/gkngkc/UnityStandaloneFileBrowser
But is probably overkill
yeah, I don't need it in runtime
and most of these functions
Works in editor
I know
Or you do the OpenFolderPanel, and then have a second popup that shows the files in the folder that you can then select from?
no
I mean... it does work, it just isn't a very nice solution. But depending on your needs may work.
I have no idea what you are doing, so just trying to suggest possible alternatives that may work depending on your use-case
I have an Asset Browser window where I can add my prefabs that can be used in the game
