#↕️┃editor-extensions

1 messages · Page 105 of 1

patent pebble
#

the examples in the PropertyDrawer documentation are rather lackluster

#

so I figured it would be more helpful to share a more specific example

shadow moss
#

Right on

#

I think I'm close

shadow moss
#

@patent pebble This produces exactly the same as having no property drawer:

public class BuildObjectPropertyDrawer : PropertyDrawer {
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
        float height = EditorGUI.GetPropertyHeight(property);

        return height;
    }

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
        Rect labelPosition =
            new Rect(position.x,
                     position.y - EditorGUIUtility.standardVerticalSpacing,
                     position.width,
                     EditorGUI.GetPropertyHeight(property, includeChildren: false));

        EditorGUI.PropertyField(labelPosition, property, label);

        float totalHeight = EditorGUIUtility.singleLineHeight;

        if (property.isExpanded) {
            foreach (SerializedProperty p in property) {
                float height = EditorGUI.GetPropertyHeight(p);

                float y = position.y + totalHeight;
                Rect r = new Rect(position.x, y, position.width, height);

                EditorGUI.PropertyField(r, p);

                totalHeight += height + EditorGUIUtility.standardVerticalSpacing;
            }
        }
    }
}
#

I haven't added the button yet

#

Very annoying that this has to be done 😦

patent pebble
#

@shadow moss does your PropertyDrawer have the [CustomPropertyDrawer] attribute?

shadow moss
#

Yes

#

I didn't paste it in the snippet, but it's in the C# file

patent pebble
#

@shadow moss have you tried using only this?

EditorGUI.PropertyField(position, property, label, true); //Draw property with children
shadow moss
#

Yes

#

But I need to replace the Action Data, not keep it

patent pebble
shadow moss
#

Sorry, I misspoke. But really, your code helped me a lot

#

I have some conditionals that I need to add, so it's more complex

patent pebble
#

just to make sure your setup is correct, does it draw the PropertyDrawer when you use the PropertyField with the includeChildren set to true?

shadow moss
#

Yes it does

patent pebble
#

alright

#

well to exclude a property you can just check for its name

#

in your case you are looping over the child properties, so just skip the one that you cant by checking the name

shadow moss
#
if (string.Equals(childProperty.name, "_actionData")) {
   ...
}
patent pebble
#

yep, you can skip it, or replace it with a button, or whatever

shadow moss
#

Thank you

shell grail
#

I am trying to get an EditorWindow menu GUILayout.Button to call a method in another script.
The GUI script is in the editor folder while the external method is in a script file in a separate asset folder.
I have these lines that resolve in Visual studio but in Unity the object type is not found.
I have not found any threads that reference this type of design.

void OnGUI()
    { 
     m_MS = GameObject.FindObjectOfType(typeof(MethodScript)) as MethodScript;

     if (GUILayout.Button("Execute an external method"))
         m_MS.ExecuteThisMethod();
     }```
#

m_MS == null

shadow moss
#

You're doing this in non-play mode

#

I may be wrong, but that could be why

#

This property drawer has been a nightmare

#

I can't believe it took nearly all day

bitter barn
shell grail
#

Noting to do with prefabs. The object I am trying to find is a script. I believe I need to make it serializable to get it onto the project database.

hushed fern
#

what's a useful editor extension i can use to show as an example for class?

#

just to show that i'm learning them

chrome mist
vestal mantle
#

Does anyone knowns how to get the CustomEditor type (or even better, the current instance) of a non Unity.Object type during runtime?

chrome mist
vestal mantle
#

Well, I know I could use reflection to get the type and create an instance, but I would like to get the one that would already exist to serialize properly

vestal mantle
chrome mist
#

technically you answered my question 😛 but lets not get pedantic

#

anyway, no there's no easy way to do that (especially since more than one Editor instance can be active)

#

my best advice is to just store a list of all active editors in a static var

#

and you can compare the "target" field

patent pebble
#

the CustomEditor type of a non Unity.Object
@vestal mantle what do you mean? Aren't custom Editors only supposed to work with types that derive from UnityEngine.Object?

#

am I missing something here?

slim zinc
patent pebble
#

aren't the target and SerializedObject properties of an Editor class only UnityEngine.Object types?

slim zinc
#

probably, but you can encapsulate your own object

patent pebble
#

you are making an Editor for your wrapper class

#

which has to be of UnityEngine.Object

vestal mantle
vestal mantle
vestal mantle
patent pebble
vestal mantle
#

I may have been looking in the wrong place due to this precision

cosmic wigeon
#

Hi there, I want to add an automatic updater for a tool I work on. So far everything is going well except the end where I clean up by removing files that should not be existing anymore after an update.
Unity just keeps crashing when I try to delete assets. Does anyone have any ideas of why that could be? I can't find anything in the log files either

hushed fern
#

How can I make a manager like the one in this picture? I already have a script and I made a list to hold all the things I want to manage. How do I create these dropdowns?

cosmic wigeon
hushed fern
#

Awesome, thanks. I’ll look into it

vestal mantle
#

Is that actually some unity editor??

restive ember
#

That's my UI but i mean to change sort by Editor but nvm figured it out by canvas

shadow moss
#

What is the method that opens up a popup with a view of assets (the circle with a dot)?

#

I'm aware of EditorUtility.OpenFilePanel

#

Found it. EditorGUIUtility.ShowObjectPicker

shadow moss
#

Are there any editor extensions that can go back and forward in the inspector?

#

As an example, if you click on an asset, then in the inspector, you click on a property. It would be nice to go back to the first asset via a keyboard shortcut (or better, a back button)

#

There was "Inspector Navigator", but it no longer exists

#

Just about every package that has this no longer exist

waxen sandal
#

We still have one in our project but it's probably 10 years old too

#

I think it's just called backbutton

onyx harness
#

NG Nav Selection

shadow moss
#

I'll look for that

onyx harness
#

It's free

#

It works with a UI button, a window, or the mouse's buttons (Windows only)

shadow moss
#

Thank you, I'm importing it now

#

Is there a way to just have the NG Nav Selection?

onyx harness
#

just keep NG Core

#

& NG Nav Selection

#

remove the rest

shadow moss
#

Thanks

mystic kayak
#

Is there any way to change a docked window’s min size? Seems locked to 100 everywhere I put it

#

Also is it possible to get the whole unity editor window size/rect so I can position popup windows at the bottom?

tough cairn
#

Trying to split a rect for a PropertyDrawer

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
    return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
    var left = new Rect( position );
    var right = new Rect( position );

    left.width = position.width * 0.33f;
    right.width = position.width * 0.66f;
    right.x = position.width * 0.33f;

    EditorGUI.PropertyField(left, property.FindPropertyRelative("hand"));
    EditorGUI.PropertyField(right, property.FindPropertyRelative("button"));
}

but this is what i get

#

ah nvm i forgot a + sign

#

right.x += 1/3 width

#

perfection

tough cairn
#

anyone else having trouble with package manager ?

#

Hub 3.x has my acc , but not the editor no matter how many times i restart it

waxen sandal
#

Nope

brave gull
#

hey all, is there a way to open a new Properties window for a specific asset?
for example, I want to add a custom inspector button that will pop open a new floating Properties window for a ScriptableObject so I can quickly edit it without losing selection of my current gameobject.

gloomy chasm
# brave gull hey all, is there a way to open a new Properties window for a specific asset? fo...

Need to use reflection. This is what I have.

public static EditorWindow OpenPropertyEditor(Object obj)
{
  if (_openPropertyWindowInfo == null)
  {
    Type propertyEditorType = typeof(EditorWindow).Assembly.GetType("UnityEditor.PropertyEditor");
    _openPropertyWindowInfo = TypeAccessor.GetMethod(propertyEditorType, "OpenPropertyEditor", typeof(Object), typeof(bool));
   }

  return (EditorWindow)_openPropertyWindowInfo.Invoke(null, new object[] { obj, true });
}
brave gull
gloomy chasm
brave gull
#

hmm, sorry but I don't really understand how to adapt this to my needs. would you mind explaining it a little?
what is "_openPropertyWindowInfo" for example?

gloomy chasm
brave gull
#

ah OK so I need static MethodInfo _openPropertyWindowInfo; declared first?

gloomy chasm
#

TypeAccessor is just a utility class I made, it would be the same as the normal propertyEditorType.GetMethod(..)

gloomy chasm
brave gull
#

OK I think I'm over my head a bit here. bit of a novice when it comes to editor windows and reflection.

#

so apologies for the many many questions.

gloomy chasm
#

All good! 😄

brave gull
#

so the TypeAccessor.GetMethod() part should actually be propertyEditorType.GetMethod() in my case?

gloomy chasm
#

It would be that, though the order of the parameters might be wrong, but your IDE should show you all of the overloads for the method

brave gull
#
using UnityEditor;
using System.Reflection;
using System;

public class EditorTools : Editor
{
    static MethodInfo _openPropertyWindowInfo;

    public static EditorWindow OpenPropertyEditor(UnityEngine.Object obj)
    {
        if (_openPropertyWindowInfo == null)
        {
            System.Type propertyEditorType = typeof(EditorWindow).Assembly.GetType("UnityEditor.PropertyEditor");
            _openPropertyWindowInfo = propertyEditorType.GetMethod(("OpenPropertyEditor", new object[] { typeof(Object), typeof(bool) }, BindingFlags.NonPublic | BindingFlags.Static));
        }

        return (EditorWindow)_openPropertyWindowInfo.Invoke(null, new object[] { obj, true });
    }
}```
#

that's what I've got now. I have a problem with typeof(Object) though: ambiguous reference between 'UnityEngine.Object' and 'object'

#

am I using the correct namespaces?

gloomy chasm
brave gull
#

oh nice, didn't know that. thanks 🙂

#

OK, so if I fix that, I get this!

gloomy chasm
gloomy chasm
brave gull
#

oops yeah, fixed that now

#

I do know how to code, honest

mystic kayak
# tough cairn EditorWindow.minSize ?

Docs explicitly state it’s not used when docked, and it doesn’t seem to be. UnityCsReference on GitHub doesn’t show anything for EditorWindow tho afaik

#

