#↕️┃editor-extensions

1 messages · Page 14 of 1

glad cliff
#

yeah so it seems like a faster solution if object itself is quite big

#

to remember atomic changes rather than whole state

gloomy chasm
#

Uhh, might be faster to undo/redo, but slower to record. But that is just a guess

glad cliff
#

for sure, but atm im only worried about operation itself, not recording, couse it feels sloooooow

gloomy chasm
#

Again, if you can I would definitely look in to using SerializedObject instead

glad cliff
#

im not sure if it will work, Ive had some issues with treating it that way because of a lot of SerializedReferences for polymorphism

gloomy chasm
#

It works fine with SerializedReference if memory serves

crude relic
#

@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

glad cliff
tepid pine
#

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?

gloomy chasm
tepid pine
#

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

gloomy chasm
tepid pine
gloomy chasm
#

(The more I am thinking about it, it feels like it isn't the case. Idk, something just feels off)

tepid pine
gloomy chasm
#

Guess it is the case. Only way around it then is to create your own base/fallback Editor and manually implement the drawing

tepid pine
#

Do you mean a fairly general one or a specific one for each case similar to this one?

gloomy chasm
#

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.

tepid pine
gloomy chasm
#

There is stuff on the forums too, but I can't find them atm

tepid pine
#

Thank

glad cliff
#

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; }
peak bloom
#

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

glad cliff
#
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

glad cliff
peak bloom
#

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

glad cliff
#

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

peak bloom
#

have you tried try-catching it?

glad cliff
#

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

peak bloom
#

try-catch and throw like a normal person? 😃

glad cliff
#

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

peak bloom
#

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

glad cliff
#

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

peak bloom
#

there's editor log so you can peek that instead

glad cliff
#

while its frozen?

#

or after killing the task?

#

seems smelly

whole steppe
#

hi

glad cliff
#

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?

wheat notch
#

Experimenting with property drawers is...... tedious.
People deal with this? UnityChanOops

tight pine
#

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.... facepalm

wheat notch
#

it came a bit short. UnityChanOops

#

Wait a second, it's clipping through. UnityChanOops

wheat notch
#

Ok, i'm goddamn glad i managed to make it look right.

supple willow
#

specially when some label wraps at the end of the rect's width

hardy apex
#

how might I approach an editor script running whenever a specific project scene is opened?

peak bloom
#

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..

gloomy chasm
unreal light
#

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

wheat notch
grave hingeBOT
#
Posting 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.

unreal light
#

i totally got trolled right there

#

give me a sec

#

bloody thing is a lot bigger now

visual stag
#

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

unreal light
#

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

visual stag
unreal light
#

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

unreal light
#

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)

visual stag
#

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

unreal light
#

i'll try this out

#

give me a second

visual stag
# unreal light i'll try this out

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);

unreal light
#

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 yaybow

#

i'm honestly surprised thats not documented anywhere

visual stag
unreal light
#

nice

#

still, tyvm

visual stag
#

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.

visual stag
#

Has neat dropdowns for getting binding paths from objects

unreal light
#

Oh Christ that's amazing

gloomy chasm
peak bloom
gloomy chasm
#

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!

glad cliff
#

Do SerializeReference prevents itself from serializing self referencing loop?

#

Or making such would theoretically break the editor?

#

ASKING FOR A FRIEND

peak bloom
#

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..

glad cliff
#

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

gloomy chasm
gloomy chasm
peak bloom
#

must be Rebuild

gloomy chasm
# glad cliff Sooo from what I tested SerializeField doesn't, but after 10 levels of depth whi...

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.

gloomy chasm
peak bloom
#

I'm not dealing with the project I mentioned the other day anymore, it was done already 🫡

supple willow
#

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

gloomy chasm
supple willow
#

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 ...

gloomy chasm
#

Yeah, but then you are not serializing it with SerialieReference.
But that is a good thing to note that it does not apply recursivly.

