#↕️┃editor-extensions
1 messages · Page 14 of 1
Uhh, might be faster to undo/redo, but slower to record. But that is just a guess
for sure, but atm im only worried about operation itself, not recording, couse it feels sloooooow
Again, if you can I would definitely look in to using SerializedObject instead
im not sure if it will work, Ive had some issues with treating it that way because of a lot of SerializedReferences for polymorphism
It works fine with SerializedReference if memory serves
@glad cliff I can confirm that you want to do recordobject whenever possible.
The number of changing properties doesn't matter, but if you're changing multiple objects you'll need to record each one
In your snippet recordobject can directly replace recordcompleteobjectundo
You don't need to manually create a group unless you need to group undos across undo flushes
Undos get flushed automatically at convenient times like when the mouse is releasing
So any undos that happen within that window will get grouped together automatically. It's only when you're doing something weird that you'll need to manually manage the grouping
yeah now I see how it actually works and it makes much more sense
Does anyone know how to draw a class with EditorGUI.Property Field which has its own property drawer? or do i have to use something else?
PropertyField uses the custom property drawer if there is one
Weird because if you saw the message I replied to to draw that class I use this code https://paste.ofcode.org/nMJLkM3XGY7ecVpaux8WSz , but it was enough to try using the EditorGUI.Property to no longer draw it as it should, I'm probably I'm wrong somewhere so I don't know
I assume you are referring to the DrawIf attribute calling the Editor.PropertyField for the SerializedProperty it is on. This is because it takes over the drawing of the field it is on, and PropertyField takes in to account attributes (iirc...)
How can I work around this problem if it exists?
I would first confirm for sure that the issue is the nested PropertyField. I am only like 75% or 80% sure that is the case. A simple ReadOnly property should do.
(The more I am thinking about it, it feels like it isn't the case. Idk, something just feels off)
Here https://paste.ofcode.org/FHDaf3X4X4jsuYvg2syt7U this is how i try to draw or draw as a ReadOnly
Guess it is the case. Only way around it then is to create your own base/fallback Editor and manually implement the drawing
Do you mean a fairly general one or a specific one for each case similar to this one?
I mean you create a custom editor for MonoBehaviour and set it as the fallback. Then loop over every serializedProperty in the SerializedObject and draw them with EditorGUILayout.PropertyField. Before doing that, you get all of the DrawIf attributes on the type, and when you go to draw a field, you check if it is one of the fields that has a DrawIf attribute, and if it is you do your special logic for drawing it.
Got it, I'll see what I can do, do you have any snippets or links where I can document myself?
This repo does the same sort of thing. Though focuses on grouping and layout of properties.
https://github.com/gasgiant/Markup-Attributes
Here is their editor.
https://github.com/gasgiant/Markup-Attributes/blob/main/Assets/MarkupAttributes/Core/Editor/MarkedUpEditor.cs
There is stuff on the forums too, but I can't find them atm
Thank
Soooo I had an issue that my data structure in my custom tool involved too much SO, because of polymorphism, and atm I didnt know about SerializedReference. Now im changed things up to use C# classes and SerializedReferences instead, which tbh made code much cleaner, shrunk it down significantly, and made everything work much faster so im happy af...
BUT...
yesterday Ive noticed that Unity crashes whenever I create an edge in a GraphView 😦 Changing things back to SerializeFields solves the issue, but then everything else doesnt work ofc, couse I made changes specificly to make it work with SerializeReferences.
The crash itself looks like Unity falls into never ending loop and just freezes until whole PC crashes. If it will help I can recreate this and make a bug report out of the logs after the crash, but it will take me like half an hour
private GraphViewChange OnGraphViewChange(GraphViewChange change)
{
Debug.Log("Changes made");
Undo.RecordObject(Controller, "State Machine changed");
//EDGES CREATION
if (change.edgesToCreate != null)
{
foreach (Edge edge in change.edgesToCreate)
{
//CREATING START EDGE (this one is being created automaticly and doesnt break the editor)
if (edge.output.node is FSMCStartNode)
{
Controller.StartingState = (edge.input.node as FSMCStateNode).State;
if (this.Query<Edge>().Where(e => e.output.node is FSMCStartNode && !e.Equals(edge)).ToList().Count() > 0)
{
this.RemoveElement(this.Query<Edge>().Where(e => e.output.node is FSMCStartNode && !e.Equals(edge)).First());
}
}
//CREATING ANY EDGE
else if (edge.output.node is FSMCAnyNode)
{
var transition = new FSMCTransition("Any->" + (edge.input.node as FSMCBaseNode).NodeName, null, (edge.input.node as FSMCStateNode).State);
Controller.AnyTransitions.Add(transition);
(edge.input.node as FSMCStateNode).State.TransitionsTo.Add(transition);
(edge as FSMCEdge).transition = transition;
}
//CREATING EDGE BETWEEN STATES
else
{
var transition = new FSMCTransition((edge.output.node as FSMCBaseNode).NodeName + "->" + (edge.input.node as FSMCBaseNode).NodeName,
(edge.output.node as FSMCStateNode).State, (edge.input.node as FSMCStateNode).State);
(edge.output.node as FSMCStateNode).State.TransitionsFrom.Add(transition);
(edge.input.node as FSMCStateNode).State.TransitionsTo.Add(transition);
(edge as FSMCEdge).transition = transition;
}
}
}
[...]
this first Debug statement doesnt even print anything before the crash, idk why but crash must be coused sowhere around here
public class FSMCTransition
{
[SerializeField] public List<FSMCConditionWrapper> conditions;
[SerializeReference] private FSMCState _originState = null;
public FSMCState OriginState { get => _originState; private set => _originState = value; }
[SerializeReference] private FSMCState _destinationState = null;
public FSMCState DestinationState { get => _destinationState; private set => _destinationState = value; }
[SerializeField] private string _name;
public string Name { get => _name; private set => _name = value; }
not quite sure what the cause of it, just want to comment that this part is terrible
foreach (Edge edge in change.edgesToCreate)
{
//CREATING START EDGE (this one is being created automaticly and doesnt break the editor)
if (edge.output.node is FSMCStartNode)
{
Controller.StartingState = (edge.input.node as FSMCStateNode).State;
if (this.Query<Edge>().Where(e => e.output.node is FSMCStartNode && !e.Equals(edge)).ToList().Count() > 0)
{
this.RemoveElement(this.Query<Edge>().Where(e => e.output.node is FSMCStartNode && !e.Equals(edge)).First());
}
}
there's unwanted behavior in OngraphChange where there's a chance it can be executed multiple times in one frame
public class FSMCState
{
[SerializeField] private List<FSMCBehaviour> _behaviours = new();
#if UNITY_EDITOR
public Vector2 Position;
#endif
[SerializeField] private string _name;
public string Name { get => _name; private set => _name = value; }
[SerializeReference] public List<FSMCTransition> TransitionsFrom = new();
[SerializeReference] public List<FSMCTransition> TransitionsTo = new();
this is how this data looks like
you mean becouse of my code, or is it jsut something we must deal with?
as said not sure if that's the cause of your crashes, just want to comment that OnGraphViewChanged is a bit buggy
ditch out that Query and tuck in your instance in node.userData to avoid boilerplates of iterating the nodes
so you can just do (node.userData as FSMCStartNode).doYourThing
ill have that in mind thanks, but anyway this havent coused any issues so far
it crashes only when creating Any edge or Edge between states
have you tried try-catching it?
I mean... I can try.
btw does the Debug.Log actually prints something at the end of the frame or exact at the given moment? Becouse when crash happens this first debug statement doesnt print anything
try-catch and throw like a normal person? 😃
using try catch at least made this first Debug statemtnt appear, but after that it still crashed
and another Debug statement at the end of OnGraphViewChange method
try-catches won't save you from your error when it throws, it's to rest stuffs out, so you know what caused those errors etc
no w8... executed that for the second time and no Debug statements appeared... nor even any error from catch block
only crash happens
I guess I ill let this crash to resolve itself instead of manually killing the editor and see if bug report will say something usefull
there's editor log so you can peek that instead
hi
hello there!
unfortunatelly this time it didnt crash my PC (i cant believe im sayint that XD)
only froze everything for 40 minutes and it would go on if I didnt kill the process ehhh..
can I find somewhere any logs to see what was happening there before I killed unity?
Experimenting with property drawers is...... tedious.
People deal with this? 
Hey ppl!! 🙂 I got something weird going on that I cannot put my finger on it... I am (on the editor side) loading a Material and a Texture2D from the AssetDatabase, adding the the texture to the material's _MainTex, then setting the material as dirty and running SaveAssets. But the matrial continues without the texture.
Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(fullPathTex);
Material mat = AssetDatabase.LoadAssetAtPath<Material>(fullPathMat);
mat.SetTexture("_MainTex", tex);
EditorUtility.SetDirty(mat);
AssetDatabase.SaveAssets();
I know that mat.SetTexture works and sets it. Works perfect at runtime but just doesn't save the connection between the texture and the material.
Ok, I understand what happens.... It's fixed. I did not provide enough info. I was generating and saving both the material and the texture before loading them back.... and I forgot to refresh the AssetDatabase before the load.... 
i feel ya. height calculation can be such a hassle
specially when some label wraps at the end of the rect's width
how might I approach an editor script running whenever a specific project scene is opened?
add a initializer [InitializedOnLoad] to your static editor class then get the guid of your scene then filter it to whatever you want
see the docs for GuidFromAsset..
You would use [InitalizeOnLoad], and then in the static constructor, you would add a callback to EditorSceneManager.sceneOpened and check if the scene that is opened is the one you want.
Hello, i've been having a bit of an annoyance with the latest LTS version and the ProjectSettings window, it seems like most if not all of the PropertyFields that are being drawn with EditorGUILayout.PropertyField() are causing the entire UI to become inactive (As if the UI code was wrapped inside EditorGUI.BeginDisabledGroup(true))
is this a known issue with 2022 LTS or am i doing something wrong?
Here's my settings provider, which i'd reckon would be the main reason why this would happen in the first place
Downside with txt sending or cs is it won't show the entire thing if it gets too big. 
Better use !code
📃 Large Code Blocks
Large code blocks should be posted as 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 get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.
i totally got trolled right there
give me a sec
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
bloody thing is a lot bigger now
Does this use any other property drawers?
My guess would be that a property drawer is doing GUI.enabled = false (or similar) and not setting it back to true
all of the code on the method produces working, interactable UI. none of the fields or controls here are drawn by EditorGUILayout.PropertyField()
but the second i try to add a field using EditorGUILayout.PropertyField() it craps out
tbh idk if one of my packages could cause that weird behaviour, cuz it doesnt seem to be intended behaviour on unity at all
And what are you drawing a PropertyField for when it craps out? Because I don't see one in your above code
yeah, because that one is the one that i'm using rn since it doesnt crap out
let me modify it by idk
making that toggle for Create Layer Index Struct use a PropertyField
give me a sec
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
here's the modified code that uses PropertyField to draw the toggle
only that one seems to be disabled, (for some reason, using EditorGUILayout.PropertyField() on a property array causes anything past it to be disabled)
I think I have experienced this before, specifically with settings providers, but I cannot remember what caused it....
Here's some code I have that I suspect was my fix for it
After you do: var settings = NebulaSettings.instance;
Add:
settings.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
settings.Save();
@unreal light
Oh and Save is a function that calls through to the protected Save function, so you will need to implement it:
public void Save() => Save(true);
well i'll be damned
yeah i hgave a "DoSave() method on my settings
yeah adding the hidedflags and now i can use property fields 
i'm honestly surprised thats not documented anywhere
https://github.com/Developer-Notes-Extension I notice that I have already made a note about this using my extension on https://docs.unity3d.com/ScriptReference/SettingsProvider.html
2023.2.0a18
Editor: Added the UI Toolkit data bindings feature to the Unity Editor, which includes data bindings support in UI Builder, Editor bindings workflow improvements, and UxmlObjects authoring workflows in UI Builder.
Has neat dropdowns for getting binding paths from objects
Oh Christ that's amazing
Yeah, it is actually pretty powerful, if a little funky. I do hope that they will actually integrate the SerializedProperty system in to it and just deprecate the current binding system. Though idk if that would make sense.
I had a back and forth with one of the devs about it and how to use it if you want to look!
https://forum.unity.com/threads/how-do-you-use-new-uitoolkit-binding-system.1446748/
this sucks tho
// Create a binding between the value of the field and the value of your behaviour
field.SetBinding(nameof(FloatField.value), new DataBinding { dataSourcePath = PropertyPath.FromName(nameof(MyBehaviour.value)) });
from the linked forum
Yeah, there is a 'lot' of boilerplate if you are doing it from code. That whole line can be done in UXML at least.
I really like you can bind to any property of a VisualElement though! I think that should me you can bind to the style.display property which will make hiding/showing fields much easier!
Do SerializeReference prevents itself from serializing self referencing loop?
Or making such would theoretically break the editor?
ASKING FOR A FRIEND
Apparently RegisterCompleteObjectUndo is perfect for when you're not using binding property in uitk.
I have ListView items connected to lots of components and RegisterCompleteObjectUndo + listView.Rebuild combo, will automagically update/rebind those undoes pretty easily..
Sooo from what I tested SerializeField doesn't, but after 10 levels of depth while serializing, it seems like it stops and just throws a warning. However it looks like SerializeReference also doesn't prevent loops, but goes forever...
I mean... from what my friend tested. I would never do such stupid thing ofc
It should. It just serializes an ID basically.
So... you are calling listView.Rebuild? Yeah... that would indeed rebuild those bindings 😉
and as expected it's turtle slow 🐢 ... I really wish RefreshItems would work, but nope
must be Rebuild
The reason that SerializeField runs in to an issue is because by default Unity serializes things as values. Meaning that you would have something like this
public class MyClass {
public MyClass otherMyClass;
}
It will just keep going because otherMyClass cannot be null (serialize as value), so every otherMyClass also has a otherMyClass field.
> Depth 0
> Depth 1
> Depth 2
> Depth 3
> Depth 4
etc.
SerializeReference on the other hand, serializes as, well, reference. It basically puts them all in a list, and then make an ID for them, so if the value is referenced by another SerializedReference, the ID is what is serializedand not the value.
I won't say anything about using SerializedObject instead. And how Undo is really not made to work well with UITk. I have beat you over the head with that enough... oh oops did I do it again? 😛
this for testing purposes only was just curios with the whole undo/redo in unity, don't worry 😂
I'm not dealing with the project I mentioned the other day anymore, it was done already 🫡
depends on the recursive field
if the field is not marked as serializeReference and is not derived from Object, then it'll infinitely recursive and hence unity won't serialize it , and gives error
like this
[Serializable] class A{ public A a;}```
the inner field is not serializereference
Yeah, I was specifically taking about SerializeReference as the message I was replying to was asking about it.
if A is serialized as SerializeReference , this will still break
since the inner a is not serializereference
that's what I'm saying
public class B : Monobehaviour { [SerializeReference] public A a;}```
I'm on mobile ...
Yeah, but then you are not serializing it with SerialieReference.
But that is a good thing to note that it does not apply recursivly.
So in my case it looks like this:
[Serializable]
public class A{
[SerializeReference] List<B> _list1;
[SerializeReference] List<B> _list2;
}
[Serializable]
public class B{
[SerializeReference] A _ref1;
[SerializeReference] A _ref2;
}
im getting a bit lost in you explenation when will it break and when it wont
in ma case it breaks, and not even with any error of some kind, editor just falls into never ending loop and freezes forever
Basically if you replaced [SerializeReference] A _ref1; with [SerialieField] A _ref1;. _ref1 would no longer serialized with SerializeReference so it would break as it would be serialzing it by reference
or to better put it into context it is
[Serializable]
public class State{
[SerializeReference] List<Transition> _transitionsTo;
[SerializeReference] List<Transition> _transitionsFrom;
}
[Serializable]
public class Transition{
[SerializeReference] State _origin;
[SerializeReference] State _target;
}
Yeah that should work just fine
well... it doesnt :/
im giving myself a minute to read again what you wrote earlier couse im lost XD
yeah I dont get it... I understand difference between SerializeField and Reference, and what im getting from it is that SerializeReference is still serialized the same way, but actuall object is just sotred somewhere else and reference is just replaced with ID. So if there is a loop with SerializeField it just serializes to some hardcoded depth limit, so with SerializeReference it should work the same I guess... but seems like it doesnt idk...
I just test to be 1000% sure and it works fine for me. Try this and see if it works for you.
[Serializable]
public class State{
[SerializeReference] public List<Transition> _transitionsTo;
[SerializeReference] public List<Transition> _transitionsFrom;
}
[Serializable]
public class Transition{
[SerializeReference] public State _origin;
[SerializeReference] public State _target;
}
[ExecuteAlways]
public class ReferenceTestBehaviour : MonoBehaviour {
[SerializeField] private State _state;
private void OnEnable() {
_state._transitionsFrom.Add(new Transition());
}
}
but in my usecase whenever I create and add new transition i have all references set up like
[ExecuteAlways]
public class ReferenceTestBehaviour : MonoBehaviour {
[SerializeReference] private State _state1;
[SerializeReference] private State _state2
private void OnEnable() {
var transition = new Transition(){_origin=_state1, _target=_state2};
_state1._transitionsFrom.Add(transition);
_state2._transitionsTo.Add(transition);
}
}
but imagine it using Constructors instead
WRONG! sry
dont rtead taht above XD
now is correct
now im talking sh*t without testing sry, but I will be able to turn on Unity in like 10 minutes
and I dont know if it makes any difference but object in which states are actually stored serializes them also as References
so I altered it a bit to match more what I have
This code, plus this before the OnEnable stuff works fine for me.
_state1 = new State();
_state1._transitionsFrom = new List<Transition>();
_state2 = new State();
_state2._transitionsTo = new List<Transition>();
I just tested
[ExecuteAlways]
public class Test : MonoBehaviour
{
[SerializeReference] private State _state1 = new State();
[SerializeReference] private State _state2 = new State();
private void OnEnable()
{
var transition = new Transition(_state1, _state2);
_state1._transitionsFrom.Add(transition);
_state2._transitionsTo.Add(transition);
}
}
[Serializable]
public class State
{
[SerializeReference] public List<Transition> _transitionsTo;
[SerializeReference] public List<Transition> _transitionsFrom;
public State()
{
_transitionsTo = new List<Transition>();
_transitionsFrom = new List<Transition>();
}
}
[Serializable]
public class Transition
{
[SerializeReference] public State _origin = null;
[SerializeReference] public State _target = null;
public Transition(State origin, State target)
{
_origin = origin;
_target = target;
}
}
and it throws NullReferenceException on _state1._transitionsFrom.Add(transition);
im on Unity 2021.3.19f1
The assignment initializer for serialized fields in Unity does not call constructor if memory serves. Try setting _state1 and _state2 in OnEnable instead.
yeap and now it works just fine.... ehhh so I rly dont know what is going on with my original problem
Just gotta work up until you recreate the logic/structure I guess
here is my original problem
whole structure is layed out right there, seems he same for me :/
I double, TRIPLE checked everything and tested a fiew things and it is really the same as in our previous test, yet it breaks. Whenver transition doesnt have a reference to state containing it, or state doesnt have a reference to a transition in which reference to this state is, everywthing works fine. It only breaks if both have references to each other. The more I know the more unlogical this issue becomes to me and im going crazy couse of that X'D
What does "break" mean in this case?
ohhh I just made it with some debug methods instead of UI and it didnt break... GraphView must be involved then, not the wasy it is serialized hmmm
by break I mean it freezes with additional window saying that unity is executing some code, and it runs forever, or until PC crashes
Ahh
I didn't look at the code tht closely. But it is probably a infinit update loop. Basically you are doing something in the Changed event callback which is causing the Changed event to be raised which runs the code again, etc.
if this is the case then if I unsubscribe this method from change event when it is invoked, then it will run only once and not force any loop, ill try that
not a solution, but a test to see if this is a problem
well, there is no looping I think, but after making it work with my debug methods and opening graph view while finally having this transition in my data, any change made to the graph couses it to break
is there a way to skip total reimport when adding a post processor?
Not that I know of.
annoying, team has to suffer reimports
Yeah, this is painful, but a little bit better with a local cache server (Unity Accelerator).
Photon Pun 2 vs Mirror
Pros and cons?
Wrong channel. #archived-networking is what you want.
Wondering if there's an a EditorGUI.Popup but works like flags? 
wdym?
I have tracked when exactly my editor crashes, but still dont know the couse of it. Apperently Whenever my data container (Scriptable Object) contains looped references in it (which is this State-Transition relation) ANY change that I make to that SO via the editor window couses it to break.
When this editor window is closed I can do it via inspector window and it is fine, but when editor window is opened crash happens no matter if I make a change with editor window or inspector window.
That makes me wonder if property bindings may be invlolved, becouse as I said I dont need to use that editor window, all it takes is it to be opened to crash whenever any change appears
Quick question, is PreviewRenderUtility can do gizmos as well, like we normally'd in the scene?
this thing is beautiful but sadly, it's undocumented
@gloomy chasm you did somethings with that right
Something like enums with flags attribute pretty much. 
Amount of options depends on the amount of contents in the string array much like a normal EditorGUI.Popup does but lets you select multiple and the output will be the total of each selection options (in int, with the elements having a value of n^2). 
further testing: I tried to apply changes not directly but via SerializedProperty, and then it crashes when I invoke SerializedObject.ApplyModifiedProperties(). Idk what does it mean, but maybe someone has a clue
The name's somewhat misleading. 
not really if you think how unity team uses it. Im sure you already used LayerMask already 😄
Ok then.
Yeah. Iirc you have to set one of the properties on the Handles class to be the camera or matrix or something from the PreviewRenderUtility
It means either you found bug or you are doing something wrong. Try to recreate the SerializedObject logic from you editor window in a standalone method that you can invoke or something.
funnily enough that is what im actually doing right now 😄
Aight, that's a start, thanks. Are there source references to one of Unity editor tools that I can peek out?
isn't it used for characterrigging too iirc
Not that I know of 🙃
Actually, maybe the animationclip preview maybe
I found a video on youtube way back in like 2018 that did it.
@peak bloom first google result 😛 https://forum.unity.com/threads/previewrenderutility-and-handles.859168/
aight, well noted, looking into it now, thanks a ton! 🫡 .. on my way creating character preview screen for Spine & Live2D with this api♥️
🥹
Yeah looks like I was right, It is just Handles.SetCamera
Along with setting the matrix
op's nickname of this thread is "the rhino is coughing" in polish 🤣
help?
@gloomy chasm yeap I recreated my problem in isolation with ease
[CreateAssetMenu(fileName ="Test", menuName = "TEST")]
public class Test : ScriptableObject
{
[SerializeReference] private State _state1 = null;
[SerializeReference] private State _state2 = null;
[ContextMenu("test")]
private void Method()
{
_state1 = new State("State1");
_state2 = new State("State2");
var transition = new Transition(_state1, _state2);
_state1._transitionsFrom.Add(transition);
_state2._transitionsTo.Add(transition);
}
}
[Serializable]
public class State
{
[SerializeReference] public List<Transition> _transitionsTo;
[SerializeReference] public List<Transition> _transitionsFrom;
[SerializeField] public string name;
public State(string name)
{
_transitionsTo = new List<Transition>();
_transitionsFrom = new List<Transition>();
this.name = name;
}
}
[Serializable]
public class Transition
{
[SerializeReference] public State _origin = null;
[SerializeReference] public State _target = null;
public Transition(State origin, State target)
{
_origin = origin;
_target = target;
}
}
public class TestWindow : EditorWindow
{
public Test soTest;
public void CreateGUI()
{
if (soTest == null) return;
var soObj = new SerializedObject(soTest);
var text1 = new TextField("State1");
var text2 = new TextField("State2");
rootVisualElement.Add(text1);
rootVisualElement.Add(text2);
text1.BindProperty(soObj.FindProperty("_state1").FindPropertyRelative("name"));
text2.BindProperty(soObj.FindProperty("_state2").FindPropertyRelative("name"));
}
[OnOpenAsset(0)]
public static bool OnOpen(int instanceID, int line)
{
var so = EditorUtility.InstanceIDToObject(instanceID) as Test;
if (so != null)
{
var wnd = GetWindow<TestWindow>();
wnd.soTest = so;
wnd.CreateGUI();
return true;
}
return false;
}
}
this is all it takes
Which part of it though?
when self referencing loop is present in a data container, any change made to it while having editor window with anything binded to some property of that container couses unity to fall into never ending update loop
in this quick test case, when i create this Test ScriptableObject, run this test method to initialize it with objects containing that self referencing loop, and then open editor window with those bindings it crashes whenever i change name of any of that states
Hmm, try it with IMGUI instead of UITK to see if that makes a difference.
Try this instead of the CreateGUI
SerializedObject so;
void OnEnable() { so = new SerializedObject(soTest); }
void OnDisable() { so.Dispose(); }
void OnGUI()
{
var property = soObj.FindProperty("_state1").FindPropertyRelative("name");
EditorGUI.BeginChangeCheck();
property.stringValue = GUILayout.Text("State1", property.stringValue);
if (EditorGUI.EndChangeCheck())
so.ApplyModifiedProperties();
}
yeah with IMGUI it works
but if this is a solution, I dont know how to mix UITK with IMGUI to make it work... anyway I say it is a bug so im gonna report this on forum
you can do it the fucky way by wrapping it with IMGuiContainer
I'm using SerializeReferences with UItk with no problem tho, and yeah lots of scriptableObjects too
apperently uitk flips itself over with SerializeReference when self referencing loop appears
want to test something? try replace all your binding properties with registerCallbacks
seems like something worth testing right!
Hmm, that feels funky to me. But I would post on the forums and see if one of the devs can confirm it.
@gloomy chasm while you're here 😂 ... can we use ExposedReference<T> to keep references of scene objects in our scriptable assets?
Literally the point of it 😛
oh! nice!.. I saw this used everywhere in Playables.. oh this is super nice
If memory servses, you need to have a component that actually keeps the references so they can be resolved though.
will test it out tomorrow 🫡
surprisingly it works. Tidious af but it definitely is a workaround
yeah, binding properties in uitk can be a bit iffy especially in older versions
text1.RegisterValueChangedCallback(s => { soObj.FindProperty("_state1").FindPropertyRelative("name").stringValue = s.newValue; soObj.ApplyModifiedProperties(); });
text2.RegisterValueChangedCallback(s => { soObj.FindProperty("_state2").FindPropertyRelative("name").stringValue = s.newValue; soObj.ApplyModifiedProperties(); });
it is not clean but gets the job done XD
Sounds like an issue with the UITK binding system. I would post on the forums about it. The UITk devs are on there pretty often.
100% gonna do it
when and if they fix it I cant wait to refactor all my code back to the current state after im gonna implement this temporary workaround XD
you can just vis.RegisterCallback<T>(x=> (target as MyClass).myField = x.newValue) but if it works then all good
Note that this is only one way binding. Changes to the SerializedObject will not be applied to the UI. So things like Undo will not update the UI. Or if something else changes it.
only as long as it is public unfortunatelly
also true
I mean, at least do property.managedReferenceValue as State if you are going to do that.
yeah, this is a massive pain 😅
definitelly it is not a superior solution, but for now the only one (except IMGUI container but... come on)
If you can, I would try out 2022.3LTS
I hate switching versions mid project -,-
if I make separate branch just to test it on newer version, UnityHub wont confuse project versions after getting back to branch with older version?
sidenote: my internet is so sh**ty that downloading newer version means that I need to leave my PC on for a night XD
What's the best way to handle this situation where I want a generic method for drawing different GUILayout fields, but all with the same layout(I want a label and flexible space, then the field)?
void drawField<T>(string label, T value) {
GUILayout.BeginHorizontal();
{
GUILayout.Label(label);
GUILayout.FlexibleSpace();
drawField(value);
}
GUILayout.EndHorizontal();
}
void drawField(Vector2Int v) {
EditorGUILayout.Vector2IntField(GUIContent.none, v);
Debug.Log("Vector2Int");
}
void drawField(object v) => Debug.Log("Unknown object: " + v.GetType());
it just outputs unknown object: UnityEngine.Vector2int
Solution was:
void drawField<T>(string label, T value) {
GUILayout.BeginHorizontal();
{
GUILayout.Label(label);
GUILayout.FlexibleSpace();
drawField((dynamic)value);
}
GUILayout.EndHorizontal();
}```
drawField("Test 2", Vector2.right);
drawField("Test 3", "this is a string");```
allows drawing any field(as long as you create a generic method for it:
```void drawField(Vector2 v) => EditorGUILayout.Vector2Field(GUIContent.none, v);
void drawField(Vector2Int v) => EditorGUILayout.Vector2IntField(GUIContent.none, v);
void drawField(string v) => EditorGUILayout.TextField(GUIContent.none, v);
void drawField<T>(T value) => Debug.Log("Unknown object: " + value.GetType());```
for future reference
This doesn't let you actually edit the fields though... 🤔
easy fix, I just wasn't at that point though:
Vector2Int foo = Vector2Int.zero;
Vector2 bar = Vector2.right;
string test = "this is a string";
void method() {
foo = drawField<Vector2Int>("Test 1", foo);
bar = drawField<Vector2>("Test 2", bar);
test = drawField<string>("Test 3", test);
}
private T drawField<T>(string label, T value) {
GUILayout.BeginHorizontal();
{
GUILayout.Label(label);
GUILayout.FlexibleSpace();
value = drawField((dynamic)value);
}
GUILayout.EndHorizontal();
return value;
}
Vector2 drawField(Vector2 v) => EditorGUILayout.Vector2Field(GUIContent.none, v);
Vector2Int drawField(Vector2Int v) => EditorGUILayout.Vector2IntField(GUIContent.none, v);
string drawField(string v) => EditorGUILayout.TextField(GUIContent.none, v);
T drawField<T>(T value) => value;```
Yup, neat idea. But does also feel like just a lot of extra work to avoid using SerializedProperty and PropertyField.
propertyfield draws the inputs on a new line
propertyfield:
vs
It shouldn't... it is what the whole inspector uses...
this is in an editor window, I dunno if that makes a difference but it's not in the inspector
I am trying to remember what causes this... might be needing to set the EditorGUIUtility.labelWidth = 0; before drawing the field.
Or maybe EditorGUILayout.PropertyField(property, GUILayout.ExpandWidth(true));
Either way, this is a 'bug'. They should be on the same line.
ah well either way ended up with a solution thanks 🙂
@gloomy chasm on 2022 LTS it doesnt break but I see it has some quirks on its own, but I can imagine they are there BECAUSE of the solution to that binding problem. Like SerializeReference being null isnt displayed at all, and when it is set to something it doesnt appear in inspector until you reopen it, also changing values in an object serialized as reference changes one visual representation of that object while rest is updated only after reopening inspector
this both fields refer to the same object, but when its position got updated visual representation of that data is updated only on this one path where it was updated at, leaving second one untouched
other issue with transitioning to 2022 arose... but rather a simple one
My node in a graph view is fully covered by a TextField, which prevents node from being dragged as this TextField captures all mouse events. In 2021 all I had to do was text.RegisterCallback<MouseDownEvent>(e => e.PreventDefault()); to solve this issue, but in 2022 it doesnt work and I have no idea how to achieve this in other way
I remember them saying they changed something about the way events work. Like they go down now by default or something like that...
SetEnable(false) lets the event pass through element now, that makes it actually easier as it wasnt working in previous version
oh! they fixed this in 2022 lts? that's nice to know
is there a way i can run code when an user modifies the ProjectSetting's Layers and Tags options?
i have a script that generates a .cs file with the game's layers and tags, but i havent found a good way to regenerate the data in the .cs file whenever the layer and tags change
I think there was an internal event for it. Another option would be to use the ObjectChangeEvent class I think
Is there a way to make a custom property be able to switch between any of its child classes within the editor? The project I'm working on needs to be able to support an arbitrary mix of any of the subclasses of the base property in a single array, and the array needs to be assigned in the editor. Each of these properties are only used once, so I really don't want to have to make them into scriptableObjects if I don't have to.
Do you mean Polymorphic serialization? [SerializeReference]
I'll try that. Thanks!
Does anyone know if UnityEngine RangeAttribute work with odin?
Ah just found the example attribute windows. It does support it
Im having trouble with getting VSC to work with Unity
I get this error Assets/PlayerController.cs(16,9): error CS0103: The name 'Console' does not exist in the current context
hey, is there any way to select an object by clicking on its gizmo?
Doesn't like an editor issue.
Go in #💻┃code-beginner.
How to get the string array value of a serializedProperty? I swear i found one but i can't find it in docs. 
There's no property that gives you the array itself?
Not that I know.
Even GPT-4 is telling me to iterate manually to build that.
Damn, i think i'm high cause i thought i saw one on docs. 
Cause i'm rereading it. 
And i ain't seeing it. 
Yeah i guess I'll do just that.
are you on 2021 or 2022? @wheat notch
boxedValue exists on new versions of Unity though I'm not sure what the restrictions are
I get errors when i use it with arrays.
Otherwise you just need to go through the properties, and I have a how-to pinned
Docs says it doesn't work with array and lists too.
Where? 
It's probably simple enough to do without it but just asking ig.
In the pinned messages.
write a helper method once, and then never again ✊
Very bottom
No idea how Odin works but default Unity has a property you set to true in the attribute
https://docs.unity3d.com/ScriptReference/CustomEditor.html
isFallback's description is somewhat esoteric 💀
hi, writing something for my game and I need to be able to select the key for an event trigger. I have the code working for that, but the issue is the list of keycodes is so big, i'd like to be able to add a search function. how would i go about doing so?
One of the attributes I made just adds a picker if that interests you https://github.com/vertxxyz/Vertx.Attributes
It also has EnumDropdown that does what you're looking for, I forget if I added it to keycode as it's been so long since I've used it
thanks will have a look
Can I introduce you to https://docs.unity3d.com/ScriptReference/IMGUI.Controls.AdvancedDropdown.html
Hopefully they were introduced through my already written drawer 😄
Somehow went over my head that you replied to the same person 😛
foreach (SerializedProperty prop in property)
{
field_rect.height = EditorGUI.GetPropertyHeight(prop);
EditorGUI.PropertyField(field_rect, prop);
field_rect.y += field_rect.height;
}
Does this iterate through all the child properties, even if they have the HideInInspector attribute? 
Even if yes, i don't have to worry about it right?
Nope, hidden ones are not shown. Only visible ones
Ah.
Does FindProperty still pick up hidden ones?
Yup
The reason the foreach doesn't is because it uses .NextVisible(..) and not .Next(..) when iterating
Aight. 
How to do a bold text with editorgui.label real quick? 
Have you worked with GUIStyle before?
Just pass EditorStyles.boldLabel as the GUIStyle
Here's an example of how it's used.
https://gdl.space/qudociloco.cs
And these styles need to be initialized from OnGUI, therefore:
private void OnGUI()
{
// At the start of OnGUI.
if (!_styleIsInitialized)
{
Style.Initialize();
_styleIsInitialized = true;
}
}
But for your immediate need, what vertx suggested is what you should do.

My personal favorite pattern for this is to use a static constructor.
static class Styles {
public static GUIStyle boldLabel;
static Styles () {
boldLabel = new GUIStyle( EditorStyles.boldLabel );
}
}
Means you can use boldLabel and it's lazily initialized on first use without any boilerplate
The block initialization syntax is good for this use case too though, I've not used that one too much. I'm old school 😄
Aren't there issues with calling this from the constructor?
I turned and twisted this all I could, a short time ago, and I ended up only calling Style.Initialize() from OnGUI
Not that I know of. It's a static constructor, which means it's lazily called on first access
So it should act identically to your initialize call from ongui
I've used this in multiple projects with no issues
It's the same pattern unity themselves use in their gui code fwiw
well it wouldn't be the first time my brainmatter was rearranged
let me try this out
Looks good 👍
Thanks for ending that mindtwist.
👍
There aren't because the static constructor isn't called until the first time a member of the class is accessed. Which would be the boldlabel in this case. Which is being accessed from a OnGUI call (presumably) so that is where the static constructor is called! 😄
Lol my bad. I skimmed over the last bit and that is were I see Mad just said the same thing, and I just missed it xD
What perplexes me is that I did in fact use a static constructor before, at least while testing; and for whatever reason I decided to ditch that.
From what I recall, I was quite vigorous about this last time around, to find out the best way.
Huh, never had an issue my self. And as Mad said, this is exactly the pattern Unity uses.
iirc there's some contexts where if you create a style it throw an error
But they should be super rare
And easily avoided
Hello, I am creating an asset for the Unity Asset Store, and it depends on a package from Unity. I was wondering how I can make it automatically download the package before installing my asset. For example, Unity's asset for the third-person character controller automatically downloads the new Input System. This is exactly what I want to do, but I can't figure out how they include the manifest.json. Any help would be greatly appreciated.
When uploading to the asset store using the AssetStoreTools. There is a toggle to include dependency packages
I have an editor tool I built a few years ago to make icons in Unity through the use of a preview window. It creates a window with a model, lets you modify background color, add a background texture, and/or add a foreground texture.
This all worked fine in the built-in renderer, but when URP/HDRP and stuff came out, it didn't work in those pipelines. The issue I'm currently having with URP is I can't get the background texture to work.
Again, works fine in Built-in, but fails in URP. Here's a snippet of the preview window logic.
if (_bgTexture != null) {
_bgTexture.filterMode = _currentFilterMode;
_previewUtil.camera.clearFlags = CameraClearFlags.Depth;
GUI.DrawTexture(new Rect(0, 0, r.width * 2, r.height * 2), _bgTexture, ScaleMode.StretchToFill, true);
}
_previewUtil.camera.Render();
if (_fgTexture != null) {
_fgTexture.filterMode = _currentFilterMode;
GUI.DrawTexture(new Rect(0, 0, r.width * 2, r.height * 2), _fgTexture, ScaleMode.StretchToFill, true);
}
_previewTexture = _previewUtil.EndStaticPreview();
GUI.DrawTexture(r, _previewTexture, ScaleMode.StretchToFill, true);
I want to copy/paste graph elements with position relative to current mouse position, but when I serialize graph elements Event.current is null. I thought that something like mouse positions is tracked by event system continously O.o
Any more clever solution that manually tracking mouse position and using last registered one when copy/paste?
It must be either a camera issue or shaders issue. Might be worh asking on #archived-urp / #archived-hdrp
I'll shoot it over there, thanks ^^
any ideas where to find the code for avatar mask creation in the cs reference ?
or rather how to create one
why you're using Event.current tho?
you can get the localPosition pretty easily by overriding HandleEvent
public override void HandleEvent(EventBase evt)
{
if(evt is PointerDownEvent pd)
{
if(pd.target is MyNode node)//or any graphelement
{
Debug.Log(pd.localPosition);
}
}
}
it doesnt differ much from my current solution. At the end of a day it is still a way of tracking where mouse was seen last time and storing it for later usage XD
couse it is a pretty standard solution ig 🤷♂️
then replace that pointerdown in my snippet with MouseMove and get the position??
graphview by default has tons of events you can just capture that
thats what im doing, but in editor window itself and not in a graph view. Might come usefull later being more accesible
btw wierd stuff with graph view but serializeGraphElements delegate does not include edges, only nodes, so for custom serialization you need to get edges through selection manually... not a big deal but i think it might be a small oversight
it does? works fine on my end 🥹
at least it doesnt include my custom edges, yet custom nodes with no problem (custom i mean derrivitives of those classes)
it should mine also custom
how did you filter those edges in your serialize callback?
i have clearly selected 2 nodes and 4 edges, yet elements contain only 2 elements (those being nodes)
get the edges from the ports then 🫡
i know i know XD im not saying its an issue for me that i cant solve, just a wierd stuff ive noticed and sharing :V
actually im using linq spaghetti for it XD
Transitions = selection.OfType<FSMCEdge>().Where(t => t.transition != null && t.transition.OriginState == state.State && states.Any(s => s.State == t.transition.DestinationState)) .Select(x => x.transition.DestinationState.GetHashCode()).ToList()
couse I want only edges between nodes that are being serialized to be serialzied as well
if you're only want to get edges between nodes why you did all that query above 😆 ... just get the nodes and check the outputPort, get the edges and see whats on the other end.. simple 🫡
couse I dont want to serialize an edge if it isnt selected
maybe... idk. It works the way ive done it and its fine 😄
and propable i would have some issues with that couse previously serialization didnt work so I made a custom one
and copy/paste works just like I wanted it to work
¿How can I know if I'm in the scene view is showing a prefab editing rather than an scene?
I believe that PrefabStageUtility.GetCurrentPrefabStage() != null should work, but not sure
scene view in prefab mode shows what is called a PrefabStage, read through its API, you may find something useful, I havent used that so cant help much more than that
I just ran into this as well. It looks like naughty attributes does overwrite all inspectors, even if you don't have any attributes added: https://github.com/dbrizov/NaughtyAttributes/issues/147
Nice. Well I've moved to Odin now. Highly recommend.
I'm having some issues with my terrain system. Whenever I click on the terrain I get this error followed by another one very similar to it. Whenever I use a tool on the terrain the very first click results in two similar errors like just described, then I can use the tool without issue, after I let off the mouse (from painting or sculpting terrain) I get the two errors again.
aside from this annoyingly common error, the terrain suite appears to be working normally
Thank you I am just dump sometimes didn't relize it was not up to date and was not seeing the button. That could have saved me like two weeks worth of work.
PreviewRenderUtility apparently not too happy being wrapped in IMGUIcontainer 
what's wrong, please help, it doesn't save state of dialogchoices
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using XNode;
using XNodeEditor;
[NodeWidth(440)]
[Serializable]
public class DecisionNode : BaseDialogNode
{
[SerializeField]
public Dictionary<string, DialogNode.DialogData> dialogChoices = new Dictionary<string, DialogNode.DialogData>();
[SerializeField]
public int decisionIndex = -1;
/*[TextArea(3, 10)] [Output(dynamicPortList = true)]
/*[TextArea(3, 10)] [Output(dynamicPortList = true)]
public List<String> choices = new List<String>();*/
protected override void Init() {
base.Init();
}
// Return the correct value of an output port when requested
public override object GetValue(NodePort port) {
return null; // Replace this
}
}
[CustomNodeEditor(typeof(DecisionNode))]
public class DecisionNodeEditor : NodeEditor
{
private SerializedProperty serializedProperty;
private int selectedTab = 0;
string addNewOptionName = "";
private bool foldoutOpen = true;
public override void OnBodyGUI()
{
DecisionNode decisionNode = target as DecisionNode;
base.OnBodyGUI();
serializedObject.Update();
EditorUtility.SetDirty(decisionNode);
selectedTab = GUILayout.Toolbar(selectedTab, new[] { "ADD", "REMOVE" });
switch (selectedTab)
{
case 0:
GUILayout.Label("OptionName");
addNewOptionName = GUILayout.TextField(addNewOptionName, 50);
if (GUILayout.Button("Add option"))
{
Debug.Log("ADD NEW OPTION: " + addNewOptionName);
decisionNode.dialogChoices.Add(addNewOptionName, new DialogNode.DialogData());
EditorUtility.SetDirty(decisionNode);
Debug.Log(EditorUtility.IsDirty(decisionNode));
// Add dynamic output port here if needed
NodePort dynamicOutput = decisionNode.AddDynamicOutput(typeof(int), Node.ConnectionType.Override, Node.TypeConstraint.None, addNewOptionName);
NodeEditorGUILayout.AddPortField(dynamicOutput);
}
break;
case 1:
if (GUILayout.Button("Remove option"))
{
Debug.Log("REMOVE OPTION");
}
break;
}
GUILayout.Space(30);
foldoutOpen = EditorGUILayout.BeginFoldoutHeaderGroup(foldoutOpen, "Choices");
foreach (var choice in decisionNode.dialogChoices)
{
GUILayout.Label(choice.Key);
NodePort dynamicOutput = decisionNode.GetOutputPort(choice.Key);
NodeEditorGUILayout.AddPortField(dynamicOutput);
choice.Value.dialog = EditorGUILayout.TextArea(choice.Value.dialog, GUILayout.Height(100), GUILayout.Width(400));
EditorGUILayout.ObjectField("Audio clip", choice.Value.audioClip, typeof(AudioClip));
EditorUtility.SetDirty(decisionNode);
}
EditorGUILayout.EndFoldoutHeaderGroup();
EditorUtility.SetDirty(decisionNode);
}
}```
PLEASE HELP
You can't serialize dictionaries
There is also no need to caps spam, it only makes it more likely people will want to ignore you.
If you're trying to serialize a dictionary, there are many implementations out there, including https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html
Spamming down SetDirty is also the worst way to dirty an object, it will not support Undo, and you should do it at the end, when you've made your modifications
how'd you determine if a component is doing custom inspector via IMGui or UItoolkit?
I'm updating my old stuffs which were made with imgui for their custom inspectors, but now I'm planning to update my tools to allow both IMgui and UItoolkit for it's custom inspector, I just need to know how to determine if they're my old stuffs(imgui) or my new ones (uitk)
Use the UIToolkit Debugger to inspect it and see what it uses
Or use the IDE's debugger and see which methods it calls
sounds like a plan!, I'll give that shot!, thannks!
oke, thanks
finally made it to work...
the wireframe somehow misaligned 
found a very good thread on how to make Handles work in PreviewRenderutility https://forum.unity.com/threads/writing-an-editor-window-that-mimics-the-scene-view.613231/#post-5754448
General question about coding structure:
- Is it safe to make only static functions, even with GUI code, without it sacrificing much performance?
Using statics would allow me to keep scripts more clean, and reuse code more easily,
but I suspect that may not be optimal when working with IMGUI.
if those statics are just helpers, why not!
if you're in a working environment (as a team), your spv or whoever incharge in checking your code quality, would nag about it if they're unnecessary or have a tendency to bloats their internal apis
Those that run once are okay, but I wonder if that still applies if the function may be called very frequently.
Well it's not like EditorWindows are ever small 😅
What I worry about is indirection that leads to slower performance.
This tool I'm currently making is designed to be visible all the time, rather than on-demand.
so I don't want that to be a drain, and I will test, but right now I'm facing a decision before moving forward.
if it's IMGui, i don't even know where to begin on how to optimize it...
Meanwhile in UItk, tons you can do to optimize things!
... object pooling for dayyss!
Like, all of the IMGUI API?
no, just the stuff I need in the project - to reduce it to almost no member methods.
In short, if the method would normally be inside a script with properties, I would instead move them to a different class or struct
To answer your question about performance. It would make no difference. Perhaps slightly faster. But we are talking about times that wouldn't make any difference.
Now whether it is a good idea from a architecture stand point. That is another question.
Can anyone assist please?
Alright, thanks 👍
is there a way to set version defines for external packages that aren't Unity's in asmdef?
apparently one of the staff suggested to edit the asdef file string manually https://forum.unity.com/threads/how-to-programmatically-detect-if-package-x-is-installed-compilation-failing.677491/
not quite sure if this still viable nowadays
Can't you set them for any packages?
for version defines, apparently we can't.. only Unity's packages only
or proly we can if the ext packages are in Packages folder..
in my case they're in Assets folder.. proly due to that
more in-depth regarding this https://forum.unity.com/threads/asmdef-questions.651517/#post-4595680
that is so unfortunate 🥲
been working in implementing an EntityStateMachine paradigm for my library, i've had the main issue where whenever i make changes in my code while i'm in playmode i'm forced to exit and then resume playmode (i'm storing my entity states in a property, so theyre basically lost whenever i reload the domain)
is there a way i could restore the entity state machine's state on domain reload
so i dont have to restart playmode
Does this kind of issue belong in a different channel? If so which one?
Could try asking in #💻┃unity-talk maybe. That is probably a more appropriate channel for it. Or maybe #⛰️┃terrain-3d
Best of luck!
Note that domain reload and exiting playmode are not the same thing. Unity doesn't persist changes from playmode, this is by design. Doesn't even recompiling scripts in play mode really. What is the reason you are trying to do recompile in playmode?
due to the nature of the states it involves changing numbers and then seeing the new result
i feel like if i could avoid having to restart playmode it would save me time
sure, little time, but time is precious after all
I mean, (unless I am misremembering) Unity doesn't 'support' recompiling in playmode. So you can get undefined behavior.
I feel like a better option would be to instead making it so you can make the changes in editor if the changes are not actual logic changes. if it is just numbers, you should be able to expose them in a window or the inspector.
But to answer your question. You would need to serialize whatever values you want to save to a string/bytes and store them in a ScriptableSingleton.
hm, i see
Thank you, I already posted in terrain but i'm getting zero response. I'll have to try unity talk
looking at my monobehaviour i think i already tried to achieve what i wanted by using compiler clauses to try to set the machine's state to its main state, here's what i mean by it
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
sadly it did not work
altho
i'm a bit silly, i just noticed that List is static, so ofc it gets lost on domain reload

Issue was found to be with the Unity Terrain Tools package, a package uninstall and reinstall resolved the issue
Writing an editor script to bulk generate materials from some textures but I'm running into an odd issue. It says this texture is not read/writeable, but it absolutely is. I've checked in the debugger and it is definitely referring to this asset file, and that file's isReadable is false. Just to make sure, I actually set the importer's isReadable to true the line before I get it, and debugger confirms that has isReadable true.
TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath($"Assets/Textures/{matDirectory.Name}/{info.Name}");
importer.isReadable = true;
Texture2D parsedTexture = AssetDatabase.LoadAssetAtPath<Texture2D>($"Assets/Textures/{matDirectory.Name}/{info.Name}");
If I just spit out the material with this asset set as the main map, it works fine. The file exists, it looks like it should, etc., but if I try to actually GetPixels() on it to change something about it, I get this error.
Okay, I fixed it by adding a importer.SaveAndReimport();. Makes it take significantly longer but at least it works now
It is absolutely obnoxious to deal with texture imports. You were correct that any modifications to the import settings requires a reimport. And if you are generating the files directly it requires a double import -- one to get an importer, and another to modify the default import settings.
In my asset, I got around this by manually generating the meta file along with the image so it imports with the correct settings the first time, but this is probably overkill for your purposes
There's no other way around this double import afaik
Hey guys!
Lately I've been here very often and I got a lot of support from community, wich helped me to create my first tool that I want to make public (for free on asset store). This tool being a simple State Machine creator (simple for now as it is very bare-bones atm, BUT IT WORKS). Now I'm looking for people that would be kind enough to have a bit of fun with it and give me some feedback before I share it on AssetStore. Anyone intrested pls send massage on a private chat so it wont get lost here 😉
Thank you in advance and I love you guys!
Why is my prefab icon so small?
This bee looks normal but its prefab icon is really small
How do i fix that
This is hopefully one of my last questions about ReorderableList,
before I start to spend my time learning UI Elements.
- ReorderableList's header background has rounded corners.
I suspect this is from the built in GUIStyle "RL Header", and that it is a Texture2D.
But when debugging all the GUIStyleStates on the style, I find no texture.
Is it something else? Or does anyone know where to find it? or how to replicate it.
I have fetched the style in three different ways
GUIStyle style = "RL Header";
GUIStyle style = GUI.skin.GetStyle("RL Header");
GUIStyle style = GUI.skin.customStyles.ToList().Find(x => x.name.Equals("RL Header"));
but they all yield the same result.
The reason I'm asking is because I am trying to make an actual copy of the style, in order to avoid messing with the built-in styles.
It needs to be inside a folder or sub-folder which is inside a folder named Editor
Then that's your problem. The attribute should not be in an editor folder
Only the drawer should be
ah, whops 😅
is that number the actual waiting list, or is it some ID ?
I just wanna be able to spawn objects "not in game" improt textures and create materials i cant figuire out where to have editor script to sxcute them
you can't use a monobehaviour thats inside a Editor folder. move it outside of that folder to use it. alternatively you can create a custom editor window to deal with it
@supple willow it seem i need to create the custom window from the script it self is that true ?
unity is confusing to me xd why i need OOP for automation
custom editor windows a little different than monobehaviours. you assign a context menu path for them (like "Tools/My Tool") and open them from the top toolbar in Unity
the doc has a really goood starting point info for it
https://docs.unity3d.com/ScriptReference/EditorWindow.html
but if that's too much work, you can just use a monobehaviour if that's easier for you
just make sure to either
- delete the script afterwards
- put it under a Editor folder
- surround the script with
#if UNITY_EDITORand#endif
Actual waiting list. The current wait time for a new asset is 4 - 6 weeks I think.
oh. that's a lot of time...
Anyone know the best way to stop my sprite preview from being blurry?
I know the image has to be to the power of 2, but is that the image preview or the image itself? It's fine when I use it in game.
public class examplewindow : EditorWindow {
[MenuItem("wellanything/Example")]
public static void ShowWindow ()
{
EditorWindow.Getwindow<examplewindow>("Example");
}
void OnGUI ()
{
GUILayout.Label("this is a label" , EditorStyles.boldLabel);
}
}
may i ask why my code doesnt work why cant recognize Getwindow
unity 2020 btw
'EditorWindow' does not contain a definition for 'Getwindow'
i literally thought api chnaged or somthing lol
thanks
art is literal chaos and programming will punish you for any tiny mistake
appriciate your comment
So OOP can only use classed so C# doesnt accept any functional programming like if you are using python in unreal right ?
Wat
I am using Photon Pun, and I am instantiating some bullets with PhotonNetwork.Instantiate for a bulletManager singleton that is just a bullet pool of inactive bullets that spawn at the start of the game.
the bullet prefabs have PhotonView component and PhotonViewTransform, but my other clients still can't see them.
the bullet prefabs are in the resources folder, so why can't other players see them?
I meant to ask if C# is an object orinted programming only
I definitely oop focused but it has some more functional elements like linq
C# is more mutli-paradigm nowadays i think?
it does indeed have stuff like lnq
linq*
but learning OOP itself will make understanding how to use C# more simple
I suppose but you can't really do pure functional, it's more oop with some other elements included
Hi, I made this piece of code for mass renaming objects in the hierarchy.
The issue is that if I close the popup window using the X button it doesn't open up again because IsOpened(bool) was never set to false.
I couldn't find an event that would get invoked on window closing so I am not really sure how to implement this:
https://gdl.space/himimufike.cs
Hi! Thought I would try my question in a more specific channel.
Is there a way to create a duplicate of a built in GUIStyle with a different name?
I found a bug in one of the core Unity internal classes for Input System where they misspelled a text reference (2022.3.2f1 and 1.6.1). It has made the panel unusable to configure input actions. I was thinking I might be able to create my own class that generates the correct GUIStyle with the wrong text name.
This is the bad code:
public static readonly GUIStyle toolbarSearchField = "ToolbarSeachTextField";
The "r" is missing in "Search". So I wanted to see if there was a way to create class that would generate a GUIStyle based on "ToolbarSearchTextField" but call it "ToolbarSeachTextField" so the panel wouldn't throw this error:
Unable to find style 'ToolbarSeachTextField' in skin 'DarkSkin' Used
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Is that possible? Or am I stuck waiting for a bug fix from Unity?
Just void OnDestory() in the editor window 🙂
https://docs.unity3d.com/ScriptReference/EditorWindow.OnDestroy.html
let me give that a try, thanks!
that worked, thank you so much!
So this was a fun bit of digging around. I think it would be possible, but would be more involved. So looks like you would need to create the style and add it to the GUISkin.current.customStyles array (get array, resize, add new style, reassign to the property)
Though it might not work, I am not 100% sure it sets the customStyles. It might just overwrite the array.
I have another question, this tool is mainly used when editing multiple objects and I noticed that it opens a new dialog for each object(executes the function that you selected) which is the reason I have the IsOpened bool in the first place.
Is there a way to execute the function only once no matter the count of selected objects or do you just have to live with workarounds?
Gotta do the workaround. Storing a reference to the window might work nicer instead of the bool. Another option would be if (Resources.FindAllObjectsOfType<MultiObjectRename>().Length > 0) return;
When you do GetWindow() Unity calls that Resources method to find if there is already an open window. So it is perfectly fine to do. But might be worse on performance, especially if you have a bunch of objects selected.
Just in case, as a note. I would recommend making sure to dirty the objects, register undo, and also use AssetDatabase.Rename if the object is an asset.
Oof... guess I'll mock an interface so i can keep working and hope for a quick fix from Unity.
You can do a PR if ya really want to. They do accept them from what I have seen. At least they did a ~year ago 🙂
those are some great tips especially the first one, gpt said that I don't have to dirt the objects but I'll do it since it's not trust worthy
Yeah, you most definitely do. That is like 101 of modifying object in editor.
(Though you don't need to dirt them if you modify them using SerializedObject and SerializedProperty as that handles it all already)
I have to say that I am not 100% sure what you meant by this.
I think I got what you meant by window, it's another approach that does not have the best performance.
What I am unsure about is using the AssetDatabase.RenameAsset().
It asks me for a path yet I don't have that because Selection.objects[i] doesn't have that property.
Thanks in advance!
I mean, when you do EditorWindow.GetWindow<MyWindow>(); to open a window. It runs this code which basically does what I described to you, finds the first EditorWindow of the type https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/EditorWindow.cs#L745
You use AssetDatabase.GetAssetPath(Selection.objects[i]); to get the path.
so, if none are running it starts a new one?
I see, if it doesn't have a path but is an object in hierarchy instead, what happens?
That is what GetWindow does, yes. I have just been talking about how Resources.FindObjectsOfTypeAll is used.
What I would do is to run two loops, one over Selection.gameObjects and rename them like how you are now. And then a second loop over Selection.assetGUIDs since those are assets. You can do AssetDatabase.GetAssetPathFromGuid() or something along those likes
How are you executing this? Why would it be opening a new window per object?
that's just how it works :/
executing it from a GameObject/NnUtils menu
what is a NnUtils menu
I don't think there is a function for getting an asset path from a Guid, which one should I use instead?
oh that's the menuItem you set up
just a subfolder I made
Might be GuidToPath
I hope this is the last question, how am I supposed to get the name from the Selection.assetGUIDs.
There are functions such as these(pic) but I am not sure if that's what I am supposed to use:
You get the asset path, then you can just do System.IO.Path.GetName(path) to get the name
Thanks a lot for helping me with this, here's the code if you'd like to take a look and give me final thoughts/recommendations:
https://gdl.space/idumudovib.cs
- The record undo should be in the Button if statement, otherwise it will be recording an undo even if you cancel. And also just because it is good code structure.
- The Asset renaming isn't doing anything right now. All you are doing is getting the asset's path, getting the file name of the path, and then setting the name to be the name it already is.
- No real reason to have
NewNamestatic since you are just resetting it anyway when the window closes. - I am surprised that this code runs, you should never use the constructor when creating an instance of a ScriptableObject, instead use
CreateInstance<MultiObjectRename>(). - And as a minor note, I recommend using the
$with the string for readability,Selection.objects[i].name = $"{NewName} {i + 1}";
Hope that helps 🙂
Thanks a lot!
In UI Toolkit is there a way to apply a gradient over text?
in a custom window I am making, I need fields for public lists just like we have in built in inspector.. is there a simple way to achieve this? I am editor scripting noob
The best way you can understand how Unity does it is actually inspecting Unity's implementation. Newer versions of Unity use UI Toolkit as the default way to draw the Editor and you can inspect their list implementation in UI Toolkit Debugger
if you don't need fancy stuffs and only the standard/default looks, you can use PropertyField and bind it to your list
also, assuming what you asked was for uitk
hi. anyone know how to set the BoxBoundsHandle to support rotation?
this is what it's doing so far
Handles.matrix = authoring.transform.localToWorldMatr
_handle.center = authoring.transform.localPosition;
_handle.size = authoring.area;
_handle.DrawHandle();
authoring.area = _handle.size;
authoring.transform.localPosition = _handle.center;
I am slightly suspicious of using local position inside of a matrix that is already making things local
^
And wouldn't the _handle store the converted position?
So you have to transform it back
same, changed that to _handle.center = Vector3.zero; but now the center of the handle stays the same
seems the results of this handle aren't updated as I'd expect
what do you mean? like set it to transform.position instead of transform.localPosition ? that's not working either
the video is
Handles.matrix = authoring.transform.localToWorldMatrix;
_handle.center = Vector3.zero; // new
_handle.size = authoring.area;
_handle.DrawHandle();
authoring.area = _handle.size;
authoring.transform.position = _handle.center; // new
let me remove some stuff to make it easier to follow
here
if (_handle == null) {
_handle = new BoxBoundsHandle();
_handle.center = Vector3.zero;
_handle.size = Vector3.one;
}
Handles.matrix = transform.localToWorldMatrix;
_handle.DrawHandle();
transform.localScale = _handle.size;
transform.localPosition = _handle.center;
red cube is not part of the system. sorry I should've hidden it
huh, funny enough, I just discovered a bug that the hide option doesn't work for SubScenes
in the LTS
I'm trying to estimate how much it is moving by
two times more than it should. let me update the code too
updated
(video of bounds changing 2 times more than they should)
Is it always 2x or does it increase more the larger it gets
I think it's 2 times
ok no it's not 2 times
Is there a way to remove things from the CreateAssetMenu? I'm working on something somewhat akin to the VRChat SDK where people can author content using unity to export as asset bundles for a different unity project. Only certain kinds of components and assets are "whitelisted", anything other than them will be stripped off of the object before being parsed, and I think it'd be better UX to just not let them add those in the first place.
Not that I know of
Dang
@supple willow
Use matrix TRS to create a rotation-only matrix using .rotation, and set the bounds handle scale to .localScale and position to .position.
You're confusing the poor thing with localToWorldMatrix
how can i fix this it doesn't let me change it it in the settings
thanks 👍! will try it tomorrow.
is there a way to force a new EditorWindow to dock in a specific way? I can get the window docked as tabs in the same window, but I'd like to have my new window docked to the right side of an existing window
ShowWindow has a parameter for that iirc
Maybe not show
GetWindow is the one
public static T GetWindow(params Type[] desiredDockNextTo);
Declaration
public static T GetWindow(string title, params Type[] desiredDockNextTo);
Declaration
public static T GetWindow(string title, bool focus, params Type[] desiredDockNextTo); ```
yes, but it docks it internally like this:
where I'm trying to make it dock like this:
Is there a way to get the mouse scroll delta within the EditorWindow class? Trying to use Event.current with no success
// draw your window
handleInput(GUILayoutUtility.GetLastRect());
}
void handleInput(Rect rect) {
Event e = Event.current;
if (rect.Contains(e.mousePosition)) {
switch (e.type) {
case EventType.ScrollWheel: {
Debug.Log(e.delta);
break;
}
// Other mouse input cases
}
}
}```
is how I handle mine
I updated the code using your recommendations, I have a few more questions tho:
https://gdl.space/owehiyuqol.cs
- That makes perfect sense, I was really tired when writing this and made a lot of mistakes so thanks for pointing it out.
- I am positive I fixed it(no clue what my brain was trying to achieve by getting the asset's name yesterday :/).
- Great recommendation, applied it.
- It did indeed run, may I ask what the difference between using a new MOR() and CI<MOR>() is? As far as I know it should do the exact same thing(unless, as you said, it doesn't use a ctor somehow?) and also, why shouldn't you ever use ctor with a SO?
- I usually do go with the string interpolation, however, as I mention earlier I was quite tired an wasn't thinking yesterday.
Thanks again for all the help you provided, it means a lot!
Yup, but you aren't going to like the answer. Reflection
Maybe I'll just let them find out when they build
Not without using reflection.
welp, nevermind, it isn't working :/
it's renaming everything to Object Name no matter the input, let me fix that real quick, I misunderstood you saying that the new name doesn't have to be static for it not having to be global 0_o
Here's the working version:
https://gdl.space/quporiqeci.cs
Looks good besides the string value issue you just noticed.
About 4. The reason that CreateInstance is used is because it creates a C++ instance of the object as well. For whatever reason, when they originally created the system back in like 2004, they went with this approach instead of utilizing the constructor. Might have something to do with the fact that Unity used to support other scripting languages.
Anyway, it is possible that they changed something so that constructors work now. Not sure. So if you use a constructor, and it seems to be working, you might run in issues later on, not sure. As I said, I didn't think it would work at all 🤷♂️
good to know, thanks!
I am really sorry, I forgot one last thing.
Why don't I have to dirty the asset I am renaming?
Firstly, you are in objects. Secondly, because Dirty tells unity that the object changed and needs to be saved. Rename, is 'simply' moving the file and updating its name automatically (if memory serves)
Trying to sort out if there is a good way to have a Overlay that is only visible with a certain tool active
or simply modify the exsitng Tool Settings overlay with my own content while the tool is active
You use the ITransite interface on the overlay, and check what tool is active in the visible property that the interface has. That is if memory servse
Actually, it strikes me there is another way that I am forgetting about
know where the docs for this area, like i see a screenshot in a doc doing what i want
but literally can not find anything referencing how
Ooh right right. I think the [Overlay] attribute has a param for the component type, which you can pass a tool type to
yeah that never references the ITransientOverlay thing in overlays, or how the hell a custon tool was able to do this
where it modified the tool settings overlay that already exists
Oh that is a context
@gloomy chasm yeah that is not for a component, you feed it the type of window
like [Overlay(typeof(SceneView), ID, Title)]
to make one that works in the scene view
Yeah I thought it had an option param, I must be thinking of a different attribute
either way i can make the ITransientOverlay do what i need so thank you for that
the docs feel very lacking, since that is also referenced no where in the docs for overlays or tools
Okay, so what you are seeing here is a editor tool context. The "Random Rotate" and "Place Object" are two seperate tool contexts
i know that i am talking about the Tool Settings part
Tool Settings is normally what contains the pivot mode and transform space
I believe that is a custom transient overlay
This is what I did for one recently
public bool visible {
get {
return ToolManager.activeContextType == typeof(WaterToolContext) &&
ToolManager.activeToolType == typeof(WaterFlowPaintTool);
}
}
yeah more or less what i am starting to do
its weird reading a few forum posts it looks like there should be a overlay that can be reused for this, but what ever this will do
i just want to avoid doing it the old OnToolsGUI way for UI, only usine that for rendering my handles
thanks for the shoutout for 1ITransientOverlay @gloomy chasm its really not mentioned in the manual at all for it so can be a little hard to find
I found it because Gabriel (the head of the editor UX) told me about it when I was asking a related question xD
so that is great he shared that, but not great that both of us have not found it otherwise
It does look like there is Tools Options, but not sure how to add to it, or if it is meant to be used for everything or not.
yeah i have enough options i rather have a overlay and not just a few buttons in the toolbar anyways
since i need like 2 sliders, a enum and some informatinal things
Yeah, he said that in newer version it is replaced with something better. haven't looked in to what that is yet though.
isnt it new in like 2021.2
Yeah.. idk. It isn't market as obsolete either, so... maybe that fell through...
either way thinks got it working, its and not even too messy
overlay does not care that its a private class in my editor tool
Yeah... but you could also not nest your view inside of your data class
makes sense in my case, since it lets me not expose more stuff publically then i need to as far as fields
this is all purely editor tooling, the data and the functions that modify the real data live on a so
I still find it best and cleanest to separate it out. Also easier to find for editing in the future. But whatever works for you 🙂
clean is relative, since i also worry about keeping stuff that can only be used one way contained, also even with it in there its still only like 300 loc for the tool and overlay
also guessing there is no non crap way to render a mesh into the sceneView like its a handle in a tools OnSceneGUI
right now i am tapping into a render feature to accomplish this but it very much feels like overkill just for a little editor tool
Graphics.DrawMeshNow()?
Just call it during EventType.Repaint
It is what all of the handles use 🙂
That does not work in URP
Best I been able to do is make a render feature I can pass the mesh off to
Try doing this
if (e.type == EventType.Repaint)
{
var startInfo = typeof(Handles).GetMethod("StartCapDraw", BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
var matrix = startInfo.Invoke(null, new object[] {position, rotation, size}); // Vector3, Quaterion, float.
Graphics.DrawMeshNow(myMesh, matrix);
}
This will set the global matrix which Handles uses along with setting the values on the material. This snippet is literally what handles does, so there is no reason it shouldn't work.
Am I tripping or is this icon a bit cut at top and bottom?
I feel like im tripping... but osmething feels of
For the first time i checked how my tool looks when editor is set to light mode, and I am confused. Some colors are properly changed and some are not, I dont know why, cause Im using unitys build in variables in my uss files.
For example:
--unity-colors-inspector_titlebar-background is dark in dark mode and white-ish in light mode
but --unity-colors-window-background is dark no matter what...
So i just refactored my SO. And for some reason, the serializedProperty isn't updating properly.
So here I am, just spamming serializedObject.UpdateIfRequiredOrScript().

Yep, broke it. 
Did you change the field name maybe?
If that's the cause, i'd get null errors instead no?
Depends on how you are using them
Something's setting them to empty but i can't find it at all.
The moment i touched something, it just gets erased. 
Hi guys, I have an issue trying to cache a GUIStyle with a Texture2D background created on the fly
I'm trying to mimic a flat button so I've created a style with 3 states (normal, hover and active) like in the image below.
AsTexture just creates a 1x1 texture with some color.. I'm using it to create the texture on the fly and the whole thing got cached in that s_flatButtonStyle reference for reuse.
The issue is sometimes (I can't reproduce this but it happen in few different project I tried it on) those textures suddenly breaks.. and I have no idea why. I never change them in my code or even access them.. it's like they got GC somehow but s_flatButtonStyle is still intact (they're still being referenced by it).
I tried to also cache one of the textures and when I do so, that specific texture works fine! 🤔
Oh and I'm using good ol' GUILayout.Button and GUI.Button to draw a bunch of them
Alright, finally fixed one of the cases.
Wanna show the code that makes the textures too?
Sure!
I'm trying to reproduce on a new empty project
Hmm, this is just a guess. And I am only 50/50 on if this is actually how it works. But the texture might be being garbage collected...
That's what I also thought but that means maybe the reference breaks.. because the style is still there and I'm not changing that background anywhere.. I even tried to fine this text .background = anywhere in the project's files but didn't find anything related
Is GUIStyle a UnityEngine.Object? It should keep it if it is
I don't think so.. I can "null coalesce" it 🙂
Just checked, it is not you're right. That would be it then
And Texture is inherits UnityEngine.Object
Yeah that is why it is being garbage collected
Need to keep them, give them "don't unload" HideFlag, and dispose of them before domain reload
You can also do this
GUI.backgroundColor = Color.red;
if (GUIlayout.Button()) { }
GUI.backgroundColor = Color.white;
In your style you just set the texture to be Texture2D.white
Though it is a bit harder to do the hover states
This is trivial to do with UIToolkit
Yes and will also look "cheap".. I'll try to keep them then, thanks for the help!
Migrating to UIToolkit is a bit too much work right now
If it is a mere window or two, migrating to UIToolkit is justified imo. Because then you can change and iterate so much faster
I had this window that took me like 4 hours to make in IMGUI back then. It took me less than an hour to migrate to UIToolkit. And now is much more expanded than it was before.
Plus you get the awesome fluff from Transition Animations
I remember comparing between the two a while ago and there was something (can't recall now) that was a deal breaker for me.. I relied on something that wasn't implemented yet in UIToolkit
I need to do this comparison again today 🙂
For this specific project its a bit too much.. it's not just 4 windows 🙂
kinda baffling how imgui is still a popular choice here.. at least from how often people asking about it here
I'm wiling to dive just for that lol
everything is so simple in uitk
BTW from which Unity version UIToolkit is built in?
At this point, with how UIToolkit is already so forward developed and stable, it's masochism
2021.something+ I believe
we no more suffering from how bad raw immediate-mode was in Imgui
That's good!
but ive noticed UITK on 2022 is much more reliable and in comparison to 2021 there are quite a lot of changes making it hard to write something on 2021 to look and work exactly the same in 2022 :V
but cant complain, it is all great
although...
yeah, tons of new and deprecated apis in 2022.. at least for the better
Not really, IMGUI was the only way for nearly 20 years. So there is vastly more info on it, and only recently did Unity start promoting UITk more as the go to method in docs and such.
that's probably the case, yeah...
they updated tons of docs too since 2022 lts released
what is the simplest way to initialize a component on scene load? I've got a static method on an editor class that I'd like to call, but right now, the only way I know to call it is from within onEnable on the actual editor script. Any suggestions?
So do you want the component to initialize on scene load, or for a static method to run?
I want to run a static method (on a class derriving from Editor). I tried [InitializeOnLoadMethod] but it doesn't seem to work unless the object is selected
InitalizeOnLoadMethod will run the method once on domain reload (scripts recompile or entering playmode)
That makes sense. Loading the scene in the editor for the first time doesn't cause a domain reload, right?
Correct
speaking of scene loading.. I found this api the other day https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager-activeSceneChangedInEditMode.html but the 1st param resulted in null/empty all the time any clue why @gloomy chasm
In a [InitalizeOnLoad] constructor you could subscribe to this event and have it run your static method https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager-sceneOpened.html`
Is there more than one params...? Or do you just mean that the 'previous' scene is always null/empty?
hmmm, nope, no idea sorry. It is possible it is a bug I guess. Though it seems like one that would be easy to be found via automated tests. So maybe not.
This is.. not so good lol
hmm I just deatached any custom stylesheets from my editor window and simply some visual elements appear like they are in a dark theme no matter what. I checked in UITK debugger and dark bg color comes directly from unitys build in stylesheet, so nothing is interfering with it, yet is uses wrong color...
at least I assume it is wrong, cause according to unity docs those colors are defined for both themes
Are you using UXML, if so, there could be an inline style defined that you forgot about or something.
no UXML in sight, pure C#
ill check in an empty project and if it persists... another bug report ehhhh
I've got an error I can't seem to decipher or squash
I'm storing my editor window preferences as json using EditorJsonUtility.FromJsonOverwrite. The first time on a new session when my editor window is opened, I get the error "unexpected recursive transfer of a scripted class". The error doesn't occur if the window is open from a previous session, or if the window is opened for a second time, and no functionality seems to break.
I've tried waiting for various delays before loading the editor preferences, but that hasn't worked. Any suggestions or even just ways I could hide the error?
I found on forum that GraphView does not support light theme and forces all of its parent elements to use dark theme instead... this is some outrageous bs O.o
it's a thing that you can do your own, no?
yeah loading a light theme style sheet manualy is not a problem, but you know, I was so hardly convinced that I was doing something wrong that I didnt want to do it cause it would be just a workaround and not a fix. But when I know there IS NO fix i feel safe doing so XD
I asked this question before, but I'm still having some trouble with it, so I'll ask it again: Is there a way to make a custom property be able to switch between any of its child classes within the editor? The project I'm working on needs to be able to support an arbitrary mix of any of the subclasses of the base property in a single array, and the array needs to be assigned in the editor. Each of these properties are only used once, so I really don't want to have to make them into scriptableObjects if I don't have to.
I was told that using [SerializeReference] would work, but all that does is make the array entry blank. In case I wasn't being clear enough, I need there to be some sort of toggle in the editor that switches the array entry's type between the various child types.
Yeah you use SerializeReference, and then you create a custom property drawer or editor that allows you to switch the types. There are also a number of extensions on github that does it automatically
Ok. I guess I must just have missed that in my research. Thanks for the help.
Something like one of these if you want premade
https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown (recommend this one by vertx)
https://github.com/mackysoft/Unity-SerializeReferenceExtensions
Ok. Thanks for the suggestions!
Sure thing, and if you don't use them, you can at least get an idea for how to do it 🙂
Yeah.
implementing one yourself isnt too much of a struggle as well
var dropdownMenu = new GenericDropdownMenu();
var types = System.AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => typeof(FSMC_Behaviour).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface);
foreach (var type in types)
{
dropdownMenu.AddItem(type.Name, false, () => AddBehaviourOfType(type));
}
var addButton = new Button(() => dropdownMenu.DropDown(root.worldBound, root, true)) { text = "Add Behaviour" };
stateContainer.Add(addButton);
I have something like this, and then a method taking a Type parameter assings new instance of that type to your field with Activators.CreateInstance<Type>()
Btw, you can use TypeCache to get the types instead. Much more performant, and convenient 😄
im using too much generalized approach instead of more unity specific without knowing there is an alternative, thanks 😄
Sigh.
serializedObject.ApplyModifiedProperties();
Debug.Log("Before: " + trigger_tags.MultiStringValue().DisplayContent());
serializedObject.UpdateIfRequiredOrScript();
ApplyNewTriggerTags(data_SO.Trigger_tags); //There's definitely something about this one causing it.
serializedObject.UpdateIfRequiredOrScript();
Debug.Log("After: " + trigger_tags.MultiStringValue().DisplayContent());
What is it we are seeing?
For some reason, the proprty isn't being applied properly.
What is ApplyNewTriggerTags?
private void ApplyNewTriggerTags(string[] tags, bool update_weaps = true, bool update_trigs = true)
{
if (update_weaps)
{
foreach (WeaponryAdditives weap_adds in data_SO.Weapon_mechanism.Weapon_additives)
{
if (weap_adds is not ITriggerReferrable ref_adds) continue;
ref_adds.Referred_Tag = data_SO.Trigger_tags;
}
}
if (update_trigs)
{
foreach (BaseTriggerMechanics trigger_adds in data_SO.Action_mechanics)
{
trigger_adds.Trigger_tags = tags;
foreach (TriggerAdditives additives in trigger_adds.Trigger_additives)
{
if (additives is not ITriggerReferrable ref_adds) continue;
ref_adds.Referred_Tag = data_SO.Trigger_tags;
}
}
}
}
I'll just do whatever solution. 
Anyways, i managed to fix it. /
Ugly, but works.

Probably need to dirty it I think
But really, it is better to avoid mixing directly setting stuff with SerializedObject
No, I mean EditorUtility.SetDirty(..)
Isn't that Obsolete?
Oh wait nvm.
serializedObject.UpdateIfDirtyOrScript();
You mean this one?
No, I mean to call EditorUtility.SetDirty(serializedObject.target) after calling ApplyNewTriggerTags(data_SO.Trigger_tags); and before serializedObject.UpdateIfRequiredOrScript();
serializedObject.ApplyModifiedProperties();
Debug.Log("Before: " + trigger_tags.MultiStringValue().DisplayContent());
ApplyNewTriggerTags(data_SO.Trigger_tags); //There's definitely something about this one causing it.
EditorUtility.SetDirty(serializedObject.targetObject);
serializedObject.UpdateIfRequiredOrScript();
Debug.Log("After: " + trigger_tags.MultiStringValue().DisplayContent());
Like this?
Doesn't seem to work so imma revert to this one. 
serializedObject.ApplyModifiedProperties();
string[] tags = trigger_tags.MultiStringValue();
for (int i = 0; i < tags.Length; i++) data_SO.Trigger_tags[i] = tags[i];
ApplyNewTriggerTags(data_SO.Trigger_tags);
trigger_tags.MultiStringValue(tags);
Does anyone know if there's a way to identify if a game object inside a prefab asset is itself a nested prefab (or part of one)?
Right now I'm trying to find references to prefabs inside other prefabs (at edit time), so that I can replace them with new objects
(we have GUNv1 and GUNv2 objects, and I want to find all the prefabs that have GUNv1 inside them , and replace them with GUNv2)
Although, a general "find prefabs inside other prefabs" is a handy thing for other situations too.
Yeah it is possible, you are going to want to use the PrefabUtility class. Reading the docs and stuff should get you what you need.
I've been through that (should have mentioned it!) There's nothing specifically to identify if a gameobject is (or is part of) a prefab inside a prefab asset.
GetNearestPrefabInstanceRoot might do the job if the prefab has been instantiated, but it's not - I'm checking prefabs in the project, not in the scene.
orrrr, maybe that will work - it uses the word "instance" so I'm assuming it means prefabs that have been "instantiated", but maybe not?
in a custom window I am making, I need fields for public lists just like we have in built in inspector..i should be able to drag and drop multiple list elements n one go.. is there a simple way to achieve this? I am editor scripting noob and I am NOT using uitoolkit
I don't fully understand but ReorderableList?
haha, yes, it looks like this is what I need - thanks @gloomy chasm for making me re-read the docs! :p
thanks
what can prevent rect.Contains(e.mousePos)?
some nesting in layout groups?
hm maybe i should add root area
is there a functionality in reorderlist by which we can drag and drop multiple elements at once, just like unity's build in inspector
have you tried with multiselect enabled?
¿Is possible to add custom buttons here?
Hi to all, Seems like a really simple one I can’t find an answer to anywhere… [ MenuItem( "MyMenu/MyWindow" ) ] //creates a new menu tab [ MenuItem( "Assets/Create/MyAsset" ) ] //Adds to the project window's create menu [ MenuItem( "Hierarchy/Create/MyObjInTheScene" ) ] //Nope ( also creates a general menu tab, called "Hierarchy" ) I’ve also...
Thanks
Is there no way to make an EnumFlagsField work with a backing type of ulong?
am i just being trolled by unity
Unity doesn't serialize unsigned fields iirc
AFAIK the serialization support of enums is surprisingly low. I doubt it can serialize anything that is not backed by int.
What's the stuff again that updates the prefab whenever the scriptable object changes and vice versa?

Ik it exists, i just don't know the terms for it.
Hmm, I'm not sure what you are referring to. Can you explain it a bit more maybe?
@gloomy chasm Ok, i never got to explain.
I just want to update certain values from the components in the gameobject, to certain values in the scriptable object in editor mode.

Is there a way to spawn empty gameobjects during editor playmode and make it stay in scene even after i come out of playmode? i dont want to make it prefab
This is a response UnityEvent<float> that is supposed to pass a value to TestResponse(float value)
public UnityEvent<T> UnityEventTResponse;
public void OnEventRaised(T value) => UnityEventTResponse.Invoke(value);```
Right now it only prints out 0 like the function shows, but the intent is to use the invoked value.
did you subscribe to it whilw in edit-mode?
just realized this could be the wrong channel to post, but it's for an editor tool 😛
Works in editor. I'm not using add listener, as this is a designer-friendly workflow
@visual stag Yeah I missed that. First time using UnityEvents programmatically. Ty
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.EditorTools;
using UnityEngine;
[EditorTool("Grid Move Tool", typeof(GameObject))]
public class GridMoveHandle : EditorTool
{
public Texture image;
public override GUIContent toolbarIcon => new("Grid Move Tool", image); // line 14
public override void OnToolGUI(EditorWindow window)
{
if (target is not GameObject obj)
return;
Vector3 pos = obj.transform.position;
EditorGUI.BeginChangeCheck();
pos = Handles.PositionHandle(pos, Quaternion.identity);
pos.x = Mathf.Round(pos.x);
pos.y = Mathf.Round(pos.y);
pos.z = Mathf.Round(pos.z);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(obj.transform, "Grid Move");
obj.transform.position = pos;
}
}
}
```What do I need to do to line 14 to get the PositionHandle to show? When I remove line 14, it shows. When I add it, it dissapears.
It seems that when I implement toolbarIcon target is something other than a GameObject?
and even when looping through targets it can't find a GameObject:
GameObject obj; // outside of the OnToolGUI method, the rest is inside that method
if (obj == null)
foreach (Object o in targets)
if (o is GameObject)
{
obj = o as GameObject;
break;
}
// obj is null here
so... what's going on here?
Try using https://docs.unity3d.com/ScriptReference/EditorTools.IDrawSelectedHandles.html for the handles
Anyways, I doubt the behaviour you're seeing is caused by toolbarIcon
Likely some user error
When making a custom editor, how can I change the dropbox using a switch?
Like basically I already have the category dropbox there and I want the subcategory options to be relevent
category is an enum and subCategory I store as an int (So that I can use different enums)
This is what I have so far
subCategory.intValue = x
I'm not sure how I create the dropbox for enums though
With category it's easy because I just do a PropertyField but how do I create one using just a raw enum?
EditorGUILayout.EnumField
Doesn't appear to exist, is it "EnumPopup()"?
Think I've nearly got it but it doesn't let me cast to int
Okay it seems I can use Convert.ToInt32() on it 🙂 Thanks for the help Navi
So do custom editor scripts not support interfaces?
hello there!
is there a way in Unity to either display property on the inspector OR listen for a value change in the inspector? I have ScriptableObject that holds some data for my UI and I'd like to be able to change values in inspector at runtime and trigger UI update events with that. Example code I've attached will visualise the problem.
I've provided screen with code, I'd like to have the onResourceAmountChanged to be called whenever I change the value in scriptable object.
What I'd like to avoid:
- OnValidate() because some of my SO's have multple events for various values
- custom inspector, too much boilerplate for simple thing
- OdinInspector because of licensing
In short, no, not with those limitations.
Editor and runtime code is not really made to be mixed like that.
Okay, I just found for it to be ultra-convenient when developing new features. Thanks for your time! 🙂
@gloomy chasm I've found that NaughtAttributes also provide this behaviour, but are open source 🙂
https://github.com/dbrizov/NaughtyAttributes
Kind of, but doesn't include passing parameters like the resource type or the amount changed. If that works for you though great!
It will handle my case. I just need to notify other systems (like UI) that "stuff was changed" by doing onResourceAmountChanged.Invoke() when its changed through inspector. Thanks!
does anyone know how I can create a URP global settings asset via script? I know how to create the file it's just finding the correct class
am I misunderstanding this? Shouldn't I be able to override this method and return true/false when I want this tool to be available? Even when returning only false it is still available.
I want to only have this tool available when editing a prefab in isolation mode. Or at the very least, not when a prefab file is selected. But I can't seem to find a way to do that, and searching online seems fruitless as of now.
noticed the same thing, if you do figure out what is going on at me. since i also want to make a way not have the tool showup in certain cases
just found this handy dandy repo for default icons https://github.com/halak/unity-editor-icons
what a cool dude 👍
at least we now know what/where to look at 😂 ..
Kinda old. I generally use the UIToolkit or IMGUI debuggers to find icons
That's definitely the way to go, yeah 👍
also, most imgui stuffs didn't really change much in recent years, I think 🥹
I think it's just broken rn
as written in the docs it's just returning boolean and nothing else
and cant be overriden.. tbh I'm not sure why you want to override that
Made a simple interface instance injector for unity.
Might help few.
Suggestions, Feedback, Critic most welcome.
Hey, nice job! A couple of things, firstly, the folder needs to be Editor not EditorExtensions. Editor is a special folder name for Unity and is not included in builds.
Second thing is, I don't think you actually need the InterfaceHolder, or the IMonoInterface, looks to me like it should work just fine with only the attribute.
Just my thoughts, and I could be forgetting or not seeing something that makes this incorrect. Either way, nice job on it 🙂
I guess you would need the InterfaceHolder<> one for casting purposes. But the non generic one isn't needed at all.
The name doesn't matter as it's using an assembly definition
Oh I didn't see that. Still best to use the Editor name though for convention and to follow standards.
Hey thanks.
My two bits on it.
Firstly.
T Assembly is marked Editor, The residing code acts as editor code and is excluded from build. Editor Extensions is a syntax i use and am bit accustomed to it 😄
IMonoInterface is optional. Anyone can choose to replace it. I just put it there since its a pattern I use. But is totally optional.
The InterfaceHolder is to hold the serialized state for the reference assigned. Im unaware how it would work if there isnt a wrapper which is not serialized. Do shed some light
I am not sure what the IMonoInterface is adding or doing. But fair enough.
Well, the non generic InterfaceHolder is just holding a Object field. And you are having to cast it when you get it. So it is in effect no different than simply having a normal object field, and casting it normally. Not even less code to write to cast it.
Yes sure, Earlier I used to do it same way.
But this was designed to restrict the field to the types of interfaces you want to allow.
For eg. If I want to restrict to only two interfaces, i.e. IShape and ICornernedShape. I can without writing extra editor code to validate types
That was the core problem I was targeting.
Later I introduced type restriction in ObjectField in property drawer so that no other components can be assigned since every component would be either (Monobehaviour/Component/UnityObject).
It is virtual and can be overriden
public virtual bool IsAvailable()
{
return true;
}
its just the unity docs page that does not show if things are virtual or abstract
oh right... thought it was property judging by the name of it
Properties can be virtual as well. It's common for Get only ones
I know I know 😅
My monobehaviour has an array of objects of different types that all extend one abstract class.
Every type has different properties. I want each entry in the array to appear with its proper editor in the inspector. Does anyone know how do do this?
One issue that I'm encountering is that serializedObject.FindProperty returns null for the array (because it is abstract)
You need to add the [SerializeReference] attribute to the array.
You have to then either make a drawer/editor to be able to select the type. Or get something like this package by Vertx that does it for you https://github.com/vertxxyz/Vertx.SerializeReferenceDropdown
thanks!
[AttributeUsage(AttributeTargets.Field, Inherited = true)]
public class RestrictAttribute : PropertyAttribute
{
/// <summary>
/// Restricts a class field to a certain type.
/// </summary>
/// <param name="type">Type to restrict to.</param>
public RestrictAttribute(Type type)
{
type_restriction = type;
}
public readonly Type type_restriction;
public bool Restrict_exact { get; set; } = false;
}
[CustomPropertyDrawer(typeof(RestrictAttribute))]
public sealed class RestrictModifier : PropertyDrawer
{
private UnityEngine.Object cached_obj = null;
private RestrictAttribute Restrict_att => (RestrictAttribute)attribute;
private Type Restricted_type => ((RestrictAttribute)attribute).type_restriction;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
position.height = EditorGUI.GetPropertyHeight(property, label);
EditorGUI.BeginChangeCheck();
EditorGUI.ObjectField(position, property, label);
if (EditorGUI.EndChangeCheck())
{
Type obj_type = property.objectReferenceValue.GetType();
bool legitimate = true;
if (Restricted_type.IsInterface)
{
legitimate = obj_type.GetInterfaces().Contains(Restricted_type);
}
else if (Restricted_type.IsClass && !Restrict_att.Restrict_exact)
{
if (!Restrict_att.Restrict_exact) legitimate = obj_type.IsSubclassOf(Restricted_type);
else if (Restrict_att.Restrict_exact) legitimate = obj_type == Restricted_type;
}
if (legitimate) cached_obj = property.objectReferenceValue;
else property.objectReferenceValue = cached_obj;
}
}
}
Tried making restrict attribute for serialized fields.
It works for the most part except it sets the field to null when i used the wrong thing no matter what. It should just save the previous thing.
Does your IDE not tell you that some of that code cannot be reached?
Nope, why would it?
if (Restricted_type.IsClass && !Restrict_att.Restrict_exact)
{
if (!Restrict_att.Restrict_exact) legitimate = obj_type.IsSubclassOf(Restricted_type);
else if (Restrict_att.Restrict_exact) legitimate = obj_type == Restricted_type; // how do you get here
}```
(You also need to check property.objectReferenceValue isn't null before you attempt to access it)
Aight.
cached_obj will be null by default, and also iirc the PropertyDrawer is shared across all instances, and you need to override CanCacheInspectorGUI to make it not do that? But I always forget whether that's how it works so don't hold that as truth
As for me personally, i have no idea how it works.
Also, i just added Debug.Log and it works now for some reason.
I should adress this though.
[Restrict(typeof(), Restrict_exact = true)]

But && !Restrict_att.Restrict_exact) wraps around that
Is there any particular ways on how i should be using this? 
The docs doesn't seem to explain much.
Or do i literally just make it return true?
false, so it doesn't cache it. But again, I forget how it works and I'm not about to test it again 😛
:p
This would probably be way easier if you used UIToolkit as you can just make the whole thing stateful
Doesn't seem to change anything whether it's true or false.

cached_obj doesn't seem like it's cached at all.
Ok, finally found the exact video about this. The title is so off good thing i remembered it's from a tutorial about property drawers instead of serializing/forcing interfaces on object fields.
For some reason this custom editor I've written has now stopped displaying or even being made active in the inspector. Even trying to print a simple Debug.Log no longer works, let alone custom GUI. What am I doing wrong?
[DisallowMultipleComponent]
public abstract class StateController : MonoBehaviour {
[SerializeField] int State; // This is what's shown in place of any custom GUI when I do try to add some
[CustomEditor(typeof(StateController), editorForChildClasses: true, isFallback = true)]
sealed class StateControllerEditor : Editor {
StateController _stateController; // Reference to casted target object
private void OnEnable() {
_stateController = target as StateController; // Probably shouldn't be using 'as', but whatever
Debug.Log("Test"); // This doesn't work
}
public override void OnInspectorGUI() => base.OnInspectorGUI(); // Tried overriding this with custom GUI, that doesn't work either
}
}
public sealed class PlayerController : StateController { } // This is what's used in the Editor, for now
My guess would be because the editor class is nested in the StateController class possibly.
It should really be in its own file inside of a Editor folder.
This is how I normally do it, because its much quicker than jumping between the original and the editor. I normally enclose the class and the using statement within an #if UNITY_EDITOR directive, but I've left that out here for the sake of brevity. I've never had an issue with this before and moving it to its own file in an Editor folder doesn't seem to make a difference.
Hmm, a couple of things to try I guess, restart Unity if you haven't. For testing, remove sealed from both the editor and the PlayerController, also try changing the type in the editor attribute to the PlayerController. Could maybe remove isFallback as well.
Again, just giving ideas of things to try, because to me it all looks right.
I've tried restarting and removing isFallback, doesn't make a difference. Changing the type to PlayerController works, but I need this editor to affect all inherited classes if possible. I haven't tried removing sealed yet, I'll go ahead and do that when I'm not AFK again.
whats the proper way to create a temp scene in editor
not preview, just a scene, single mode, cant be saved on accident
Nevermind, I figured it out. StateController was abstract, so it wasn't serialising anything. Sorry to have bothered you.
You can't? What are you wanting to do exactly?
i want to misuse editor created scene as a work space for tooling
will see if it does what i think it does
The stage is what the prefabs use when you edit them in the scene
Nope, that is just what prefabs use
You can use it for anything
Sounds like it might be what you want?
This has more implementation info https://docs.unity3d.com/ScriptReference/SceneManagement.PreviewSceneStage.html
works, nice
simpler than expected
is there some hashset built into editor for foldout/expanded states?
SerializedProperty has an "isExpanded" property. That's usually used to save expanded states.
not using them here, no problem
GUILayout.Button with no style - works as expected
as soon as i use custom style - hover state starts lagging behind, as if there is no repaint happening only if i scroll/click
style has all textures set, so no nulls
font set/unset doesnt change anything
going to compare them in debugger
lol custom guistyle on button breaks automatic repaint in the window
i dont know why i dont know how i dont want to know
Yuup, so Unity actually treats the built in style special. Particularly noticeable with the button style as you noticed. It auto repaints on mouse move(enter/exit?) for them, but not for custom styles.
😵💫
With a custom style, it doesn't trigger a repaint on mouse move or enter/leave. Instead it just does the normal perodic repaint. That is why you see it 'agging behind'
Just need to repaint yourself
any idea on how to register when item is being dragged in a reorderable list view? listView.RegisterCallback<DragUpdatedEvent>(e => Debug.Log("dragging")); doesnt work :/ I know this event relates to an actual object being dragged, but registering it on list item doesnt work either
Hello guys! I'm trying to implement this extension into my project but I am a beginner when it comes to extensions. What am I missing here?
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ReadOnlyAttribute : PropertyAttribute
{
}
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property,
GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
public override void OnGUI(Rect position,
SerializedProperty property,
GUIContent label)
{
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
Essentially if I put a class inside here it works fine but outside of this script I cannot use the [ReadOnly] attribute
i.e this works inside the script above ^
public class Test
{
[ReadOnly] public string a;
[ReadOnly] public int b;
[ReadOnly] public Material c;
[ReadOnly] public List<int> d = new List<int>();
}``` but not outside of it
ultimately I want to be able to serialize fields but have them greyed out in the inspector
Like this
Is the ReadOnlyDrawer in an editor folder? And the ReadOnlyAttribute should not be in a editor folder.
Ahh ok, let me try that
Wait should I just drop in my ReadOnlyDrawer.cs into my install's editor folder?
No
Everything is relative to your assets folder
So in your assets folder you should create an editor folder somewhere, that's where your editor specific code (like propertydrawers) go
Oh wow that solved it lol
Thank you both. I'm curious how that works? How come just changing the location from Assets/Scripts to Assets/Editor fixes it?
Unity has a number of folder names that are special. It finds them and treats them differently. Anything in a folder called Editor is compiled in to the editor assembly and not included in a build. Things in a folder called Resources are always included in a build and can be loaded by path at runtime. There are a couple of others, but those are the main two.
Ahhhh I see, thank you!
kind of an odd quirk but glad to know about it
Yeah, everyone agrees 😛
It was a design decision from nearly 20 years ago though, so we can't be too hard on Unity about it haha
The editor folder is actually being replaced with assembly definition files
And that's the recommend use for the future, the folder will never og away though since legacy projects are a thing unfortuanteyl
Oh, you mean having a assembly definition file set to editor only?
Yeah, I guess that is true. But tbh, I do like that the Editor folder force everyone to have consistent naming haha.
IIRC the Editor folder doesn't work if you put them in packages
Really? Thinking about it, I guess I'm not sure since I always use a assembly def file when I make packages...
Would make sense I guess though
Oh wait
That's probably because packages have a asmdef in the root
And thus it counts editor as runtime
What?
You mean like a hidden one?
No, I do this, sometimes I will have a Scripts folder around the Editor and Runtime folders. But no additional Asmdef in it, since the other already have them
com.My.Package
> Editor
> Asmdef
> Runtime
> Asmdef
Yeah
I have something like this in my code
foreach (var prop in behaviour.GetChildren())
{
var p = new PropertyField(prop);
foldout.Add(p);
p.BindProperty(prop);
}
where GetChildren() is a simple extension method
public static IEnumerable<SerializedProperty> GetChildren(this SerializedProperty property)
{
var nextElement = property.Copy();
bool hasNextElement = nextElement.NextVisible(false);
if (!hasNextElement)
{
nextElement = null;
}
property.NextVisible(true);
while (true)
{
if ((SerializedProperty.EqualContents(property, nextElement)))
{
yield break;
}
yield return property;
bool hasNext = property.NextVisible(false);
if (!hasNext)
{
break;
}
}
}
Problem occurse when prop refers to a collection, adding or removing items from it doesnt update the inspector, it needs to be reopen to see change in size of a collection. What am I doing wrong here?
uh I think I get it... collections are serialized as a series of properties on the same level (parent-children wise) so elements are not any kind of children of collection property, and collection property itself only indicates that X consecutives properties are part of the collection, and I dont iterate through them at all
Althogh still dont know what to do with it :/
no w8... whole collection is returned as a single serialized property... idk what im doing
actually it doesnt update even in debug screen, so its not like my inspecotrs implementations fault
it is pretty far nested, could it be the issue?
Actually its more like any list inside SomeClass which is stored as [SerializeReference]List<SomeClass> is not updating
It is possible it is a SerializeReference bug. I would try recreating in the simplest way possible and see if it still does it
Is it possible to get a PrefabStage from a game object reference?
quick doc search would have done you well
That's a static method I'm pretty sure
oh whoops
my bad!
haha
Perfect, thanks.
👍
yeah Ive tryed and sometimes im able to recreate it and sometimes not, and still cant find a common factor on when exactly it happens...
Can I create a material variant with code? I don't see some way in the docs
Is there an equivalant to how you can do prefab variants using PrefabUtility.SaveAsPrefabAsset(objSource, variantAssetPath); ?
U mean variant as a derivitive of original material or simply a copy of one? If its the latter you can simply pass existing material into a constructor to get exact replica. If you want a variant in the same meaning what a prefab varint is, then I didnt even know such thing exists tbh XD
You just set the parent on the material. Unlike prefabs. Material variants exist at runtime
Oooh, yes I think this is it!
Yes it worked. Thank you.
any way to keep drag running when cursor leaves window? i know it DragExits when it loses focus, i wonder if there is some easy way to prevent it
Do you mean drag data outside of a window (like dragging a prefab from the project to hierarchy window), if so you use DragAndDrop. If you mean like dragging a field, then you simply need to Use() the event.
just keep the drag running, its slider in window if dragged outside it interrupts it, i figured to use MouseUp after drag start, but it breaks when over other window i assume because onGui is not running, ill try through editor update callback
No, it works fine. You just need to Event.current.Use()
at which point? already have it in MouseDrag
Uhh... MouseDown, maybe dragstart.... let me look real quick
So, looks like this is what Unity does.
MouseDown
- Set GUIUtility.hotControl to id
- Use()
MouseUp - Set GUIUtility.hotControl to 0
- Use()
MouseDrag - Check if GUIUtility.hotControl is id.
- Use()
ID is gotten from GUIUtility.GetContrlID(..)
This is from reading the source code of GUI.Slider(..)
ill test if gui slider has the same issue, then check its source
It doesn't, unless I have misunderstood what you saying
thank you
What would an approach be to add a custom field or element to an object's header? Tried looking for some utility for it, but most searches about "headers" default to the component headers and its attribute. Basically wanting to add a label to it if a certain component exists on itself.
There is a static event Editor.headerGui (or something like that)
That is mostly used for PropertyDrawers. It tells Unity to treat the section within the rect as a single property. This is relevant for things like prefab overrides. Normally like if you want to have two fields on the same line (like a min and max field for example), you the change to one of them will mark the whole line as overridden. Not sure if that makes sense to you.
Ok this seems to be exactly what I want, sick 
Yeah, it is pretty nice!
Can I allow drag'n'drop conversion in custom property drawer / editor?
Say I want to keep List<Tuple<MyScriptableObject,int>>, e.g. keeping track of number of items which are scriptable objects.
As tuple ain't serializable, I simply create
[System.Serializable]
public class MyTuple
{
public MyScriptableObject Object;
public int Count;
}
and use that instead. I also made a simple propertydrawer that puts them side to side, e.g.:
[CustomPropertyDrawer(typeof(MyTuple))]
public class MyTuplePropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var leftRect = new Rect(...);
EditorGUI.PropertyField(leftRect, property.FindPropertyRelative(nameof(MyTuple.Object)));
var rightRect = new Rect(...);
EditorGUI.PropertyField(rightRect, property.FindPropertyRelative(nameof(MyTuple.Count)));
}
}
However... now I lost the ability to drag and drop items in bulk. Before when I used simple list, I could bulk select items and drag and drop them inside. Is there a way to enable it now also? As is it naturally doesn't work, as they're not the same time. I wondered about defining an implicit conversion operator, but that doesn't fix it. Is there some kind of even i can leverage or anything of the sort?