It’s weird tho because in 2021.2 I can now shrink all the default Unity windows down to nothing, which is really nice

gloomy chasm
mystic kayak
#

But not for custom editors? 🤔

#

There’s also a weird bug where the minSize specified is a little bigger when the new window is first opened, then when I dock it and undock it again, it will use the real minSize

near plover
#

I'm trying to add a MenuItem to unity. I added a script to my Editor folder that looks like this: ```using UnityEngine;
using UnityEditor;

public class ConfigSelector : MonoBehaviour
{
[MenuItem("Window/blah/config")]
static void ConfigOptions() => Debug.Log("hello");
}```

I can see the Window/blah/config menu item in my editor, but it's always disabled. Do I have to do something to allow custom menu items? I tried adding a validator, but it doesn't seem to make a difference.

#

I just restarted the editor and now it works. Shrug. Guess I don't need help afterall.

patent pebble
#

@near plover MenuItems are weird sometimes

#

sometimes they don't update until you restart Unity

#

i face that problem a lot when I'm reordering them by changing their priority parameter

near plover
#

Good to know. At least I know how to work around it, and I don't expect to update the menu item itself very often.

#

Thank you!

patent pebble
#

@near plover another workaround I use is commenting out the entire script, saving, clicking on Unity so it recompiles, uncomment the script again, and go back to Unity

#

but be careful doing that with your MonoBehaviours because you'll lose data

near plover
#

Interesting

patent pebble
#

all of my MenuItems are just in editor-only scripts, so I don't need to worry about losing data

near plover
#

Same for me, but still a good thing to remember.

regal quartz
#

is it possible to use netbeans as code editor instead of visual studio?

onyx harness
#

forget what I said, it should work without as well

hushed fern
#

can you use a loop to make multiple foldouts for a list of objects?

hushed fern
#

great. now i'm wondering, if i have an editor script to make a custom inspector for an object, is there a way to access a member variable of that object in the editor script?

#

Like if I have a manager that holds a list of objects, what is the best way to access that list in the editor script

gloomy chasm
patent pebble
#

is there a way of getting the current InspectorWindow that is drawing an instance of Editor?

#
[CustomEditor(typeof(SomeMono))]
public class SomeMonoEditor : Editor
{
    private void OnEnable()
    {
        // How do I get the InspectorWindow that is creating this Editor instance? 
    }
}
#

I'm making a tool that relies on knowing the InspectorWindow in which an Editor is being drawn in

#

I'm digging around in the source code but I haven't found anything to solve this

onyx harness
#

Yes

#

Let me find the code

#

Well shit, i dont have it

#

you can have a list of all the Inspectors, but not the currently drawing

#

The thing is, Editor is not related to a Inspector

#

It can be drawn from anywhere

hushed fern
#

because right now i just have this

gloomy chasm
hushed fern
#

so i'd want to get the list like i already did, make a for loop, and use the same process each time i iterate?

patent pebble
#

i'll keep searching to see if I can figure something out

onyx harness
#

Hum...

#

I remember I did it

#

but i forgot how

gloomy chasm
#

SerialzedObjects

onyx harness
#

Look for GUIView.current

patent pebble
#

@onyx harness there's the class ActiveEditorTracker but that only keeps track of the "main" Inspector window

gloomy chasm
patent pebble
onyx harness
#

From it check window

patent pebble
#

to check if they exist, what position they're in, etc

onyx harness
#

better to inject yourself and keep a list yourself

patent pebble
#

i had already gotten it functional, but it relied only on the "main" inspector window, doesn't support additional inspectors

onyx harness
#

I have high hope in GUIView.current.window

patent pebble
#

@onyx harness allright, I'll dig through there too and see if I can find anything useful

gloomy chasm
onyx harness
#

not last repainted, but currently being drawn

patent pebble
#

hmmmm, with my current setup I would need to know the window when the Editor is instantiated

onyx harness
#

If I'm correct

onyx harness
#

@patent pebble how did it go?

patent pebble
#

I'll let you guys know when I do

onyx harness
#

I guess GUIView didnt worked out

patent pebble
timid coyote
#

how can i save a list after the editor window is closed and then load it when its opened?

onyx harness
#

Use EditorPref

#

Or SessionState

#

Or any system to persist data

timid coyote
onyx harness
#

And what is it?

timid coyote
onyx harness
#

What is InputActionReference?

#

An Object?

timid coyote
#

a scriptable object

onyx harness
#

It gets more complex now

#

Either use a ScriptableObject to store the data, as it can easily save reference to Unity Object

#

Or you will have to implement a way to remember the "ID" of your InputActionReference

timid coyote
#

oh

onyx harness
#

If InputActionReference is an asset in the project, maybe use its GUID

#

If it is volatile, maybe use the InstanceID

#

I have absolutely no idea what is your context, so I just throw ideas

timid coyote
#

ty

snow summit
#

Im trying to open the lighting tab from a custom Editor window button. is this possible?

onyx harness
#

I guess yes

#

EditorApplication.ExecuteMenuItem("Window/Rendering/Lighting Settings");

#

This just call the menu, which obviously opens your window

patent pebble
#

InspectorWindow & Editor instance

snow summit
wispy delta
#

uuuh so i've been trying to figure out why setting the background texture for a text area's style is bugging out. it would only draw with the texture when pressing my mouse down

on a whim i moved the unity window from my 4k monitor to a 1080 one and the problem went away?!

i attached a gif showing the problem. you can see the background switch to the intended dark texture when i press my mouse down

(excuse the lack of mouse in recording, sharex won't show it on a 4k monitor for some reason)

#

I'm assuming this should be reported as a bug, but figured I'd post in here for a quick sanity check

#

pretty straightforward code

EditableMessageStyle.normal.background = 
EditableMessageStyle.hover.background =
EditableMessageStyle.active.background =
EditableMessageStyle.focused.background = background;
...
messageProperty.stringValue = EditorGUILayout.TextArea
(
  messageProperty.stringValue,
  EditableMessageStyle
);
mystic kayak
#

anyone know why a UIElements TextField's TextInput would be white? The debug inspector doesn't show anything white colors applied to it, and none of the colors I edit change that part

gloomy chasm
mystic kayak
gloomy chasm
mystic kayak
#

nope

#

it works in the editor preview if I change it

#

and the uxml and uss is being updated in the editor view because I can change the layout and flow and other colors

gloomy chasm
#

Try to change the color in the UIToolkit debugger I guess just to make sure. You also use it to see if the style sheet is even present

mystic kayak
#

stylesheet is present

#

background color changes the background color, but there's still the white box

mystic kayak
#

and the box is drawn on top of the text too

gloomy chasm
#

Sorry I'm not sure what to tell you

brazen tiger
#

How can I make such a color selector for my character script in Inspector?

brazen tiger
#

thanks.. let me check

brazen tiger
patent pebble
#

@brazen tiger here's something to get you started

#

you can see all the different sections on the left of that docs page

bitter barn
brazen tiger
patent pebble
#

either way they're gonna have to learn how to use IMGUI

#

for selecting from predefined colors you would need to use some kind of combiation of GUI.Button and EditorGUI.DrawRect or something along those lines

#

or you could draw a ColorField and intercept mouse down events to prevent it from being clicked but allow the click to go through to a button that returns the color from the ColorField

hushed fern
#

it should be able to edit more than just the name, and it should work for every character in the list of characters

onyx harness
#

When you right-click, you select the Asset

#

Or in the MenuItem you have the context provided in the argument

#

Well you don't have any selection, what path are you expecting?

#

Project window has a different selector system

#

They probably handle that internally

patent pebble
#

@stiff vine i don't think you can click the "background" of the project browser, it just selects the asset of whatever row you clicked

#

to get the asset you clicked you just use Selection.assetGUIDs or whatever it's called

#

ah wait there's an easier way

#

it gives you the GUID, from that you can get the path with AssetDatabase.PathToGUID or whatever

#

or what Mikilo said, you can just add a MenuItem to the Asset

#

@stiff vinewhat issues are you having? I've never had any problem with the default "Copy Path" menu in Unity

#

how are you able to click the empty space in the project view?

#

is this a version-specific thing in Unity?

#

for me it always select the asset in the row i click

#

if I click on the actual empty space below the "Packages" folder. I still get the right click Menu, but there asset-specific menu items are disabled

#

ooooh right the two column layout

#

i literally never used it 😅

onyx harness
#

This is what I said

#

Project has an internal selector for the folder

patent pebble
#

i would use the two column layout if it had an option to still show the assets in the main column
i hate having to click around all the folders to see what's inside them

patent pebble
bitter barn
onyx harness
#

Woah, never seen an ad big like this that you cant even close

bitter barn
#

Yea I didn't feel like creating an account or paying for Discord Nitro or a pastebin service without ads 😄 I miss the 90s where the internet was free.

patent pebble
#

@bitter barn can you share a screenshot of how your editor looks? I'm curious

bitter barn
patent pebble
#

nice

#

i have a similar implementation using IMGUI

#

brb gonna look for it

bitter barn
#

Or maybe IMGUI (although I'm a fan of the new system)

[CustomEditor(typeof(ColorSource))]
public class ColorSourceEditor_IMGUI : Editor
{
    public override void OnInspectorGUI()
    {
        Rect rect = EditorGUILayout.GetControlRect();
        rect.width = EditorGUIUtility.labelWidth;
        EditorGUI.LabelField(rect, "Color");

        rect.x = rect.xMax;
        rect.width = rect.height;

        var source = (ColorSource)target;

        for (int i = 0; i < ColorSource.Palette.Length; i++)
        {
            if (i == source.ColorIndex)
                EditorGUI.DrawRect(rect, Color.white);

            Rect swatchRect = rect;
            swatchRect.xMin += 2;
            swatchRect.xMax -= 2;
            swatchRect.yMin += 2;
            swatchRect.yMax -= 2;
            EditorGUI.DrawRect(swatchRect, ColorSource.Palette[i]);

            Event evt = Event.current;
            if (rect.Contains(evt.mousePosition) &&
                evt.type == EventType.MouseDown &&
                evt.button == 0)
            {
                serializedObject.FindProperty("colorIndex").intValue = i;
                serializedObject.ApplyModifiedProperties();
                evt.Use();
            }

            rect.x = rect.xMax;
        }
    }
}
onyx harness
#

When doing IMGUI prefer PropertyDrawer in most cases

patent pebble
#

@bitter barn here's a similar implementation I have

#

it's encapsulated in its own method so it's easier to use

#

to use it I just call

_selectedColorIndex = LayoutControls.ColorSwatch("Color", _index, _swatchColors, ref _color);
#

and I have the option to change the swatch colors on right click

patent pebble
brazen tiger
patent pebble
#

is there an easy way of getting some sort of global notification when ANY EditorWindow is closed?

onyx harness
#

I think yes

patent pebble
#

i've been looking for a while and can't find anything usable

#

hmmm... 😓

onyx harness
#

shit, i would swear there is some event somewhere

patent pebble
#

@onyx harness that one is called from EditorWindow.Close() through a call to UpdateWindowMenuListing()

#

is it possible to subscribe to reflected events?

#

i have no clue if or how I can do that 😅

onyx harness
#

yes

#

of course you can

#

good find

#

i had others

#

I think there are many indirect ways to try to know this event

patent pebble
#

on this line

DynamicMethod m = new DynamicMethod("DynamicEvent", typeof(void), arguments, typeof(ShortcutUtility));
onyx harness
#

oh

#

put whatever you want

#

shit should have change that 🙂

patent pebble
#

oh, i see

#

never used this class before so I had no clue what to do with it lol

onyx harness
#

just updated it

patent pebble
#

thanks!

onyx harness
#

yeah, it just needs a Type

#

any Type

#

Panel.AfterUpdaterChange
This might give a clue.

HostView.actualViewChanged
This one and other similar to it give a little minor hint

#

Do you need an realtime signal or delayed signal is ok?

patent pebble
onyx harness
#

Cuz you can monitor general events, windows often hook them in

#

it's pretty heavy

patent pebble
#

just to give some context

#

i'm caching IMGUI control IDs so I can check them against an editor tool

#

so i need to do frequent cleanups on the cached IDs so they don't get mixed in when Unity re-does all the controls

#

i don't know if Unity reuses the same control IDs often or not

#

i'm just adding this as a safety check, seems like the sane thing to do

onyx harness
#

well, then get a Resources.Find of all the windows every then & now, and compare, and do your clean

patent pebble
#

but I just wanted to see if it was possible to get an event on editor window closes

#

i'm trying to register to the events using the example you shared by I always get errors

#

i don't know what I'm doing wrong 😓

#
CSharpMeta.ResolveEvent("UnityEngine.UIElements.Panel.AfterUpdaterChange").Add(MyTest);
#
CSharpMeta.ResolveEvent```
onyx harness
#

