#↕️┃editor-extensions
1 messages · Page 27 of 1
Alright
Answer: can't be done
https://forum.unity.com/threads/request-for-a-new-editor-callback-postprocessprefab.559837/
Not entirely related to the new prefab workflows but still this would be super useful:
Right now, the editor exposes a PostProcessScene attribute that...
Is there a way to capture the Right click event when right-clicking an Object field?
Or add something to the right click menu?
https://docs.unity3d.com/ScriptReference/EditorApplication-contextualPropertyMenu.html
This exists for property fields in general. But that field is lacking a lot of menu items so I'm doubting whether it's a property field
Hmm yeah that didn't work. It might not be possible to do what I wish that way.
private void HandleOverview()
{
scrollViewRect = new(
new Vector2(statusLabelRect.xMin, statusLabelFieldRect.yMax + (textFieldHeight * 0.5f)),
new Vector2(mainPanelRect.width - characterWidth, mainPanelRect.height - (textFieldHeight)));
GUILayout.BeginArea(scrollViewRect);
overviewScrollPosition = GUILayout.BeginScrollView(overviewScrollPosition, GUILayout.Width(scrollViewRect.width), GUILayout.Height(mainPanelRect.height));
foreach (SimulatedBody body in bodies)
{
EditorGUILayout.ObjectField(body.Rigidbody.gameObject, typeof(GameObject), true);
}
GUILayout.EndScrollView();
GUILayout.EndArea();
}
Basically I am adding a bunch of structs to a list.
Then I wish to be able to locate those objects in the scene. That works as expected with the above.
But since the above are object fields they also exhibit other functionality that I am not using but maybe I could use.
So I thought about the right click menu and such
Is it possible to draw this list, but remove the foldout?
ReorderableList
is idea of creating Property drawer and using new "runtime" binding system bad? cos i really like workflow but i am not sure if it can even work properly with serialized property :/
maybe all i need is custom Data Binding class that will also serialize it back?
well, i made quick test and this works a charm for now:```CSharp
public class SerializedDataBinding : DataBinding
{
public SerializedProperty serializedProperty { get; set; }
protected override BindingResult UpdateSource<TValue>(in BindingContext context, ref TValue value)
{
var baseResult = base.UpdateSource(in context, ref value);
serializedProperty.boxedValue = value;
serializedProperty.serializedObject.ApplyModifiedProperties();
return baseResult;
}
}
I have found one...
it does not update properly if property setter affects other fields...
so here is update:```CSharp
public class SerializedPropertyDataBinding : DataBinding
{
public SerializedProperty RootSerializedProperty { get; set; }
protected override BindingResult UpdateSource<TValue>(in BindingContext context, ref TValue value)
{
var baseResult = base.UpdateSource(in context, ref value);
RootSerializedProperty.boxedValue = context.dataSource;
RootSerializedProperty.serializedObject.ApplyModifiedProperties();
return baseResult;
}
}```
Anyone figured out how to set up a timeline with control tracks and clips and save it properly without the ControlPlayableAssets falling apart upon reopening the scene?
So given this view here, I have a Scrollview that I wish to show a scrollbar on more dynamically than I got here
It needs to be this small before a scroll bar even shows up
I know it's because I give the scrollview the wrong GUILayout.Height() number, but I'm not sure how to do it.
private void HandleOverview()
{
scrollViewRect = new(
new Vector2(statusLabelRect.xMin, statusLabelFieldRect.yMax + (textFieldHeight * 0.5f)),
new Vector2(mainPanelRect.width - characterWidth, mainPanelRect.height - (textFieldHeight)));
GUILayout.BeginArea(scrollViewRect);
overviewScrollPosition = GUILayout.BeginScrollView(overviewScrollPosition, GUILayout.Width(scrollViewRect.width), GUILayout.Height(scrollViewRect.height));
foreach (SimulatedBody body in bodies)
{
EditorGUILayout.ObjectField(obj: body.Rigidbody.gameObject, objType: typeof(GameObject), allowSceneObjects: true);
}
if (includeNonRigidbodies)
{
foreach (GameObject go in nonRigidbodies)
{
EditorGUILayout.ObjectField(obj: go, objType: typeof(GameObject), allowSceneObjects: true);
}
}
GUILayout.EndScrollView();
GUILayout.EndArea();
}
Finally got it
While I think I know the answer to this question, I would like confirmation.
I have a custom attribute that turns a float/int into a modifiable slider - the min and max values are both FloatFields that can have their value changed, stored as variables inside the attribute class. Anytime the scene is reloaded or the scripts are recompiled both values default back to 0. I have tried everything I could think of, and tried to find any answers online, but nothing has worked so far. Is my only solution to use Vector3s as opposed to floats (x=min,y=value,z=max) or is there some other way to get it working how I want?
Is there a way to disable a button? Or is the alternative only to not render them?
GUILayout.BeginArea(buttonGroupRect);
GUILayout.BeginHorizontal();
isAddPressed = GUILayout.Button("Add");
isRemovedPressed = GUILayout.Button("Remove");
isClearPressed = GUILayout.Button("Clear");
GUILayout.EndHorizontal();
GUILayout.EndArea();
These buttons. Can I disable them? Or should I just not render them?
Turns out GUI.enabled exists
How do I make this simulation actually run?
In my code it uses the EditorWindow's Update method but that only seems to run when I move my mouse or press buttons.
Try turning Auto Refresh on in the scene view settings dropdown
I guess you could also just manually call SceneView.RepaintAll()
Aaand there's this
https://docs.unity3d.com/ScriptReference/Editor.RequiresConstantRepaint.html
SceneView.RepaintAll works nicely there
@real spindle Any guesses as to how I solve the last issue here?
Basically at the end of the simulation, despite the simulation being done, I have to move my mouse at least once before it updates the frame and makes the buttons usable again.
It's like OnGUI() is waiting but I can't seem to trigger it manually because when I try it says I can't use GUI methods outside of OnGUI()
Did you check this? @pale sequoia
That didn't seem to be anything I can use?
It returns a bool but there are no parameters and I can't call it
I'm deriving from EditorWindow so maybe that's why?
Oh thats and editorwindow?
It is, yea.
What if you call Repaint() after each OnGUI()?
At the end of OnGUI I mean
Oh yeah, that did it actually.
Maybe I can find a way to have it be called only when I need it rather than all the time to save on calls.
Yeah 👍
Thanks for the help
Np
Oh turns out it's enough to call Repaint after my simulation is done and I do clean-up
I don't have to call it in OnGui
That means it'll only be called once at the end of my simulation
Yep, was gonna suggest that, but you figured it out
This was more to test if it has any effect at all ^
Pretty wasteful
Yeah I realised
I also tried to optimize my use of SceneView.RepaintAll()
{
if (simulate)
{
SceneView.RepaintAll();
if (simStep >= maxIterations)
{
statusString = $"Done simulating in {maxIterations} iterations.";
PostSimulate();
}
else
{
Physics.Simulate(Time.fixedDeltaTime);
ResetAllBodies(unaffectedBodies);
if (simulatedBodies.All(rb => rb.IsSleeping()))
{
statusString = $"Done simulating in {simStep} iterations.";
PostSimulate();
}
}
simStep++;
}
}
Here it only gets called for the number of simulation steps that takes place
The reason is that when a domain reload happens, all fields, events, etc. (instance or static) are reset to their default state. Basically it is like they are created for the first time. Then any serialized data is re-applied (actual implementation may differ). The thing is, attributes cannot be serialized by Unity. You can only really use them for hardcoded data.
So yes, your own realistic option is to use a Vector3. However, there is a second option if you don't mind slightly different behavior. You can have the min and max always be a set amount different than the actual value. So every time the field is shown for the first time, you get the current value and then add say, 5 and that is the default max, and remove 5 and that is the default min.
Hey guys. I have this script that creates a prefab that turns an FBX object into a prefab using a template. However when i create the prefab, it turns the prefabs that are in the template into just standard game objects. how can i fix this?
Script: https://gdl.space/alogukisub.cs
thanks guys
Maybe you want this?
https://docs.unity3d.com/ScriptReference/PrefabUtility.InstantiatePrefab.html
This is similar to Instantiate but creates a Prefab connection to the Prefab.
Thanks! This looks like what i want. I might have implemented it wrong on first try, though, as its creating a prefab variant of Template, when i want a whole new Prefab with the nested prefabs still having their connections
In that case, you should duplicate the actual prefab asset
(but I'm not sure how I'd do that, either..)
where do you draw gizmos too in custom editors?
im trying to use gizmos draw mesh but it wont let me do it when i subscribe to scene view
theres also no OnGizmosDraw function and OnSceneGUI only executes when a scene event happens not every frame
it allows handles but not gizmos yet handles has no draw mesh function
Several options there..
You could use Graphics.DrawMesh for example, i think that should work in Editor.
What i'm doing, sometimes, if the Editor is a Custom Inspector for a Component i just expose a Callback for the OnDrawGizmos
How do you guys sort your uss and uxml, UITK controls, windows etc.?
So far, I have been having separate folders for Controls, Windows, PropertyDrawers, Editors. and View for VisualElement controls that are more specific and less generic. And then a folder UI, for all the uss, uxml, icons etc.
But, as time has gone on this has felt less good to me. So, curious if there is a nicer way.
I use OnSceneGUI in the custom editor just fine - maybe you are tryign to add it inside the component instead of the component's custom editor ?
If you mean "only when scene event happens", for example when you move the mose, scroll or something, and it stopping when you stop (in editor)
then you can try EditorApplication.QueuePlayerLoopUpdate();
Hey, could anyonw help me with this question related to sliders in Unity UI Toolkits? #🧰┃ui-toolkit message
i had to end up using Graphics.RenderMesh
How do i display a serializable custom struct in a custom editor?
I want to make a custom editor so the radius member updates the scale of the child sprite
Using a PropertyField.
If you don't have an object you've serialized it on, you can serialize it into the Editor itself and create a SerializedObject from the editor.
Though, if you want a serializable structure to be styled different you should be making a custom PropertyDrawer, which the inspector will just draw because it uses PropertyField
Oooh!!!
Okay
That explains a lot
Thank you
OH I'VE BEEN MISUSING EditorGUILayout REALLY BAD LMAO
yeah okay this pattern makes WAY more sense
been trying to set indexer value with reflection , but writing to the struct doesn't seem to update it
Vector3 _value = new Vector3(4, 5, 6);
var _type = typeof(Vector3);
float new_value_x = 99f;
int x_index = 0;
System.Reflection.PropertyInfo _indexer_prop = _type.GetProperties().First(x => x.GetIndexParameters().Length > 0);
// GET ---
Debug.Log(_indexer_prop.GetMethod.Invoke(_value, new object[] { x_index }));
// SET ---
// Method 1
_indexer_prop.SetValue(_value, new_value_x, new object[] { x_index } );
// Method 2
//_indexer_prop.SetMethod.Invoke( _value, new object[] { x_index , new_value_x } );
//Method 3
//System.Reflection.PropertyInfo indexerProperty = _type.GetProperty("Item", new[] { typeof(int) }); // "Item" is the name of the indexer
//if (indexerProperty != null && indexerProperty.CanWrite) indexerProperty.SetValue(_value, new_value_x , new object[] { x_index });
// --
Debug.Log(_indexer_prop.GetMethod.Invoke(_value, new object[] { x_index }));
Debug.Log(_value);
the console looks something like this :
4
4
(4, 5, 6)
not perfect but this works :
public static void VectorIndexerSet<T>( object item, TypedReference itemTR , int index , T new_value )
{
string[] field_names = new string[] { "x", "y", "z", "w" }; // Vector2, Vector3, Vector2Int, Vector3Int, Vector4, Quaternion
if( type == typeof(Color32) || type == typeof(Color) ) field_names = new string[] { "r" , "g" , "b" , "a" };
item.GetType().GetField( field_names[ index ] ).SetValueDirect( itemTR , new_value );
// Doesn't work :
//var p = _type.GetProperties().First(x => x.GetIndexParameters().Length > 0);
//p.SetValue(_value, new_value, new object[] { index } );
//p.SetMethod.Invoke( _value, new object[] { index , new_value } );
//_type.GetProperty("Item", new[] { typeof(int) }).indexerProperty.SetValue(_value, new_value, new object[] { index });
}
also handy :
public static int VectorIndexerSize( object item ) {
PropertyInfo indexerProperty = item.GetType().GetProperty("Item", new[] { typeof(int) });
if ( indexerProperty != null && indexerProperty.CanWrite ) return indexerProperty.GetIndexParameters().Length;
return 0;
}
public static T VectorIndexerGet<T>( object item , int index ) {
var p = item.GetType().GetProperty("Item", new[] { typeof(int) });
return (T) p.GetMethod.Invoke( item , new object[] { index });
}
use
Vector3 _value = new Vector3(4, 5, 6);
int c = NKD.Reflection.VectorIndexerSize( _value );
NKD.Reflection.VectorIndexerSet( _value, __makeref( _value ) , 0, 99.8f );
Debug.Log( NKD.Reflection.VectorIndexerGet<float>( _value, 0 ) );
Are there any best practices or typical conventions when it comes to custom icons for my scripts? I'm thinking of putting them in Editor/Resources but not sure if that's a good idea or not
Curious about icon dimensions too
Okay, got my answer to the last question https://www.foundations.unity.com/fundamentals/iconography
Depends, that works, but I generally just put them in a Icons folder and then using the AssetDatabase using this technique to get the path to my packages editor folder #↕️┃editor-extensions message
so im trying to to open the editor window from inspector, and the serializeobject i use is what object in inspector
the problem is log in Create GUI and called first, before log in Open Window, and that means, the code ````window.SerializedObject = new SerializedObject(fileRenamer)``` will not be called yet, when my textfield are need it
GetWindow both gets/creates a instances and also calls Show() on it
i mean how i can pass the target from my inspector to editor window, and create new SerializedObject from it, if the Create GUI are called first, then only after that my window.SerializedObject = new SerializedObject(fileRenamer); are called
What I am saying is the reason that CreateGUI is getting called first is because GetWindow is calling Show(). So you calling window.Show() does nothing. Instead, you can just create the window like you would for a scriptable object with CreateInstance. And that will fix your problem
it is not a scriptable object, just a regular monobehaviour class
I am a talking about the FileRenamerEditorWindow
im sorry if im not understand it
You replace var window = GetWindow<FileRenamerEditorWindow>();
With var window = CreateInstance<FileRenamerEditorWindow>();
thank you so much, i know editor window is a scriptable object, but never thinking off using CreateInstance instead of Get Window
so anyway if we want to open multiple editor window with same type we also use create instance right
nice
Yup
another question
searchField = new TextField()
.SetName("search-field");
searchField.BindProperty(TargetPathProperty);
searchField.value = "Paste a Path or use Select Folder Button to locate";
``` so if i use BindProperty, my searchField.Value = "blabla" wont change the value of Textfield, but if i commented it, the textfield accepting that value, i dont get it, isn't even if we bind a property to it, using searchField.value still set the value to textfield, and save it to property its bind to?
Not sure I follow, but something to note is that BindProperty doesn't bind right away. It actually enqueues, it and every 100ms Unity checks to see if there is anything to bind, and binds it.
So, setting the .value right after binding will just set it in the TextField, and not the property you are trying to bind.
searchField = new TextField()
.SetName("search-field");
searchField.SetValueWithoutNotify("Paste a Path or use Select Folder Button to locate");
searchField.BindProperty(TargetPathProperty);
```this is my actual code, so i give its a value without notify, for a hints, the bind property....i was remember before i can do like this, but now its just take the value from the property, even when i bind it after
but anyway thanks for reply, for now i just set the value in the property when the path are inccorret
oh anyway this is what happens after i click button
private void OnClickPickFolderButton()
{
searchField.value = EditorUtility.OpenFolderPanel("Select Folder", "", "");
}
``` turn out set value are working, its updating my property to, just somehow when set value after create the textfield its didnt work
Yeah again, because when it binds (up to 100ms later), it just sets the VisualElement's value to whatever the value of the property is.
Could anyone explain to me why this updates my useInstanced variable in the Inspector, but the Label I am making does not update?
I am assuming that CreatePropertyGUI must be called differently than the old IMGUI workflow.
/// Options to display in the popup to select constant or variable.
/// </summary>
private readonly List<string> popupOptions = new List<string>
{ "Use Instanced", "Use SO Variable" };
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
// Get properties
SerializedProperty useInstanced = property.FindPropertyRelative("UseInstanced");
PopupField<string> popupField = new PopupField<string>(popupOptions, useInstanced.boolValue ? 1 : 0);
popupField.RegisterValueChangedCallback(evt =>
{
useInstanced.boolValue = evt.newValue == popupOptions[0];
useInstanced.serializedObject.ApplyModifiedProperties();
});
Label label = new Label($"{useInstanced.boolValue}");
PropertyField propertyField = new PropertyField(useInstanced);
container.Add(popupField);
container.Add(propertyField);
container.Add(label);
return container;
}```
It's just weird to me that the label I am making wouldn't be constantly grabbing the new value of useInstanced.boolValue as it changes
(This is a PropertyDrawer for the Editor, btw)
Actually now I am noticing it does update, but only if I click on some non-field part of the Inspector (like the background) after I update the checkbox
when you see my mouse go to the bottom right, that is me clicking and only then the label updates
(I know I could just update the label inside of RegisterValueChangedCallback, but this is just a test question. What I am really trying to do is draw one PropertyField or another based on the value of useInstanced)
What if you manually repaint the window?
CreatePropertyGUI is only called once when initializing the window, it does not work like OnGUI
you have to either listen to the value change callback or schedule a repeating execution
They do
but the label change is not put there
Thanks, I had a feeling it did not work like OnGUI
With my ultimate goal to be to paint a different PropertyField depending on the value of the dropdown, what would you suggest?
As far as I know right now, I can't add a PropertyField anywhere else but inside the CreatePropertyGUI
Ah right, you gotta bind the label to the property
And if you want to change content, you can disable the old thing and enable the new one
I'm creating a UI for a movile game... But i don't know what to take by reference while scaling and creating the UI... how could i do that?
Should I active that and adjust it to that size??
#🧰┃ui-toolkit would probably be a more apt channel since it doesn't really have anything to do with editor scripting.
How can I group variables in the inspector window with a „hide“ button?
Like sometimes there is a „little arrow“ and when clicking on it you get multiple additional variables in the inspector
What do you mean by this?
I think that is called a Foldout
private void OnGUI()
{
GUILayout.BeginHorizontal();
GUILayout.BeginVertical(new GUILayoutOption[]{GUILayout.Width(200) });
{
ItemLibrary itemLibrary = GetLibrary();
itemLibrary.items.ForEach(item => {
EditorGUILayout.LabelField(item.name);
});
}
GUILayout.EndVertical();
GUILayout.BeginVertical();
{
id = EditorGUILayout.IntField("ID", id);
itemName = EditorGUILayout.TextField("Item Name", itemName);
description = EditorGUILayout.TextField("Description", description);
icon = EditorGUILayout.ObjectField("Sprite", icon, typeof(Sprite), false) as Sprite;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedObject.FindProperty("itemType"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("rarity"), true);
...
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
if (GUILayout.Button("Create"))
{
CreateItem();
SetNextId();
}
}
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
is this an old way to make tools? seems very primitive and I don't know how to give label an onclick
yes it very old hahhaa, now we use UI Toolkit to make editor scripts, but that still fine
anyway what is that id, itemName etc?, a property?...if so just use EditorGUILayout.Property field, and u dont need change check if using properties, its will automatically do apply modified properties
moving this from #archived-code-advanced:
#archived-code-advanced message
in short: I'm trying to list all broken managed references on a prefab
SerializationUtility.HasManagedReferencesWithMissingTypes does not work on a prefab asset object
PrefabUtility.HasManagedReferencesWithMissingTypes does work
However, there is no GetManagedReferencesWithMissingTypes method on PrefabUtility, so I can't ask for a list of the broken references
I guess I could instantiate the prefab, test it with SerializationUtility, and then destroy the instance..?
I'm moving a bunch of classes to new namespaces and assemblies, and I want to be able to actively check for any broken managed references.
i find it really weird that nobody has talked about this online. Searching for "HasManagedReferencesWithMissingTypes" on google gives...8 results
I tried instantiating the prefab and then checking all of its monobehaviours with SerializationUtility.GetManagedReferencesWithMissingTypes. However, it didn't find anything.
perhaps I need to break the prefab connection first
oh, these aren't connected anyway, since I used Object.Instantiate
ah: once you instantiate a prefab, the information about the missing type goes away
(or even just drag one into the scene, maintaining the prefab connection)
I guess you can't ask for any more information than "is something missing"?
I see that Unity can only print warnings about the specific missing types after I open the prefab in isolation mode
I guess this will be good enough -- I'll get told which prefabs are broken, and I can inspect them to find out what exactly is missing
i think this entire concept works if we purchase any unity project. otherwise there will be no broken prefabs.
this is a good concept fen. i dont know about this. but learnt now from documentation.
I you can do a good old file read, iirc the format for managed references is pretty predictable, so should be hard to parse.
I am thinking about that
I'm also thinking about just using find-replace to update the references
instead of having to insert a MovedFrom attribute, reserialize all of my assets, and then remove the attribute again
{class: HumanoidAnatomy, ns: , asm: Assembly-CSharp}
it's super consistent
Yeah
...assuming it doesn't wrap for very long names, at least
I don't know much about YAML
I don't know any serializer that wraps, ever
anyway, it sounds like I can just do a project-wide sed operation on all of my prefabs
well, on my prefabs and on my scriptable objects
and my scenes
Yeah
I'm currently bikeshedding the new namespace, so I have some time to consider this
😁
Haha
VSCode has limited refactoring capabilities compared to Visual Studio or Rider, which makes this marginally more annoying
can't easily move a type to a different namespace
hi, im using reflection to update some of the private values on an object from its editor script. as far as i can tell i have the reflection part working because after i click the button the do the stuff all the transform values update from null to what i wanted them to be but as soon as i click play they all revert back to null.
resolved, i didn't want to use serializefield because i didnt want the variables i was changing to show up in the inspector but it turns out you can combine hideininspector with serializefield [HideInInspector, SerializeField]
I'm not sure how i broke it. But it's an achievement. 
It's an SO with a custom editor.
I created a new one.
Closed unity and checked it again.
The associated script for a ScriptableObject cannot be loaded when, for example, its sctipt's name does not correspond to the class'
Now i see, i forgot that name refactoring doesn't change file names under some specific condition.
Hi, after making a change on the graph view in unity, when we enter domain reload, as we can guess, the whole graph goes and it is as if it is opened from scratch.
The most practical or beautiful way to prevent this, what are your suggestions?
I used scriptable object to save and load the graph.
But I don't keep the continuous changes somewhere without save / load operations, there is no SO Instance that is kept instantly, what do you think I should do?
this worked a treat, btw
i just have to paste all of the changed class names into a python script, and I can then automatically update the namespace and assembly names
This makes it reasonably painless to move namespaces or assemblies. Still a bit fiddly to enter the class names, but that's not the end of the world.
Nice!
Depends on how you are populating the graph. But yeah it will be treated like it is opened for the first time (sort of, as visual elements keep some of their state) on domain reload.
You must keep the changed data somewhere right? You are not crawling the visual elements to grab the values when you save right?
I dont reflect any changes before save/load operations pressed like ,
Save :
Gather all graph elements from view
Fetch all data (pos,data etc..)
Fill SO ınstance in related node fields and save SO
i got the idea i think i just have to create a data before assembly reload then i need to create graph from strach and hold all informations
for now i just have to figure out also Undo class for tons of things 
i should implement these earlier xd
The way Unity does it for the ShaderGraph is to make a copy of the graph object and apply all changes to it. And then on save, copy the serialized data from the copy to the original
Thank you, I'll try and do it.
I also want to ask you one more question if you have any knowledge.
list view component in graph view has nice basic features (recycle - reorder etc).
If you use it in graph view, there is no problem, but when you put it in node, a bug occurs, I saw it in forums, people complain about the same situation, but I couldn't find the solution anywhere.
Have you encountered this before ?
No, but I haven't used GraphView for a few years now. What bug?
I got it, thanks again, I explained it here, maybe we can have an idea.
https://discussions.unity.com/t/graph-view-list-view-problems/363699
Hmm.. I feel like I remember running in to something like this recently. I think making it non-reorderable or not use the Animated mode worked for me. Or maybe I just opted to write my own simple list view element....
let me try the fixes you said and see, or as you said I will have to make my own list view as the last solution
Hey people, is there a Tool that allows me to easily select a prefab?
Let's say I put down a chair and decide that I want to turn that into a Table instead is there something that allows me to change the prefab with a simple click?
No, not a built-in one, but i think there are free and paid Tools on the Asset Store that do similar things. Optionally, i think it's not too hard to write it yourself 🙂
Question, regarding the Editor, if i set the value of a serialized property and the field of the target object. Is there a need to Update or ApplyModifiedProperties?
if you edit the targetObject directly, then you need to Update the SO, if you edit the serializedObject/Property then you need to apply to persist it to the targetObject
I for some reason can not figure out how to put a forward slash in a MenuItem
I want to be a ZED dropdown, and then have 'Copy Prefabs to /ZED/Prefabs' as the option
For C# I can only find backslash as an escape char, not forward slash
[MenuItem("ZED/Copy Prefabs to /ZED/Prefabs")]
Doing it with 2 strings, 1 being literal, does not work
There's an internal Menu class that has some utilities but AFAIK even with that, it's not possible
type: {class: FullBodyBipedEffectorIKSelector, ns: Pursuit.Code.InverseKinematics,
asm: Assembly-CSharp}
😭
Unity wraps it
this means i'll need to actually parse the YAML
Nah, you can still just do a basic read, just need to do more checks and maybe read the next line
You should be able to just check the line ending to see if you need to get the next line too
It is worse, but not too bad.
I have to look regex up every time I use it haha. It is great though.
this would be the most correct option
although it could cause a ton of churn if I write the YAML back out in a different format
I can re-serialize the assets in Unity afterwards
It'd be nice if you could just directly modify the managed reference type in Unity.
You can access it, but it is read-only (????)
Yeah of course, cause you set it via the managedRefereceValue property
I guess it's inferred from whatever you actually put in there, yeah
Otherwise the data and type would (possibly) be mismatched
this is going at it from the other direction: re-interpreting the serialized data
It's a lot faster when editing yaml files directly
I've done something similar with regex and modifying the files before
this is gross but it's behaving
i can use capture groups instead of specifying a specific class, namespace, or assembly
so that I can rewrite every class in a specific namespace + assembly into another namespace + assembly
Hi, how can I get rid of CTRL - O, CTRL-S shortcuts by default. I use these keydown events in my editor window but then scene save and open events are running, I need to clear them when they focus on my window but how?
ok just adding this line it solved after actions .d
e.StopImmediatePropagation();
How can I make so that if you create my scriptable object from an asset (right click on top of an existing asset, create, my thingy) I get to use the asset you selected?
Similar to how if you create a material while selecting a shader the material is automagically connected to the shader 🤔
Write a custom creation script that uses the Selection class to detect what you're clikcing on
the easiest would you use CreateInstance, and save it, so you still have instance of that asset you create
but that really different from what u want, sorry
any info on what a "custom creation script" is or where to investigate? 🤔
sorry, never heard of it and googling scriptable object custom creation script ain't helping 😅
ohhhh, you mean like a button in the editor instead of using the create menu?
That's the super basic solution
Unity's implementation does a lot more but I don't have a snippet available
It might be in the reference source though, not sure
If you want to be able to rename the asset right away like you can with Unity, you can use a EndNameEditAction (Example of usage with Prefab) with the ProjectWindowUtil.StartNameEditingIfProjectWindowExists()(Example of usage with Prefab).
And right below that example there is a example of havinga validate menuItem. Basically it wll gray the menu item out if it is not valid.
Hey, I've been working on my item editor all day today.
Now the work is finished for the armor and I've been trying to figure out the error for almost 2 hours, but to no avail.
Maybe one of you has a little time and can take a look at my script.
The problem is this:
Everything is displayed correctly in the editor, as recorded in the code, but after I created the item, it not only has the parameters I passed on but all the variables are filled.
Each.
Even those that I didn't assign a value to.
they aren't even initialized...... -.-
I would like to thank you in advance and would be grateful for any help.
Hmm, I don't understand the issue. Can you try explain it a bit more?
Jetzt habe ich herausgefunden, dass er beim Erstellen des Items, dem neuen Item einfach alle Variablen des BaseItem.cs übergibt, als auch die Variablen der HelmetItem.cs.
Grundsätzlich habe ich in meinem Editor aber nur wenige Felder die befüllt werden dürfen und auch nur diese sollen zuletzt auf das Item angwandt werden, so habe ich es zumindest versucht umzusetzen.
Denn ein WeaponType uvm. macht bei einem Helm keinen Sinn drum habe ich dieses im case ja garnicht mit initialisiert.
Dennoch ist er am Ende auf meinem Artikel drauf.
I only know English unfortunately.
oh shit. xD sorry
Now I have found out that when creating the item, it simply passes all the variables of the BaseItem.cs to the new item, as well as the variables of the HelmetItem.cs.
Basically, I only have a few fields in my editor that can be filled and only these should be applied to the item last, at least that's how I tried to implement it.
Because a WeaponType and much more doesn't make sense for a helmet, that's why I didn't initialize it in this case.
Nevertheless, it is on my article at the end.
i missed, to put it in the translator. xD
Okay I think I sort of get it. I would recommend changing how you are creating the items.
If you make the item instance when you select the type, you can just draw the Editor of the item instead of having to manually draw the fields.
And in the Create Item method, that is when you save the item you made before.
Another benefit to doing this is that all of the UI code for each item (Armor, Weapon, Consumable etc.) can be in their own class. And you would get undo/redo support.
So when the type changes, you create a new instance of the item type that was selected. And then create a editor for it using Editor.CreateEditor(item). Then you can call editorInstance.DrawDefaultInspector().
However I do recommend using UIToolkit for your editor GUIs instead of IMGUI.
Then you can use the InspectorElement element, which does the same thing, but better.
Thanks for your help, I will try it, when I’m home. 🙏🏻
I appreciate it.
And yeaaaa, I’m a UI Nooble 😅
I never made a editor window before, I’m happy that I learned it.
Learning the UI toolkit-ui document stuff is a thing that I planned for the next years 😆
need some help regarding property drawers not saving its contents
pretty much i have a property thats being displayed in an array and everything saves fine and all, the problem is that once i undo the changes on git, the undo isnt reflected on unity unless i modify the property and resave the asset
im not sure if its related but i have a suspicion with my use of find property relative? but heres a snippet:
A website to host temporary code snippets.
started the snippet with BeginProperty and ended with EndProperty so assumed it should be fine
At a first glance the drawer just uses PropertyField, and doesn't do anything more, so I imagine the problem is with a custom editor if you use one
I don't know if you have to use Begin and End property in a property drawer. If there's no custom editor I would try removing that
I've suspected that so I've tried removing the begin/endprop and also I attempted to use this on a monobehaviour I knew that wasn't using a custom editor but no luck on both
What's the simplest way to display an array/list in an editor window?
Been looking around for a while
#📲┃ui-ux would be the channel you want. This channel is for discussing creating custom editor windows and such. You can just copy your message. Delete it from here, and paste it in that channel.
Depends, is it a serialized property? Are you usng IMGUI or UIToolkit? Do you just need to see it, or do you need to be able to add/remove element? Reorder them?
alright my issue was fixed in the dumbest way possible
I am trying to make a tool that applies an action to a list of gameobjects in the scene, I'm not using any of that fancy stuff dunno what that is
when you manually clear an array unity serializes it as [], but when the array is created at first it serializes as blank, so when i tried to git undo the changes to the asset, git reverted it back to the blank serialized representation which is still empty
Right... where are you storing this list?
but for some reason unity doesnt recognize a blank serialized fields as anything so it doesnt repaint the property properly
I don't think I need storage? You open the tool up, add your objects and click the button
So I guess in the editor class itself
Okay, so the list would be in the editor window itself. That makes it easy. Just have a serialized list of GameObjects. Create a serializedObject of the window, and then get the list property.
Then you can just bind a ListView to the property in CreateGUI()
Yeah, this is what I need help with. Tutorials online are telling me to do crazy shit like this and I'm new to editor tools in Unity
Yeah that is using the old IMGUI system. And yeah... it was clunky
public class ListWindow : EditorWindow
{
// We mark the list for Unity to serialize, so that we can bind to it using SerializedObject and SerializedProperty.
[SerializeField] private List<GameObject> _gameObjects;
// A SerializedObject is a way of accessing the fields in a UnityEngine.Object that are actually serialized.
private SerializedObject _serializedObject;
private void OnEnable()
{
// We make SerializedObject of this window, so we can get and bind to any serialized fields in it (in this case '_gameObjects')
_serializedObject = new SerializedObject(this);
}
private void OnDisable()
{
// We need to cleanup the SerializedObject when the window closes.
_serializedObject?.Dispose();
}
// This is where we initialize the UI when we using the new UIToolkit system.
private void CreateGUI()
{
// We get the property that represents the '_gameObjects' field.
SerializedProperty gameObjectsProperty = _serializedObject.FindProperty("_gameObjects");
var listView = new ListView();
// We bind the ListView to the list of gameObjects, so that way when either the list or the property change, they are both updated.
listView.BindProperty(gameObjectsProperty);
// We add the list to the root element so Unity knows to render it and processing input, binding, etc.
rootVisualElement.Add(listView);
// We need to tell Unity to try to bind to this serialized object. It will then go through all of the children of the rootVisualElement, and try to bind them.
rootVisualElement.Bind(_serializedObject);
}
}
Thanks for this and the detailed explanations. Love you.
You're welcome! 🙂
@gloomy chasm I'm trying to use the UI Builder to do this, having trouble binding to the list
public class PrefabReplacer : EditorWindow {
[SerializeField] List<GameObject> prefabs = new();
[SerializeField] private VisualTreeAsset tree;
[MenuItem("Tools/PrefabReplacer")]
public static void ShowExample() {
PrefabReplacer wnd = GetWindow<PrefabReplacer>();
wnd.titleContent = new("PrefabReplacer");
}
public void CreateGUI() {
tree.CloneTree(rootVisualElement);
}
}```
So if I set binding path to be prefabs, it does nothing
If I set the Bindings type at the top to PrefabReplacer, it does nothing
How do I do this?
You still need to have a SerializedObject and still call rootVisualElement.Bind(_serializedObject); Otherwise how is Unity to know what it should bind to?
Also you want to use the Binding Path, as that is used for the editor. the Data Source Path is used for runtime binding.
But that's not how he does it here?
Like building your own UI tools? Here we go step by step with the UI Builder to quickly create an Inspector for real-time Play mode debug data visualization. Then we’ll enhance it using USS Transitions and the Vector API, migrate it to a custom Editor window, and finally port it to the Player/Runtime.
Learn more about the UI Toolkit: https://on...
That is because that is a Editor which automatically binds to the target object.
You need to do the binding when using an EditorWindow since it doesn't natively have any sort of target or anything.
Ah
Worked :D
public class PrefabReplacer : EditorWindow {
[SerializeField] List<GameObject> prefabs;
[SerializeField] SerializedObject sObject;
[SerializeField] float sus;
[SerializeField] private VisualTreeAsset tree;
[MenuItem("Tools/PrefabReplacer")]
public static void ShowExample() {
GetWindow<PrefabReplacer>().titleContent = new("PrefabReplacer");
}
private void OnEnable() { sObject = new(this); }
private void OnDisable() { sObject?.Dispose(); }
public void CreateGUI() {
tree.CloneTree(rootVisualElement);
rootVisualElement.Bind(sObject);
}
}```
Been working on making a sequencer. I am pretty happy with how it is coming together. Easier than I thought it would be.
You can change the length clips, and change the length while respecting the other clips. If a clip overlaps another it will shorten it or just get rid of it (when you stop dragging).
Lots to do, like playing, multi select, moving the clips with drag and drop, and integrating the zoom and offset in to the sequence element instead of as those sliders. But its getting there 😄
Also, the clip elements are all recycled and so only the ones that are visible are actually in the visual element tree
Cool stuff 👍
Just like you are doing right there? Not sure I understand the issue.
How are you trying to show it? Also, right click on the window title of the inspector and select "Debug" in the menu that comes up. Then see what the 'real' value of Max Stack is.
In some versions of Unity the default value defined in code is not used when making an element in an array.
You can just use PropertyField I think.
You are already using it?
EditorGUI.PropertyField(..)
You are already getting the value with maxStackProperty.intValue
If you just want to show it , you just put it right there.
is there a way to add functionality when you press the + sign on a list PropertyField?
for ReorderableLists it's list.onAddDropdownCallback =, but im not sure how to do it for just a normal list
i went on this whole journey of reorderablelists just to realize new unity lists are reorderable by default and i was looking at really old stuff
It strikes me there was but I am not remembering atm. There is this though https://docs.unity3d.com/ScriptReference/UIElements.BaseListView-itemsAdded.html
It is pretty simple, you are given a index, when an item is added.
what im really trying to do is when you click the +, you get a context menu of Types to choose from. then it adds an instance of that Type to the list
still new to custom editors. am i supposed to be able to get a reference to the property field?
Ahh it is a property field? You will have to create the ListView yourself.
It is easy 🙂
var lv = new ListView();
lv.BindPrperty(yourListProperty);
// That's it
oh dang
hey is it normal that the editor is still validating despite being over an hour?
#💻┃unity-talk would be of more help. This channel is for making custom editor windows and stuff.
But probably not I would say.
thx
There might be other stuff you need to enable to get it to act like the default one, like lv.showAddRemoveFooter and lv.reorderable, I can't remember which options are automatically enabled when bound to a property.
But to answer your question, it appears that the ability to do a dropdown was removed.
So if you want a dropdown you will have to add a new VisualElement that opens a menu when clicked.
noted
why doesnt is null fire the log but == null does ? ( _dependencyField is ObjectField)
Ahh you have found a no no when it comes to Unity.
So, UnityEngne.Objects have a linked object on the C++ side. So when you call Destroy it is destroying that C++ side object. And to get it to play nice with the C# side, the equality operator == is overridden to check against the C++ object. So when you do obj == null it is checking if the C++ object is null.
However, the is keyword is not overridden. So it is checking against the C# object, which has not be garbage collected yet.
So in short, you the only null check you should use with a UnityEngine.Object is== null
(So do not use obj is null, obj?.foo or var val = obj ?? new GameObject();)
i knew about the c++ part but didnt know they didnt override the is keyword, thanks a lot :DD
Sure thing 🙂
but i think in some parts of my code, i wrote scriptableobject is null or !scriptableobject
but it works, idk there
Because you !scriptableObject is also valid. For some reason the decided that you can compare a UnityEngine.Object to a bool which would be the same as a null check
As far as scriptableObject is null, maybe it just hasn't been null yet? or hasn't been set? Either way, I would strongly recommend replacinging it with a normal null check.
yep, thanks again 😄
I am trying to write a custom editor panel tool thing but I cannot seem to stylize it as desired.
The stylizing code/functions behave completely erratic and abnormally. Look here how the mouse hover event only happens if I hover onto it from the right edge, and then only if I do it slowly
Is this IMGUI?
My code is obviously garbage but I cant find any useful examples online that shows the correct way to stylize things. How do I change the colors of a popup while retaining all of the popup's other stuff?
Basically are you using the OnGUI method? or the GUI, GUILayout, EditorGUI, orEditorGUILayout claasses?
If so, then you are using IMGUI (Immediate Mode GUI)
I am using OnGUI yes. And those classes
I will post my bad dropdown code for reference since it seems itll be useful
Right, I would honestly recommend switching to UIToolkit, it is soooo much better for doing more complex or custom styled GUIs. Sadly it will require a complete rewrite, and learning a new system. But it is so much easier to use and style I think it would be worth it for you.
But I can take a look at the dropdown code still for you if you want
Yeah a complete rewright like you suggest is not in the books for me, for the reason you said exactly, total rewrite and learn new system 😿
public static GUIStyle CreateModifiedDropdownStyle(Color normalTextColor, Color normalBackgroundColor, Color hoverTextColor, Color hoverBackgroundColor)
{
GUIStyle originalStyle = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).FindStyle("Popup"));
GUIStyle modifiedStyle = new GUIStyle(originalStyle);
Texture2D normalBackgroundTexture = CreateTexture(normalBackgroundColor);
Texture2D hoverBackgroundTexture = CreateTexture(hoverBackgroundColor);
modifiedStyle.normal.textColor = normalTextColor;
modifiedStyle.normal.background = normalBackgroundTexture;
modifiedStyle.hover.textColor = hoverTextColor;
modifiedStyle.hover.background = hoverBackgroundTexture;
modifiedStyle.active.textColor = normalTextColor;
modifiedStyle.active.background = normalBackgroundTexture;
modifiedStyle.focused.textColor = normalTextColor;
modifiedStyle.focused.background = normalBackgroundTexture;
return modifiedStyle;
}```
```csharp
GUIStyle dropdownStyle = UIUtils.CreateModifiedDropdownStyle(
Color.white,
new Color(0.2f, 0.2f, 0.2f),
Color.yellow,
new Color(0.3f, 0.3f, 0.3f)
);
// TARGET DROPDOWN
string[] targetNames = actors.Select(character => $"{character.CharName} (AC{character.Actor.charData.AC})").ToArray();
int previousIndex = targetCharacterIndex;
targetCharacterIndex = UIUtils.DrawGenericDropdown(targetNames, targetCharacterIndex, OnTargetSelectionChanged, dropdownStyle);
public static int DrawGenericDropdown(string[] dropdownOptions, int selectedIndex, Action<int> onSelectionChange, GUIStyle style)
{
int newIndex = EditorGUILayout.Popup(selectedIndex, dropdownOptions, style);
if (newIndex != selectedIndex && onSelectionChange != null)
{
onSelectionChange(newIndex);
}
return newIndex;
}```
You know what, I think if you do Repaint(); at the end of the OnGUI method it would solve the issue possibly.
Relevent code to me trying to get and set the color styles
I can try that
Another reason why this might be broken is that I am initializing the style every single frame
private void OnGUI()
{
InitializeStyles();
Unity treats the built in GUIStyles differently than custom ones, and doesn't trigger a repaint on hover for custom ones but does for the built in ones.
because I am trying to edit the style heavily and I couldnt find a sollution to fix the problem that my changes were not updating
I didnt want to have to close and reopen the tab entirely every single time I recompiled my code to see the visual change, but I couldlt find any other way here to 100% foolproof garuntee it would update
I use a static class pattern
public class MyWindow : EditorWindow
{
private void OnGUI()
{
if (GUILayout.Button("my Button", Styles.MyByttonStyle))
{
}
}
private static class Styles
{
public static GUIStyle MyButtonStyle;
static Styles() // edit note: removed access modifer
{
MyButtonStyle = new GUIStyle(EditorStyles.helpbox);
MyButtonStyle.normal.textColor = Color.red;
}
}
}
This is actually what Unity does internaly too.
I am a little confused by what you're showing me there.
Does this somehow replace the need to call InitializeStyles() every frame?
Ill be honest I have no idea what I am doing
Storing styles in a static sounds like a good idea, but how is that physically done? 
I dont want to be recreating the style from scratch every frame, that was a shitty hack trying to get a result by any means possible that work (it didnt work)
I edited my code to fix the errors.
It still says access modifiers are not allowed on static constructors after trying to fix the same
Looking at your now
Ah okay removed the public as well like you did
Basically when a class is accessed (created a instance, or calling a static method/property) for the first time, the static constructor is called (this is true for any class, not just static classes). So we take advantage of it to initialize our styles.
So the styles are initialized when you first call Styles.MuByttonStyle
Because that is the first time that a memeber of Styles is accessed
Interesting, let me try testing that out. Porting my code into the static UIUtils
Okay that did seem to work. Also discovered my problem is:
private static Texture2D CreateTexture(Color color)
{
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
return texture;
}```
this was totally wiping out my dropdown by rendering over top of all.
So my question is how do I correctly set the background color 🤔
Is the grey body of this dropdown something other than 'background'?
Should be background.
Hrmg it wants an image, there doesnt appear to be any way to set just a color
Isn't there a backgroundTexture or something?
looking at all the options for guistyle.normal.<stuff>
there is background and scaled background but they're both images
no other reference to a BG that I can find
Yeah normak.background is a texture.. so it should work
You can open the IMGUI debugger and have a look what is going on if you want
windows/analyze/IMGUI debugger
The problem with a bg texture is that it just flood fills and wipes out everything
You lose all of the stylizing that a normal dropdown has 
unless the problem is that my texture draw method is dumb incorrect
Might be clearing the margin when setting the texture?
Im having the problem I mentioned before again.
The problem is changes arent updating.
scratch that the problem is that I am dumb
and edited the wrong value
changed button style when I meant to change dropdown
static UIUtils()
{
//MyButtonStyle = new GUIStyle(EditorStyles.iconButton);
//MyButtonStyle.normal.textColor = Color.white;
Texture2D normalBackgroundTexture = CreateTexture(Color.blue);
normalBackgroundTexture.filterMode = FilterMode.Point; // Optional: makes sure the texture is not filtered
MyDropdownStyle = new GUIStyle(EditorStyles.popup);
MyDropdownStyle.normal.textColor = Color.white;
MyDropdownStyle.normal.background = normalBackgroundTexture;
MyDropdownStyle.border = new RectOffset(0, 0, 0, 0);
MyDropdownStyle.padding = new RectOffset(4, 4, 4, 4);
MyDropdownStyle.margin = new RectOffset(0, 0, 0, 0);
MyDropdownStyle.overflow = new RectOffset(0, 0, 0, 0);
}```
still is a floodfill, trying to adjust those values.
Is this what you meant by clear the margin?
What are you wanting? Setting the background texture to be blue is going to make it... blue.
What I want is the exact same appearance of the dropdown on the left, except colored blue.
well, not blue, but a color. Blue is just debug.
Try calling GUI.backgroundColor = Color.blue before drawing your dropdown field (with a normal style)
XY problem - what I actually want ultimately is I want my editor panel to be easier to use by color coding stuff, because its turning into a blur thats hard to navigate
my x problem is my panel is shit and hard to use
my y sollution I thought would solve this is coloring stuff
OOoh, so that can solved by redesigning it a bit.
Removing the texture entirely?
// TARGET DROPDOWN
GUI.backgroundColor = Color.blue;
string[] targetNames = actors.Select(character => $"{character.CharName} (AC{character.Actor.charData.AC})").ToArray();
int previousIndex = targetCharacterIndex;
targetCharacterIndex = UIUtils.DrawGenericDropdown(targetNames, targetCharacterIndex, OnTargetSelectionChanged, UIUtils.MyDropdownStyle);
Yeah just don't specify the style at all. Let it draw with the default style.
Hm in that case its not blue, whatever is blue appears to be being overriden
The style being used currently
let me change the text color to be sure its even being used
Yeah it is being used, the position and color are changed
yellow is not bad, draws the eye
I am going to try to move my stuff into tabs so that its less of a crapshoot 'everything panel'
but I was having problems with stylizing this as it just keeps getting darker and darker
and I couldnt stop it from getting darker and darker with each new box or whatever, because I couldnt set colors 🤔
which is why my xy came to 'how do I set the bg color'
when the real question is 'how do I make my editor panel less shit and more functional
You can do EditorGUI.DrawRect to just draw an area with a color
I generally recommend against using color like this in the editor. You can do stuff to make the UI easier to read. Since I don't know what things do it is a bit hard to say. But a few suggestions.
Add a bit of vertical spacing between the top "actor" row and the row bellow it of "Ctr, dex, con. etc" would help
Making sure all of the fields are vertically aligned. So like in the "Conditions" section, have the "Name" field and the "None" field that is below it be the same width (same with the other fields like "DC' and "Duration" and the ones below them)
The second row of buttons ("Str", "Dex", etc.) seem like they would be better as tabs or a dropdown or toggles or something.
Adding some foldout could help too. Having the sections like "Conditions" have a background with a different color along with a horizontal border on the bottom of it (like component headers in the inspector)
This site has some great info for styling editors https://www.foundations.unity.com/
Hope this helps @idle tree (I gotta get back to actually working now haha)
It does 👍 Thanks for all the tips, looking over it now
do styling using IMGUI editor way is really dififcult, like for giving background color either you create new texture and apply color there, or using GUI.backgroundColor = yourColor, then after that restore the background color to last background color, which is not a good way
2 line of code foreach gui element that you need assign color to
I'm having a strange issue with the blackboard window. I didn't change any specific behavior within its movement, but its moving like this:
I can't even lock it in place by setting its Rect position, it just ignores it
Try restart. Or disable sticky keys.
sticky keys is already disabled, and I've restarted multiple times. this has been going on for the last 3 days
hell, its been going on the entire time I've been working with the blackboard
Why do i get this message when im one of the 2 owners of the project
Hey - Has anyone made an EditorTool for painting UI elements? I am trying to make one to manage some nodes on a skill tree.
However, determining which node my cursor is over when I click is proving to be next to impossible.
public override void OnToolGUI(EditorWindow window)
{
Vector2 eventMousePosition = currentEvent.mousePosition;
PointerEventData pointerEventData = new(EventSystem.current);
pointerEventData.position = eventMousePosition;
List<RaycastResult> results = new();
raycaster.Raycast(pointerEventData, results);
for (int index = 0; index < results.Count; index++)
{
...
}
}
raycaster is a reference to the GraphicRaycaster on my canvas
Canvas is a ScreenSpace - Overlay that is set to "Scale with Screen Size" if that matters.
I do get results! But the results are as if there is an offset from my cursor.
So I tried to account for the offset by adding a static offset of my own.. but the offset is not consistent, so its never right for all nodes on the canvas. Its driving my batty. Is there a better way to determine which UI element in the editor?
Iirc the editor and game have two different root corners. Like the editor is top left and the runtime is bottom left? Also might need to convert from GUI to Screen space
I did end up having to do
Vector2 eventMousePosition = currentEvent.mousePosition;
eventMousePosition.y = Screen.height - eventMousePosition.y;
which helped.
What do you mean convert from GUI to Screen space?
And I think the evt.mousePosition might be relative to the VisualElement... but I don't remember
(see the Note on that page. That is what you are seeing i think)
eventMousePosition = GUIUtility.ScreenToGUIPoint(currentEvent.mousePosition);
/*eventMousePosition = currentEvent.mousePosition;
eventMousePosition.y = Screen.height - eventMousePosition.y;
eventMousePosition.y -= yNodeOffset;
eventMousePosition.x -= xNodeOffset;*/
PointerEventData pointerEventData = new(EventSystem.current);
pointerEventData.position = eventMousePosition;
List<RaycastResult> results = new();
raycaster.Raycast(pointerEventData, results);
SkillTreeNode hoveredNode = null;
for (int index = 0; index < results.Count; index++)
{
hoveredNode = results[index].gameObject.GetComponent<SkillTreeNode>();
if (hoveredNode)
{
Debug.Log($"Hovering over {hoveredNode.gameObject.name}");
ClearCurrentNode();
SelectNewNode(hoveredNode);
break;
}
}
if (hoveredNode == null)
{
ClearCurrentNode();
}
Its still super off far off. So is GUIUtility.GUIToScreenPoint
if I instead use the commented-out section, I can get to to be close but its just not consistent at all.
there MUST be a proper solution to this surely... I wish I could see what Unity does when I click into the scene view normally.
ooh. Thats a lot closer..
I have to turn off some other UI elements that "get in the way" since it doesnt give me a list of all things under cursor position.. but it works! Thanks a lot. I can work with this for sure.
You can pass them in to the list of game objects to ignore
oh nice. I appreciate the help! I might even use the filter param, depending
is there any extension for unity that provide object detection for video ? thank you
so if we put video on the engine , this library will track all the objects inside the video , or certain of it
Is there any common workaround for "Binding is not supported for managed reference" warning? I Have my custom Bindable visual element that binds perfectly to a field with [SerializeReference] attribute, everything works smoothly as butter, yet that warning log in consol is just driving me crazy
Hiho, I'm trying on a PropertyDrawer for RectOffset that is used for HorizontalLayout padding.
I got it to draw like I want it to, but changes to the fields are not updated to the object.
I was not able to use PropertyFields, as I needed to access the sub-properties of m_Padding and property.FindPropertyRelative() did not do it either.
So I get a reference to the actual data and modify that directly.
Any idea how to get the object to update?
RectOffset has no Padding property?
I don't see any reason in your code why you couldn't use SerializedProperties.
Padding is of Type RectOffset. If I would use EditorGUILayout.PropertyField(property), I would just get the default drawing that Unity already does. I want it to look like the image.
property.FindPropertyRelative("top") does not work. top is a AutoProperty and also extern. I don't know what is the exact issue, but I'm not able to retrieve the sub Properties (top, left, bottom, right) of m_Padding
m_Top, m_Bottom, m_Left, m_Right. They are just serialized like normal fields on the backend. All Unity private fields follow the same naming convention.
god damn it, I tried those names as well. For some reason its working now... Thank you 🫡
You're welcome
is unity ink good or reliable?
Hey, I swear there was some class that let you save data that's tied to the editor (like EditorPrefs, but data is lost once the session ends), am I misremembering?
SessionState is probably what you are thinking of.
yes it is thanks
everyone online was saying just use EditorApplication.quitting to erase the key and and i was like I swear im not crazy lol
Lol, yeah.. haha. You can also use ScriptableSingleton for more complex data (or just instead of SessionState) and just not put the File attribute on it
thanks lol, i just need a bool tho haha
hi, i need an editor script to be able to read and maybe update a private variable on a component say when a button is pressed. ive looked up a couple methods and ive been using reflection so far but i was wondering if i could put the editor script in the same file/ as a nested class definition and wrap it in #if unityeditor or something similar.
Sure you can
Making a custom inspector, how do I check if the selected object is in the scene or a prefab in the Asset folder?
There are a lot of ways, AssetDatabase.Contains() might be the most straight forward. There is also EditorUtility.IsPersistant() which is a bit different. And for prefabs I think there is something in PrefabUtility
Hi there everyone! Could someone help me to "normalize" both uxml sizes so they look the same height/weight in game window? now they look too different... also I'd like to know how could i start designing the UI having in reference different size windows... how could i do that too?
Could anyone try to help me with that?
This is the wrong channel. This channel for for discussion around creating custom editor windows, property drawers etc. You want #🧰┃ui-toolkit. You can delete the message here and paste it there to avoid double posting.
I am working on some UI for showing a tween's settings in the editor. Does this feel like it makes sense? Or does it feel too unclear?
hey im trying to use a build script to build a windows client and a linux dedicated server but i cant seem to get the server to build, heres my code:
using UnityEngine;
public class BuildScript
{
[MenuItem("Build/Build Client and Server")]
public static void BuildClientAndServer()
{
string[] scenes = { "Assets/Scenes/MainMenu.unity", "Assets/Scenes/MainScene.unity" };
BuildPlayerOptions clientBuildOptions = new()
{
scenes = scenes,
locationPathName = "Builds/Client/AfterfallClient.exe",
target = BuildTarget.StandaloneWindows64,
options = BuildOptions.None
};
BuildPlayerOptions serverBuildOptions = new()
{
scenes = scenes,
locationPathName = "Builds/Server/Afterfall_Dedicated.x86_64",
target = BuildTarget.StandaloneLinux64,
options = (BuildOptions)StandaloneBuildSubtarget.Server
};
Debug.Log("Building Client...");
BuildPipeline.BuildPlayer(clientBuildOptions);
Debug.Log("Client Build Completed!");
Debug.Log("Building Server...");
BuildPipeline.BuildPlayer(serverBuildOptions);
Debug.Log("Server Build Completed!");
}
}
I get the error Error building Player: Currently selected scripting backend (IL2CPP) is not installed. which seems like its trying to build a client instead of a server
Im trying to convert a custom editor for a scriptable object into a property drawer for a struct, but i can't figure out how to draw handles in a drawer
https://hastebin.com/share/iwimotivuw.java
The custom editor clipped the GL context within a rectangle of space reserved with GUILayoutUtility. I assume i would need to reserve a VisualElement and add it to my visual element tree somehow, but I don't know how to translate the GUILayoutUtility command into property drawer stuff
I barely even understand how the GUILayoutUtility api works, and I have no clue how i would get a Rect for use with GL.BeginClip, or if i can even do that within a property drawer
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
What version are you on?
If you are on 2022+ you can use the Vector API instead of GL https://forum.unity.com/threads/introducing-the-vector-api-in-unity-2022-1.1210311/
Otherwise I would probably slap it in a IMGUIContainer visual element 🙂
(Another option is to use the MeshGenerationContext shown in that thread. But that would be rather clunky to do)
Manual page on using the Vector API https://docs.unity3d.com/Manual/UIE-radial-progress-use-vector-api.html
What search terms should i use to look this stuff up? I've been having a lot of trouble finding answers online
Look what stuff up?
For making custom editor stuff
There seems to be a bunch of different systems that all kinda overlap and i've been really confused trying to learn what to use
Ahh, hmm. I would say UIToolkit (used to be called UIElements) would be the main thing to look at.
IMGUI (GUILayout, EditorGUI, etc.) is outdated and being replaced with UIToolkit.
You should (almost) always use SerializedObject and SerializedProperty to get and set values on objects.
But, nothing really specific to look up or terms to use.
Okieeee
I have gone on a grand adventure!!! My custom property drawer is almost kind of working!
Major problem: I made a custom VisualElement for displaying line graphs. The property drawer using that element is on a prefab.
If i close and reopen the prefab, the visual element is displayed properly using a callback listening to VisualElement.generateVisualContent for a little while (longer than a frame but less than a second). Closing and reopening the inspector on that object doesn't make it show up again. Here's how it looks for the short time it is visible:
(After it disappears, that space remains allocated but blank)
This is the custom element, I don't really understand what the Uxml boilerplate is doing (UI editor integration maybe?)
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace Editor {
public class GraphElement : VisualElement {
public new class UxmlFactory : UxmlFactory<GraphElement, UxmlTraits> { }
public new class UxmlTraits : BindableElement.UxmlTraits {
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc) {
base.Init(ve, bag, cc);
}
}
private VisualElement graph;
public GraphElement() {
style.alignItems = Align.Stretch;
graph = new VisualElement();
graph.style.minWidth = 200;
graph.style.maxWidth = 1000;
graph.style.minHeight = 200;
graph.style.maxHeight = 800;
graph.generateVisualContent += DrawCanvas; // adds DrawCanvas as a callback
Add(graph);
}
// [(0, 0), (1, 1)]
public List<(Vector2[] points, Color color)> lines;
void DrawCanvas(MeshGenerationContext ctx) {
if (lines == null) return;
var painter = ctx.painter2D;
foreach (var l in lines) {
painter.strokeColor = l.color;
painter.lineWidth = 2f;
painter.BeginPath();
painter.MoveTo(l.points[0]);
for (int i = 1; i < l.points.Length; i++) painter.LineTo(new (l.points[i].x * graph.layout.width, l.points[i].y * graph.layout.height));
painter.Stroke();
painter.ClosePath();
}
}
}
}
Additionally, some small things with the formatting of the property drawer, I can't find answers on the right way to do this
...
// TODO: How do i make this label's indent line up with above properties, it's slightly to the left currently
// TODO: How do i format the name to not be camelCase?
root.Add(new Label(approximatorProp.name)); // Header name
// TODO: How do i indent this box and all of its children?
var infoBox = new Box();
root.Add(infoBox);
...
you don't need to do any factory stuff unless you're using UXML. (And in 2023+ it's obsolete, replaced with source-generating attributes)
I can't see anything that would break your element. I presume lines are not being set the second time around. Do some debugging 🤷
// TODO: How do i format the name to not be camelCase?
Use DisplayName or ObjectNames.Nicefy
// TODO: How do i make this label's indent line up with above properties, it's slightly to the left currently
The others are in a box which has some margin
// TODO: How do i indent this box and all of its children?
Just add some margin
No like. The callback only ever gets called once
oooo, thx!
I cant find whats supposed to cause generateVisualContent to fire, and it only fires once for some reason
Call MarkDirtyRepaint to get it to run if you're not modify the rect
Oooooh
Hmm
I'm calling MarkDirtyRepaint on it, but it's not calling the generateVisualContent callback
It does get called when i resize the inspector window though, and now the graphic is staying instead of disappearing
Yeah, if i change the values in the inspector boxes then resize the VisualElement, it works
This updates all the serialized members of the approximator
private void UpdateApproximator() {
approximatorProp.FindPropertyRelative("k1").floatValue =
dampingCoefficient / (Mathf.PI * responseFrequency);
approximatorProp.FindPropertyRelative("k2").floatValue =
4 * Mathf.PI * Mathf.PI * responseFrequency * responseFrequency;
approximatorProp.FindPropertyRelative("k3").floatValue =
responseBehavior * dampingCoefficient / (2 * Mathf.PI * responseFrequency);
Debug.Log($"Set approximator params to k1:{dampingCoefficient / (Mathf.PI * responseFrequency)} k2:{4 * Mathf.PI * Mathf.PI * responseFrequency * responseFrequency} k3:{responseBehavior * dampingCoefficient / (2 * Mathf.PI * responseFrequency)}");
UpdateGraph();
}
Then this generates the points that the graph uses
private void UpdateGraph() {
const int CurveSamplePoints = 256;
const float DemoLength = 6f;
const float Timestep = DemoLength / CurveSamplePoints;
const float StepTime = 1f;
var approximator = (Approximator)approximatorProp.boxedValue; // create a duplicate of the approximator to draw a graph
Vector2[] stepFunc = new Vector2[CurveSamplePoints];
Vector2[] curve = new Vector2[CurveSamplePoints];
// Draw the step func
for (int i = 0; i < CurveSamplePoints; i++) {
float t = (float)i * Timestep;
float y = t > StepTime ? 1 : 0;
stepFunc[i] = new Vector2(t, y);
}
// Draw the approximator curve
approximator.Initialize(1, new[] {0f});
Debug.Log($"Running approximator with params k1:{approximator.k1} k2:{approximator.k2} k3:{approximator.k3}");
float[] targets = new float[1];
float max = 1, min = 0;
for (int i = 0; i < CurveSamplePoints; i++) {
float t = (float)i * Timestep;
targets[0] = stepFunc[i].y;
float y = approximator.Update(Timestep, targets)[0];
if (y > max) max = y;
if (y < min) min = y;
curve[i] = new Vector2(t, y);
}
max += 0.1f;
min -= 0.1f;
// Normalize the points on both curves
float delta = max - min;
for (int i = 0; i < CurveSamplePoints; i++) {
stepFunc[i] = new(stepFunc[i].x / DemoLength, (1 - (stepFunc[i].y - min) / delta));
curve[i] = new(curve[i].x / DemoLength, (1 - (curve[i].y - min) / delta));
}
graph.lines = new() { (stepFunc, Color.green), (curve, Color.white) };
graph.MarkDirtyRepaint();
Debug.Log("Marked graph as dirty!");
}
this solution is gross but might work https://forum.unity.com/threads/markdirtyrepaint-not-working.1485054/
in the editor inspector, I am creating a List of my own.
when I am adding a new element to the list, it wouldn't update the inspector.
I have tried to...
If nothing turns up ill probably resort to that
Seems like you might be setting the root element dirty, not the one you're subscribed to for the visuals
Okay, final problem, im editing a prefab, and even though i'm going through SerializedProperty it doesn't dirty the prefab and when i reopen it all my settings are gone
Oop, that's not it actually
Dirtying it by changing other properties saves correctly
Just had to add an ApplyModifiedProperties() on the parent SerializedProperty's SerializedObject
private void UpdateApproximator() {
k1Prop.floatValue = dampingCoefficient / (Mathf.PI * responseFrequency);
k2Prop.floatValue = 1 / (4 * Mathf.PI * Mathf.PI * responseFrequency * responseFrequency);
k3Prop.floatValue = responseBehavior * dampingCoefficient / (2 * Mathf.PI * responseFrequency);
approximatorProp.serializedObject.ApplyModifiedProperties();
//Debug.Log($"Set approximator params to k1:{dampingCoefficient / (Mathf.PI * responseFrequency)} k2:{1 / (4 * Mathf.PI * Mathf.PI * responseFrequency * responseFrequency)} k3:{responseBehavior * dampingCoefficient / (2 * Mathf.PI * responseFrequency)}");
UpdateGraph();
}
Ooh, also interesting!
approximatorProp.serializedObject.ApplyModifiedPropertiesWithoutUndo() doesn't make the prefab save
Is it possible to Hide the default cube Icon from gameObjects in the hierarchy window?
I am trying to set custom icons which has partially worked but they are on top of the cube icons
You basically just have to draw a rect over it and then draw yours
which I tried, but then it will look funky when you select an object
You have to check the selected state too :/
I did that as well haha, But I do not think I can match the color exactly since its semi transparent
let me retry though
so you would change the style color directly? What I am currently doing is setting the background color to the blue one instead
No, you draw the style instead of drawing a color.
Draw the style? How is that done?
style.Draw (or maybe style.normal.Draw?)
https://docs.unity3d.com/ScriptReference/GUIStyle.Draw.html
I think what most people normally do is just fully overwrite the item. But I could be wrong. There are a lot of packages on github that do stuff with the hierarchy (like custom icons, alternating rows, groups, etc.), so you could look at a few of them to see what they do.
You sure this is correct? Or am I doing something wrong?
if (isSelected)
{
GUIStyle myStyle = GUI.skin.GetStyle("TV Selected");
myStyle.Draw(iconRect, true, false, false, false);
}
nvm got it!
thanks a lot!
Is it possible to add an image / button up here?
If I remember correctly you can do it, but I am unsure how to do it at the moment. I saw some way of doing it for the project window, maybe you will get more result with that.
I have an editor panel im writing and for some reason every time I update the fields of one box, they ALL update to match that result, and I honestly cannot for the life of me find the bug. I've gone through the code step by step method by method repeatedly and I cannot find a single mistake
What are possible reasons why this might be occuring?
Is it possible if I can get like a voice chat with someone to walk through the code with me step by step? Because I've done it so many times now and don't find a single mistake anywhere, yet the bug persists
I need outside eyes, I cant move forward on anything until this is fixed, but I cant fix it myself, but it has to be fixed
I found one single thing that does fix it, but it breaks a bunch of other things, and I cannot comprehend -why- doing this one thing fixes it
because it seems to be completely totally unrelated, I cannot see how they relate at all
its like holding an apple unlocks a door, there's no linking causality
Maybe I found a bug with unity itself?
UNlikely, more likely that I am just wrong
I really truly need help with this, I've exhausted every channel and resource I have trying to solve this, I can't find a lifeline and really need someone to take a look, but there's just way too much code to post page after page of it
I am so lost in the forest I cannot even see the trees of HOW to debug find the problem 
Well, the first thought would be that it is either they are all bound to the same object or all objects are getting set at once. But it is hard to start figuring out if you don't share the code.
Also, I get you are frustrated, but all the additional text just makes it harder to get in to it, a simple "I am lost and have no idea where to go from here" would be more than enough 🙂
Sure, I just haven't had any traction with 'Im lost and need help'
I've had requests to share code but every time there's too much code to share, like to share everything that gets asked for is bigger than the biggest paste code
I can try again here definitively
!code
📃 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.
For now, just share the class that contains that editor code.
Sure
How much of it? the entire thing is 600 lines long
Just the stuff related to the issue as far as I am aware?
Yeah the entire thing, in one of the sites linked in the bot message above
Sure okay
SaveLogic(guiConditionData, guiConditionData.conditionData.save1.results[0], guiConditionData.conditionData.save1.totalResult);
SaveLogic(guiConditionData, guiConditionData.conditionData.save2.results[0], guiConditionData.conditionData.save2.totalResult);
It uses the property.displayname of the elements. So when you do EditorGUI.PropertyField it is using that
These two lines are where the error occurs as far as I am aware.
The issue is that every validation field entry thing class is somehow all referencing the exact same pair of classes and overwriting their results for every field, which makes no sense
I don't even know how to debug this, because they're int fields
and I am in creating new versions of classes in mutiple places, there's no way that everything is somehow all referencing the same class
As far as I am aware
I must be wrong because the error is still happenign
I'm also aware that the values im trying to reference are buried crazy deep nested classes within classes but I have so much data to pass around I couldn't find any better way to encapsulate it 
Hmmm, bit hard to say. I would try using or IDLE's debugger and set a break point when you change a value to see what happens. It is possible that they are all being references.
What's IDLE? I can use VSCode and breakpoint on the value but there are many unique instances of the class so I am not sure how checking when the value is being set to will help, like I don't know what to do with the moment of that breakpoint to tell me anything
Oops, I meant IDE haha
Step through the code until after the value is changed, and look at the list to see if the others changed too.
How do I debug log a value being changed? I can log the value's value but you cant code hook to variables as far as im aware.
This is my problem, I cannot find it being changed, I cannot find why its not unique because according to everything I can find in my code, its unique, so whats occuring is physically impossible
this is why I am desperate to screenshare with you to step you through my code, because to my broken wrong stupid understanding, its all perfect 100% functional, there are no mistakes. Except its not working, and I cannot find the mistake. I need your help to find it.
I am just not skilled enough, not smart enough, not knowledgeable enough, its beyond my ability to solve.
I'm on like round 7 of trying to step through every single line of code to find out whats wrong but the constantly variable is that I dont know whats wrong or how to determine whats wrong
and worse its gui code so its called every frame so I cannot simply hook to a single method
because I cannot capture the moment it changes because the gui is called 1000s of times a frame
Please will you or anyone here help step through this, I need this fixed but I am not capable of fixing it myself. I am desperate, I am begging. I dont know what more I need to say or do or offer here
Aw fuck I am an idiot, I think I finally get whats going on
every time the character makes a save, I am writing the save directly into the data field, no wonder its all the same value because there's only one condition that is being saved over and over
the problem: I was overwriting the save result with every save attempt.
because I was storing the save result value one layer too deep in the class structure
I was writing the save into the Condition
and not into the ValidationStack containing the condition
because every condition validation stack is unique but the condition is the same condition every time
so I cannot store the roll result in the condition, I had to store it in the validation stack instance OF the condition's current roll result
Is this just a bug in Unity 6? I have to click these now for them to go away about half the time
I think #💻┃unity-talk would be better channel but to answer your question, I think it is a bug. Just yesterday heard last time someone complaining about code compilation window going away faster when clicking it (in unity 6 only)
fair I'll try there
I noticed them also
It can make it seem like it's stuck loading something but seems that it's only a visual error
could anyone help me with this? #🧰┃ui-toolkit message
This got me interested so I ported a tool I made in the past to work in the editor for normal projects https://github.com/nomnomab/Unity-Editor-BepInEx might be useful for you in the future 👍
There is a property hook in there as an example (it's also very experimental so let me know if you hit an issue)
Question! How do I make my custom editor script display prefab changes as well as the functionalities to revert? This is in reference to the BOLD variable names in the inspector when a prefab value is changed.
Use SerializedProperty to set the values instead of setting them directly
If you are using IMGUI (GUILayout, EditorGUI, etc.) then either draw the fields with PropertyField() or surrounded with Begin/EndProperty()
holy hell lol you're a life saver could not figure this out for the life of me
A follow up to this, is there a way I can remove the attributes already within the script such as headers? Found that using SerializedProperty grabs the headers that were already in the script to begin with?
nope
Let me amend
Most EditorGUILayout.IntField/Slider/etc methods have a override that takes a SerializedProperty. And I think that will not do the decorators (header attribute) and will still give the prefab overrides
ooooo the GUIContent override? I’ll look into that more tho I didn’t have too much luck with it earlier but I didn’t dive too deep into that specific aspect. Thank you!
What? No?
Wait.. am I going crazy... I know there were overrides that took SerializedProperty...
Any one of these?
No I was meaning EditorGUILayout.FloatField() but looking at the docs I guess I was misremembering
But I guess going back, the only option would be to draw it yourself, surrounded by a begin/endProperty block
oh rip
Well it’s not too much of a hassle! I’ll just remove the old attributes. Thank ya!
I was looking at FieldInfo as a potential solution but was unable to get that to work properly
Sure thing. Oh and I totally recommend taking a look at using UIToolkit instead of IMGUI. It is newer, and so much nicer to work with. Especially for doing any sort of styling.
oh hype! I’ve been using Naughty Attributes but I’ll check that out as well!
Is there a code way to open a prefab preview?
Equivalent of double clicking prefab, which opens you a blue skybox scene, where only this prefab is rendered.
To be more specific: I want to create temporary game object (unsaved one) and open like this.
This is for preview of assets purposes
yeah, I actually found it already. But currently lacking info on how to close existing stage
is there a way to somehow mark the world origin? maybe the grid lines for 0 are of the corresponding color? or add a funny gizmo at 0,0,0? 🤔
something like the 3d cursor on blender 🤔
Hey all, what determines whether this "Select" window allows you to pick only Assets or also Monobehaviours from your scene? (pic 1 vs 2, the tabs)
I'm trying to attach a gameobject's component to a modified Timeline SignalEmitter but it seems like scenes aren't in the scope of its selection
You cannot references things that live in a scene from an asset.
Ah that's unfortunate. thanks though, I'll find a workaround
hi, serializedobject.findproperty keeps returning null and nothing ive found online is helping here is the OnEnable function in my editor script and the field as seen on the target class.
What's biped behaviour look like?
You can't serialize that
cant serialize abstract classes?
No. You would need to use SerializeReference, which comes with it's own problems, or inherit from a Unity object like ScriptableObject
ok thanks
i have this problem
someone could help me
public override void OnInspectorGUI() { DrawDefaultInspector(); OrionFile f = (OrionFile)target; if (GUILayout.Button("Create new Animation")) { Save(f); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Save Animation")) { if(f.GetOrion() != null) { f.Save(f.GetOrion()); } } if(GUILayout.Button("Load Animation")) { string path = EditorUtility.OpenFilePanel("Load animation", "", "orn"); Debug.Log(path); if (path.Length != 0) { f.Load(path); } } GUILayout.EndHorizontal(); GUILayout.BeginVertical(); if (GUILayout.Button("Reset Animation")) { if(f.GetOrion() != null) { f.GetOrion().ClearLayers(); } } GUILayout.EndVertical(); }
this looks fine, you did call begin horizontal already, are you sure already compile the scripts?
yes I did it
but you can use this instead
public override void OnInspectorGUI()
{
DrawDefaultInspector();
OrionFile f = (OrionFile)target;
if (GUILayout.Button("Create new Animation"))
{
Save(f);
}
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("Save Animation"))
{
if (f.GetOrion() != null)
{
f.Save(f.GetOrion());
}
}
if (GUILayout.Button("Load Animation"))
{
string path = EditorUtility.OpenFilePanel("Load animation", "", "orn");
Debug.Log(path);
if (path.Length != 0)
{
f.Load(path);
}
}
}
using (new EditorGUILayout.VerticalScope())
{
if (GUILayout.Button("Reset Animation"))
{
if (f.GetOrion() != null)
{
f.GetOrion().ClearLayers();
}
}
}
}
``` its way cleaner, and you can be sure, where the scope of your layout
dont works look
where is line 35,
so weird, even when u used return inside horizontal/vertical scope, that error is supposed to be not exists
paste your entire script, to pastebin, so i can see full of it
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.
work as excpected on my side
i know look
but when i use the load option of save option
it happens
how i can fix it?
so lets break down, you click load its open this
then animation loaded
but then that weird error called
tbh, i don't know why, even if the file not loaded and return error, the layout error blabla should not exist, lets just wait for other person
it's too weird
if (GUILayout.Button("Load Animation"))
{
string path = EditorUtility.OpenFilePanel("Load animation", "", "orn");
// Debug.Log(path);
// if (path.Length != 0)
// {
// // f.Load(path);
// }
GUIUtility.ExitGUI();
}
``` add ```GUIUtility.ExitGUI()``` seems like when your open the panel window, your inspector lose focus, and that make the clean up of your layout are not finish
been moved away from IMGUI to UI Toolkit, and i forgot this thing can happens
i'm learling about this and i dont find information of this
ive search in youtube, reddit, and more and i dont find
not really, just call exit GUI if you call something that make your editor lose focus, like the EditorUtility.OpenFilePanel("Load animation", "", "orn"); or the EditorUtility.SaveFilePanel("Save animation", "", "", "orn"); because this open another window and take focus from your inspector
is there a way to hide all scene gameobjects when using my editor code because the scene is getting in the way when dealing with handles
im trying to draw waypoints and the scene objects make it harder for me to see everything
Layers?
Move cursor over the area on the left of your objects in the hierarchy, then click on the eye.
Here is documentation about how to hide it via code:
https://docs.unity3d.com/ScriptReference/SceneVisibilityManager.html
when using a propertyfield (toolkitui) on an array element, is there a way to remove the foldout?
i guess you just manually iterate the serialized property?
Hi - I'm getting terrible coil whine while prototyping in the editor due to running at 450+ fps 4k. Is there any way to limit the fps?
thanks thats what i was looking for ! 🙂
I'm not sure if this is the best place to ask, but I am unable to get the autocomplete/autofill function working in Visual Studio.
I was going through the various fix options listed here: https://stackoverflow.com/questions/42597501/unity-scripts-edited-in-visual-studio-dont-provide-autocomplete
I ended up noticing that when I am in Visual Studio and select "Open File" my .cs script files have a Firefox icon next to the. Originally, trying to open scripts in Unity opened them in Firefox rather than Visual Studio so I suspect that is why. I deleted those scripts, restarted Unity and Visual Studio, created two new blank scripts in Unity, and when I went to open them in VS again they still had Firefox icons next to them.
Is that indicative of what the problem might be?
My main goal is to get the autocomplete working
not sure what the thing is about firefox icons, but it just sounds like you need to configure your IDE?
!ide
If your IDE is not autocompleting code
or underlining errors, please configure it.
Select one:
• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)
• VS Code
• JetBrains Rider
• Other/None
and yes it would have been better in #💻┃code-beginner but i'll just answer you here to avoid more criss crossing
thanks! I'll give this all a look.
i guess either you make the property drawer, or use listview and bind property, so you can set Show Foldout Header to false
whats the easiest way to draw directly to the game screen from an editor window? I want to overlay a plus symbol in the center of my game screen when I hover over a button, and the hover and such is done, now I just need to find out how to draw from the editor. Is there a way to do this without needing to go to another script to do the drawing, or to add anything to the hierarchy?
In the left screenshot, my code is on the left and a tutorial's code is on the right.
Do I need an extra extension to have colors not all be blue like this for code types?
Usually the text isn't formated properly if the IDE isn't configured properly. Issues with IDE configuration are a common problem. Here is a link to some tutorial:
https://www.youtube.com/watch?v=4ElwPXo4oCc
If it doesn't help, you can try other tutorials.
Got it figured out. Just needed to be using VS (purple program) rather than VSC (blue program)
I'm getting a nullpointer when I have a script extend ScriptableObject if the class has a type parameter.
eg:
using UnityEngine;
[CreateAssetMenu(menuName = "Test")]
public class Test : ScriptableObject
{
}
versus
using UnityEngine;
[CreateAssetMenu(menuName = "Test")]
public class Test<T> : ScriptableObject
{
}
The Test<T> causes a nullpointer
Am I not allowed to use scriptableobjects in this way?
The error is:
NullReferenceException: Object reference not set to an instance of an object UnityEditor.ProjectWindowUtil.CreateDefaultAsset (UnityEngine.Object asset, System.String pathName) (at <5e9bcb0c6eb440e5b39f9058a30f9f50>:0)
This is not allowed, there is no way to specify what is T in this case
You can have generic scriptableobject, but you cannot create a generic scriptableobject.
[CreateAssetMenu(menuName = "TestFloat")]
public class TestFloat : Test<float>
{
}
Not sure what your goal is, but you can have references to other ScriptableObjects inside ScriptableObjects. Or maybe this package here will help you: https://github.com/mackysoft/Unity-SerializeReferenceExtensions
I was trying to do what Simferoce wrote, create a generic scriptableobject as a base and create subclasses. I have decided to go a different route.
Hey, got a problem where my custom editor script doesnt like letting me assign scriptable object variables. It just rejects them.
Use PropertyField or use the return value of ObjectField to set the field on the instance (and you have to dirty the instance) (Really just use PropertyField)
i am using EditorGUILayout.PropertyField
Then show code
whats the code paste website this server uses.
uhh, searched $code on google and couldnt find a code paste website.
Alright if I used pastecode.io?
https://pastecode.io/s/7wt4wpsb
Try calling serializedObject.ApplyModifiedProperties() at the end of your oninspectorgui
Yeah $code is supposed to show the info about using a code paste website but apparently it's the wrong tag
Yeah, it works now! Thank you and hope you have a nice day!
Hey, I have a custom editor using a StyleSheet that I just serialized and linked in our toolkit. I am trying to move our toolkit to a package but apparently serialized references break for this. What suggestions do you have for loading a stylesheet in a package?
Are you sure the guid didn't just change?
no, I checked the .meta files the reference's guid still matches the style sheet
What I can do is use AssetDatabase and find the stylesheet with the given name. Not a beautiful solution hence why I was looking for an alternative :(
I guess I can use the guid to load it
Yeah use the GUID
Tbh, no idea why it doesn't work. I'd expect it to but it's also not something I'm doing atm
I import the package, it works. I can see the reference set in the .cs file. If I restart the project the reference field is completely missing 🤷♂️
!code
📃 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.
Hello. I am looking for a way to label this list, instead of Element 1, Element 2, etc, I enter a custom string
Like this?
wouldn't you just add a string for name to the class?
[System.Serializable]
public class ForestType
{
public string name;```
System Font is not the same as my... actual system font. How do i selectively pick a Editor Font?
Ohh yes I think I figure it out.
It looks a little weird though. Why is that?
[CustomPropertyDrawer(typeof(GearItem))]
public class MyCustomClassDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty nameProperty = property.FindPropertyRelative("label");
string customLabel = nameProperty.stringValue == String.Empty ? "Element" : nameProperty.stringValue;
EditorGUI.PropertyField(position, property, new(customLabel), true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return EditorGUI.GetPropertyHeight(property, label, true);
}
}```
In what way does it look weird?
Ah these, yeah idk
Hey everyone, i need a little help with a editor script. i'm a beginner on unity and C#, but experienced programmer
Ask away
My problem is in this print.
I tried make a editor script on unity and need use a class MonoBehaviour, but cannot use this by missing reference, error: The type or namespace Interactablecould not be found (are you missing a using directive or an assembly reference?)
Editor script: Assets/Editor/InteractableEditor.cs
MonoBehaviour script: Assets/Scripts/Interactable.cs
i'm stuck about 2 hours, and cannot found nothing on google that could help me, already tried a lot of things
Are you using assembly definitions?
And does this error also show in Unity or only in Visual Studio?
i'm beginner on C# and unity, so can explain how i can check this?
in VS show Intellisense error, but on unity show null exception on Injectable
Clear the console in Unity and check if there's any compiler errors
If you can't see the VS errors in Unity, then your VS is acting up
Because the code looks fine (unless you are using assembly definitions, which I doubt because you would know)
The console of unity is empty, i'm trying running a little code inside of editor to test his functionality
But no errors on unity, only VS
Okay so there is no actual error, VS just fails to recognize the Interactable class which you presumably just created
Could try Edit > Preferences > External Tools > Regenerate project files and see if that helps
right, but now?
i tried this, but no result
And close/reopen visual studio
tried too
And maybe unity
Reinstall too
Did you configure it with the correct steps? !ide
If your IDE is not autocompleting code
or underlining errors, please configure it.
Select one:
• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)
• VS Code
• JetBrains Rider
• Other/None
Yes, all steps were made
Ah yeah, this "Arquivos diversos" is "Miscellaneous files" which indeed means that it's not properly configured
i'm using lts recommended unity and VS installed by hub
I hadn't noticed that
Not sure then, you should ask in #💻┃code-beginner or #💻┃unity-talk since it's not an editor tooling issue
You have the Visual studio editor package?
i'm not sure
Well, that's one of the steps in that page. Don't skip steps
At least if you are using Unity 2020+
oh, yes, i have it
what should be written here?
Regenerated project, now is written Assembly-CSharp-editor, but not working
I think it is very clunky to have all of this for a simple name in the editor
[CreateAssetMenu(fileName = "EnemyGear", menuName = "Scriptable Objects/EnemyGear")]
public class EnemyLoadout : ScriptableObject {
[SerializeField] public List<EnemyLoadoutEntry> loadout;
}
[Serializable] public class EnemyLoadoutEntry {
public string label;
public List<GearItem> gear;
}
[CustomPropertyDrawer(typeof(EnemyLoadout))]
public class EnemyLoadoutDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty nameProperty = property.FindPropertyRelative("label");
EditorGUI.PropertyField(position, property, new(nameProperty.stringValue == string.Empty ? "Element" : nameProperty.stringValue), true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return EditorGUI.GetPropertyHeight(property, label, true);
}
}
Is it really the only way?
I am pretty sure you don't need the property drawer. But you might have to rename label to name
How else can I name elements of a list of a custom class?
Unity automatically pulls the name for the element in a array/list if the element has a field named name or something similar (like _name etc.)
Oh wow. That worked. I did not know.
Still slightly annoying to have a dedicated class container for the name, but it is better 🙂
I mean you would have to have that anyway since Unity can't serialize a list of lists.
But yeah, it is a bit annoying
custom editor for that, you can set the flexgrow to 1
Hey all, I'm making a quick editor extension for a particular prefab that uses raycasts, however when I send my raycast it's hitting things from the scene I'm in even though I opened the prefab directly, any clue?
okay well I opened in a scene without colliders and it's not hitting my object at all even though there is a collider on the object
DrawLine/DrawRay are not showing up either
hm, i'm not sure how the prefab isolation view interacts with physics (if at all)
Perhaps it has its own physics scene?
private void OnBeforeSceneGui(SceneView obj)
{
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage != null && prefabStage.prefabContentsRoot == _chunk.gameObject)
{
Event e = Event.current;
if (e.type == EventType.MouseDown && e.button == 1)
{
Ray worldRay = HandleUtility.GUIPointToWorldRay(e.mousePosition);
Debug.Log(worldRay);
Debug.DrawRay(worldRay.origin, worldRay.direction * 1000, Color.red, 5.0f); // Draw the ray for debugging
if (Physics.Raycast(worldRay, out var hit, Mathf.Infinity))
{
Debug.Log("hit " + hit.transform.name);
// ShowContextMenu();
}
e.Use();
}
}
}
this is all I'm doing
@safe sorrel surprisingly, it does!
doing _chunk.gameObject.scene.GetPhysicsScene() worked
ah, nice, I was just trying to figure out how to find that scene :p
ah, GetPhysicsScene is an extension method
yup
I'm trying to manually serialise a class, and every time i try to set a value in the inspector it immediately sets it back to what it was before. why is this happening?
i'm using the SerialisationCallBackReciever and a custom property drawer.
public void OnBeforeSerialize()
{
// Convert m_rawValue to double for serialization
serialisedValue = m_rawValue / (double)Fix64Constants.ONE;
}
public void OnAfterDeserialize()
{
// Convert serializedValue back to m_rawValue
m_rawValue = (long)(serialisedValue * Fix64Constants.ONE);
}
What? I don't see how the above code relates to this gif. What you are serializing doesn't appear to be shown in the gif.
public class Entity : MonoBehaviour
{
public Fix64 timeScale = 1;
public Fix64 deltaTime = 0.01666666666;
public FixVector2 position;
public FixVector2 velocity;
private void Start()
{
deltaTime = 0.016666666;
position = new FixVector2(1, 1);
GameManager.Instance.SendNotification(MessageType.Info, position.ToString(), 10);
velocity.y = 10;
}
private void FixedUpdate()
{
velocity.y += -9.81 * timeScale * deltaTime;
transform.position += velocity;
}
}
trying to serialise this stuff.
I see, so I assume you have a custom PropertyDrawer than for Fix64?
Also, what is Fix64Constants.ONE, and serializedValue, m_rawValue? Cause this conversion logic seems strange to me.
I do, yes. As for the conversions, I'm just reusing the logic they've used in the constructors for fix64 so I couldn't tell you what it means
Right, can you show the property drawer since there is a good chance that is where the issue is.
I've just gone to bed unfortunately 😭 I'll show when I wake up
https://gdl.space/ajokolixob.cs
here are the drawers. I will concede that i had these generated because it was late and i wanted a quick and dirty solution, so this probably isnt even written well
I'm going to be honest, this makes 0 sense to me. It looks like you are converting a long to a double. But Unity can serialize doubles.... And if m_rawValue is serializable... why are you doing custom serialization for it in the first place...?
They are making their own fixed point number, which uses an integer to represent a number with a decimal place. It looks like they want to serialize it as a double, maybe because they assume long can't be serialized. Or because they want to be able to edit it as a double in the editor and assume they have to serialize as such to do so, which is not the case.
@dusk dome there shouldn't be any reason to convert for serialization. Unity can serialize the raw value, while the property drawer exposes it as if it's a double.
https://github.com/blafed/FixedMath
This is what I'm using. It stores the raw value as a long.
Unity can serialize long, just not readonly
I made it not read-only in my implementation. I'm assuming the issue comes from directly trying to change the raw value?
As maybe the class doesn't support that or something breaks
I need to call Save() on my ScriptableSingleton whenever I make a change to its serialized properties. It's being displayed in a custom EditorWindow. With IMGUI, this is simple, since you can just check if anything has changed at the end of the GUI method.
I'm using UIToolkit, so I can't do that. What can I do instead?
turns out saving a ScriptableSingleton prevents you from undoing!
...or maybe not
might've just had a Skill Issue there
idk why i thought a long was like a floating point thing but turns out its just a massive integer
yes, it's just a 64-bit integer
confused about how i'm meant to be representing this data
A long is just a big integer, and a double is a big float
Anyone know how to setup copy-paste functionality in a custom graphview? the documentation for it is completely empty
Scratch that, for everyone looking into this problem, you need to write your own delegate functions for the copy and paste
Is there an easy way to get a property drawer for a given type? I'd like to implement a multi type list where each type defines its own property drawer and those property drawers are then drawn in the inspector when displaying the list.
Nevermind, I be rather silly
i would expect test1 and test2 to be overlayed on top of each other since both control rect and menurect have the same position only with varying dimension. why is test1 up there when it should be where test2 is?
note im also ending the area its just not in the screenshot
I'm having an issue when trying to display a multi type list in the inspector where I retrieve a serialized reference to the list. The issue is that when i was using serializefield, the data was displaying on my custom inspector fine but now that I'm using serializereference, the data for each propertydrawer doesn't show up when pushed to the property is passed to my inspector GUI. Is there something I can do? I'll post the code here in a bit
By default every value is null when serializing with SerializeReference instead of being a new instance. So most likely nothing is being displayed because nothing is there to display
Strange, so what you're saying is that reference values are null. What can I do do get said value then. I may need to read more of the details on seralize reference
Appreciate the help
Oh, it doesn't serialize polymorchic types
[SerializeReference] does.
oh ok so just the regular serializefield doesn't I misread
Correct
https://gdl.space/yobojekisi.cs
This is how I'm currently accessing the serialized reference in the object. My desired result is to display the objects individual property drawer and display that in the editor
It is recognizing the entries in the list but as you said, they are null so that explains why nothing is added to the property drawers
So I'm not quite getting how I should handle this. I'm not actually able to access the value though serialized reference to modify the array?
You can set them using the serialized property .managedReferenceValue
Also you can use the static TypeCache class to get all types derived from a specified type
I see, I guess I did it in a rather roundabout way lol
Oh what! I just read the docs, I had no idea this was a thing!
It is super handy!
Did some testing, the property drawer isn't getting called at all because of the null values here. You were correct but how should I go about fixing this?
It really depends. You could show a dropdown where you select a type when you click "Add" or chose a default type and then show a dropdown for each item so they can change it. Or get/make a drawer that adds a dropdown to all ManagedReference feilds.
I see so, something that derives from property drawer to handle these instance!
Or something like this https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
Wonderful! Thank you so much for all your fantastic help!
You're most welcome!
Is there any way to set keybinding to SearchActions in custom searchprovider? I'm creating custom searchactions but only the first two get key binding("enter", "alt+enter") by default. Any more don't getkeybinds and can't add in the shortcuts menu. Maybe I'm missing something to enable shortcuts for them:
var provider = new SearchProvider(_providerId, "Search In Scene"){
///
};
provider.actions.Add(new SearchAction(_providerId, "Select", new GUIContent("Select"))
{
handler = FocusOnGameObject,
closeWindowAfterExecution = true
});//getting "enter" key without doing anything
provider.actions.Add(new SearchAction(_providerId, "Ping", new GUIContent("Ping"))
{
handler = PingGameObject,
closeWindowAfterExecution = false
});//getting "alt enter" key without doing anything
provider.actions.Add(new SearchAction(_providerId, "Frame", new GUIContent("Frame"))
{
handler = PingAndFrameGameObject,
closeWindowAfterExecution = false
});//no keybinding at all
@hushed ingot Pinging since you're the only one here who posted about searchactions
why cant i directly change the serialised value? i'm trying to use a fixed point numbers system that stores numbers in a long as the raw value.
i want to use the serialised value, which is the value used by the simulation system.
Cause you are overwriting it with the RawValue in the OnBeforeSerialize callback I assume
yup
public void OnBeforeSerialize()
{
// Convert m_rawValue to double for serialization
serialisedValue = m_rawValue / (double)Fix64Constants.ONE;
}
public void OnAfterDeserialize()
{
// Convert serializedValue back to m_rawValue
m_rawValue = (long)(serialisedValue * Fix64Constants.ONE);
}
so what am i meant to do here?
When you make a change to the object the OnBeforeSerialize method is called.
So lets say that m_rawValue is 10. When you change serializedValue to say 2 that will tricker the OnBeforeSerialize method to be called
In that method you are setting the serializedValue, So the 2 that you just assigned to it is getting overwritten by the new value you are assigning it
Does that makes sense @dusk dome?
yeah kinda, so when im trying to set the serialised value it automatically sets the serialised value to the raw value because of on before serialize?
Correct
Don't set the serializedValue from anywhere beside OnBeforeSerialize. Another hacky option is to add a bool, that when set to true, the OnBeforeSerialize method will just set it to false and return. Then, before you change the serializedValue from the GUI, you set the bool to true.
But really, I don't see any need for custom serialization at all.
All you are doing is converting from one unity serialized type to another unity serialized type.
im trying to use a fixed point number system, and i guess the only way it can be displayed is via a double? its meant to have a fixed amount of accuracy
I don't really get it, but you're rawValue can be serialized natively by Unity. So I see no reason to have it also serialized in to a long in serializedValue
raw value is a long. i cant really explain it well, but i do need the custom serialisation is all i can say for certain. im trying to use numbers with a fixed amount of decimal points to ensure cross platform determinism in my game
Okay or long, it doesn't matter as both long and double can be serialized by Unity
So converting one to the other for serialization is pointless
But maybe you have some reason I don't get.
Regardless, only edit m_rawValue, serializedValue should be stricktly internal to the class/struct
the only reason i wanted to edit the serialised value is because theres a really annoying conversion between the raw value and the serialised value. as its storing the value in a long it divides the value by luike 4 million or whatever
You could maybe do some sort of custom field that does conversion to/from before setting/getting the value. Or again, keep editing the serializedValue and use the hacky bool trick
probably. this seems to work too
public void OnBeforeSerialize()
{
m_rawValue = (long)(serialisedValue * Fix64Constants.ONE);
}
public void OnAfterDeserialize()
{
// Convert serializedValue back to m_rawValue
m_rawValue = (long)(serialisedValue * Fix64Constants.ONE);
}
just the same thing tiwce
seems to work the best for what i want
What... but you are not not even using the serialization for what you were originally....
idk man 😭 this works for what i want it to. its setting the value in a readable way, and its saving the raw value properly. This is what i wanted originally, but i guess i was just doing it wrong before
Whatever works for you I guess 👍
thanks for your help, though, you showed me to the root cause, probably wouldnt have looked there if it wasnt for you 😄
how can i get a draggable field?
to let me increment and decrement
like standard transform and stuff
i want something like this
IIRC FloatField does that already, try that
i need it for a double field, though
Ok apparently DoubleField doesn't have the drag functionality but try a PropertyField
Actually, DoubleField does have drag if you give it a Label
float labelWidth = 15f;
float fieldWidth = (position.width - labelWidth * 2 - 4) / 2;
Rect xLabelRect = new Rect(position.x, position.y, labelWidth, position.height);
Rect xRect = new Rect(position.x + labelWidth, position.y, fieldWidth, position.height);
Rect yLabelRect = new Rect(position.x + labelWidth + fieldWidth + 4, position.y, labelWidth, position.height);
Rect yRect = new Rect(position.x + labelWidth + fieldWidth + labelWidth + 4, position.y, fieldWidth, position.height);
var xSerializedValue = property.FindPropertyRelative("x").FindPropertyRelative("serialisedValue");
var ySerializedValue = property.FindPropertyRelative("y").FindPropertyRelative("serialisedValue");
if (xSerializedValue == null || ySerializedValue == null)
{
Debug.LogError("fv2 properties not found!");
return;
}
double xValue = xSerializedValue.doubleValue;
double yValue = ySerializedValue.doubleValue;
EditorGUI.LabelField(xLabelRect, "X");
xValue = EditorGUI.DelayedDoubleField(xRect, GUIContent.none, xValue);
EditorGUI.LabelField(yLabelRect, "Y");
yValue = EditorGUI.DelayedDoubleField(yRect, GUIContent.none, yValue);
idk if im doing this right
Instead of using LabelFields try putting the X/Y label where you have GUIContent.none
Works fine for me, at least with the EditorGUILayout version
does appear to be draggable now, but the positions are all fucked. will fix that now, though
Is there a reason you're using IMGUI? It's just making layout problems harder for you
im using a fixed point custom number type. as such i need to use a custom conversion from doubles and to this fixed point number.
That doesn't really explain why you can't use UIToolkit
i'll use UI toolkit from now on then
https://docs.unity3d.com/ScriptReference/PropertyDrawer.html
Eg. everything related to VisualElements on this page.
It's very different from IMGUI, so there will be a learning curve
okay, thanks for showing me this. its 2am now so i think i'll leave learning it for tommorow
this looks like its for custom editor windows, though.
does this work for built in properties inside the standard inspector though?
Yes. The default inspector is UIToolkit, and it will work in custom editors made with UIToolkit.
UIToolkit doesn't work inside IMGUI editors. You can be use IMGUI property drawers inside a UIToolkit editor for compatibility reasons
Hey I’m sorry but this is probably a better place to ask can anyone give me a link for ndk r23b(23.1.7770620)? I need this to progress my game because apparently I didn’t have it
Nope
@tall inlet (From #💻┃code-beginner message)
Use:cs SettingsService.OpenProjectSettings("Project/Tags and Layers");
The class itself is TagManager and the inspector is TagManagerInspector
I need it to be Menu item so i can attach a new funcion there
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
public class LayerNamesToList : MonoBehaviour
{
[MenuItem("Edit/Project Settings/Tags and Layers/Get Layer Names", priority = 50)]
private static void GetLayerNames()
{
var layerNames = new System.Collections.Generic.List<string>();
for (int i = 0; i < 32; i++)
{
string layerName = LayerMask.LayerToName(i);
if (!string.IsNullOrEmpty(layerName))
{
layerNames.Add(layerName);
}
}
Debug.Log("Layer Names:");
foreach (var name in layerNames)
{
Debug.Log(name);
}
}
}
#endif
I thought you wanted to open the Tag manager with code
Why can't you open it from that menu item function?
i want to add a new custom function to that menu
but using that code
the option isnt there
Oh you want to add new functionality to the settings menu window itself?
Ye
in this case to print a list with all the layers but thats just a placeholder to test if it works and then implement the real thing
I haven't done that level of editor modding, but maybe someone else here knows.
Maybe you could dock your own EditorWindow to the TagManager window at least
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
public class RectTransformUpdate : MonoBehaviour
{
[MenuItem("CONTEXT/RectTransform/Snap Anchors To Corners", priority = 50)]
private static void Execute(MenuCommand command)
{
RectTransform rectTransform = command.context as RectTransform;
RectTransform parent = rectTransform.parent as RectTransform;
Vector2 parentSize = parent.rect.size;
Vector2 parentMin = parent.rect.min;
// Find corner point coordinates in parent's local space
Vector3[] corners = new Vector3[4];
rectTransform.GetWorldCorners(corners);
corners[0] = parent.InverseTransformPoint(corners[0]); // Bottom left
corners[2] = parent.InverseTransformPoint(corners[2]); // Top right
Undo.RecordObject(rectTransform, "Anchor Modification");
rectTransform.anchorMin = new Vector2((corners[0].x - parentMin.x) / parentSize.x, (corners[0].y - parentMin.y) / parentSize.y);
rectTransform.anchorMax = new Vector2((corners[2].x - parentMin.x) / parentSize.x, (corners[2].y - parentMin.y) / parentSize.y);
rectTransform.sizeDelta = Vector2.zero;
rectTransform.anchoredPosition = Vector2.zero;
}
[MenuItem("CONTEXT/RectTransform/Snap Anchors To Corners", validate = true)]
private static bool Validate(MenuCommand command)
{
RectTransform rectTransform = command.context as RectTransform;
return rectTransform.parent != null && !PrefabUtility.IsPartOfImmutablePrefab(rectTransform);
}
}
#endif
for example this works nicely and clean
cuz [MenuItem("CONTEXT/RectTransform/Snap Anchors To Corners", priority = 50)] is the right route
And you want that to be a button in the tag manager window?
Ok I see now, my bad, I didn't know that MenuItem works for context menus too - I always used [ContextMenu] instead 🤔
So, do u know which route should I use or how can I archieve the same result?
I don't know how to modify existing settings windows but maybe someone else knows
Context for others: Needs to add a context menu item for TagManager/TagManagerInspector
started work on UI Toolkit, but idk how to make the elements side by side in code.
public class FixVector2Drawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
var x = new PropertyField(property.FindPropertyRelative("x").FindPropertyRelative("serialisedValue"), "X");
var y = new PropertyField(property.FindPropertyRelative("y").FindPropertyRelative("serialisedValue"), "Y");
container.Add(x);
container.Add(y);
return container;
}
}
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
container.style.flexDirection = FlexDirection.Column;
var propertyLabel = new Label(property.displayName);
propertyLabel.style.marginBottom = 2;
container.Add(propertyLabel);
var horizontalContainer = new VisualElement();
horizontalContainer.style.flexDirection = FlexDirection.Row;
horizontalContainer.style.alignItems = Align.Stretch;
var x = new PropertyField(property.FindPropertyRelative("x").FindPropertyRelative("serialisedValue"), "X");
var y = new PropertyField(property.FindPropertyRelative("y").FindPropertyRelative("serialisedValue"), "Y");
x.style.marginRight = 5;
y.style.marginLeft = 5;
horizontalContainer.Add(x);
horizontalContainer.Add(y);
container.Add(horizontalContainer);
return container;
}
i've got this code now
but thsi looks peretty terrible
Instead of using a PropertyField, you can use a Label with a FloatField. Style the Label with a fixed width and set its flex growth to 0. Then style your FloatField with a fixed width. If you want it to scale properly when you resize your inspector, you should use % for either fixed width.
would this work with a double field?
I want to be able to drag the values back and forth like a standard property
Yes. Actually, seeing your screenshot I assumed you'd need a FloatField, but the logic is the name for a DoubleField. Whatever is the type of field you want (text, int, double, float, bool), using a Label + something will work since it only aims at controlling the display/style.
var horizontalContainer = new VisualElement();
horizontalContainer.style.flexDirection = FlexDirection.Row;
var xLabel = new Label("X");
xLabel.style.width = Length.Percent(5);
var x = new DoubleField();
var yLabel = new Label("Y");
yLabel.style.width = Length.Percent(5);
var y = new DoubleField();
horizontalContainer.Add(x);
horizontalContainer.Add(y);
not sure if i've done this right 😅
and the values dont reflect hte peoprty either
i know its because i havent linked them, but idk how to with the double field
just realised i didnt add the labels to the container
var horizontalContainer = new VisualElement();
horizontalContainer.style.flexDirection = FlexDirection.Row;
var xLabel = new Label("X");
xLabel.style.width = Length.Percent(5);
horizontalContainer.Add(xLabel);
var xField = new DoubleField();
xField.style.width = Length.Percent(45);
UnityEditor.SerializedProperty xProperty = property.FindPropertyRelative("x").FindPropertyRelative("serialisedValue");
if (xProperty != null)
{
xField.BindProperty(xProperty);
}
else
{
Debug.LogError("Could not find property X");
}
horizontalContainer.Add(xField);
var yLabel = new Label("Y");
yLabel.style.width = Length.Percent(5);
var yField = new DoubleField();
yField.style.width = Length.Percent(45);
UnityEditor.SerializedProperty yProperty = property.FindPropertyRelative("y").FindPropertyRelative("serialisedValue");
if (yProperty != null)
{
yField.BindProperty(yProperty);
}
else
{
Debug.LogError("Could not find property Y");
}
horizontalContainer.Add(yField);
I added some log in case you made a mistake to find both x and y properties, but it's not mandatory
I could have explained, but it was easier showing you your code with corrections ^^'
is there any way to bind the label to the property so i can drag left and right liek standard vectors?
Let me ask a question first, what is the type of you property ? Isn't it a Vector2 ?
its a custom fixed point data type
its not a standard vector 2
like a unity vector 2
but it is a vector2 like type
OK. That's why you're accessing x and y like this
yeah
odd question, and i already know the answer is no, but is it possible to run JS functions in editor? for example i press a button and it downloads a json file (this is a JS function using a specific library no its not a normal file)
To answer your question, you can not simply bind the Label to that kind of behaviour. You have to implement the behaviour yourself unfortunately.
i see. I asked because the property field was able to do this pretty easily. no idea why the double field and label doesnt work
you can do it if you use the label of the DoubleField, but you'll have the same issue has before that you can't control the label and field width
yeah. i can probably look around and find my own way to do that. dragging is crucial for me because its a lot easier to do that then manually write in numbers
But let me try something to ease your life
OK. I wasn't sure about my other solution as Unity tends to inline some part of its controllers but it is possible to override the styling through USS.
In USS that will look like this
.vector-field {
flex-grow: 1;
flex-shrink: 0;
width: 40%;
}
.vector-field Label {
width: 10%;
min-width: 15px;
}
.vector-field #unity-text-input {
width: auto;
min-width: auto;
flex-grow: 1;
}
looks like css lol
for a property field?
You would need to get some additional library for running the functions. So no, not natively.
This way all you have to do is @dusk dome
var horizontalContainer = new VisualElement();
horizontalContainer.style.flexDirection = FlexDirection.Row;
// get stylesheet somehow, this was not unity code xD
if (styleSheet != null)
{
horizontalContainer.styleSheets.Add(styleSheet);
}
var xField = new DoubleField("X");
xField.AddToClassList("vector-field");
UnityEditor.SerializedProperty xProperty = property.FindPropertyRelative("x").FindPropertyRelative("serialisedValue");
if (xProperty != null)
{
xField.BindProperty(xProperty);
}
else
{
Debug.LogError("Could not find property X");
}
horizontalContainer.Add(xField);
// do the same for Y
wouldnt that make it open the the stylesheet every time its updated?
In contrary of IMGUI, this is supposed to be called once when you open your inspector
oh right