glad cliff
#

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

gloomy chasm
glad cliff
#

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;
}
gloomy chasm
glad cliff
#

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...

gloomy chasm
# glad cliff or to better put it into context it is ```cs [Serializable] public class State{ ...

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());
  }
}
glad cliff
#

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

glad cliff
gloomy chasm
glad cliff
#

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

gloomy chasm
glad cliff
#

yeap and now it works just fine.... ehhh so I rly dont know what is going on with my original problem

gloomy chasm
glad cliff
#

whole structure is layed out right there, seems he same for me :/

glad cliff
#

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

gloomy chasm
glad cliff
#

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

gloomy chasm
#

Ahh

gloomy chasm
glad cliff
#

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

karmic ginkgo
#

is there a way to skip total reimport when adding a post processor?

gloomy chasm
karmic ginkgo
#

annoying, team has to suffer reimports

short tiger
grim iron
#

Photon Pun 2 vs Mirror
Pros and cons?

gloomy chasm
wheat notch
#

Wondering if there's an a EditorGUI.Popup but works like flags? UnityChanThink

glad cliff
#

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

peak bloom
#

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

waxen sandal
#

@gloomy chasm you did somethings with that right

wheat notch
# glad cliff wdym?

Something like enums with flags attribute pretty much. UnityChanThink
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). UnityChanThink

glad cliff
#

oh I get it. You need a mask field for that, not a Popup

glad cliff
wheat notch
#

The name's somewhat misleading. UnityChanThink

glad cliff
wheat notch
#

Ok then.UnityChanOkay

gloomy chasm
gloomy chasm
glad cliff
#

funnily enough that is what im actually doing right now 😄

peak bloom
#

isn't it used for characterrigging too iirc

gloomy chasm
#

Actually, maybe the animationclip preview maybe

#

I found a video on youtube way back in like 2018 that did it.

peak bloom
#

aight, well noted, looking into it now, thanks a ton! 🫡 .. on my way creating character preview screen for Spine & Live2D with this api♥️

gloomy chasm
#

Yeah looks like I was right, It is just Handles.SetCamera

#

Along with setting the matrix

glad cliff
elder pine
glad cliff
#

@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

gloomy chasm
glad cliff
#

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

gloomy chasm
#

Hmm, try it with IMGUI instead of UITK to see if that makes a difference.

gloomy chasm
# glad cliff when self referencing loop is present in a data container, any change made to it...

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();
}
glad cliff
#

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

peak bloom
#

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

glad cliff
#

apperently uitk flips itself over with SerializeReference when self referencing loop appears

peak bloom
#

want to test something? try replace all your binding properties with registerCallbacks

glad cliff
#

seems like something worth testing right!

gloomy chasm
peak bloom
#

@gloomy chasm while you're here 😂 ... can we use ExposedReference<T> to keep references of scene objects in our scriptable assets?

gloomy chasm
peak bloom
#

oh! nice!.. I saw this used everywhere in Playables.. oh this is super nice

gloomy chasm
#

If memory servses, you need to have a component that actually keeps the references so they can be resolved though.

peak bloom
#

will test it out tomorrow 🫡

glad cliff
peak bloom
#

yeah, binding properties in uitk can be a bit iffy especially in older versions

glad cliff
#
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

gloomy chasm
glad cliff
#

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

peak bloom
gloomy chasm
glad cliff
gloomy chasm
peak bloom
glad cliff
#

definitelly it is not a superior solution, but for now the only one (except IMGUI container but... come on)

gloomy chasm
#

If you can, I would try out 2022.3LTS

glad cliff
#

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

analog laurel
#

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

analog laurel
#
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

gloomy chasm
analog laurel
# gloomy chasm 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;```
gloomy chasm
analog laurel
#

propertyfield:

#

vs

gloomy chasm
analog laurel
#

this is in an editor window, I dunno if that makes a difference but it's not in the inspector

gloomy chasm
#

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.