Well it exists between 2019.1 & 2020.2

#

You sure you are in between?

patent pebble
#

2020.3

onyx harness
#

hehehe

#

well shit

patent pebble
#

i tried a bunch of other events, none of them work with the CSharpMeta class

onyx harness
#

Error saying something?

#

MAybe none of them exist in your version ;p

patent pebble
# onyx harness Error saying something?

this one for example

Exception: Event not found at UnityEditor.EditorWindow.s_UpdateWindowMenuListingOff with UnityEditor.EditorWindow.
CSharpMeta.ResolveEvent 

when doing this ```cs
CSharpMeta.ResolveEvent("UnityEditor.EditorWindow.s_UpdateWindowMenuListingOff").Add(Test);

#

and I know that exists for sure

#

because I can subscribe to it with this

private static FieldInfo m = AccessedType.Field("s_UpdateWindowMenuListingOff");
public static Action UpdateWindowMenuListingOff
{
    get { return (Action)m.GetValue(null); }
    set { m.SetValue(null, value); }
} 
#

but sadly that one doesn't get called consistently, it seems to only fire the first time a window is closed 😓

onyx harness
#

Strange, I will look at it tomorrow

patent pebble
onyx harness
#

s_UpdateWindowMenuListingOff is a delegate

#

AddEvent is for event

#

I need to implement delegate in their as well

patent pebble
#

ah

#

whoops

#

but it still doesn't work with UnityEngine.UIElements.Panel.AfterUpdaterChange

#

that's an actual event, right?

onyx harness
#

nope

#

a delegate as well

patent pebble
#

ah lol

#

ok, my bad! 😅

onyx harness
#

i'll do it tomorowx 🙂

patent pebble
onyx harness
#

you're welcome good sir!

#

night night

#

Check this one:
EditorWindowBackendManager.sRegisteredSystems

#

Object.OffsetOfInstanceIDInCPlusPlusObject
is quite interesting

#

It has been a while I haven't dig into the code

#

fun stuff I find

patent pebble
#

yeah I'm not very experienced with reflection and source code stuff

#

so I miss a lot of things 😅

#

trying to get better at it

onyx harness
#

dnSpy

#

& explore

#

simple as that

#

or or or

#

Get the root View

#

and collect all its children

#

might be much simpler than we think

#

Or just Resources.Find<EditorWindow> end of story

#

i'm out, cya

patent pebble
#

Or just Resources.Find<EditorWindow> end of story
right, the issue is I want to get a notification when an EditorWindo is closed
getting all the windows is not a problem

onyx harness
onyx harness
patent pebble
#

@onyx harness yep i use your NGTools stuff pretty much every day

patent pebble
onyx harness
#

yep should work well

patent pebble
#

i was trying to do it as instantly as I could

#

but it's just too much hassle

onyx harness
#

yeah I understand that

#

quite the feat

#

one day, perhaps Unity will provide us some 🙂

#

or

patent pebble
#

lol yeah
time to submit to Unity's wishes... again... 😓

onyx harness
#

What you can do

#

Check for new EditorWindow

#

(same problem)

#

but hook into UIToolkit event when it closes

#

Might work

#

I'm really out this time

#

cya!

patent pebble
#

hahaha same

#

g night!

patent pebble
#

ah i figured out why the s_UpdateWindowMenuListingOff was only working once
it's because the hooked methods get overriden in this:

internal static void UpdateWindowMenuListing()
{
     s_UpdateWindowMenuListingOff?.Invoke();
     s_UpdateWindowMenuListingOff = EditorApplication.CallDelayed(BuildWindowMenuListing);
}
#

fixed it with a delay call and resubscribing

#
public static class IDCacheCleaner
{
    [InitializeOnLoadMethod]
    private static void Initialize()
    {
        EditorWindowAccessor.UpdateWindowMenuListingOff += AnyWindowClosedOrOpened;
    }

    private static void AnyWindowClosedOrOpened()
    {
        EditorApplication.delayCall += ClearCacheIDs;
        EditorApplication.delayCall += ReSubscribe;
    }

    private static void ReSubscribe()
    {
        EditorWindowAccessor.UpdateWindowMenuListingOff += AnyWindowClosedOrOpened;
    }
}
onyx harness
#

But does it give what you want? I don't think so

patent pebble
#

which in this particular case is enough

#

it would be nice to get more detailed notifications tho

#

but at this point i'll take whatever i can get lol

#

i don't know if I have to cover more cases tho
because I don't know when Unity reconstructs internal UI data like the control IDs and such

#

so far it seems like covering any time the Selection changes and any time any EditorWindow is opened or closed seems to be enough

#

time will tell I guess 😅 if my tools break whenever something happens in the editor that triggers a rebuild of the internal UI data i'll notice

onyx harness
#

Now that you say that... I will myself too need a way to know when any window opens, to inject the tooltips system

patent pebble
#

another thing I just noticed about the delegate s_UpdateWindowMenuListingOff
it also gets raised when you enter playmode

#

in my case it's a benefit, but I can see some situations where it can become a detriment

patent pebble
#

for now this approach seems to work

#

so... if it ain't broke, don't fix it 🙃

onyx harness
patent pebble
#

that delegate gets invoked when an EditorWindow is closed, when the EditorWindow constructor is called and when a DockArea is destroyed

#

so i guess any of those 3 situations happens when entering Play Mode?

timid coyote
#

can I extract the children that were added to a parent using AssetDatabase.AddObjectToAsset?

teal timber
#

was there something like an attribute or something that let you specify which level of a game object's hierarchy you want selected when clicking on it in the editor? like for example if i have a root object with no mesh in it, with a child that contains the actual mesh - i want to select the root object when clicking on the child

teal timber
#

yeah, thanks!

teal timber
#

this happens the moment i select more than one of an object i have an editor script running on (the multiple object editing attribute is on), everything seems to be actually working fine but i have no idea to address this error since doubleclicking it doesn't take me anywhere and that info isn't very helpful

#

i'm also running odin inspector which might mess with those propertydrawers, i guess i'll just leave it be since everything seems to be working anyway

timid coyote
#

I have a strange bug, when i open the window, the name is correct, but when I add something to the list/field, it changes to the namespace name of the window editor script. Does someone know why?

molten sierra
#

Hi, I want to bind a key in Unity Editor (F12) to execute a method in one of my scriptable object, is that possible?

vapid prism
molten sierra
#

Wow thank you!!

#

I want also want to call a method every time a specific field in my scriptable object is changed, is that possible?

vapid prism
molten sierra
#

Thanks! To track it, should I create a private field in the scriptable object and store that specific field's value every time OnValidate is called? Or is there a better way to do that?

vapid prism
#

Yeah that's how I would do it

#

Leave it private, or use [NonSerialized] if it's public (since you dont really care about it during runtime)

molten sierra
#

Thanks for the answer!

molten sierra
#

I'm trying to track changes of a string variable in a scriptable object. But the OnValidate method is called every time I hit a key to edit a string variable in my scriptable object, and it reads the current editing value of that string, not the final value (when I press Enter). How do I prevent this behavior and make it read only when I press Enter?

#

For example, my string variable's current value is "Hello", I want to execute a method when I change it to "Hello World", but the OnValidate function is called every key stroke I type in, so it reads:
"Hello "
"Hello W"
"Hello Wo"
...
(I have not pressed Enter yet)

patent pebble
#

@molten sierra are you making a custom Editor for the scriptable object?

molten sierra
#

I'm not, just using a normal scriptable object.

#

Or if there is a way to make a custom editor for it, but can display all the fields without having to give custom code for everything then I will make a custom editor for it (it has about 30 fields).

patent pebble
#

i think there's an attribute to do that too for regular fields without custom Editor

#

can't remember the name

molten sierra
#

Oh nice! Thanks for the info, I will try to find it.

patent pebble
#

ah found it

#

@molten sierra put that on the fields you want to delay

molten sierra
#

Sweet thanks!

molten sierra
patent pebble
#

what you can use is PropertyDrawers

molten sierra
#

Thanks!

patent pebble
#

as far as I know you can write a PropertyDrawer for example for the type "string" and every field of type string in your project will use it

#

you can use a delayed field in that PropertyDrawer to achieve what you want

molten sierra
#

Ohh that's interesting!

patent pebble
#

i've never used a drawer for default types like that, so I don't know if there's other considerations to take into account

#

but I assume it just works the same as PropertyDrawers for custom classes

molten sierra
#

Thank you, I will look into it.

molten sierra
#

Hi, is there a way to show a dropdown list of strings which fetches its values from a local string array, using PropertyDrawer?

For example:
public string[] options = { "a", "b", "c" };
[DropdownList(options)]
public string selection; // I want this show up in inspector as a dropdown list, showing values from "options" array.

I found this PropertyDrawer, it's close but it only takes static string values, not runtime string array: https://gist.github.com/ProGM/9cb9ae1f7c8c2a4bd3873e4df14a6687#file-stringinlistdrawer-cs

Gist

A PropertyDrawer to show a popup field with a generic list of string for your Unity3d attribute - ExampleBehavior.cs

onyx harness
#

I can help, what have you done?

molten sierra
onyx harness
#

You have to give it a constant, so give it the name of the target field

molten sierra
#

But... if I only give it the name of the target field, how does it know which object to get the field from?

onyx harness
#

In the property drawer

#

you have many fields

#

You have the SerializedProperty from which you can access the Object

#

Get the object, and use the field name of extract your strings

molten sierra
teal timber
#

what would be the best way to run editor code for any new gameobjects added to the scene, either from the create menu, or dragged in as prefabs or whatever ...?

#

EditorWindow.OnHierarchyChange seems like the most promising place i can find for now except it looks like i would need to keep track of which objects are actually new in the scene manually which would be a pain and start incurring overhead when scenes grow large ...

#

MonoBehaviour.Reset is great but apparently only runs when the component is added to a gameobject, and not when the gameobject (in the form of a prefab) is added to a scene

sage oyster
#

How to either;

Go to asset in the Project window
Open the asset Properties (like right click Properties) so it opens a window

#

ok i figured step A. Preferable step B

patent pebble
#
private static Type propertyEditorType = typeof(Editor).Assembly.GetType("UnityEditor.PropertyEditor");

private static MethodInfo methodInfo = propertyEditorType.GetMethod("OpenPropertyEditor", 
                                                                            BindingFlags.Static | BindingFlags.NonPublic,
                                                                            null,
                                                                            new Type[] { typeof(Object), typeof(bool) },
                                                                            null);

public static EditorWindow OpenPropertyEditor(Object obj)
{
    return (EditorWindow)methodInfo.Invoke(null, new object[] { obj, true });
}
#

and you use it like so

PropertyEditorAccessor.OpenPropertyEditor(someComponent);
#

you can pass any component type as the parameter for OpenPropertyEditor, like a Transform, a MonoBehaviour component, etc

sage oyster
patent pebble
#

if all you want is to literally open the Properties window like Unity does by default, use the code I shared

#

@sage oyster ah it seems like they exposed that method in recent versions of the engine

#

check if EditorUtility has the OpenPropertyEditor method

#

i'm in 2020.3, which doesn't have it

#

they added it in 2021.1

smoky jasper
#

Hello, I have a gameObject with children gameObjects. I can't move the parent gameObject using the editor because when I select it, the first child is automatically selected. So I can only move the first child instead of moving the entire group. Is it normal ?

sage oyster
smoky jasper
#

In the editor, when I move an object using the snapping, is it possible to add a "delta" ? I mean, I whould like to have the snapping at (0.5, 0.5, 0) or (1.5, 1.5, 0) or (2.5, 2.5, 0) instead of entire values (0, 0, 0) (1, 1, 0) (2, 2, 0).

#

I have tried to make an editor script but the OnSceneGUI is not called after a snapping move. I would like to adjust the position by myself after the move. Is it possible ?

patent pebble
#

@smoky jasper you can change the snapping increment values in the grid options if i remember correctly

smoky jasper
patent pebble
#

Freya Holmer has an example of grid snapping tool

#

🔽 click for timestamps & info!

this was originally streamed as a course for students at http://futuregames.se/, who were super kind to let me both stream this live as well as upload it here! so massive thanks to the people at FutureGames!!

💖 Patreon ❱ https://www.patreon.com/acegikmo
🐦 Twitter ❱ https://twitter.com/FreyaHolmer
📺 Twitch ❱ http...

▶ Play video
#

at the end of this video

#

and the beginning of part 2

smoky jasper
#

from the video it' not an auto snapping function

patent pebble
smoky jasper
#

How Can I past source code here ?

patent pebble
#

it says how to share big chungs of code

#

use one of those websites

smoky jasper
#

All objects that contains a script inheriting from "Entity" should be impacted by this script

#

It works, but only if this gameObject, which have a script inheriting from "Entity", doesn't have a child gameObject

patent pebble
#

are you sure you actually have the parent object with the Entity component on it selected?

smoky jasper
#

yes, now I use the Move Tool instead of the Rect Tool, so the parent is selected

#

Well... I just remove the scrip component and readd

#

and now it works...

tropic rampart
#

I have a class, HexBoard, which handles the procedural generation of a board for my game.

#

There are several different shapes I can generate the board in. These shapes are stored in the enum GenerationType. Each enum corresponds to a function, but these do not all have the same function signature, because each shape is defined with different variables. In the given code, the two defined shapes are Hexagonal (defined by a radius) and Rectangular (defined by an x and y).

#

My desired way of controlling things is to have a window such as this one, where you may choose a Shape, and it will provide you with only the necessary fields, then a button that destroys the current board and generates a new one with the given data.

#

As shown in this image.

#

Given that each function has a different signature, how can I best define my variables? If I keep the variable scope local only to their enum processing, the fields will be erased as soon as I try to modify them

#

I currently have instead made those arguments class variables, as an array of 2 ints, and simply ignore the ints which are not relevant to that data type. This feels like a band-aid fix to me, is there a more appropriate way I can declare my IntFields?

#

This is my code. I've omitted the actual class declaration so I can cut out a tab, know that all of this is contained inside the class.

#
HexBoard board;
HexBoard.GenerationType genType;
int[] generationArgs = new int[2];

public override void OnInspectorGUI() {
  HexBoard board = (HexBoard) target;
  genType = (HexBoard.GenerationType) EditorGUILayout.EnumPopup("Generation Shape", genType);
  GenerationFunction generate = () => {};
  
  switch (genType) {
    case HexBoard.GenerationType.Hexagonal:
      generationArgs[0] = EditorGUILayout.IntField("Size", generationArgs[0]);
      // generate = () => board.GenerateHexagonalTerrain(size);
      generate = () => Debug.Log(string.Format("Pretending to generate a hexagon of size {0}", generationArgs[0]));
      break;
    case HexBoard.GenerationType.Rectangular:
      EditorGUILayout.BeginHorizontal();
      EditorGUILayout.LabelField("Size");
      generationArgs[0] = EditorGUILayout.IntField("X", generationArgs[0]);
      generationArgs[1] = EditorGUILayout.IntField("Y", generationArgs[1]);
      EditorGUILayout.EndHorizontal();
      // generate = () => board.GenerateRectangularTerrain(x, y);
      generate = () => Debug.Log(string.Format("Pretending to generate a rectangle of size {0}, {1}", generationArgs[0], generationArgs[1]));
      break;
    default:
      Debug.LogError("Unrecognized Option");
      break;
  }
      
  EditorGUILayout.Separator();
  if (GUILayout.Button("Generate Board")) {
    generate();
  }
}```
#