analog laurel
#

ah well either way ended up with a solution thanks 🙂

glad cliff
#

@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

glad cliff
#

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

gloomy chasm
glad cliff
#

SetEnable(false) lets the event pass through element now, that makes it actually easier as it wasnt working in previous version

peak bloom
unreal light
#

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

gloomy chasm
hollow bluff
#

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.

gloomy chasm
hollow bluff
hard pine
#

Does anyone know if UnityEngine RangeAttribute work with odin?

#

Ah just found the example attribute windows. It does support it

hidden glade
#

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

floral ridge
#

hey, is there any way to select an object by clicking on its gizmo?

wheat notch
#

How to get the string array value of a serializedProperty? I swear i found one but i can't find it in docs. UnityChanThink

wheat notch
tawdry kraken
wheat notch
#

Damn, i think i'm high cause i thought i saw one on docs. UnityChanPanicWork

#

Cause i'm rereading it. UnityChanPanicWork

#

And i ain't seeing it. UnityChanPanicWork

wheat notch
tawdry kraken
#

are you on 2021 or 2022? @wheat notch

visual stag
#

boxedValue exists on new versions of Unity though I'm not sure what the restrictions are

wheat notch
visual stag
#

Otherwise you just need to go through the properties, and I have a how-to pinned

wheat notch
#

Docs says it doesn't work with array and lists too.

wheat notch
visual stag
#

In the pinned messages.

tawdry kraken
#

write a helper method once, and then never again ✊

visual stag
#

No idea how Odin works but default Unity has a property you set to true in the attribute

tawdry kraken
lime arrow
#

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?

visual stag
#

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

lime arrow
#

thanks will have a look

visual stag
#

Hopefully they were introduced through my already written drawer 😄

waxen sandal
#

Somehow went over my head that you replied to the same person 😛

wheat notch
#
                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? UnityChanThink
Even if yes, i don't have to worry about it right?

gloomy chasm
wheat notch
#

Ah.

wheat notch
gloomy chasm
#

The reason the foreach doesn't is because it uses .NextVisible(..) and not .Next(..) when iterating

wheat notch
#

Aight. UnityChanOkay

wheat notch
#

How to do a bold text with editorgui.label real quick? UnityChanThink

tawdry kraken
wheat notch
#

Nope.

#

Actually.

visual stag
#

Just pass EditorStyles.boldLabel as the GUIStyle

tawdry kraken
#

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.

wheat notch
crude relic
#

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 😄

tawdry kraken
crude relic
#

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

tawdry kraken
#

well it wouldn't be the first time my brainmatter was rearranged

#

let me try this out

#

Looks good 👍

tawdry kraken
crude relic
#

👍

gloomy chasm
#

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

tawdry kraken
gloomy chasm
waxen sandal
#

iirc there's some contexts where if you create a style it throw an error

#

But they should be super rare

#

And easily avoided

storm quail
#

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.

gloomy chasm
wraith token
#

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);
glad cliff
#

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?

glad cliff
wraith token
#

I'll shoot it over there, thanks ^^

tough cairn
#

any ideas where to find the code for avatar mask creation in the cs reference ?

#

or rather how to create one

peak bloom
#

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);
        }
    }
}
glad cliff
#

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

glad cliff
peak bloom
#

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

glad cliff
#

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

peak bloom
glad cliff
#

at least it doesnt include my custom edges, yet custom nodes with no problem (custom i mean derrivitives of those classes)

peak bloom
peak bloom
#

how did you filter those edges in your serialize callback?

glad cliff
#

i have clearly selected 2 nodes and 4 edges, yet elements contain only 2 elements (those being nodes)

peak bloom
#

get the edges from the ports then 🫡

glad cliff
#

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

peak bloom
#

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 🫡

glad cliff
#

couse I dont want to serialize an edge if it isnt selected

peak bloom
#

you can simply manually add them via addToSelection iirc

#

and it willl be serialized