Also my row is borked in Rectangular mode. I'm aware of this but it's not something I'm concerned with right now, I can figure that out on my own.

delicate cargo
#

How would I go about making a "blueprint" system somewhat similar to bolt?

I want to be able to draw and drop If statements, strings and Save Variable statements.
Thanks, Please @ me if you respond to this.

gloomy chasm
# delicate cargo How would I go about making a "blueprint" system somewhat similar to bolt? I wa...

With a lot of complex code. Basically it is one of those things that if you are asking, it is probably too advanced for you atm (This isn't meant as an insult to you to be clear!).

With that said, I will give you a brief overview.
You would need to decide if you want to use code snippets, or reflection for the logic. You would also need to pick what form of serialization to use depending on what option you choose. This doesn't even touch on the editor/UI side of things, only the backend.

gloomy chasm
#

Actually I would most likely have each variable stored separately for each type just so when switching types the fields will have proper values.

tropic rampart
#

Alright, that sanity check is a huge help, then. Thanks.

gloomy chasm
#

Yeah I totally get that. Sure thing!

delicate cargo
gloomy chasm
delicate cargo
#

My goal is to try and create a framework that would allow for people to easily make branching narrative games

gloomy chasm
delicate cargo
#

Any in mind?

gloomy chasm
# delicate cargo Any in mind?

Not particularly, most (almost all) of them are node based, so maybe they would not be that applicable for you if that isn't what you are going for

delicate cargo
#

I think node based may be what I'm looking for

#

Imma search the asset store for a bti

patent pebble
gloomy chasm
visual stag
patent pebble
visual stag
#

well, it does so 🤷

patent pebble
#

my data doesn't even survive inspector rebuild

#
[Serializable]
[CustomEditor(typeof(SomeMonoForDomainReload))]
public class SomeMonoForDomainReloadEditor : Editor
{
    [SerializeField] private float _someFloatInEditor;
    [SerializeField] private string _someStringInEditor;

    private SerializedObject _editorSerObj;
    private SerializedProperty _someFloatInEditorProp;
    private SerializedProperty _someStringInEditorProp;

    private void OnEnable()
    {
        _editorSerObj = new SerializedObject(this);
        _someFloatInEditorProp = _editorSerObj.FindProperty("_someFloatInEditor");
        _someStringInEditorProp = _editorSerObj.FindProperty("_someStringInEditor");
    }

    public override void OnInspectorGUI()
    {
        _editorSerObj.Update();
        EditorGUILayout.PropertyField(_someFloatInEditorProp);
        EditorGUILayout.PropertyField(_someStringInEditorProp);
        _editorSerObj.ApplyModifiedProperties();
    }
}
visual stag
#

what is "inspector rebuild"

patent pebble
visual stag
#

Well that's not gonna work

#

The instance is serializable but its lifetime is as long as it is open

#

it doesn't persist if you select other things or close/reopen windows

patent pebble
#

ah I see

#

it does actually survive Domain Reload, whoops

visual stag
#

you shouldn't even need to do the whole ScriptableObject thing, Unity will handle that afaik

patent pebble
#

yeah i was just randomly testing

#

@visual stag they do reset when I enter play mode tho

#

Otherwise windows would reset their state whenever you entered play mode
this got me thinking they would survive entering play mode 😅

visual stag
#

I am unsure whether Editors would work across playmode because what you have selected in play mode is not the same instance as in edit-mode. Maybe it would work with fast playmode switch

#

EditorWindows is where this is relevant to me personally

patent pebble
#

ah I see I see

#

makes sense

#

i have experienced situations when I'm inspecting an Editor in a separate window and sometimes they become a different instance from the actual editor in the Inspector window

#

i can't remember what caused this, but probably play mode or something like that

#

by "Editor in a separate window" I mean popping out the Properties window or re-creating the editor with Editor.CreateEditor

tropic rampart
#
[CustomEditor(typeof(HexBoard))]
public class HexBoard_Inspector : Editor {
  HexBoard board;
  [SerializeField]
  HexBoard.GenerationType genType;
  [SerializeField]
  int hexGenSize;
  [SerializeField]
  Vector2Int rectGenSize;

  [SerializeField]
  GameObject defaultTile;

  delegate void GenerationFunction();

  void OnEnable() {
    board = (HexBoard) target;
    defaultTile = (GameObject) base.serializedObject.FindProperty("defaultTile").objectReferenceValue;
  }

  public override void OnInspectorGUI() {
    serializedObject.Update();

    defaultTile = (GameObject) EditorGUILayout.ObjectField("Default Tile", defaultTile, typeof(GameObject), false);
    EditorGUILayout.Separator();
    genType = (HexBoard.GenerationType) EditorGUILayout.EnumPopup("Generation Shape", genType);
    GenerationFunction generateBoard = () => {};
    switch (genType) {
      case HexBoard.GenerationType.Hexagonal:
        hexGenSize = EditorGUILayout.IntField("Size", hexGenSize);
        generateBoard = () => board.GenerateHexagonalTerrain(hexGenSize);
        break;
      case HexBoard.GenerationType.Rectangular:
        rectGenSize = EditorGUILayout.Vector2IntField("Size", rectGenSize);
        generateBoard = () => 
          board.GenerateRectangularTerrain(rectGenSize.x, rectGenSize.y);
        break;
      default:
        Debug.LogError("Unrecognized Option");
        break;
    }
    EditorGUILayout.Separator();
    if (GUILayout.Button("Generate Board")) {
      generateBoard();
    }

    Debug.Log(serializedObject.ApplyModifiedProperties());
  }
}```
#

Sorry if this is getting a little long

#

The key line here is the line where I set the defaultTile object

#

This is a Private, Serialized Field, which is meant to hold a reference to a GameObject

#

And sure enough, in the inspector, I have the correct field and can place a GameObject in it for instantiation

#

But whatever value I set in there gets totally erased when I switch to Play Mode

#

And even if I set it again, the reference is never actually received by the actual HexBoard GameObject

#

It has nothing to instantiate

#

I've found solutions, but they seem to rely on me making this defaultTile public, which shouldn't need to be the case given that the default inspector can handle this field just fine

#

I've been put under the impression that ApplyModifiedProperties is supposed to fix this, it never returns true and doesn't seem to do anything

visual stag
#

you cannot combine non-SerializedObject/Property functions with ApplyModifiedProperties

#

if you are not going through the SO, ApplyModifiedProperties is just going to ignore your work.
Use Undo.RecordObject if you can't use SerializedProperty modifications to do the work

tropic rampart
#

I don't understand, am I not using SerializedObject?

#

Right in OnEnable I set defaultTile = (GameObject) base.serializedObject.FindProperty("defaultTile").objectReferenceValue

visual stag
#

No, that is not doing anything with the serialized property

#

except immediately discarding it

onyx harness
patent pebble
onyx harness
#

Should work, but feel free to poke me if it doesn't

#

it's not battle tested

patent pebble
timid coyote
#

i dont understand why im getting this error for the line 155

bitter barn
#

There's nothing on line 155 and when exactly does the error happen and where does it say the line?

#

InvalidOperationException could be thrown by some SerializedObject that you're trying to iterate while not allowed. For example, when debugging and trying to expand SerializedProperty values in the debugger (at least it used to do that in the past, haven't seen the issue in a long time).

timid coyote
bitter barn
#

Does anyone have an idea how I can fix my issue with custom property drawers: I have a base drawer defined in a UPM package und a child drawer in the project's regular assembly. There base drawer has useForChildren: true, and the child drawer should override it. This normally works fine, but in my current setup it sometimes doesn't work. Meaning, on some machines, the child drawer is used, on others the base. Sometimes, when I recompile the drawer works, other times it doesn't. It feels like the order of compilation affects which of the two drawers Unity detects first and uses, although they should have a clear order. Is that some known issue or could there be anything I'm doing wrong? If I create the same setup of drawers in my main assembly, everything works fine.

waxen sandal
#

Any chance it's only broken if you start Unity with compilation errors?

bitter barn
#

no

#

but it involves generics, so maybe that's tripping Unity up (but well not always, I'm seeing it working every once in a while...)

west drum
#

Do you guys know a reason why this line could not work?

ProjectWindowUtil.CreateScriptAssetFromTemplateFile(templateLocation, "NodeTemplate.cs");

I know for a fact that "templateLocation" is correct, since I tried doing a AssetDatabase.LoadAssetAtPath(templateLocation, typeof(Object)); and it did indeed fetch the asset. So I do not understand why the Script is not being created...

bitter barn
#

What's happening instead? Where do you call this line? It should create an asset and start name editing, so it needs to happing in a call that lets you do interactive stuff, like OnGUI in the editor. Also you need to have the project window open and maybe even not locked (not sure).

#

There are a couple of things which would lock the AssetDatabase and would prevent script file creation, e.g. AssetDatabase.StartAssetEditing.

west drum
#

Yes, this is happened, after I try to give a name to a folder

#

I want to create a folder, and then a script within it

#

Let me show you a little more

#
    public class Foo : EndNameEditAction
    {
        public override void Action(int instanceId, string pathName, string resourceFile)
        {
            var folderPath = Path.GetDirectoryName(pathName);
            var folderName = Path.GetFileName(pathName);
            var folderGuid = AssetDatabase.CreateFolder(folderPath, folderName);
            var folder = AssetDatabase.LoadAssetAtPath(pathName, typeof(Object));

            ProjectWindowUtil.ShowCreatedAsset(folder);

            var location = ConversaFolderLocator.GetFolderPath();
            var templateLocation = $"{location}/Templates/NodeTemplate.cs.txt";
            
            // This is just to prove that the asset exists
            var foo = AssetDatabase.LoadAssetAtPath(templateLocation, typeof(Object));
            Debug.Log(foo);

            ProjectWindowUtil.CreateScriptAssetFromTemplateFile(templateLocation, "NodeTemplate.cs");
        }
    }
#

And what is happening instead is... nothing. The folder gets created, but it is empty

patent pebble
#

@west drum maybe you need to refresh the AssetDatabase before creating the script?

#

i've never had problems using CreateScriptAssetFromTemplateFile, but I call it from a MenuItem

#

unity gets the destination path from your current selection in the Project

#

so that may be another cause

#

make sure you select the folder you want the new script to be in

crimson yew
#

So, i need help with Universal RP for 2d lights
I want to make my character have a light in itself, but if i make it have shadows, the light desappears, since the light is inside him.
Please, help, what can i do??

image 1: shadow intensity = 0
image 2: shadow intensity = 1

crimson yew
#

oh, sorry

west drum
#

@patent pebble In the end I did myself the File.Write

patent pebble
#

@onyx harness hey i've been trying your update to the CSharpMeta class and seems to work fine, however I have a couple of questions:

    • How can I use it to hook to delegates that aren't of type Action<>, and Func<>? For example this one in EditorApplication
internal static CallbackFunction globalEventHandler;
    • How can I pass a parameter of Action, instead of Action<T>?
      I see you've created method signatures with the type Action<object[]> callback as a parameter, but it would be nice to just use Action, because Unity has a bunch of those
#

I've tried tinkering around with the code but my knowledge of delegates is very poor, and this is a little bit out of my depth 😅

#

I saw you have this method there

private static void AddDelegate(object target, FieldInfo fieldInfo, Delegate callback, Type returnType, Type[] arguments)

I tried using it but I get errors with the Type[] arguments, i tried passing a null array, an array with length 0, and tried doing fieldInfo.FieldType.GenericTypeArguments;
but i couldn't make it work

onyx harness
#

hum... I have to try 😅

patent pebble
#

it would be super nice to just pass a method as the callback without having to do

private static void SomeMethod(params object[] args) // :(

and instead just have this

private static void SomeMethod() // :)
onyx harness
#

Yeah, I will handle those cases later 😄

patent pebble
#
public static void AddDelegate(string path, Action callback)
{
    FieldHandler handler = CSharpMeta.ResolveField(path);
    CSharpMeta.AddDelegate(handler.target, handler.memberInfo, callback);
}

private static void AddDelegate(object target, FieldInfo fieldInfo, Action callback)
{
    Action @delegate = (Action)fieldInfo.GetValue(target);
    @delegate += callback;
    fieldInfo.SetValue(target, @delegate);
}
public static void AddDelegate(string path, Delegate callback)
{
    FieldHandler handler = CSharpMeta.ResolveField(path);
    CSharpMeta.AddDelegate(handler.target, handler.memberInfo, callback);
}

private static void AddDelegate(object target, FieldInfo fieldInfo, Delegate callback)
{
    Delegate @delegate = (Delegate)fieldInfo.GetValue(target);
    @delegate = Delegate.Combine(@delegate, callback);
    fieldInfo.SetValue(target, @delegate);
}
#

after googling a little bit and trying to understand this stuff better, I managed to fumble this together and it seems to work

#

for Action, and Delegate types that don't have any return type and no parameters

#

i was already doing something similar from a copypasted code form your NGTools website, with the proxy reflection code your site generates @onyx harness

onyx harness
#

Hehehe glad someone used it :p

patent pebble
#

it's a pretty awesome tool for people like me who aren't very experienced with reflection

#

right now I know how to make it so I could manage without your site, but it's just way easier to get a neat list of reflected members, methods, etc and just hit copypaste on the generated reflection code

visual stag
#

I mentioned this elsewhere, but I've tried multiple times to make a Rider extension just to generate reflection. Never got past the point where I'm setting the basic extension shit up 😛

onyx harness
onyx harness
onyx harness
visual stag
#

It doesn't help that I have to learn Kotlin or some shit

#

and that the UI and backend are two entirely separate services

onyx harness
#

Kotlin is their backend language?

visual stag
#

There's a painful mix of languages and choices

patent pebble
#

@onyx harness another issue.
How can I get the actual argument values from the invoked callback? They all just return null

#

for example ```cs
CSharpMeta.AddDelegate("UnityEditor.EditorApplication.focusChanged", callbackFunction);

when my method is invoked, the args has the correct size, 1
#

which is supposed to be a bool, but it's just null

#

Here's the class

public static class ApplicationFocusChangeEvents
{
    [InitializeOnLoadMethod]
    private static void Initialize()
    {
        EditorApplicationAccessor.RegisterToFocusChanged(OnApplicationFocusChanged);
    }

    private static void OnApplicationFocusChanged(params object[] args)
    {
        Debug.Log($"args.Length: {args.Length}");
        for (int i = 0; i < args.Length; i++)
        {
            if (args[i] == null)
            {
                Debug.Log($"args[{i}].GetType(): is null");
            }
            else
            {
                Debug.Log($"args[{i}].GetType(): {args[i].GetType()}");
            }
        }
    }
}
onyx harness
#

Wait for me to implement it, maybe for Action or proxy delegate it doesn't work

#

I'm implementing the full class C# generator, then I will update CSharpMeta

patent pebble
#

@onyx harness ah! I see, i'll wait for it
thanks again for all the help!! 😋

onyx harness
#

@patent pebble Soon soon

#

Might not have the time to update CSharpMeta, this one is already taking time more than expected

patent pebble
#

you've helped me a lot already I don't wanna stress you over it

barren moat
#

How can I assign a struct to a SerializedProperty?

visual stag
#

assign its contents to the sub properties 😄

barren moat
#

hm

#

Trivial:

        var fireAudio = weapon.FireAudio;
        var fireAudioProperty = serializedAttack.FindProperty("_fireAudio");
        var guidProperty = fireAudioProperty.FindPropertyRelative("Guid");
        guidProperty.FindPropertyRelative("Data1").intValue = fireAudio.Guid.Data1;
        guidProperty.FindPropertyRelative("Data2").intValue = fireAudio.Guid.Data1;
        guidProperty.FindPropertyRelative("Data3").intValue = fireAudio.Guid.Data1;
        guidProperty.FindPropertyRelative("Data3").intValue = fireAudio.Guid.Data1;
        fireAudioProperty.FindPropertyRelative("Path").stringValue = fireAudio.Path;
#

lol

#

Maybe I should use a recursion

visual stag
#

It do be like that sometimes...

barren moat
#

There's some enumeration built into SerializeProperty too right?

#

Maybe that'd simplify

visual stag
#

Could 🤷

barren moat
#

Ah well, looks like I've got it working now anyway. Next time!

onyx harness
#

Very far from good, because I don't have locally the exact member information.
So you have to cast yourself everything

patent pebble
#

that's so nice

#

So you have to cast yourself everything
a small price to pay

onyx harness
#

If it gets more traction one day, I might bring the full data into NG UV, but it will suffice for now

patent pebble
#

thanks for all the effort you put into it 💙

onyx harness
#

I'm off to bed, tomorrow CSharpMeta in the oven 😄

short tiger
#

I don't know how well known this is, but you can get compile-time access to Unity's internal API if you name one of your assembly definitions one of these:

Unity.InternalAPIEditorBridge.001 - Unity.InternalAPIEditorBridge.024
Unity.InternalAPIEngineBridge.001 - Unity.InternalAPIEngineBridge.024

Unity.InternalAPIEditorBridgeDev.001 - Unity.InternalAPIEditorBridgeDev.005
Unity.InternalAPIEngineBridgeDev.001 - Unity.InternalAPIEngineBridgeDev.005

These assembly names are includes with all the InternalsVisibleTo assembly attributes defined in the Unity core dlls. I've seen Unity.InternalAPIEditorBridge.012 used by a Unity package, probably to access the internal API. The Dev ones presumably are meant to be used by devs, but it's not documented anywhere.

#

Here's the full list

#

The assembly name isn't pretty or descriptive, but compile-time, safe access to internals is very nice. You even get IntelliSense.

waxen sandal
#

Yeah there were some other ones in the past as well

real ivy
#

Is there a plugin or addon which can scan a project's scenes an d determine which assets within the project are NOT USED? I'd like to be able to cull out all the stuff I'm not using w/o doing it manually and inevitably making a mistake

#

Asking for a friend

#

Im guessing gotta fetch all assets, then check each scene, check each scene objects, materials etc

But also can look into the "select dependencies"(?) option see what it does?

waxen sandal
#

There's AssetHunter and there might also be something in Mikilo's NGTools

gloomy chasm
#

Does anyone know if there is any performance difference between using .Next(..) and .FindReletiveProperty(..)? (Assuming that the property you want is the next one)

waxen sandal
#

I don't know but next is probably ever so slightly faster

#

Depending on the implementation

gloomy chasm
#

That is kind of what I was thinking too

onyx harness
#

The question is strange

#

regarding the purpose of the 2

gloomy chasm
#

I wonder how iterating an array with Next compares to GetArrayElementAtIndex?

gloomy chasm
onyx harness
#

One iterates, the other looks up

onyx harness
#

and I think we already know the answer

gloomy chasm
onyx harness
#

FindRelativeProperty still have to parse & lookup a string

gloomy chasm
onyx harness
#

Strings that you will have to extract somehow

onyx harness
gloomy chasm
onyx harness
#

And Navi is right, AssetHunter is exactly what you need, but if I stand correct, it gives a result after a build isn't it?

#

NG Asset Finder can also precisely (exact paths) give you dependencies

#

But it can not state straight that this asset is not used in build

real ivy
#

He just wants those unused assets (for the scene) be selected, so he can remove it

onyx harness
#

Oh, he wants to remove any asset used by a specific scene

onyx harness
#

Isn't Unity enough to get the dependencies?

#

Or you want additionally cross dependencies, to avoid mistake

#

I've started a graph map of the project years ago, but never finished unfortunately =X

#

Somehow I feel it would help a lot of people

waxen sandal
#

We do that for asset bundles, it's useful but slow

onyx harness
#

Oh you manage to get a good graph? Nice

waxen sandal
#

Good is subjective 😛

onyx harness
#

This graph math problem is too huge for me

#

I'm shit at math T___T

waxen sandal
#

It's mostly the asset bundle graph driving it

#

Not so much asset to asset graph

onyx harness
waxen sandal
#

I don't think Unity does half stars, so it's rounded down

#

Although the last review is worrisome

onyx harness
#

Yeah, 7h ago

waxen sandal
#

(fyi I had good experiences in the past with it)

onyx harness
#

I'm sure the asset is good, something must have happen to go below 4.5*

gloomy chasm
onyx harness
#

No surprise

gloomy chasm
#

I didn't think it would be quite such a difference

#

Though not surprised that Next is vaster, just didn't think it would be that much faster

waxen sandal
#

That's more than I expected

#

According to a random website it's 4.4

onyx harness
#

4.4 what? XD

waxen sandal
#

Their rating

#

4.4035

onyx harness
#

He is the only one posting feedbacks/bugs directly on my Discord :p
This guy is motivated

gloomy chasm
onyx harness
#

Please do tell, I'm all ears about UX/UI

#

Maybe not in this channel, either DM me or my Discord

gloomy chasm
#

I will DM you, yeah this channel isn't right for it haha

#

(I will in a bit actually, I gtg for a bit soon)

onyx harness
#

no worry

waxen sandal
#

I will actually try out your back button thing since the one we're using now is probably 10 years old

onyx harness
#

I can give you the code if you want

#

Because using the mouse, is insanely more effective

#

And I want you to be more effective 🐙

waxen sandal
#

Nah I'll try to convince my company to buy it if it is actually useful

#

No promises

onyx harness
#

But it's free... XD

#

NG Nav Selection is free

#

It's included in NG Tools Free and there is no Pro version of it

whole steppe
#

how can I alter the scale factor of an fbx model in an editor window

hoary grove
#

Is there an extension or something that auto sets sprites to Point (No Filter) among other settings? I always forget whenever I import a new sprite then spend a min complaining that it looks like shit.

hoary grove
hoary grove
#

Yup. "New" lol

karmic ginkgo
#

back in 2018 presets were broken

#

still some properties dont participate in them, and its not really automation

gloomy chasm
visual stag
gloomy chasm
# visual stag

Idk what Properties package even is yet, but I need to find some place to complain give feedback about this

visual stag
#

well, I'd advise you to not just randomly start picking at things you haven't even used

#

That part just sounds like a parity with the Unity serializer

#

which is very sensible

gloomy chasm
visual stag
#

well, seeing as it requires the IProperty interface, you would know that

gloomy chasm
#

It looks like it might have been originally created with DOTS, so the public field might be with structs in mind

#

My main thing is that Unity has a tendency to encourage the use of public fields in classes which is bad design and something the C# guidelines specifically says not to do.

#

But this is kind of off topic oops haha

gloomy chasm
#

Was doing performance testing with SerializedProperty, I feel like this test of a custom 'FindProperty' is slower than the built in one...
(build-in took about 1.5 seconds for 100k iterations, and this is test of a custom one is only 10k)

velvet kite
#

I see that the tool handle has 2 orientations by default: local and global.

#

I'm wondering if it's possible for me to change it to a new (custom) orientation?

onyx harness
#

@patent pebble I updated CSharpMeta to handle simple Action & Func<object>.
But unfortunately, I couldn't reproduce the bug you described.
I tested on Action, and a delegate of Action, both worked without me changing my code

barren moat
#

oh nvm, I'm dumb. I had the wrong case in the filename!

barren moat
#

Is it safe to use Resources.FindObjectsOfTypeAll in the editor to find all instances of components on prefabs?

barren moat
#

hm, so I think I've found a bug? Or maybe I'm just confused.

var objects = Resources.FindObjectsOfTypeAll(scriptClass);
foreach (var obj in objects) {
  if (PrefabUtility.IsPartOfPrefabAsset(obj)) {
    var go = obj is Component
      ? (obj as Component).gameObject
      : (GameObject) obj;
    var prefab = go.transform.root.gameObject;
    EditorUtility.SetDirty(prefab);
    Debug.Log($"Set prefab {prefab} dirty!", prefab);
  }

I'm using this method to mark prefabs dirty. But when I do it and resave they do not reserialize.

#

If I replace the "SetDirty" with an AssetDatabase.ForceReserialize it does reserialize.

#

What's the deal?

barren moat
onyx harness
#

You must load everything manually if you want to get everything

patent pebble
#

But unfortunately, I couldn't reproduce the bug you described.
the bug was probably just me using the incorrect generic arguments and arguments 😅

onyx harness
#

No no, I was wrong, I got an error

#

Did more testings

patent pebble
#

errors... hate 'em, can't live without 'em

patent pebble
#

@deep plover copypasting the same message across mulitple channels is against the rules

#

when asking a question try to find the most suitable channel and only post your message there

stark geyser
#

@deep plover Don't cross-post. Also completely unrelated to this channel. Pick one relevant channel in #🔎┃find-a-channel

deep plover
#

@stark geyser how long should i wait before i post the question on another channel so is not considered cross posting?

barren moat
#

As opposed to the build

#

But now I've learned

#

A horrible lesson

onyx harness
#

If you want assets, use AssetDatabase

barren moat
#

I want to get all prefabs with an instance of a component somewhere in their hierarchy.

#

It's not that simple

onyx harness
#

Make a text search of the GUID

barren moat
#

It does seem to work more than you'd expect though

onyx harness
#

or use the filter

barren moat
barren moat
onyx harness
#

I guess you need it programmatically

velvet kite
#

How do I create a positionHandle with custom rotation and position?

#

(And attach it to an object when I need to?)

gloomy chasm
patent pebble
#

is there a way of getting a SerializedProperty's actual height?

#

I want to get the actual height of the property and ignore the value that my PropertyDrawer returns in the GetPropertyHeight method

#

docs say this If the property has a custom PropertyDrawer, the function will return the height returned by that drawer.

gloomy chasm
patent pebble
gloomy chasm
patent pebble
#

yeah

#

there has to be a way of just getting the raw height, including all the children

gloomy chasm
#

see how it handles it if there is no property drawer

patent pebble
#

if there's no property drawer it just returns the single line value

#

i think i can use the PropertyHandler class to use an empty instance of it

#

Unity does this internally:

internal static PropertyHandler GetHandler(SerializedProperty property)
{
    if (property == null)
        return s_SharedNullHandler;

    // Don't use custom drawers in debug mode
    if (property.serializedObject.inspectorMode != InspectorMode.Normal)
        return s_SharedNullHandler;

    // If the drawer is cached, use the cached drawer
    PropertyHandler handler = propertyHandlerCache.GetHandler(property);
    if (handler != null)
        return handler;

    ...

  // Field has no CustomPropertyDrawer attribute with matching drawer so look for default drawer for field type
    if (!handler.hasPropertyDrawer && propertyType != null)
        handler.HandleDrawnType(property, propertyType, propertyType, field, null);
onyx harness
#

@patent pebble CSharpMeta done.

patent pebble
#

i'll report any bugs i find

onyx harness
#

Yep yep.
Usage is simpler.
CSharpMeta.Add("path", callback);
with callback being either a variadic function or a matching delegate.
It automatically handles event & delegate.

#

And should work for both instance & static.

patent pebble
#

@onyx harness aaah that's so nice! 😊

#

thanks again man! 🧙‍♂️ ⚔️

remote yarrow
# barren moat I want to get all prefabs with an instance of a component somewhere in their hie...

I experimented with every way I could find of doing this a while back. FindObjectOfType I hate because of the things it 'almost' does but then doesn't quite. I also tried AssetDatabase.Find( [text search] ) - note that I also use the undocumented (I filed bugs on this a year ago - still unfixed) parameters that you can find if you look in the Unity source code.

Eventually this workd for me:

string[] guids = AssetDatabase.FindAssets("t:Prefab a:assets" /** Undocumented feature, because Unity staff don't document the core APIs */ );
#

...and then loaded every one of them to do an 'if ( TryGetComponent<> )' on them

visual stag
#

Which part is undocumented? a:assets?

remote yarrow
#

Last time I checked (last week I think) yes

visual stag
#

At least there you can just use the searchInFolders parameter

remote yarrow
#

(someone else was trying something similar and getting stuck, and I dug out this code for them)

#

Behind the scenes the a: stuff gets converted into a properly typed class (which I've begged to be made public, because it's a lot less confusing and a lot elss error-prone than this 'magic acronym' stuff - but been rejected)

#

(e.g. I literally can't remember what a: does any more. It's so opaque and confusing. I will have to go digging in the source to re-understand it)

visual stag
#

Restricts the search area

#

all, assets, or packages

remote yarrow
#

so ... if it was 'restrict-search-area:' that would be acceptable

visual stag
#

that would be a pain in the ass to type in the search window

remote yarrow
#

(I know it's single letter because it's intended for use in UI and no-one wnats to type long strings, since UnityEditor doesn't have auto-complete 😦 ... but that's no excuse for forcing scripts to use the same approach, when it's dangersous in code)

#

Anyway, it seems to work great, I've been using it a year or 2 for auto-upgrading prefabs in large projects, hasn't failed yet.

pure raft
#

Any ideas how to go about generating collider surrounding all selected game objects ? Image as example.

bitter barn
# pure raft Any ideas how to go about generating collider surrounding all selected game obje...

Yes. Are you looking for ideas for the algorithm? Loop over all selected objects, find all meshes, loop through all vertices, if the vertex x position is greater than the largest known position, save it and so on. This way you construct an axis aligned bounding box.

If the collider has other requirements (like fitting more closely, or being a rotated box) then its more complicated, but first you would need to define your problem better 😉

#

Maybe state why you need the collider in the first place, maybe you want something different. There are so many ways, e.g. if you need a mesh collider that tightly fits the geometry, you could simply combine all meshes into one, but maybe you only want the convex hull (there's an algorithm for that), etc.

pure raft
#

@bitter barn Thanks for the reply. Indeed I'm not sure what is best approach, but I'm looking to enable / disable objects meshrenderer and colliders upon player entering trigger. Each "trigger" area hold objects related to that room. Image attached as more visual explaining.

#

So my first idea was to somehow generate collider surrounding such areas, but maybe that is too complex and box colliders could work just as fine ? Opinions are very welcome on this matter.

bitter barn
#

Is that for performance optimization? Like a custom culling system? If the player leaves a room and can't see it, disable it? Because that would be something you could achieve with Unity occlusion culling. But if you want to manually have control over maybe playing animations and running scripts and also disable some parts of that, you could go with the trigger system.

However, these sorts of systems always have issues in places where multiple trigger boxes overlap or its unclear where the player could go/see. You might want to try placing manual trigger colliders only in the doorways first and see how it works.

But depending on what you're going for, it could make sense to generate a collider that follows the convex hull.

pure raft
bitter barn
#

Sometimes its faster to build a tool that helps you manually edit boxes because auto generation can become really difficult. Could always just take the selection, press a button, instantiate a new Transform in the middle of all pivots, add the collider in script and then start editing the box collider manually with Unity tools. Or maybe calculate the bounding box and spawn the box, but then activate Unitys edit tools from script and manually tweak the result. Just to speed up to the process.

pure raft
#

t. Could always just take the selection, press a button, instantiate a new Transform in the middle of all pivotsThat actually sounds like best approach, did not think of center bounds. That approach should speed up collider creating enough as we are not talking about 100's rooms here. Thanks for the tip !

barren moat
barren moat
onyx harness
#

@real ivy Hey I've been thinking about implementing a project cleaner in NG Tools, but then I looked up the store for such assets and found few.
They are all paid, is that what stopped you?

barren moat
#

What would it do? Find orphaned assets?

#

Or rename things?

onyx harness
#

He was looking for a tool to determine if an asset is unused by the build

barren moat
#

Yeah cool. Not the most ergonomic solution but you can also check the build log and diff it against the assets folder

onyx harness
#

Yeah clearly

#

To my surprise, there are not many assets doing it

remote yarrow
remote yarrow
#

I think ... if you hit significant performance problems with this approach ... then it would be worth submitting a bug report to Unity. This is a pretty common use-case, so they'd want to either fix/improve the performance of this approach, or create a new API route that's more optimized (but I think you'll be fine)

onyx harness
#

they just released a new Search thing

#

Maybe it can help

patent pebble
#

yeah it used to be a package called QuickSearch, they rebranded it as Search and they are trying to replace the basic search features with it

#

haven't tried it for like a year or two, it was a little bit cumbersome to use

#

but it was very promising

onyx harness
#

Yeah quicksearch looked nice

#

Search looks definitely cool

onyx harness
#

Yep yep saw it

remote yarrow
#

" released in version 2021.1, Search has since become a core workflow for Unity users" -- but Unity 2021 isn't even released yet, it's still in beta no? 2020 LTS has been out less than a year.

#

Oh, OK, it has an 'experimental' version in 2020. But I thought we weren't supposed to use/trust experimental packages, that's why they got hidden away?

waxen sandal
#

2021 is out

#

Just not LTS

remote yarrow
#

i.e. beta. Anyway ... some of those search features do look pretty cool, I look forward to them (in a production build of Unity :))

onyx harness
#

2021.2.8f1
it's starting to be a while now

patent pebble
#

maybe you could check what ReorderableList was clicked, hook to its onAddCallback delegate and manually set the last index as a new instance?

#

i do something similar for some of my tools but I don't remember if I implemented my own ReorderableList or if I hooked to the default ones

#

maybe someone here knows if there's an easier solution

#

but given that ReorderableList is an undocumented API, i wouldn't bet on it 😅

remote yarrow
#

Almost all of the main APIs are documented. The new stuff - some teams especially (UIToolkit I'm glaring at you) - has a vast amount undocumented. But outside the specialist/niche APIs its pretty good.

(If you want to know what true documentation hell was like ... go look at Unity v2 and v3. That was pain. Endless pain)

patent pebble
#

yeah I feel like mostly everything is well documented
some examples do suck a little bit, and there's almost zero examples with images

#

but other than that, the only few undocumented features are mostly related to editor stuff

#

at least they maintain a public repository with the source code so we can browse through it if we need to

gloomy chasm
#

It is not

#

That is simply how adding elements to a SerializedProperty array works in Unity

patent pebble
#

yeah that's why I suggested that one of the most likely ways of doing that is to hook into the default ReorderableList callbacks

#

i was looking into the tests I did for that, and it's not too complicated

#

there's some things to take into consideration tho, for some of the ReorderableList delegates
some of them only call the default code when those delegates have no methods subscribed to them

#

for example onAddCallback & onRemoveCallback

#

Unity does this internally:

if (list.onAddCallback != null)
{
    list.onAddCallback(list);
}
else
{
    DoAddButton(list);
}
#

so if you hook a method to onAddCallback , you need to make sure you handle whatever you want to happen

#

this made me think somewhere down the line some built-in editor feature will affect those callbacks

#

while it's easy to just get every visible ReorderableList in the Unity editor, hook to their callbacks and call your own custom logic...
I don't know how safe it is, and if it will break some default feature 😅

full stream
#

Does URP have any support for Perspective-based decals? I want to project an image onto an object, but the URP decal system doesn't get larger the farther from the source you are.

slim zinc
#

things usually don't become larger the further away you are.......

full stream
#

I mean in the sense of a projector

#

I want objects to look 3d from a specific place, sort of like superliminal

unkempt rivet
#

I used to get compile time errors when trying to reference things from UnityEditor.iOS.Xcode or UnityEditor.iOS.Xcode.Extensions without having the iOS module installed.
The newer versions of Unity no longer have that problem. Does anyone know what/when it changed? I couldn't find anything in the changelog.

waxen sandal
#

It's a bug that they give errors

bitter barn
#

I remember posting about that issue in the forum because it caused us lots of pain. Even the simple fast that we had to wrap our code into IF_SOMETHING_IOS causes stuff like refactorings to cause compile errors on other platforms etc. But I wonder how they would be able to fix this other than just including the code on every platform. Or maybe they found a way to only include empty shells for public API methods and nothing else.

waxen sandal
#

We solved it by adding the ios platform to our docker build 😛

unkempt rivet
#

ohh.. it's a bugfix!

#

Well, shared pain is half the pain I guess. Still would love to figure out what changed even if it's just to know if it's coming back or not.

unkempt rivet
#

now, going back to old versions, I can't even reproduce it. 😅

patent pebble
#

how can I calculate the width and height of a GUI control, taking into account text wrapping?

#

is there something similar to GUIStyle.CalcSize() but that takes into account a maximum width constraint?

#

ah, nevermind I can just do this, made a simple extension method

public static Vector2 CalcSizeConstrained(this GUIStyle style, GUIContent content, float maxWidth)
{
    Vector2 size = style.CalcSize(content);
    if (size.x > maxWidth)
    {
        size.x = maxWidth;
        size.y = style.CalcHeight(content, maxWidth);
    }

    return size;
}
waxen sandal
#

I usually just use the max width in those cases even if the string could theoretically be shorter

patent pebble
#

almost as a sort of "tags"

waxen sandal
#

Ah right

patent pebble
#

I'm implementing validators for PropertyAttributes

#

and it's a lot more readable to have the valid types in their own boxes

#

😓 Discord loves introducing artifacts in my gifs for some reason

#

this one shows a little bit better the varying-size "grid"

#

i usually just do all of this on GUILayout/EditorGUILayout

#

but i needed to make this for PropertyDrawers

south beacon
#

Hi, I'm currently trying to understand how Unity allows you to define an asset as a default value for newly created components.
To investigate this I'm using Unitys "Input System UI Input Module" as an example. If I create this component via the editor it automatically has the "Actions Asset"-field set to the "DefaultInputActions". How is Unity doing this and where is it defined? 'actionsAsset' is not defined anywhere in the MonoBehaviour, so I guess it has to be done somewhere in the InputSystemUIInputModuleEditor, but I can't figure it out 🤔

tardy pecan
#

Isn't that done through default presets?

#

Or maybe a similar thing? I know that they store the default action asset in the Input package

spare kernel
#

i didnt really know where to ask this, but how can i change where in my cursor sprite is the point where the player clicks? because i have this image but the area where you click is top left instead of the center of the circle

sullen crystal
#

hm... guys, the intellisense and debugging is not working for unity in visual studio. i checked to see if the external script editor is set to visual studio but i dont have any visual studio options in the dropdown. (not sure if im in the right chat)

unkempt sparrow
#

mainWindow.totalShapes = EditorGUILayout.LabelField("totalShapes", varLoader.BlendShapes.ToString());

cannot source target type void to type int

BlendShapes returns a int any ideas?

patent pebble
#

@unkempt sparrowwhat are you trying to do?

#

a LabelField doesn't return anything

#

it's just text to display on the editor

#

you'll probably want to use an IntField

unkempt sparrow
#
public void OnGUI()
        {
            DrawDefaultInspector();
            varLoader mainWindow = (varLoader)target;
            EditorGUILayout.BeginHorizontal();
            mainWindow.avatar = EditorGUILayout.ObjectField(varLoader.avatar, typeof(GameObject), true) as GameObject;
            EditorGUILayout.EndHorizontal();
            editorAvatar = mainWindow.avatar;
            if (GUILayout.Button("Collect Blendshapes"))
            {
                totalShapes = mainWindow.BlendShapes(editorAvatar);
                
            }
            EditorGUILayout.IntField("Blendshapes", totalShapes);
        }
#

thats my editor script right now

#
public class varLoader : MonoBehaviour
    {
        public GameObject avatar;
        public int BlendShapes(GameObject avatar)
        {
            MeshFilter mesh = avatar.GetComponent<MeshFilter>();
            Mesh currentMesh = mesh.sharedMesh;
            Debug.Log(currentMesh.blendShapeCount);
            return currentMesh.blendShapeCount;
            
        }

this is my main script currently

#

it dosent have any errors but all it makes it this

#

no button or a int field with the current amount of blend shapes on the object

patent pebble
#

is your Editor class targetting the varLoader class?

unkempt sparrow
#

there should be 20

#

yes

#

[CustomEditor(typeof(varLoader))]

patent pebble
#

public void OnGUI() don't do this

#

you need to override the OnInspectorGUI method

#
public override void OnInspectorGUI()```
unkempt sparrow
#

ok

#

it has gotten very mad

#

hahaha

patent pebble
#

i recommend checking the documentation carefully for this sort of stuff

#

the examples are pretty clear

unkempt sparrow
#

yeah i have been following them very closely but havent figured this out yet

unkempt sparrow
#

im on 2019.4.29f1

patent pebble
#

nah, the errors are just your code

unkempt sparrow
#

ok

patent pebble
#

what's in line 26 of your script?

unkempt sparrow
#

um?

#

hahah

patent pebble
#

it's telling you that you have a null object reference

unkempt sparrow
#

yeah thats the object field

#

should it be inside the button so it only activates when its pressed?

#

OOOOO

patent pebble
#

why are you doing an ObjectField when you already have an exposed GameObject reference in your MonoBehaviour?

patent pebble
unkempt sparrow
#

still dosent get the right number but it looks right now

unkempt sparrow
patent pebble
#

that's what you're getting from it

unkempt sparrow
#

i was told not to use a skinned mesh render but i think that is what i should be using

#

it has 20 blendshapes though

patent pebble
#

debug your code

#

only way to make sure 🙃

#

Debug.Log everything

unkempt sparrow
#

this is the current error

#

same as before so i dont think its getting to the mesh yet

patent pebble
#

i don't know what's on that line

unkempt sparrow
#

the object field

#

mainWindow.avatar = EditorGUILayout.ObjectField(varLoader.avatar, typeof(GameObject), true) as GameObject;

patent pebble
#

yes but you don't need an objectfield when you already have a public GameObject reference

#

you already have this

public GameObject avatar;
unkempt sparrow
#

ok but that dosent have anything in it

#

i need to assign the game object to it correct?

patent pebble
#

i suppose so, you can't get data from an empty reference, can you? 😅

unkempt sparrow
#

nope hahah i dont think you can

#

im just confused to what your suggesting

patent pebble
#

i'm telling you that you don't need to make an ObjectField

unkempt sparrow
#

ok??? so just delete the line?

patent pebble
#

yes

unkempt sparrow
#

OOOO

#

I GET It

#

since the script is on the object you dont need the object feild

#

ahhhh

#

i seeee

patent pebble
#

Unity automatically makes fields for your public fields

#

that's what you're telling Unity to do with the DrawDefaultInspector()

#

to make those automatic fields

unkempt sparrow
#

the only issue with this is that it will eventually be a window not associated with a specific object