glad cliff
#

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

burnt dove
#

¿How can I know if I'm in the scene view is showing a prefab editing rather than an scene?

glad cliff
#

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

pale galleon
barren moat
unborn ibex
#

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

storm quail
peak bloom
#

PreviewRenderUtility apparently not too happy being wrapped in IMGUIcontainer kekwait

haughty bluff
#

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

visual stag
#

There is also no need to caps spam, it only makes it more likely people will want to ignore you.

#

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

peak bloom
#

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)

visual stag
#

Or use the IDE's debugger and see which methods it calls

peak bloom
#

sounds like a plan!, I'll give that shot!, thannks!

haughty bluff
peak bloom
#

the wireframe somehow misaligned kekwait

tawdry kraken
#

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.

peak bloom
#

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

tawdry kraken
#

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.

peak bloom
#

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! UnityChanThumbsUp... object pooling for dayyss!

tawdry kraken
haughty bluff
#

: )

tawdry kraken
gloomy chasm
peak bloom
#

is there a way to set version defines for external packages that aren't Unity's in asmdef?

#

not quite sure if this still viable nowadays

waxen sandal
#

Can't you set them for any packages?

peak bloom
#

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

peak bloom
#

that is so unfortunate 🥲

unreal light
#

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

unborn ibex
gloomy chasm
gloomy chasm
unreal light
#

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

gloomy chasm
#

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.

unreal light
#

hm, i see

unborn ibex
unreal light
#

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

https://hastebin.com/share/sopiderupu.csharp

#

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

unborn ibex
simple bloom
#

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.

simple bloom
#

Okay, I fixed it by adding a importer.SaveAndReimport();. Makes it take significantly longer but at least it works now

crude relic
# simple bloom Okay, I fixed it by adding a `importer.SaveAndReimport();`. Makes it take _signi...

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

glad cliff
#

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!

lapis summit
#

Why is my prefab icon so small?

#

This bee looks normal but its prefab icon is really small

#

How do i fix that

tawdry kraken
#

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

visual stag
#

Then that's your problem. The attribute should not be in an editor folder

#

Only the drawer should be

tawdry kraken
#

ah, whops 😅

supple willow
#

is that number the actual waiting list, or is it some ID ?

gray tangle
#

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

supple willow
gray tangle
#

@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

supple willow
#

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_EDITOR and #endif
gloomy chasm
weary sage
#

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.

gray tangle
#

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'

waxen sandal
#

GetWindow

#

Capitalization matters in programming

gray tangle
#

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 ?

waxen sandal
#

Wat

royal fjord
#

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?

gray tangle
#

I meant to ask if C# is an object orinted programming only

waxen sandal
#

I definitely oop focused but it has some more functional elements like linq

unreal light
#

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

waxen sandal
full cedar
#

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

solid saffron
#

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?

gloomy chasm
full cedar
#

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?

gloomy chasm
#

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.

solid saffron
gloomy chasm
full cedar
gloomy chasm
#

(Though you don't need to dirt them if you modify them using SerializedObject and SerializedProperty as that handles it all already)

full cedar
full cedar
gloomy chasm
gloomy chasm
full cedar
full cedar
gloomy chasm
gloomy chasm
crude relic
full cedar
#

executing it from a GameObject/NnUtils menu

crude relic
#

what is a NnUtils menu

full cedar
crude relic
#

oh that's the menuItem you set up

full cedar
full cedar
#

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:

gloomy chasm
full cedar
#

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

gloomy chasm
# full cedar Thanks a lot for helping me with this, here's the code if you'd like to take a l...
  • 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 NewName static 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 🙂

alpine bolt
#

In UI Toolkit is there a way to apply a gradient over text?

brazen tiger
#

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

alpine bolt
peak bloom
#

also, assuming what you asked was for uitk

supple willow
#

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;
visual stag
waxen sandal
#

^

#

And wouldn't the _handle store the converted position?

#

So you have to transform it back

supple willow
#

seems the results of this handle aren't updated as I'd expect

supple willow
#

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;
waxen sandal
#

What's the size of that red cube?

#

Is it 1x1?

supple willow
#

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

waxen sandal
#

I'm trying to estimate how much it is moving by

supple willow
supple willow
#

(video of bounds changing 2 times more than they should)

waxen sandal
#

Is it always 2x or does it increase more the larger it gets

supple willow
#

I think it's 2 times

supple willow
#

ok no it's not 2 times

simple bloom
#

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.

crude relic
#

Not that I know of

simple bloom
#

Dang

crude relic
#

@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

unique violet
#

how can i fix this it doesn't let me change it it in the settings

supple willow
analog laurel
#

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

waxen sandal
#

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); ```
analog laurel
#

yes, but it docks it internally like this:

#

where I'm trying to make it dock like this:

waxen sandal
#

Ah

#

Only with a bunch of reflection I thin

wary jacinth
#

Is there a way to get the mouse scroll delta within the EditorWindow class? Trying to use Event.current with no success

analog laurel
#
  // 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
full cedar
# gloomy chasm - The record undo should be in the Button if statement, otherwise it will be rec...

I updated the code using your recommendations, I have a few more questions tho:
https://gdl.space/owehiyuqol.cs

  1. That makes perfect sense, I was really tired when writing this and made a lot of mistakes so thanks for pointing it out.
  2. I am positive I fixed it(no clue what my brain was trying to achieve by getting the asset's name yesterday :/).
  3. Great recommendation, applied it.
  4. 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?
  5. 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!
gloomy chasm
simple bloom
full cedar
gloomy chasm
# full cedar I updated the code using your recommendations, I have a few more questions tho: ...

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 🤷‍♂️

full cedar
#

I am really sorry, I forgot one last thing.
Why don't I have to dirty the asset I am renaming?

gloomy chasm
tepid roost
#

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

gloomy chasm
#

Actually, it strikes me there is another way that I am forgetting about

tepid roost
#

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

gloomy chasm
#

Ooh right right. I think the [Overlay] attribute has a param for the component type, which you can pass a tool type to

tepid roost
#

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

gloomy chasm
#

Oh that is a context

tepid roost
#

@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

gloomy chasm
#

Yeah I thought it had an option param, I must be thinking of a different attribute

tepid roost
#

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

gloomy chasm
tepid roost
#

i know that i am talking about the Tool Settings part

#

Tool Settings is normally what contains the pivot mode and transform space

gloomy chasm
#

This is what I did for one recently

public bool visible {
  get {
     return ToolManager.activeContextType == typeof(WaterToolContext) &&
            ToolManager.activeToolType == typeof(WaterFlowPaintTool);
  }
}
tepid roost
#

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

gloomy chasm
tepid roost
#

so that is great he shared that, but not great that both of us have not found it otherwise

gloomy chasm
tepid roost
#

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

gloomy chasm
tepid roost
#

isnt it new in like 2021.2

gloomy chasm
#

Yeah.. idk. It isn't market as obsolete either, so... maybe that fell through...

tepid roost
#

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

gloomy chasm
tepid roost
#

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

gloomy chasm
#

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 🙂

tepid roost
#

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

tepid roost
#

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

gloomy chasm
#

Just call it during EventType.Repaint

#

It is what all of the handles use 🙂

tepid roost
#

That does not work in URP

#

Best I been able to do is make a render feature I can pass the mesh off to

gloomy chasm
# tepid roost That does not work in URP

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.

glad cliff
#

Am I tripping or is this icon a bit cut at top and bottom?

#

I feel like im tripping... but osmething feels of

glad cliff
#

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...

wheat notch
#

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. UnityChanPanicWork

gloomy chasm
wheat notch
#

If that's the cause, i'd get null errors instead no?

gloomy chasm
#

Depends on how you are using them

wheat notch
#

Something's setting them to empty but i can't find it at all.
The moment i touched something, it just gets erased. UnityChanPanicWork

shell beacon
#

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! 🤔

shell beacon
#

Oh and I'm using good ol' GUILayout.Button and GUI.Button to draw a bunch of them

wheat notch
gloomy chasm
shell beacon
#

I'm trying to reproduce on a new empty project

gloomy chasm
# shell beacon Sure!

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...

shell beacon
#

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

gloomy chasm
shell beacon
#

I don't think so.. I can "null coalesce" it 🙂

gloomy chasm
#

Just checked, it is not you're right. That would be it then

shell beacon
#

And Texture is inherits UnityEngine.Object

gloomy chasm
shell beacon
#

Oof.. does that mean I need to keep the textures too?

#

I'm too lazy for that 😂

gloomy chasm
#

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

shell beacon
#

Yes and will also look "cheap".. I'll try to keep them then, thanks for the help!

shell beacon
alpine bolt
#

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

shell beacon
#

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 🙂

peak bloom
#

kinda baffling how imgui is still a popular choice here.. at least from how often people asking about it here

shell beacon
#

I'm wiling to dive just for that lol

peak bloom
#

everything is so simple in uitk

shell beacon
#

BTW from which Unity version UIToolkit is built in?

alpine bolt
alpine bolt
peak bloom
#

we no more suffering from how bad raw immediate-mode was in Imgui

shell beacon
glad cliff
#

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

peak bloom
#

yeah, tons of new and deprecated apis in 2022.. at least for the better

gloomy chasm
peak bloom
#

they updated tons of docs too since 2022 lts released

hardy apex
#

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?

gloomy chasm
hardy apex
#

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

gloomy chasm
hardy apex
#

That makes sense. Loading the scene in the editor for the first time doesn't cause a domain reload, right?

gloomy chasm
#

Correct

peak bloom
gloomy chasm
gloomy chasm
peak bloom
#

yes the previous one

#

always null no matter how many times I changed it

gloomy chasm
#

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.

peak bloom
#

sad kekwait

#

the api seems pretty neat tho, compared to others while in edit mode

shell beacon
glad cliff
#

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

gloomy chasm
glad cliff
#

no UXML in sight, pure C#

#

ill check in an empty project and if it persists... another bug report ehhhh

hardy apex
#

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?

glad cliff
#

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

peak bloom
#

it's a thing that you can do your own, no?

glad cliff
#

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

hollow bluff
#

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.

gloomy chasm
hollow bluff
hollow bluff
gloomy chasm
#

Sure thing, and if you don't use them, you can at least get an idea for how to do it 🙂

glad cliff
#

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>()

gloomy chasm
glad cliff
#

im using too much generalized approach instead of more unity specific without knowing there is an alternative, thanks 😄

wheat notch
#

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());
gloomy chasm
wheat notch
#

For some reason, the proprty isn't being applied properly.

gloomy chasm
#

What is ApplyNewTriggerTags?

wheat notch
#
        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. UnityChanPanicWork

#

Anyways, i managed to fix it. /

#

Ugly, but works.

gloomy chasm
#

Probably need to dirty it I think

#

But really, it is better to avoid mixing directly setting stuff with SerializedObject

wheat notch
#

I alr tried using UpdateIfRequiredOrScript.

#

At anywhere i can think of.

gloomy chasm
#

No, I mean EditorUtility.SetDirty(..)

wheat notch
#

Isn't that Obsolete?

#

Oh wait nvm.

#

serializedObject.UpdateIfDirtyOrScript();

#

You mean this one?

gloomy chasm
#

No, I mean to call EditorUtility.SetDirty(serializedObject.target) after calling ApplyNewTriggerTags(data_SO.Trigger_tags); and before serializedObject.UpdateIfRequiredOrScript();

wheat notch
#
                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. UnityChanOkay

                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);
ocean geyser
#

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.

gloomy chasm
ocean geyser
#

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?

brazen tiger
#

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

waxen sandal
#

I don't fully understand but ReorderableList?

ocean geyser
karmic ginkgo
#

what was the api for setting cursor in editor?

#

resize etc

karmic ginkgo
#

thanks

#

what can prevent rect.Contains(e.mousePos)?

#

some nesting in layout groups?

#

hm maybe i should add root area

brazen tiger
#

is there a functionality in reorderlist by which we can drag and drop multiple elements at once, just like unity's build in inspector

supple willow
burnt dove
#

¿Is possible to add custom buttons here?

waxen sandal
#
burnt dove
#

Thanks

unreal light
#

Is there no way to make an EnumFlagsField work with a backing type of ulong?

#

am i just being trolled by unity

waxen sandal
#

Unity doesn't serialize unsigned fields iirc

burnt dove
#

AFAIK the serialization support of enums is surprisingly low. I doubt it can serialize anything that is not backed by int.

unreal light
#

well thats fun

#

thanks unity

wheat notch
#

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.

gloomy chasm
wheat notch
#

Lemme just open up my unity.

wheat notch
#

@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.

wheat notch
#

Ok eventually found a way to do it.

brazen tiger
#

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

alpine bolt
#

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.
peak bloom
#

did you subscribe to it whilw in edit-mode?

alpine bolt
#

just realized this could be the wrong channel to post, but it's for an editor tool 😛

alpine bolt
alpine bolt
#

@visual stag Yeah I missed that. First time using UnityEvents programmatically. Ty

atomic sable
#
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?

waxen sandal
#

Anyways, I doubt the behaviour you're seeing is caused by toolbarIcon

#

Likely some user error

whole steppe
#

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

waxen sandal
#

subCategory.intValue = x

whole steppe
#

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?

waxen sandal
#

EditorGUILayout.EnumField

whole steppe
#

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

whole steppe
#

So do custom editor scripts not support interfaces?

hot meadow
#

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
gloomy chasm
#

Editor and runtime code is not really made to be mixed like that.

hot meadow
#

Okay, I just found for it to be ultra-convenient when developing new features. Thanks for your time! 🙂

gloomy chasm
hot meadow
#

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!

brisk summit
#

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

atomic sable
#

https://docs.unity3d.com/2021.3/Documentation/ScriptReference/EditorTools.EditorTool.IsAvailable.html

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.

tepid roost
peak bloom
#

what a cool dude 👍

#

at least we now know what/where to look at 😂 ..

visual stag
peak bloom
peak bloom
#

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

steel cave
gloomy chasm
# steel cave Made a simple interface instance injector for unity. Might help few. Suggestions...

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.

visual stag
gloomy chasm
steel cave
# gloomy chasm Hey, nice job! A couple of things, firstly, the folder needs to be `Editor` not ...

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

gloomy chasm
steel cave
# gloomy chasm I am not sure what the IMonoInterface is adding or doing. But fair enough. Well...

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).

tepid roost
#
public virtual bool IsAvailable()
{
    return true;
}
#

its just the unity docs page that does not show if things are virtual or abstract

peak bloom
#

oh right... thought it was property judging by the name of it

tepid roost
#

Properties can be virtual as well. It's common for Get only ones

peak bloom
#

I know I know 😅

slender sleet
#

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)

gloomy chasm
wheat notch
#
    [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.

visual stag
wheat notch
#

Nope, why would it?

visual stag
#
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)

wheat notch
#

Aight.

visual stag
#

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

wheat notch
#

Also, i just added Debug.Log and it works now for some reason.

wheat notch
visual stag
#

But && !Restrict_att.Restrict_exact) wraps around that

wheat notch
#

Oh, i forgot to remove that.

wheat notch
#

The docs doesn't seem to explain much.

#

Or do i literally just make it return true?

visual stag
#

false, so it doesn't cache it. But again, I forget how it works and I'm not about to test it again 😛

wheat notch
#

:p

visual stag
#

This would probably be way easier if you used UIToolkit as you can just make the whole thing stateful

wheat notch
#

Doesn't seem to change anything whether it's true or false.

#

cached_obj doesn't seem like it's cached at all.

wheat notch
#

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.

sullen tendon
#

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
gloomy chasm
#

It should really be in its own file inside of a Editor folder.

sullen tendon
#

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.

gloomy chasm
sullen tendon
#

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.

karmic ginkgo
#

whats the proper way to create a temp scene in editor

#

not preview, just a scene, single mode, cant be saved on accident

sullen tendon
gloomy chasm
karmic ginkgo
#

will see if it does what i think it does

gloomy chasm
karmic ginkgo
#

and its only for prefabs?

#

so preview?

gloomy chasm
#

Nope, that is just what prefabs use

#

You can use it for anything

#

Sounds like it might be what you want?

karmic ginkgo
#

simpler than expected

karmic ginkgo
#

is there some hashset built into editor for foldout/expanded states?

short tiger
karmic ginkgo
#

not using them here, no problem

karmic ginkgo
#

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

gloomy chasm
karmic ginkgo
#

😵‍💫

gloomy chasm
#

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

glad cliff
#

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

waxen sandal
#

IIRC there's no easy way

#

Best to look at the source though

waxen iris
#

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

gloomy chasm
waxen iris
#

Wait should I just drop in my ReadOnlyDrawer.cs into my install's editor folder?

waxen sandal
#

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

waxen iris
#

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?

gloomy chasm
waxen iris
#

kind of an odd quirk but glad to know about it

gloomy chasm
waxen sandal
#

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

gloomy chasm
#

Yeah, I guess that is true. But tbh, I do like that the Editor folder force everyone to have consistent naming haha.

waxen sandal
#

IIRC the Editor folder doesn't work if you put them in packages

gloomy chasm
waxen sandal
#

Oh wait

#

That's probably because packages have a asmdef in the root

#

And thus it counts editor as runtime

gloomy chasm
#

You mean like a hidden one?

waxen sandal
#

Nah

#

You don't create one in the root/in the root of your scripts folder?

gloomy chasm
#

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
waxen sandal
#

Ah

#

I guess that's unity recommends nowadays

gloomy chasm
#

Yeah

glad cliff
#

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?

glad cliff
#

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

glad cliff
#

Althogh still dont know what to do with it :/

glad cliff
#

no w8... whole collection is returned as a single serialized property... idk what im doing

glad cliff
#

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?

glad cliff
#

Actually its more like any list inside SomeClass which is stored as [SerializeReference]List<SomeClass> is not updating

gloomy chasm
barren moat
#

Is it possible to get a PrefabStage from a game object reference?

crude relic
#

quick doc search would have done you well

barren moat
#

That's a static method I'm pretty sure

#

oh whoops

#

my bad!

#

haha

#

Perfect, thanks.

crude relic
#

👍

glad cliff
lone halo
#

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); ?

glad cliff
#

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

gloomy chasm
karmic ginkgo
#

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

gloomy chasm
karmic ginkgo
#

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

gloomy chasm
karmic ginkgo
gloomy chasm
gloomy chasm
#

ID is gotten from GUIUtility.GetContrlID(..)

#

This is from reading the source code of GUI.Slider(..)

karmic ginkgo
#

ill test if gui slider has the same issue, then check its source

gloomy chasm
#

It doesn't, unless I have misunderstood what you saying

karmic ginkgo
#

thank you

wheat notch
#

What does EditorGUI.BeginProperty do?

#

Seems like i can get away without using it. UnityChanThink

plucky knot
#

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.

gloomy chasm
gloomy chasm
# wheat notch What does `EditorGUI.BeginProperty` do?

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.

plucky knot
#

Ok this seems to be exactly what I want, sick nice

gloomy chasm
honest python
#

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?