#↕️┃editor-extensions

1 messages · Page 113 of 1

rough harbor
#

hey guys, does anyone know how I can get the selected device name in the device simulator?

#

in other words, i want to get this

plucky knot
rough harbor
#

Holy molly thanks @plucky knot this is great

plucky knot
#

You can do so much more since they did the UIElements stuff to the entire editor

#

It's so nice

#

But when in doubt pop open the UI Toolkit Debugger and see if what you want is available (and not hidden in an IMGUIContainer) 😄

rough harbor
#

ohhhhh this is amazing @plucky knot thanks so much for this advice!!

gloomy chasm
#

Anyone know a good way to store settings to be used at runtime?

#

Storing in the Resources folder is so ugly and messy...

crude relic
#

can you clarify

#

what kind of settings

#

editor settings?

#

runtime as in build?

gloomy chasm
#

For example, like tags. You create them in editor and then access them at runtime(build)

crude relic
#

ah

#

I've always just used Resources lol

#

and SOs, of course

gloomy chasm
#

Yeah same, but it is so... ew

crude relic
#

¯_(ツ)_/¯

#

you can always abstract it away so you're not dealing with it directly

gloomy chasm
#

The file/folders are still going to be there though

crude relic
#

I'm pretty good at ignoring that lol

tough cairn
#

anyone got a post processor* for importing fbx file ( prevent animation and material import ) ?

waxen sandal
crude relic
#

@tough cairn does a preset work?

#

you can set the preset as the default if that's what you're looking for

primal minnow
#

Did Unity hid a lot of Editor classes which were accessible before ?
I was looking at someone's github repo and they have used a lot of classes from UnityEditor that are not accessible anymore. Is there any replacement for that ?
My plans are for making custom debug console(replacement to Unity's default debug console).

visual stag
#

Elaborate. Nobody can help you if you do not have any specifics at all

primal minnow
primal minnow
visual stag
#

which are?

primal minnow
# visual stag which are?

ListViewState, SplitterState, SplitterGUILayout, LogEntry, LogEntries, ListViewElement, ListViewGUI, FlexibleMenu, FlexibleMenuModifyItemUI

Methods such as TempContent, LoadIcon from EditorGUIUtility, ToolbarSearchField from EditorGUI
a lot of properties from EditorGUILayout and EditorGUI.

etc

visual stag
#

I don't believe stuff like SplitterGUILayout has ever been non-internal

primal minnow
#

not even in v5 ?

visual stag
#

I wonder if the "UnityEditor.Facebook.Extensions" assembly definition was some sort of hack to get access to the internals of Unity

#

because it doesn't make much sense to have named their assembly definition that otherwise?

primal minnow
#

Right, I am gonna explore that.

visual stag
#

yeah... seems like a hack

primal minnow
#

What do they mean by open ?

visual stag
#

definitely internal since it was made

#

I have no idea. I presume, clicking on it at all breaks it. I would seek out other methods for accessing the internals. I think there are assembly definition names you can use

primal minnow
visual stag
#

That's what I'm saying. I have heard there are names you can use for asmdefs which make them compile as core code. But I cannot remember where I have seen that mentioned, so I can't be of much help there.
Maybe that's a false memory though. There's also this: https://github.com/mob-sakai/CSharpCompilerSettingsForUnity, which is a full-on dependency to have, but might be fine, as you can get it to modify one asmdef. I personally wouldn't want it in my project as a dependency unless it was important though.

primal minnow
#

Gives the reason for having that asmdef

visual stag
#

Name the assembly Unity.InternalAPIEditorBridge.001 (make sure you rename the Name inside the assmdef)

primal minnow
visual stag
#

Not sure what those assemblies are used for tbh.

dusty comet
#

Hello, how could I focus the Inspector editor window if I have them pinned in the same area?

gloomy chasm
#

Because the latter is much easier to do than the former.

dusty comet
#

If I am in ProjectManager I want it to switch to the inspector tab

dusty comet
#

the problem with that is that idk the name of the inspector window

crude relic
#

dig into the reference source

gloomy chasm
#

But I think it is InspectorWindow

crude relic
#

it is inspectorwindow

#

but it's internal

gloomy chasm
#

It inherits from PropertyEditor (not that it matters in this case)

#

Type inspectorWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.InspectorWindow);

crude relic
#

beat me to it

gloomy chasm
#

Man, I am really starting to look forward to 2023 for the editor.
Cinemachine, Input system, Timeline, and others are moving to UITK.
Cinemachine, ProBuilder, Terrain, Particle system, and more are moving to using Overlays.
Localization package is doing a UI/UX redesign.
The inspector will be using UITK by default.
And I suspect the Editor Design System site will be up by then along with possibly seeing Graph Tools Foundation some time in 2023.
And of course there is Splines too.

tough cairn
#

anyone knows how to access remapped materials ?

#

can it be done in a postprocessor ?

#

all i really need are the string names "DarkBrown" , "DarkGreen" etc .

tough cairn
#

thanks

#

trying to write a postprocessor but every change to the script the editor will re-import all my assets ( which takes at least 2 minutes )
i thought about something like separating the classes so the compiler won't detect changes in the first one and avoid re-import the assets

class AssetPostprocessorEv : AssetPostprocessor
{
    public static event System.Action<AssetPostprocessor> PreprocessModel;
    void OnPreprocessModel() => PreprocessModel?.Invoke( this );
}

in a separate file :

public class FBXImporter : AssetPostprocessor
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
    static void Import()
    {
        AssetPostprocessorEv.PreprocessModel += APP =>
        {
            Debug.Log( APP.assetPath );
        };
    }
}

but it doesn't seem to work

#

i right click on a single file and select re-import from the context menu

random valley
#

Hello to everyone.

I was wondering if is possible to create a custom editor window that automatically populates additional options based on your input.
For instances, I need a number of folders, but if the number is higher than 0, I need to be able to have options to input a value of how many assets will be created in those folders e.g scriptable objects.

I am able to create the parent folders (Such as Section 1,Section 2, Section 3), but adding the additional values I am uncertain of.

I created a image to help show what I aim for if it is understood. Sorry for my english.

gloomy chasm
random valley
#

GUILayout I am using, thank you

gloomy chasm
#

You just use a for loop in that case

#
for (int i = 0; i < numberOfSections; i++)
{
  sections[i] = EditorGUILayout.IntField("Assets in Section " + i, sections[i]);
}
#

Something like that

#

Please read the code and not just try to copy paste it as you will not learn much by copy pasting it. Feel free to ask questions 🙂

random valley
#

many thanks. i was unsure if i must have had to create a new int property value for each of the sections. I am just beginning to learn how to use the customised editors so thank you for your help sir

gloomy chasm
#

Sure thing.

random valley
#

I believe i am making an error in some area. I have created an array of values named assetsPerSection to save my new values. In OnGUI, i attempt to add the value as in your example of 'sections[i]', but it will always reset the value. How best to initialise and save the values? Should I use button perhaps to force the initialization only when I need to?

gloomy chasm
#

And I would use a list so you can just use Add(..)/Remove(..) instead and keep the values

real ivy
#

Everytime i change something related to serialization (most often it's adding/commenting [SerializeReference]), i get this error and have to restart editor
(I think) it's a bit different each time
Should i be concerned?

waxen sandal
#

Unity bug afaik, updating should help

peak bloom
#

ListView kinda broken when deleting multiple items

#

also, the bigger the list is the slower it will get... proly pooling would help?

#

the slowness is very noticeable, like so much delays when scrolling through

#

CollectionVirtualizationMethod.FixedHeight; only helps a bit, once it goes above 150 elements, the lag starts to kick in

gloomy chasm
hybrid oar
#

hi, how can i use "EditorGUILayout.BeginFoldoutHeaderGroup" from inside "ShowMaterialProperty" function

using UnityEngine;
using UnityEditor;

public class CustomShaderGUI : ShaderGUI 
{
    
    bool SettingsOpen = true;
    bool Settings2Open = true;
    
    string propertyName1 = "Base Map";
    string propertyName2 = "Normal Map";
    
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        ShowMaterialProperty(materialEditor, properties, SettingsOpen, propertyName1);
        ShowMaterialProperty(materialEditor, properties, Settings2Open, propertyName2);
    }

    private void ShowMaterialProperty(MaterialEditor materialEditor, MaterialProperty[] properties, bool propertyStatus, string propertyName)
    {
        propertyStatus = EditorGUILayout.BeginFoldoutHeaderGroup(propertyStatus, propertyName);
        if (propertyStatus)
        {
            string[] references = { "_MainTex"};
            foreach (string reference in references)
            {
                MaterialProperty matReference = FindProperty(reference, properties);
                materialEditor.ShaderProperty(matReference, matReference.displayName);
            }
        }
        EditorGUILayout.EndFoldoutHeaderGroup();
    }
}

When I use it as above, it doesn't turn off, it stays open all the time.

#

No problem when I use it inside the "OnGUI" function

using UnityEngine;
using UnityEditor;

public class CustomShaderGUI : ShaderGUI 
{
    
    bool SettingsOpen = true;
    
    string propertyName1 = "Base Map";
    
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        SettingsOpen = EditorGUILayout.BeginFoldoutHeaderGroup(SettingsOpen, propertyName1);
        if (SettingsOpen)
        {
            string[] references = { "_MainTex"};
            foreach (string reference in references)
            {
                MaterialProperty matReference = FindProperty(reference, properties);
                materialEditor.ShaderProperty(matReference, matReference.displayName);
            }
        }
        EditorGUILayout.EndFoldoutHeaderGroup();
    }
}
gloomy chasm
gloomy chasm
peak bloom
#

basically, only 1 editorWindow as a container for the uitoolkit

#

let me show you, give me a sec

peak bloom
# gloomy chasm The error you were getting was from IMGUI not UIToolkit

oh wow, I think you're kinda on point, I added editor.minSize & maxSize and lock the layout size, and the error is gone...

the listview here was parented to a Box set to stretchedToParentSize, so I guess the error caused by the EditorWindow when child elements get shrunk.. either way this sounds like a bug

#

let me try to dock it somewhere and see if the error can be reproduce

#

ah yes, when docked, the error gets triggered again even with minSize/maxSize set

#

*dont mind the static background sound

#

just mute it

gloomy chasm
#

LOL

hybrid oar
gloomy chasm
gloomy chasm
tough cairn
#

how do i get Texture2D from gameobject similar to this using asset data base loading a prefab ?

gloomy chasm
tough cairn
#
            var prefab = AssetDatabase.LoadAssetAtPath<GameObject>( prefab_path );

            Debug.Log( prefab ); > "prefab (UnityEngine.GameObject)"

            var icon = AssetPreview.GetAssetPreview( prefab ); // GetMiniThumbnail

            Debug.Log( icon ); > "Null"
#

anyway to use a temporarily camera so i can do Graphics.DrawMesh ? Doesn't seem like its possible to create new camera

#

unity why ? ....

  public sealed class AssetPreview
  {
        [FreeFunction("AssetPreviewBindings::GetAssetPreview")]
        internal static extern Texture2D GetAssetPreview(int instanceID, int clientID);
gloomy chasm
tough cairn
#

on prefab variants ?

#

also the Preview Render Utility is returning null as well

#
            var preview = new PreviewRenderUtility( false );

            preview.AddSingleGO( prefab );

            preview.BeginPreview( new Rect( 0, 0, 128, 128 ) , "" );

            preview.Render( true );

            var icon = preview.EndPreview() as Texture2D;

            Debug.Log( icon ); > "Null"
#

ah... its a render texture

#

is there anyway to convert to Tex2D ? seems like the other way around is the only way

gloomy chasm
tough cairn
#

its not im just sleep deprived 🙃 its a render texture , the cast is null

tough cairn
#

still no luck


var preview = new PreviewRenderUtility(false);
preview.AddSingleGO(prefab);
preview.BeginPreview(new Rect(0, 0, 128, 128), "");
preview.Render(true);
var render_texture = preview.EndPreview() as RenderTexture;

var icon_flags = UnityEngine.Experimental.Rendering.TextureCreationFlags.None;
var icon = new Texture2D(256, 256, render_texture.graphicsFormat, 1, icon_flags);
icon.Apply(false);

try { Graphics.CopyTexture(preview.EndPreview(), icon); }
catch (System.Exception e) { Debug.LogError(e); }
finally { preview.Cleanup(); }

Debug.Log(icon);

byte[] bytes = icon.EncodeToPNG();

File.WriteAllBytes(Path.Combine(folder_icons, icon_name), bytes);

            >> "Result texture output is black"
random valley
waxen sandal
#

Use SerializedObjects instead of directly accessing the value

gloomy chasm
primal minnow
#

Is it possible to "hook" into the Unity logger ? As in when Unity logger receives any kind of log(info, warning, error, etc), I wanna tap into that data(type of log, file name, line name)
[I am working on some automation]

waxen sandal
primal minnow
primal minnow
#

Yep, can't do that.

visual coral
#

How can I hide "(script)" ?

gloomy chasm
visual coral
#

Thanks!

tough cairn
gloomy chasm
#

Neat!

tough cairn
#

i can no longer reimport after using the preview utility - and the prefab inspector will be blank

#

doing manual

AssetDatabase.ImportAsset( prefab_path , ImportAssetOptions.ForceUpdate );

will make the assets project window blank ( in addition to not being able to reimport from context menu and the inspector asset is blank )

#

blank ...

#

Its possible to do reimport from the context menu after script complication and it will make it normal again

#

why can't submit issues to the repo ❓

gloomy chasm
gloomy chasm
tough cairn
#

the default cube prefab generates well , however my prefab variants won't

waxen sandal
rotund sluice
#

sorry

tough cairn
#

ok i figured it out, the scale was wrong , in fact the it was so small that PreviewRenderUtility.DrawMesh didn't event render a single pixel

tough cairn
#

on the side note - all those odd behaviors were due to me calling DestroyImmediately on the textures after they have been rendered

#

which is quite odd - if i put DestroyImmediately anywhere in the same function After attempting to read data from it - it will break

#

almost like the code runner doesn't respect order of execution and will jump back in time to mess up with the code

fathom ermine
#

I'm usually a bit of a lurker here... but has anyone else upgraded to Visual Studio 2022 after getting an in-app notice that the software was outdated, only to find that VS2022 doesn't do all the fancy Unity features like highlighting broken syntax or making suggestions? Like, if I type mathf. and it used to pop up the list of mathf things to choose, but now it only suggests previously declared variables and functions and nothing else

#

I'm hoping I'm just doing something wrong, but I can't figure out what

fathom ermine
#

I hope I asked this in the right place. Nothing that I googled solved my problem.

fathom ermine
#

I'll run through it all again, but as far as I can tell I've already done all the required steps :/

fathom ermine
#

maybe I should give up and go back to VS 2019

novel otter
#

Just upgrade 2020 to 2021 my project was broken and all prefab is missing

weak spoke
novel otter
#

😀 yes

real ivy
#

Hi all
I have a
[SerializeReference] SomeBaseClass data; in an SO and it doesn't persist editor restart
SomeBaseClass and all derived class has [Serializable], all have unique field

real ivy
#

Im not sure why something this simple doesn't work

But a suspicion is.. i'm using plastic scm and i'm currently assigning data in OnValidate, and all t he SOs are still greyed out (need to press Check Out to edit values), even tho i can see the value updated
Maybe it's this? Nope, no difference
I'm on 2020.3.18

Anyone have tried something this basic? On this or earlier version?

real ivy
#

Ok nvm
I need to do SetDirty in OnValidate
Huh..

novel otter
mossy wren
#

Normally when you turn off autorefresh, you forget to hit it before play.

#

So nothing is gained.

#

so you NEVER forget

#

finally be able to get the gains of turning off auto refresh (tabbing from code to editor doesn't cause a load)!!!!!!!!

#

This should have been a core feature of Unity like 8 years ago

#

I just recently figured out how to make editor extensions

#

This is huge huge huge for those who want to turn off auto refresh

#

But don't cuz it takes a brain process to remember to hit refresh before play

mossy wren
#

It saves 30 minutes of dev time per 8 hours of coding. So if you have 100,000 devs world wide doing 8 hour sessions( a physics order of magnitude rough estimation), thats 3,000,000 minutes of dev time added a day or 1.5 million hours of man hours a day would be gained by adding this as a core feature.

#

When you hit f12: it compiles and runs, runs if compiled and stops if playing.

It takes a bit of training to get to f12 to compile+run/stop, but it is something you don't forget once you're in a habit unlike hitting two key combinations in the old mode.

waxen sandal
trail dawn
#

And in like, fewer words.

primal forum
#

Where do I ask how to add Unity module to my microsoft visual studio so it is recognizing the code im writing and can autocomplete it? Sorry didnt find any channel so idk where to ask. As you can see by the picture it is now all white and its not letting me autocomplete the code

waxen sandal
primal forum
patent pebble
#

@mossy wren just some feedback, you may just want to do that automatically whenever the editor enters play mode is about to enter play mode (while Autorefresh is off)
that way you don't have to rely on the user remembering to press a button

vapid prism
#

Is there a resource somewhere with the order of execution for event functions for editor scripts? Having some issues with first time initialization and OnEnable/OnDisable during domain reload

worldly echo
#

How to create an array in the Custom Editor ? I see many posts online but none of them comes up with a the same solution 🧐

lyric herald
#

serialized properties

#

if it's an array on an editor window and not part of component editor, u need to get a ref to the window itself and use the FindProperty method w/ that ref to serialize the array

#
    [SerializeField] private List<Sprite> _sprites;
    private SerializedObject _serializedObject;
    private void OnEnable()
    {
        _serializedObject = new SerializedObject(this);
    }
    private void OnGUI()
    {                        
        EditorGUILayout.PropertyField(_serializedObject.FindProperty("_sprites"));
        _serializedObject.ApplyModifiedProperties();
    }
#

here's an example for doing that on an editor window

#

it's pretty much the same thing for a component inspector editor, so if you find a tutorial or documentation that goes thru a similar process, that's your answer

#

FindProperty() and using the property name as a string for the parameter is the way to do it. make sure to serialize the property

#

hope that helps

#

@worldly echo

worldly echo
#

Thank you 🙂 I will look into that @lyric herald

lyric herald
#

cool, good luck!

#

just went thru the exact troubles myself, so figured i'd share the more complicated scenario

#

cuz there's 0 documentation for referencing an editor window itself as the serialized object

#

a fair bit more straight forward and clear documentation when dealing w/ inspectors

worldly echo
#

@lyric herald So let's say I have this In my MonoB class:

    public int[] orderOfEvents;```

then In my Custom Editor I have:
    //Number of Events
    EditorGUILayout.BeginHorizontal();
    EditorGUILayout.LabelField("Number of Events", GUILayout.Width(EditorGUIUtility.labelWidth));
    thisCutscene.numberOfEvents = EditorGUILayout.IntField(thisCutscene.numberOfEvents);
    EditorGUILayout.EndHorizontal();
And now I want to make so my array is of size numberOfEvents
vapid prism
worldly echo
vapid prism
#

did you set up a SerializedObject of the editor itself like tpop mentioned?

lyric herald
#

can read up on that

#

if u don't serialize the object and use a serialized property, the editor won't save the changes, and you also can't show an array

#

intfield is just for a single integer

#

afaik

#

the only way to surface an array in an editor window or inspector is thru serialized property, or by manually writing code to iterate thru the array and drawing each variable in it separately

#

which is not a good solution

worldly echo
#

private SerializedObject _serializedObject;

#

and public void OnEnable()
{
_serializedObject = new SerializedObject(this);
}

#

right ?

vapid prism
#

yes

#

also read through the links tpop put, they explain how the serialization work

lyric herald
#
        EditorGUILayout.PropertyField(_serializedObject.FindProperty("orderOfEvents"));
vapid prism
#

The tl;dr is that you never ever want to directly edit a variable, you always want to do it through a property field

lyric herald
#

yeah. if you don't you'll just be banging ur head, cuz unity will not save half of what ur tryin to accomplish

#

the most important thing to know about serialized properties and objects, is that they are automatically integrated into unity's save system in the editor. and they also go thru some additional backend structure. None of which is easily reproduced manually thru code, and if ur struggling w/ serialized objects n properties, then trying to handle the backend stuff u get for free by avoiding serialized objects/properties is prolly over ur head anyway.

#

but using them is as simple as getting a serializedObject ref to the editor window ur working with, and using the FindProperty method to get the serialized property ur after.

worldly echo
#

Okay all this is still a bit obscure to me 😬 I will dig through the doc !

vapid prism
# worldly echo Okay all this is still a bit obscure to me 😬 I will dig through the doc !

The SerializedObject page has a really clean example of how to do a Sine wave animation. The important detail here is that your editor window works exactly like any other MonoBehaviour editor. Note how the example specifies that it's an Editor for that script? Since it's an editor it has access to serializedObject which is simply the MonoBehaviour that's edited/shown in the inspector.

But in your EditorWindow you don't really have a specific object, so instead you reference your own window as a SerializedObject. That's what tpop showed before. From that point on it works exactly as if you were making an editor for a MonoBehaviour. So you can get the reference to any variables you want to draw using the exact same method as the SineAnimationEditor example

#

This way you have automatic undo support and everything will look just like it does in the editor

#

Are you starting to understand or still brain implosion? (I know I was stuck on brain implosion for some time)

worldly echo
#

Brain melting but I think it's because of Fatigue + Allergies x)

vapid prism
#

haha np, can you paste the code you have atm? and I'll show you how to change it

worldly echo
#

Oh boy if you want but it's very messy xD

vapid prism
#

Should be fine

worldly echo
#

I need to go to sleep I think. What I'm trying to build right now is a Custom Cutscene Editor for a 2D game

vapid prism
#

oh right you have a custom Editor, I though we were on EditorWindow

#

this makes stuff a lot easier

#

Let's assume we have a completely clean OnInspectorGUI()

worldly echo
#

All right

vapid prism
#

So bascially the code is currently```cs
[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
public override void OnInspectorGUI()
{

}

}```

#

The first thing you always want to do is make sure your serializedObject (the monobehaviour we're editing) is always up to date. And finally any changes we make should be applied ```cs
[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();

    //Actual code goes here

    serializedObject.ApplyModifiedProperties();
}

}```

#

So it's important to make sure that you always .Update() before doing anythying. and always end with ApplyModifiedProperties()

#

for starters lets just draw the public int numberOfEvents; variable

#
[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        var numberProp = serializedObject.FindProperty("numberOfEvents");
        EditorGUILayout.PropertyField(numberProp);

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

And that's it, now we're drawing a field that you can edit undo and whatever modify it however else you want

#

So how do we draw that array? Simple, the exact same way

#
[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        var numberProp = serializedObject.FindProperty("numberOfEvents");
        EditorGUILayout.PropertyField(numberProp);

        var numberArrayProp = serializedObject.FindProperty("orderOfEvents");
        EditorGUILayout.PropertyField(numberArrayProp);

        serializedObject.ApplyModifiedProperties();
    }
}
#

You can skip the whole making a local variable and just put it straight in the PropertyField call if you want

#

If you try this out, does it draw for you?

worldly echo
vapid prism
#

Right nice, see the pattern here? I don't use any of those specific IntField, ObjectField, FloatField etc. Only PropertyField

#

PropertyField automagically knows what it's supposed to draw

#

So for your original question, how do we detect a change and update the array accordingly?

worldly echo
#

Nice, and it's suseptible to undo shenanigans if I understood correctly ?

vapid prism
#

correct, it handles undo without any problems

#

So to see if something was changed we use a ChangeCheck: ```cs
[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();

    EditorGUI.BeginChangeCheck();
    var numberProp = serializedObject.FindProperty("numberOfEvents");
    EditorGUILayout.PropertyField(numberProp);
    var change = EditorGUI.EndChangeCheck();
    if(change)
    {
        //Value was changed!
    }

    var numberArrayProp = serializedObject.FindProperty("orderOfEvents");
    EditorGUILayout.PropertyField(numberArrayProp);

    serializedObject.ApplyModifiedProperties();
}

}```

#

Last thing is to modify the array size of your array

[CustomEditor(typeof(Cutscene))]
public class CutSceneEditor : Editor
{
    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        EditorGUI.BeginChangeCheck();
        var numberProp = serializedObject.FindProperty("numberOfEvents");
        EditorGUILayout.PropertyField(numberProp);

        var numberArrayProp = serializedObject.FindProperty("orderOfEvents");
        
        var change = EditorGUI.EndChangeCheck();
        if(change)
        {
            numberArrayProp.arraySize = numberProp.intValue;
        }

        EditorGUILayout.PropertyField(numberArrayProp);

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

since we call serializedObject.ApplyModifiedProperties(); at the end it will apply the modification we did in code

#

And that's about it really

#

Keep using PropertyField for the rest of your UI and draw what you want etc

worldly echo
#

Okay Thanks a lot four your time and fo rthe help !

#

I would lie if I understood all of it but I will come back to it tomorrow 😁

vapid prism
#

Yeah it's a pretty simple base to start on, give it a good rest and it will probably make a lot of sense tomorrow ^^

worldly echo
#

Yeah that's probably wiser x)

#

Thanks again though 🙂 I will keep you updated if I manage to make something cool with it ^^

vapid prism
#

Sure, feel free to @ me tomorrow if something crops up

tight pine
#

Hi guys, I am writing a property drawer for a serializable class but I am running into an issue. I have the drawer in it's simplest form right now (basically doing nothing):

#if UNITY_EDITOR
    [CustomPropertyDrawer(typeof(AssetSwitcher<GameObject>), true)]
    public class AssetSwitcherDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty (position, label, property);
            EditorGUI.PropertyField(position, property.FindPropertyRelative("collection"), label);
            EditorGUI.EndProperty ();
        }
    }
#endif

And soething goes wrong with the height not being calculated right (Check screenshot). I am pretty sure I am just making a really stupid mistake.

patent pebble
#

@tight pine you need to override GetPropertyHeight

#

right now your PropertyDrawer thinks it has 0 height

#

so you need to tell it exactly how tall of a space it needs to reserve

tight pine
#

ho, so I need to do something like ask the property how tall it is (it changes depending on the number of elements) do I need to use EditorGUI.GetPropertyHeight on the "collection" property?

#

Thanks a lot @patent pebble!

#

a curiosity, Why don't property drawers work like custom editors where you can use EditorGUILayout instead to automate most of this stuff?

vapid prism
tight pine
#

@vapid prism Good point. Makes sense 🙂

vapid prism
#

as for overriding GetPropertyHeight, make sure you also check the .isExpanded property of your array to ensure that it works for both closed and expanded views. You can use EditorGUIUtility.singleLineHeight to get a standard line height, and EditorGUIUtility.standardVerticalSpacing to get the spacing between the lines

#

Then it's just a matter of calculating all the lines and multiply by those values

tight pine
#

This seems to work perfect:

#if UNITY_EDITOR
    [CustomPropertyDrawer(typeof(AssetSwitcher<GameObject>), true)]
    public class AssetSwitcherDrawer : PropertyDrawer
    {

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            return EditorGUI.GetPropertyHeight(property.FindPropertyRelative("collection"), true);
        }

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty (position, label, property);
            EditorGUI.PropertyField(position, property.FindPropertyRelative("collection"), label);
            EditorGUI.EndProperty ();
        }
    }
#endif
#

For both expanded and collapsed

patent pebble
#

yeah that seems to work fine for PropertyFields

#

if you are doing something else like buttons or other GUI fields you usually have to manually calculate the height

tight pine
#

But of course when I add more stuff I will need to calculate stuff and add to it

patent pebble
#

yeye

tight pine
#

hahah 🙂 jinx

#

Thanks a lot guys, you rock @patent pebble and @vapid prism !!

tight pine
#

Just one more thing, how can I get access to the object represented by property? (On the code above I want to access my AssetSwitcher<GameObject>)

vapid prism
tight pine
#

I want to call a function on that object when a button is pressed

#

Basically to autofill the 'collection' array

vapid prism
#

Hmm, would it be easier if you made an editor for whatever your AssetSwitcher<GameObject> is used in? Since you're in a property drawer it could technically belong to any class

tight pine
#

But it can be used in anything 😬

#

I do not need to deal with the class containing it. It can handle itself.

#

But I see how that can be a problem...

vapid prism
#

Yeah I'm not sure actually how to do this

tight pine
#

Thanks @vapid prism, I will explore a little more and make some tests. If I find a solution I will post it here.

#

I should be able to add and change elements on the array from the property. So my only problem is that I cannot call the function on the AssetSwitcher class that autofills the array.... so I guess I will have to move that logic into the PropertyDrawer

patent pebble
#

@tight pine there's a couple ways of doing it
it depends exactly what target object you want to get to call the method from
for example if the field your property represents is a C# class's instance in a field inside of a MonoBehaviour
or if it's just a field in a MonoBehaviour

tight pine
#

Which should be ok cause this would be the only place where it gets called.... as far as I can see....

patent pebble
#

so I guess I will have to move that logic into the PropertyDrawer
this is also a viable option
i guess it depends what your design needs

#

usually if the code is editor-only it should be fine to move into the drawer

#

but sometimes that's not possible

#

brb, gonna dig out an example I have somewhere

tight pine
#

It is editor only

#

Basically fills up the array with all the prefabs on a folder.

patent pebble
#

@tight pine here's a quick example

#

i'm a bit rusty so I may be forgetting some caveats of this solution, so don't take it as a 100% perfect approach

#

so test it thoroughly when you use it

tight pine
#

Thank you sooooo much!!!

#

I will have a look

patent pebble
#

no problem

#

with this sort of thing, specially when mixing "normal" stuff and SerializedProperty/SerializedObject stuff

#

you will most likely need to use reflection

#

unless it's a very simple thing

tight pine
#

Yeah, it's a really smart solution!! A lot of thinking went into this 🙂

#

I am testing just moving the logic to the drawer, in my case that is totally ok. And I am now trying to fill the array directly on the property. Still not sure if it is going to work but about to test it.... but it might be I will have to go the reflection way...

patent pebble
#

doing the filling logic directly form your drawer should be fine

#

dealing with arrays and serialized properties can get tricky if you've never dealt with them

#

so feel free to ask for help here if you need it

#

lots of helpful peeps around this channel usually

tight pine
#

calling

collection.objectReferenceValue = objects[i]; // collection is a SerializedProperty and objects[i] is a GameObject

and I get:

type is not a supported pptr value.
visual stag
#

Yeah, that's not how it works.

tight pine
#

🙂 @visual stag Thanks I thought that would be the case

visual stag
#

It's important to note that you cannot get/set serialized properties which are not at the base of the serialization hierarchy.
The only thing you can do with a serialized property of a collection is set .arraySize, and get its members via the helper methods. It doesn't have a .xValue property

tight pine
#

Damn... today I am hitting walls 🤦🏻‍♂️

tight pine
#

Ok, I think I need some sleep, tomorrow I'll come up with something hahaha Thanks a lot guys!! It was super helpful!!

umbral rover
#

Kinda dumb question. Is there a way to have a specific custom editor extension still be available even when there are compiler errors? I'm building a package where upon import it has errors due to not finding references for certain scripts which need to be pointed to with an asmdef that I want to generate in a different location. Currently I manually create an asmdef in the desired location but I want to add a context menu option for it instead so it's easier for the end user.

karmic ginkgo
#

yes move it into a dll

misty igloo
#

serialized fields are null/empty during the OnPreprocessBuild method, anyone have an idea on this as the fields are definitely populated in the inspector

rare surge
#

Hi guys, I tried to make buttons for every direction with PropertyDrawer. If is there a template or by default a code in unity I can use it.. otherwise my quesion is. How can I fill left and right button like up and down which uses the origin "position" variable.
I did for the left and right button this

Rect origin = position;
Rect horizontal = origin;
horizontal.width = 100f;
#

Ok I just guessed it but this is enough horizontal.width = Screen.width / 2f

#

It works with it

crude relic
#

@rare surge the rect you get for property drawer expands to the entire available width of the window

#

so you can use that rect width instead of Screen.width

rare surge
#

@crude relic thanks, it is even better.

crude relic
#

yw

real ivy
#

I have "ActiveSkill : ScriptableSkill : ScriptableObject" and i wanna change it to simply "DataSkill : ScriptableObject", and currently there is still "ActiveSkill : DataSkill" but empty

All my SO data's are all of type ActiveSkill
Can i change this type to DataSkill now?

visual stag
#
ItemData = serializedObject.FindProperty("_itemData");
ItemDataType = ItemData.FindPropertyRelative("Type");

...

int previousValue = ItemDataType.intValue;```
zenith maple
#

@visual stag I can do first part in OnEnable() without issue?

visual stag
#

Yeah, as long as you create the SerializedProperty field for ItemDataType

zenith maple
#

how does this behave for null ItemData?

visual stag
#

Ah, actually, with your setup it's much more annoying... sorry

#

ItemData is an objectReferenceValue, meaning it's in a whole other serialized property hierarchy

zenith maple
#

But I can check if it is null and then do the appropriate thing right?

visual stag
#

you could just use ItemData.objectReferenceValue directly, which is the ScriptableItemData

zenith maple
#

okay, I'll check it out 😄 thanks

vapid prism
#

I noticed that having a IMGUI Scroll view taller than all it's content will add a horizontal scroll bar for some reason. I also noticed that setting max height fixes this.

So how can I limit the max height of the scroll view to it's content's total height? In my case it's only filled with 32 GUILayout.Label so I thought that I could just get the max height like so: var maxHeight = EditorGUIUtility.singleLineHeight * 32; but it doesn't match and limits the scroll view to 29 items in height. How would I calculate the height?

The behaviour I am looking for is no scroll bars to show when the window with the scroll view is large enough to show all of the content.

vapid prism
#

Hmm I think this was some sort of bug actually. I was manually setting the alwaysShowHorizontal to false in my ScrollViewScope, but by not setting it at all it works as expected.

waxen sandal
vapid prism
pure siren
#

Is there a way to tell if a SerializedProperty has a CustomPropertyDrawer?

crude relic
#

you can probably use TypeCache 🤔

pure siren
#

Yeah probably, just ended up not worrying about it though. Might revisit it later.

#

Has anyone seen this error before when using EditorGUI.PropertyField:
InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)

#

It happened when I reordered my list

patent pebble
#

i've had that happened sometimes while manipulating a SerializedProperty or SerializedObject "improperly"

#

as in them getting destroyed before the serialization stuff has time to finish

#

the error seems pretty generic, so it probably can be triggered by a variety of situations

#

as far as I can tell, the error is telling you "a SerializedProperty doesn't exist"

pure siren
#

I see, I'll look through my reordering code again. Thanks!

patent pebble
#

if you are removing/reordering stuff from a list it can mean you are manipulating the list and not applying the changes

#

I've had similar situations happen to me

pure siren
#

So the problem was in my CustomPropertyDrawer for the serializedProperty. I was trying to store relative properties so it wouldn't have to find them every OnGUI call, but it seems they were becoming "bad" references even though they weren't null.

tough stream
#

Hi there! i was thinking of having a label with a tooltip in a property drawer of mine. So, i did it! first, i first initialised my guicontent:

                text = "Dialog line : " + LocalizationManager.GetTranslation(((ETranslationKeys)key.enumValueIndex).ToString()),
                tooltip = "Dialog line : " + LocalizationManager.GetTranslation(((ETranslationKeys)key.enumValueIndex).ToString()),
            };```
It basically reads a line of dialogue, and the tooltip is basically going to be used so that even long paragraph can be displayed if there's not enough space in editor. It goes like this:
#

so you can see my label on the right. But weirdly enough : no tooltips when hovering.

#

at first, thought it was the rect, might just be wrong, so i decided to draw it:

#

it's there, and perfect.

waxen sandal
#

Unity tooltips are buggy af

tough stream
#

then i thought maybe another rect is overlapping with it, but still nothing

waxen sandal
#

And it's bugged in 2021.3 that it doesn't show ever

#

IIRC it also doesn't show in playmode

tough stream
#

how convenient 🥴

#

well, thanks a lot!

waxen sandal
tough stream
#

(if you saw my upgraded tool, Navi; you'd be proud )

waxen sandal
#

Send pics

tough stream
#

-sexy
-shows error that say why your scenario would not work

waxen sandal
#

Is that graph view?

tough stream
#

nope! XNode

#

a free github thingy

#

it's so cool

waxen sandal
#

Ah I think I used that in the past

#

Was a little painful back then 😛

#

(also the contrast on that great line 😬 )

#

Looks good though

tough stream
#

i think i can change it, i'll see lol

#

yeah! I changed the architecture of my dialogs, and... Of anything lol
We're currently developping a game with this tool and it's so amazing how easy it was

waxen sandal
#

Sure

tough stream
#

nice! i won't forget 👀

peak bloom
#

xNode, ugh, the good ole imgui

waxen sandal
#

oh yeah that's a thing now as well

tough stream
#

only 2020.1?

peak bloom
#

still in preview, yes

tough stream
#

ooooh okok

peak bloom
#

GTF will replace all graph tooling in Unity

#

more future proof I guess

tough stream
#

Oof lol

#

i'll upgrade my project when they announce Unity 2.0 and redo basically everything, at least deleting useless things that still are codeable lol
I mean at some point, you gotta admit redoing a project from the beginning is easier when you have really precise experience: you coded the EXACT same thing in the past
So if you correctly wrote what went wrong, you can do it better, right? 🤡

#

One day, we gonna have it one day

waxen sandal
#

Why do you think most rewrites fail?

tough stream
#

i don't think it does fail, i've done this all my life and it's incredible how this works amazingly well
I just don't know if unity devs would make a rewrite work skull

#

By the way, GUIStyle.CalcHeight still doesn't work with wordwrap in 2021.2.8f1?

#

i mean, is there an issuetracker of this somewhere?

#

(i'm testing this, brb)

#

Code:

            GUIStyle labelStyle = new() {
                wordWrap = true,
                alignment = TextAnchor.UpperLeft,
            };
            GUIContent labelContent = new() {
                text = "Dialog line : " + LocalizationManager.GetTranslation(((ETranslationKeys)key.enumValueIndex).ToString()),
                tooltip = "Dialog line : " + LocalizationManager.GetTranslation(((ETranslationKeys)key.enumValueIndex).ToString()),
            };
            Rect labelRect = new Rect(keyRect) {
                x = keyRect.x,
                y = keyRect.y + keyRect.height + 4,
                height = labelStyle.CalcHeight(labelContent,keyRect.width),
            };
            Rect CharRect = new Rect(labelRect) {
                y = labelRect.y + EditorGUIUtility.singleLineHeight + 4,
                height = EditorGUIUtility.singleLineHeight,
            };
            Rect conditionsRect = new Rect(CharRect) {
                y = CharRect.y + EditorGUI.GetPropertyHeight(property.FindPropertyRelative("character")) + 4 + EditorGUIUtility.singleLineHeight,
                x = CharRect.x - 10,
            };
            EditorGUI.LabelField(labelRect,labelContent,labelStyle);

Behavior:

#

im i missing something on my Character Rect maybe?
oh wait-

#

ok it works lol

waxen sandal
#

Lol

#

Afaik it should work sooo ;P

tough stream
#

Weird, i'm trying some things and:
Code:

//In my dialog line: 
[Serializable]
    public class LocalizedDialogLine : DialogLineBase {
        [SearchableEnum] public ETranslationKeys Key;
        public bool functionsUnfolded = false;
        public float LabelHeight=18;
        public override string ToString() {
            return "- " + character.ToString() + " : \"" + LocalizationManager.GetTranslation(Key.ToString()) + "\"\n";
        }
    }
//########################In Editor: script (of my dialog line)
            var Height = property.FindPropertyRelative("LabelHeight");

          Rect labelRect = new Rect(keyRect) {
                x = keyRect.x,
                y = keyRect.y + keyRect.height + 4,
                height = labelStyle.CalcHeight(labelContent,keyRect.width),
            };
            Height.floatValue = labelRect.height;
            Debug.Log(Height.floatValue);

Basically, after calculating the height, i'm stocking it into a variable i've got into my dialog line object.
behavior:
Basically tells me that sometimes the height is actually fifteen

waxen sandal
#

Yeah that's not what you're suppsoed to do

tough stream
#

(i need to do that so that i can have my GetPropertyHeight that's well calulcated:

public override float GetPropertyHeight(SerializedProperty property,GUIContent label) {
            var functionsUnfolded = property.FindPropertyRelative("functionsUnfolded");
            var Height = property.FindPropertyRelative("LabelHeight");
            return EditorGUI.GetPropertyHeight(property.FindPropertyRelative("Key"))
                + EditorGUI.GetPropertyHeight(property.FindPropertyRelative("character"))
                + (functionsUnfolded.boolValue ? EditorGUI.GetPropertyHeight(property.FindPropertyRelative("Conditions"))
                + Mathf.Max(EditorGUI.GetPropertyHeight(property.FindPropertyRelative("reactionsAfterLine")),EditorGUI.GetPropertyHeight(property.FindPropertyRelative("reactionsBeforeLine")))
                + Mathf.Max(EditorGUI.GetPropertyHeight(property.FindPropertyRelative("AfterDialogEvents")),EditorGUI.GetPropertyHeight(property.FindPropertyRelative("BeforeDialogEvents")))
                : EditorGUIUtility.singleLineHeight)
            + Height.floatValue
            + 10;
        }```
waxen sandal
#

You should recalculate it in your height method

tough stream
#

oh well i can do that too yeah
Thanks lol

#

but how?
Ive got position.width in public override void OnGUI(Rect position,SerializedProperty property,GUIContent label), but not in getPropertyHeight

#

(because i need this width to calculate my height)

waxen sandal
#

Oh yeah

#

Too bad 😛

#

Try screen.width?

tough stream
#

My window doesn't take the whole screen lol

#

Brb need to grab something to eat, don't hesitate to spam me with answers lol

waxen sandal
#

screen.width is magic and returns the width of the window

tough stream
#

No way 😳😳

#

I'll try naively lol

#

and what do you propose for the y of the rect? screen.y? 🥴

#

(i think i don't need it, i'm messing with you)

#

Okay, things aren't working, and other things are

#

you know what's working? The tooltip 🥴

#

that's a thing i didn't expect bloodsob

waxen sandal
#

The height is what you calculate

tough stream
#

y was the y position of the rect, but i do not need it because all i need is the height (so basically, the deltaY, so distance between y and y+height)

waxen sandal
#

Yes

tough stream
#

but forget about it, since the tooltip works, i'll just cut the text if it's too long, or just display "hover for dialog line"

#

so for the tooltip to work, i guess you need to also have a GUIStyle

pearl drift
#

Hi! Is there some high level functions in unity to implement "Rect Tool" controls like for sprites on a screen?

waxen sandal
#

Never used it though

pearl drift
#

@waxen sandal yes, this is for creating custom editor tool, but i want just use already existed Rect Tool for my monobehviour

waxen sandal
#

Oh, I don't think so then

tawny rover
#

Hello, i installed visual studio 2022 community edition, but my editor doesn't have intellicode... Do you guys know how to install the autofill with unity scripts ? I installed the unity dependancy and also the intellicode one

#

i reinstalled the 2019 edition, but still, there is no autocompletion

austere adder
#

I have an .fbx file exported from Blender with a bunch of different meshes.
I'm writing a tool that will take those meshes and do some processing,
Since the importer seems to create a GO for every mesh and automagically populates the right materials and everything I thought I could use these GO in the code but when I use AssetDatabase.LoadAllAssetsAtPath the resulting GOs don't have meshes or materials populated

#
// filters out prefabs starting with _ and main assets
var prefabs = paths.Select(path => AssetDatabase.LoadAllAssetsAtPath(path))
        .SelectMany(x => x)
        .Select(x => x as GameObject)
        .Where(x => x != null && !x.name.StartsWith('_') && AssetDatabase.IsSubAsset(x.GetInstanceID()))
        .ToList();
#
var mesh = prefab.GetComponent<MeshFilter>().mesh; // null but in the editor it's populated
var materials = prefab.GetComponent<MeshRenderer>().materials; // also null
copper portal
#

Can I get the path of created scene?

tight pine
#

Hey guys! Hope you are all good (Happy kingsday if you are in NL :)) I'm still juggling serialized objects and found an issue that I can't find enough info on:
I am writing a property drawer for a generic (serializable) class and all its subclasses and template types. And I need to check some loaded assets against the type that an array expects:

My class structure (just the important part):"

public class AssetSwitcher<T> : Switcher<T> where T : Object 
{
  public T [] collection;
}

And I am loading assets from a folder on the project and adding them to the collection. But I want to load only the ones with the right type
Here's the relevant code from the PropertyDrawer:

[CustomPropertyDrawer(typeof(AssetSwitcher<>), true)]
public class AssetSwitcherDrawer : PropertyDrawer
{
[...]
      public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
      { 
            [...]
            SerializedProperty collection = property.FindPropertyRelative("collection");
            string folderPath = GetCurrentlySelectedFolder();
            if(folderPath != "")
            {
                if(GUI.Button(buttonRect, "Load from folder"))
                {
                    Debug.Log($"Loading objects in folder: {folderPath}");
                    IEnumerable<string> assetFiles = GetFiles(folderPath);
                    foreach (string path in assetFiles)
                    {
                        if(!path.Contains(".meta")) {
                            Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
                            Debug.Log($"Found a object of type: {obj.GetType()}. Looking for: {collection.arrayElementType}"); // THIS IS THE PROBLEM == Output: Found a object of type: UnityEngine.GameObject. Looking for: PPtr<$GameObject>
                            //if(obj != null && obj.GetType().ToString() == collection.arrayElementType)                       // <== Thus, this does not work
                            int index = collection.arraySize;
                            collection.InsertArrayElementAtIndex(index);
                            collection.GetArrayElementAtIndex(index).objectReferenceValue = obj;    
                        }
                    }
                    
                }
            }
      }
}

Actual question: How can I get the actual type of the object (UnityEngine.GameObject in this test case) instead of the serialized object type PPtr<$GameObject>?

astral shadow
#

Does anyone know how I can display these dashes when multiple objects are selected?

Using EditorGUI.FloatField

gloomy chasm
gloomy chasm
#

But if it is just a label then

astral shadow
#

Works fine 🙂

tight pine
#

@gloomy chasm Thank you so much! Having a look...

tight pine
#

@gloomy chasm Works amazing!! What a cool product! and super clean code!

gloomy chasm
daring creek
#

Hello everyone. Can you help me with CustomInspector. I have a struct with 2 fields and want to make that looks like in Vector2

waxen sandal
#

You make a property drawer for that type, then calculate the positions to be on the same line and draw them using EnumField and FloatField

daring creek
#

I never before do CustomEditor what should I do at first. Be glad if you leave link to article

waxen sandal
#

Seems pretty similar to what you're doing

daring creek
#

@waxen sandal but what if I working with struct

#

Or better I should change to class

waxen sandal
#

It doesn't matter for propertydrawers

daring creek
#

And I already use CustomEditor

gloomy chasm
#

Did you read the link?

#

Basically for MonoBehaviours and ScriptableObjects you create custom editors and for structs and class you create custom property drawers

daring creek
#

It's because first two from Unity?

waxen sandal
#

Yes

daring creek
#

And CustomPropertyDrawer is for all Serializable things

#

?

gloomy chasm
#

Yeah

daring creek
#

Thx!

#

But what if I want to use List

gloomy chasm
#

What do you mean?

daring creek
#

NullReferenceException: SerializedProperty is null

gloomy chasm
#

That is because there is no serialized field called position I imagine

daring creek
#

Oh I get

#

But It doesn't work for X

#

Because X is interface..

gloomy chasm
#

Unity can't serialize interfaces unless you serialize the field with the [SerializeReference] attribute (even if the field is public)

daring creek
#

Welp I change to class and it's work now

#

ok

#

:3

daring creek
#

How I can move fields to left a bit

whole steppe
#

is there a way or an asset, that lets me add a gameobject to multiple scenes at once? I have 100 scenes and opening it one by one to add the objects takes bit long 🙂

daring creek
#

100 scenes

#

You do smth wrong

whole steppe
#

why that

daring creek
#

idk. for example: If in each scene you just changing obstacles you can use one scene

whole steppe
#

its actually a level based game where each scenes has a different style

#

but I need a object on some of these scenes to add

daring creek
#

use instantiate on start

#

also Don't destroy on load can be useful for you

whole steppe
#

cool, heard about that, so there is no way to add it with like drag and drop?

daring creek
#

I don't sure about this. But if you drag one scene to another them have to merge

whole steppe
#

hmm ok, this don't destroy thing, this the same like if I would drop a object to multiple scenes, I just save some time with it, right?

daring creek
#

yup

whole steppe
#

cool thx

daring creek
#

How I can change text inside of this fields

#

@waxen sandal @gloomy chasm

gloomy chasm
#

Can't

#

I mean, you can, but it would be a lot more work than it is worth and takes a bit of trickery.

daring creek
#

ok

#

Thank you any way

#

😄

#

@gloomy chasm then how I can get number of element but write Item instead of ELement

gloomy chasm
daring creek
#

🙂

#

Exist way to show tooltip when I hover on Elements in list

#

?

gloomy chasm
#

label.tooltip

daring creek
#

Thanks

daring creek
gloomy chasm
daring creek
#

stop...

waxen sandal
daring creek
#

Oh... I got what you mean with that method

gloomy chasm
daring creek
#

You're right

waxen sandal
#

What about, if it's not in an array 🤯

daring creek
#

😐

gloomy chasm
#

Listen, I was just answering the question that was asked!

#

Ooh I know

#

Use the propertyPath instead

#

duh

#
string path = property.propertyPath;
if (path.EndsWith(']'))
{
  int index = path.LastIndexOf('[') + 1;
  label.text = "item " + path.Substring(index, path.Length - 1);
}
waxen sandal
#

What about... double digit numbers

gloomy chasm
#

Yeah I just remembed

#

Okay, I think that will do. I don't remember exactly what numbers Substring takes

waxen sandal
#

I don't think you have to pass the second parameter (also it's not the end index, it's the length)

gloomy chasm
#

The last character is ]

#

The second param is the character count isn't it.

#

Ehh it is close enough to get the idea across

#

Unrelated. But in the newest 2022.2 alpha there is this, and I have no idea what it could mean

#

And I really want to know

waxen sandal
#

Well, time to install the alpha

abstract solar
#

I need to analyze all of my scenes as part of the build process. How do I get the root game objects of every scene in my build settings? SceneManager.GetSceneByBuildIndex(i) only works when the scenes are loaded.

gloomy chasm
# waxen sandal Well, time to install the alpha

Yeah... no idea what changed :/
I looked at float and object fields, try dragging and stuff, tried the list. Looked at it in the UITK Debugger, and the inspector in debug mode. Absolutely no idea...

gloomy chasm
abstract solar
#

hm. ill have to think of something else, then

gloomy chasm
#

You can read the actual file if that helps

abstract solar
#

maybe

tardy pecan
#

hey! anyone knows if the shadergraph node editor framework is out of experimental state? It's usable but I thought that with the release of the visual scripting thing they might have something that can be used to make custom node editors?

gloomy chasm
tardy pecan
#

Yeah I actually have a whole dialogue editor based on it, but I'll soon need to make a generic node editor version so that I can make node editors for other purpose and not have to redo everything

#

So it would be nice if they released something official

gloomy chasm
#

Ah, Unity is working on a package called GraphToolsFoundation which will handle both the view and data side of creating graph based tools. At some point every graph based tool in Unity will use it. However it's development has moved internal and I wouldn't expect to see anything until 2023.2, maybe 2023.1 (could be 2024 or later of course)

tardy pecan
#

ooh damn that's very cool!

#

Because right now I have to handle it myself and it's quite a pain haha

gloomy chasm
#

Yeah I get that! It really is a pain. There is a github project called like "Blue Graph" or something like that

#

it does the same sort of thing

#

Not official of course

#

I would say right now to definitely not use the GraphToolsFoundation package that is publicly available though

tardy pecan
#

Oh yeah I guess it'll change a lot??

#

(quite curious to see how it works though)

gloomy chasm
#

Yeah I expect it to change a lot. The lead dev has moved over to who was the lead(?) of UIToolkit, so I expect it to be a lot nicer

#

The API right now it really bad with a lot, and I mean a lot of boilerplate

tardy pecan
#

oooh yeah well I'll stick to my thing for now I guess lol

gloomy chasm
#

Yeah haha

tardy pecan
#

And then in 3 years I'll probably make the switch, seems reasonable enough haha

#

thanks for the tips!

gloomy chasm
#

Sure thing! Best of luck!

tardy pecan
#

Ay thanks!

frail swan
#

hey

#

i’m on unity apple silicon

#

and for soem reason cant find progrids

#

i went to the projetc settings

#

and enabled preview packages

#

but still couldnt find it

tight pine
#

Does anyone have any idea why this:

string folderPath = EditorUtility.OpenFolderPanel("Load assets from folder", "Assets", "");

inside of the OnGUI() of a property drawer results in:

InvalidOperationException: Stack empty.
System.Collections.Generic.Stack`1[T].Pop () (at <6073cf49ed704e958b8a66d540dea948>:0)
UnityEditor.EditorGUI.EndProperty () (at <780782bc035845f9909cebbd4c983ae3>:0)
Moonlander.Shapeshifter.AssetSwitcherDrawer.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Shapeshifter/Switchers/AssetSwitcher.cs:93)
UnityEditor.PropertyDrawer.OnGUISafe (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at <780782bc035845f9909cebbd4c983ae3>:0)
UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.Rect visibleArea) (at <780782bc035845f9909cebbd4c983ae3>:0)
UnityEditor.GenericInspector.OnOptimizedInspectorGUI (UnityEngine.Rect contentRect) (at <780782bc035845f9909cebbd4c983ae3>:0)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at <3d6ac16e3c754a199373804b462a1b72>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

Note: The call to EditorUtility.OpenFolderPanel works fine, panel appears, right path comes out of it but it fails on the end of the OnGUI function. Even if I comment out everything else and just leave that call, it still fails.
On the other hand, if I replace it with:

string folderPath = "[Path to the same folder that I selected on the panel]";

everything works just fine.... 🤔

waxen sandal
#

Probably because that call is blocking

#

IIRC

tight pine
#

@waxen sandal ho Maybe that's something. A timing issue maybe...

#

Thanks a lot.

#

That gives me some room to explore... it's weird that everything else I do after the call runs just fine and the error just happens when the function returns

#

But yeah, it also makes sense that the problem can appear only when unity does not expect OnGUI to take that long....

#

Strange that there is not much mention of that anywhere (Googling around like a maniac)

hexed kernel
#

How do I validate a scene name on OnValidate on a ScriptableObject?

waxen sandal
tight pine
#

Thanks a lot

tight pine
#

@waxen sandal in the end I just changed it to a "Drag&Drop the folder here". It's more fun then browsing anyway :). Thanks a lot!

crude relic
#

@tight pine try slapping a GUIUtility.ExitGUI after you get the file back

#

Oh the link mentions that already

tight pine
#

🙂 yeah, I think that would work. I first though it would stop execution of the function so I didn't eve try it cause I thought drag and drop would be better UX anyway.

#

Now that I read the docs I see that it does not stop the execution, just prevents other events from evaluating

#

In any case, smarter every day! 🙂 next time I know

#

Thanks a lot @crude relic

red sapphire
#

Could someone lend me a hand on a custom property drawer? It's my first time implementing one of these and I'm getting a bit of odd behaviour:

#

List resize:

List Resize:
public static void Resize<T>(this List<T> list, int newSize, T defaultValue = default(T)) {
    if (newSize < 0) return;
    if (newSize == list.Count) return;

    int size = list.Count;
    if (newSize < size) {
        list.RemoveRange(newSize, size - newSize);
    } else if (newSize > size) {
        if (newSize > list.Capacity) {
            // this bit is purely an optimisation, to avoid multiple automatic capacity changes.
            list.Capacity = newSize;
        }
        list.AddRange(System.Linq.Enumerable.Repeat(defaultValue, newSize - size));
    }
}
short tiger
#

That's pretty complicated for your first property drawer, so well done for getting it somewhat working

red sapphire
#

Prefab Matrix:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Centribo.Common.Extensions;

[System.Serializable]
public class PrefabMatrix {
    public GameObject this[int x, int y] {
        get {
            if (x >= Matrix.Count) return null;
            if (y >= Matrix[x].Count) return null;
            return Matrix[x][y];
        }

        set {
            if (x >= Matrix.Count) return;
            if (y >= Matrix[x].Count) return;
            Matrix[x][y] = value;
        }
    }

    public int Width, Height;
    public List<List<GameObject>> Matrix; // [col][row]

    public void ResizeMatrix() {
        Matrix ??= new List<List<GameObject>>();

        Matrix.Resize(Width, new List<GameObject>(new GameObject[Height]));
        foreach (List<GameObject> column in Matrix) {
            column.Resize(Height, null);
        }
    }
}
#

PrefabMatrixDrawer:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace MaplePoweredGames {
    [CustomPropertyDrawer(typeof(PrefabMatrix))]
    public class PrefabMatrixDrawer : PropertyDrawer {
        const float GRID_SPACING = 2;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            PrefabMatrix matrix = fieldInfo.GetValue(property.serializedObject.targetObject) as PrefabMatrix;

            label = EditorGUI.BeginProperty(position, label, property);
            // EditorGUIUtility.labelWidth = 48f;
            Rect contentRect = EditorGUI.PrefixLabel(position, label);
            EditorGUI.indentLevel = 0;

            // Width/Height control:
            float fullContentHeight = contentRect.height;
            float fullContentWidth = contentRect.width;
            contentRect.height = EditorGUIUtility.singleLineHeight;
            contentRect.width *= 0.5f;
            EditorGUIUtility.labelWidth = 48f;
            EditorGUI.PropertyField(contentRect, property.FindPropertyRelative(nameof(PrefabMatrix.Width)), new GUIContent("Width"));
            contentRect.x += contentRect.width;
            EditorGUI.PropertyField(contentRect, property.FindPropertyRelative(nameof(PrefabMatrix.Height)), new GUIContent("Height"));
            matrix.ResizeMatrix();

            if (matrix.Width == 0 || matrix.Height == 0) return;

            contentRect.x = GRID_SPACING;
            contentRect.width = EditorGUIUtility.currentViewWidth - (GRID_SPACING * 2);
            contentRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
            contentRect.height = fullContentHeight - EditorGUIUtility.singleLineHeight - EditorGUIUtility.standardVerticalSpacing;

            float cellWidth = (contentRect.width - (GRID_SPACING * (matrix.Width - 1))) / (float) matrix.Width;
            float cellHeight = (contentRect.height - (GRID_SPACING * (matrix.Height - 1))) / (float) matrix.Height;

            for (int y = 0; y < matrix.Height; y++) {
                for (int x = 0; x < matrix.Width; x++) {
                    float xPos = contentRect.x + (x * (GRID_SPACING + cellWidth));
                    float yPos = contentRect.y + (y * (GRID_SPACING + cellHeight));
                    Rect cellRect = new Rect(xPos, yPos, cellWidth, cellHeight);
                    Object value = EditorGUI.ObjectField(cellRect, matrix[x, y], typeof(GameObject), false);
                    matrix[x, y] = value as GameObject;
                }
            }

            EditorGUI.EndProperty();

        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
            PrefabMatrix matrix = fieldInfo.GetValue(property.serializedObject.targetObject) as PrefabMatrix;
            if (matrix.Width == 0 || matrix.Height == 0) {
                return EditorGUIUtility.singleLineHeight;
            } else {
                // Could be reduced but this makes it clearer what's going on
                return EditorGUIUtility.singleLineHeight + (matrix.Height * EditorGUIUtility.singleLineHeight);
            }
        }
    }
}
red sapphire
#

So if i set the size of the matrix, it displays correctly, but if i drag a prefab into a slot, it fills the whole row of values for some reason

#

even more oddly, if i then increase the width to another size:

  • if i drag a prefab into the same slot, it will fill that whole row again, except for the empty slots that got added by the width increase
short tiger
#

If I had to guess what is happening, it's that somehow the same list instance is being used in more than one row/column

#

Unity can't serialize a List<List<>> can it?

#

Or are you not trying to serialize this?

red sapphire
#

nope, hence needing to write a custom property drawer

short tiger
#

But it probably won't save

#

Have you checked that? Like if you set some of the items, save the scene and then reopen the scene

red sapphire
#

no i don't think it'll save right now, just been focusing on trying to get the editor working first before i figure out the serialization part

#

oh i know what it might be

#

Matrix.Resize(Width, new List<GameObject>(new GameObject[Height]));

#

they're all going to point to the same thing

short tiger
#

Makes sense

#

If I were to make something like this, I would use a flattened 1D array. It's also best to write property drawers to only use SerializedProperty to interact with the serialized field, which would be easier with a flattened 1D array.

red sapphire
#

fair, i might need to flatten it to a 1D array

#

for anyone reading, here was the fix:

public void ResizeMatrix() {
    Matrix ??= new List<List<GameObject>>();

    Matrix.Resize(Width, null);
    for(int i = 0; i < Matrix.Count; i++){
        if(Matrix[i] == null){
            Matrix[i] = new List<GameObject>();
        }

        Matrix[i].Resize(Height, null);
    }
}
red sapphire
red sapphire
#

Update for anyone following:
Flattening to 1D list makes unity serialize it automagically. Here's the new PrefabMatrix class:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Centribo.Common.Extensions;

[System.Serializable]
public class PrefabMatrix {
    public GameObject this[int x, int y] {
        get { return FlattenedMatrix[Width * y + x]; }
        set { FlattenedMatrix[Width * y + x] = value; }
    }

    public int Width, Height;
    public List<GameObject> FlattenedMatrix;

    public void ResizeMatrix() {
        FlattenedMatrix ??= new List<GameObject>();
        FlattenedMatrix.Resize(Width * Height, null);
    }
}
#

my suggestions for any fixes/additions for anyone looking to use this:

  • Add safeguards for index out of bounds on the getter/setter
  • Make resizing the matrix make sure elements are in their correct positions in the 2D matrix once resized
crude relic
slim zinc
#

is there a way to customize InitializeOnLoad? InitializeOnLoad is run on project startup, domain reload, script compilation, ....
i would like to only run the code when opening the project and creating a new script (and optionally when closing the project)
so is there a way to check for the current editor state or any specific api i could use for this?

peak bloom
#

Prolly you're looking for sessionState

slim zinc
astral shadow
#

I want to set the color of some gui in a property drawer based on a non serialized property

public class WeightedObject<T>
{
    float lastPingTime;
    public float LastPingTime => lastPingTime
    public void Ping() { lastPingTime = Time.time; }
}

This is all good.

However I'm not sure how I can get the actual value so as I can check for the LastPingTime value in my custom property drawer.

The actual property drawer is a generic type, so usual casting is not working.

    [CustomPropertyDrawer(typeof(WeightedObject<>), true)]
    public class WeightedObjectPropertyDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var value = //How to get the actual value?
            if (Time.time - value.LastPingTime > 1) { Debug.Log("Was pinged within the last second."); }
        }
    }
#

Any ideas?

#

I really dont want to serialize the ping

waxen sandal
#

You can theoretically use the fieldInfo property to get the value but t's a bit of a pain

slim zinc
#

You need to use reflection

waxen sandal
viscid bear
#

I have created an unity editor tool to speed up the work flow which I am going share with other users. I don't want them to edit code so I am trying to create dll library of the code using visual studio.

I have added all my script and unityengine.dll, unityedtior.dll references to the visual studio. Since the tool is using components from TextMeshPro. I am unable to create it as this requires reference of tmpro's namespace. How can I add reference in my dll for tmpro as there is no .dll file for it?
I thought of creating .dll of tmpro or add scripts to visual studio form package folder to get around with it but I am unsure if this will workor not.

astral shadow
astral shadow
#
var targetObject = property.GetValue();
var field = targetObject.GetType().GetProperty("LastPing");
var lastPing = field.GetValue(targetObject);
Debug.Log(lastPing);

Using @gloomy chasm s extensions I was able to do it!

#

Thanks!

tight pine
#

Looks super cool @astral shadow

celest pilot
#
    #if UNITY_EDITOR
    [CustomEditor(typeof (CharacterBehaviour)), InitializeOnLoadAttribute]
    public class CharacterBehaviourEditor : Editor {
        CharacterBehaviour customInspectorVariable;
        
        SerializedObject customInspector;

        private void Awake() {
            customInspectorVariable = (CharacterBehaviour) customInspectorVariable;
            customInspector = new SerializedObject (customInspectorVariable);
        }
        public override void OnInspectorGUI() {
            customInspector.Update();
            EditorGUILayout.Space();
            GUILayout.Label("Character Behaviour", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 16 });
            EditorGUILayout.Space();
        }
    }
    #endif
``` `NullReferenceException: Object reference not set to an instance of an object` for the line where `customInspector.Update();` is, but I am setting it in Awake so why does it not work?
muted cave
celest pilot
#

just make a custom inspector and display "Character Behaviour" in it

muted cave
celest pilot
#

because "Header" does not have a way to center it and make it look like a title

muted cave
#

It's a lot of work for something non essential, but here are a couple things wrong with your code:

  1. You dont need the '#if Unity_Editor' and '#endif', they are used for something different. Awake() won't be called on Editor scripts. OnInspectorGUI() is called every time you want to display a 'CharacterBehaviour' in the Inspector, so use that as your Awake substitute.
    And again, this is so much work it's not worth it. You need to make a label for every variable you want to display. If you want to add a new variable to your CharacterBehaviour you also have to go into this script and add a new Label.
#

@celest pilot

celest pilot
#

The property or indexer 'CharacterBehaviour.CanPlayerMove' cannot be used in this context because the set accessor is inaccessible

muted cave
#

also make your your CharacterBehaviourEditor script is a seperate File and in a folder called 'Editor'

celest pilot
#

it's alright

muted cave
#

CanPlayerMove getter is private, use the field name, I assume canPlayerMove

celest pilot
#
#if UNITY_EDITOR
[CustomEditor(typeof (CharacterBehaviour)), InitializeOnLoadAttribute]
public class CharacterBehaviourEditor : Editor {
    string Version = "v0.1.0b";

    CharacterBehaviour characterBehaviour;
    SerializedObject customInspector;

    SerializedProperty CanPlayerMove;

    void OnEnable() {
        characterBehaviour = (CharacterBehaviour) target;
        customInspector = new SerializedObject(characterBehaviour);

        CanPlayerMove = customInspector.FindProperty("CanPlayerMove");
    }
    public override void OnInspectorGUI() {
        customInspector.Update();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        EditorGUILayout.Space();
        GUILayout.Label("Character Controller", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 16 });
        GUILayout.Label("Version: " + Version, new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter });
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

        GUILayout.Label("Movement Flags", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
        characterBehaviour.CanPlayerMove =
            EditorGUILayout.ToggleLeft(new GUIContent("Can Player Move", "Determines whether the player can move around."), characterBehaviour.CanPlayerMove);
    }
}
#endif
celest pilot
#

wait don't tell me I have to make everything public

#

that's CanPlayMove

#

could you explain what exactly do I have to change in order to make it work?

vapid prism
#

Hang on, I misread a bit

celest pilot
#

uhh sure

vapid prism
#

Okay, so instead of having all your variables public you instead use the serialized property system. I will use your [SerializeField] private Camera Camera; as an example since it doesn't have any public getter.

So for a bare minimum custom Editor what you need is this: ```cs
[CustomEditor(typeof (CharacterBehaviour))]
public class CharacterBehaviourEditor : Editor {

SerializedProperty cameraProperty;

void OnEnable() {
    cameraProperty = serializedObject.FindProperty("Camera");
}

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

    EditorGUILayout.PropertyField(cameraProperty);

    serializedObject.ApplyModifiedProperties ();        
}

}

#

note how I grab the property through FindProperty and supply the name of the variable. Then draw it using PropertyField

#

Also note the Update and ApplyModifiedProperties happening first and last, respectively. Which is required to support undo etc

celest pilot
#

what is serializedObject? I don't see it declared anywhere

vapid prism
#

It's inherited since it's an Editor

#

It represents the CharacterBehaviour (because of the attribute) of whatever you current have shown in an inspector

#

So unless you don't need a method reference or similar you can just straight up use FindProperty

celest pilot
#
    public override void OnInspectorGUI() {
        customInspector.Update();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        EditorGUILayout.Space();
        GUILayout.Label("Character Controller", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 16 });
        GUILayout.Label("Version: " + Version, new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter });
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

        GUILayout.Label("Movement Flags", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
        characterBehaviour.CanPlayerMove =
            EditorGUILayout.PropertyField(new GUIContent("Can Player Move", "Determines whether the player can move around."), characterBehaviour.CanPlayerMove);

        customInspector.ApplyModifiedProperties(); 
    }
``` I have no idea what this error means ` error CS1529: A using clause must precede all other elements defined in the namespace except extern alias declarations
`
celest pilot
#

I fixed it by doing this, but now I got 3 more errors popping up

vapid prism
#

Is your Editor part of a Editor folder?

celest pilot
#

no but it's linked to the monobehaviour so you don't need to put it in such folder

vapid prism
#

You have to put it in that folder unless you want to deal with tons of #if

celest pilot
#

I'm fine with that

#

could you tell me how to fix these errors?

  1. The property or indexer 'CharacterBehaviour.CanPlayerMove' cannot be used in this context because the set accessor is inaccessible
  2. Argument 1: cannot convert from 'UnityEngine.GUIContent' to 'UnityEditor.SerializedProperty'
  3. Argument 2: cannot convert from 'bool' to 'UnityEngine.GUILayoutOption'
vapid prism
#

2 and 3 is probably just wrong argument on whatever function it is. As for 1 I need to see code, but you're trying to set the value of a Property that doesn't have a set{} implemented

celest pilot
#

I think I fixed it... but

#
#if UNITY_EDITOR

[CustomEditor(typeof (CharacterBehaviour)), InitializeOnLoadAttribute]
public class CharacterBehaviourEditor : Editor {
    string Version = "v0.1.0b";

    CharacterBehaviour characterBehaviour;
    SerializedObject customInspector;

    SerializedProperty CanPlayerMove;

    void OnEnable() {
        characterBehaviour = (CharacterBehaviour) target;
        customInspector = new SerializedObject(characterBehaviour);

        CanPlayerMove = customInspector.FindProperty("CanPlayerMove");
    }
    public override void OnInspectorGUI() {
        customInspector.Update();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
        EditorGUILayout.Space();
        GUILayout.Label("Character Controller", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 16 });
        GUILayout.Label("Version: " + Version, new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter });
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

        GUILayout.Label("Movement Flags", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
        EditorGUILayout.ToggleLeft(new GUIContent("Can Player Move", "Determines whether the player can move around."), EditorGUILayout.PropertyField(CanPlayerMove));

        customInspector.ApplyModifiedProperties(); 
    }
}
#endif
#

NullReferenceException: Object reference not set to an instance of an objectI'm getting this again

vapid prism
#

Remove InitializeOnLoadAttribute I don't see why you need it

#

Probably what's causing issues

celest pilot
#

let me try that

carmine quiver
celest pilot
#

nothing changed

#

still getting that error

vapid prism
#

which file and line?

#

also I just realised something

#

do you know how auto implemented properties work?

celest pilot
#

I don't think so

#
UnityEditor.EditorGUILayout.IsChildrenIncluded (UnityEditor.SerializedProperty prop) (at <4cbd678da9d34d10b88d29af4998c9e0>:0)
UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUILayoutOption[] options) (at <4cbd678da9d34d10b88d29af4998c9e0>:0)
CharacterBehaviourEditor.OnInspectorGUI () (at Assets/Scripts/Mechanim/Movement/CharacterBehaviour.cs:183)```
#

full error

#

EditorGUILayout.ToggleLeft(new GUIContent("Can Player Move", "Determines whether the player can move around."), EditorGUILayout.PropertyField(CanPlayerMove));

#

this line specifically

vapid prism
#

Yeah okay, so whenever you use any form of this:
public int MyThing {get; set} C# will automatically create a field for you. Meaning that it will expand that to ```cs
public int MyThing
{
get { return myThing; }
set { myThing = value; }
}
private int myThing;

Now the problem here is that the name of the private field `myThing` isn't actually that. It will actually be something like `private int <MyThing>k__BackingField`
And since Unity serializes field by the name, that's what will be serialized. So your FindProperty will have to look for that name instead.

This is only an issue since you specified `[field: SerializeField]` on your property
celest pilot
celest pilot
carmine quiver
#

You cant, if you specify ToggleLeft.

If you just do PropertyField then it does work

#

If you want to do toggleleft, then do prop.boolvalue = toggleleft()

celest pilot
#

but I need that specific button..

vapid prism
#

Yeah so if you remove it it will not longer serialize, so it won't exist at all. This is one of the reasons you ideally shouldn't use C# Properties all that much in anything that needs editor support in Unity. So either create your own private backing field or skip the property

celest pilot
vapid prism
celest pilot
#

becaue what you're saying makes me think that it won't work at all

carmine quiver
vapid prism
carmine quiver
#

Can you confirm that your CanPlayerMove serializedproperty is found and works?

carmine quiver
#

Then this properties is not relevant right @vapid prism ?

#

If he finds the Serializedproperty, its not the backing field

celest pilot
#

EditorGUILayout.PropertyField(CanPlayerMove) doing just that should work, yes?

#

if the serialized property does work of course

carmine quiver
vapid prism
celest pilot
carmine quiver
#

I cant, you can search the manual for SerializedProperty though

celest pilot
#

it gives me NullReferenceException: Object reference not set to an instance of an object still with doing just EditorGUILayout.PropertyField(CanPlayerMove); :/

carmine quiver
#

So indeed CanPlayerMove is null.

#

It cant find your property

celest pilot
#

this is all CanPlayerMove is atm public bool CanPlayerMove { get; private set; } = true;

carmine quiver
#

Does that serialize?

#

Can you change it in the inspector?

celest pilot
#

I removed serialization

carmine quiver
#

Then why are you trying to use a SerializedProperty on it

celest pilot
carmine quiver
#

Yes

#

And after you made it not serializable, you couldnt use a serializeable property on it.

#

I mean..

celest pilot
#

whoops that is my bad, let me bring it back and try again

carmine quiver
#

YOu can do:

target.CanPlayerMove = Editor.ToggleLeft(target.CanPlayerMove, etc etc)
If you make the setter accessible. But i dont understand why you would, this value is not stored in any way

celest pilot
#

still gives me that error... I'm about to give up

carmine quiver
#

What error my friend

celest pilot
#

null reference NullReferenceException: Object reference not set to an instance of an object

#

it persists, I have no idea why

carmine quiver
#

When you debug.log it, what does it show?

celest pilot
#

I mean I was able to edit it in unity's inspector while serialized

celest pilot
carmine quiver
#

or what?

#

Editor or?

celest pilot
#

or the mono itself

carmine quiver
#

I dont understand what you mean, but whatever suits you

vapid prism
#

[field: SerializeField] private int TestInteger { get; set; } serializes to <TestInteger>k__BackingField on 2020.3

FindProperty does not find TestInteger but does find <TestInteger>k__BackingField

carmine quiver
#

(imo, once you do serialization, you shouldnt do properties. But thats just my opinion)

vapid prism
#

So the thing i explained about auto implemented properties is what's currently screwing you over

#

so you have to do FindProperty("<CanPlayerMove>k__BackingField") if you actually want to use a backing field.

#

It will be a lot simpler to not use auto properties here

celest pilot
#

I'm using 2021.11.1f

celest pilot
#

I did both

vapid prism
#

The easiest solution here is what Tijmen was hinting at, do not use properties. Also never use [field: SerializeField] until you're comfortable with auto properties

celest pilot
#

could you repeat what he said? I didn't quite catch it...

vapid prism
#

If you want to use C# Properties make sure to type out the full backing field yourself

#

That way you will have control of that Properties serialization

#

as an example:

#

Instead of cs [field:SerializeField] public int MyIntegerProperty {get; private set;} always do```cs
[SerializeField] private int _myIntegerField;
public int MyIntegerProperty
{
get { return _myIntegerField; }
private set { _myIntegerField = value; }
}

#

then in your custom editor you simply FindProperty("_myIntegerField")

#

and it will always work

celest pilot
#

I see, thanks !

#

say @vapid prism I know this is not a place to ask this but would you be up for testing my game sometime?

vapid prism
celest pilot
trail dawn
#

You're also not allowed to post off topic in these channels.

#

You can't post random download links, obviously. We already have enough bots scamming people that way.

celest pilot
trail dawn
#

You can, of course, use itch to share you game.

celest pilot
trail dawn
celest pilot
#

great thanks

zenith estuary
#

Easy enough to make a FindAutoProperty extension method

#

Alternatively the method can do a normal FindProperty, and if that returns null, attempt to find <PropertyName>k__BackingField

visual stag
#

If they just wanted a modified header, they should have just made a property decorator, not a whole editor

thick bay
#

uhoh i've been brought to the dark side

crude relic
#

As I was saying you could probably have an easy solution by serializing the array of objects

thick bay
#

objects being what a class or struct

crude relic
#

So something like:

[Serializable]
public class MyClass {
  public Sprite sprite;
  public Sprite[] replacements;
}

// then, in your script body
public MyClass[] sprites;
#

This will appear as a list in the editor

thick bay
#

unity's having a fit about [Serializable] seems to think it doesn't exist

crude relic
#

You need to import the using statement

#

Try clicking the lightbulb in vs

thick bay
#

oh that makes sense

#

right well this seems to work thanks very much kind sir

crude relic
#

👍

teal dagger
#

hello i have a problem can anyone help please?
i made an editor window and cant seem to find how to only allow behavior when clicking inside the green area (Rect)
i tried making a button but it didnt work.
currently my code detects a mouse click anywhere in the window which is not what i want
This is my current Code


            if (Event.current.type == EventType.MouseDrag)
            {
                if (Event.current.button == 0 && insed)
                {
                    TimelineOffset += Event.current.delta.x;
                    GUI.changed = true;
                }
            }
            if (Event.current.type == EventType.ScrollWheel)
            {
                if (Event.current.button == 0 && insed)
                {
                    TimelineZoom -= Event.current.delta.y * TimelineZoomSpeeds;
                    TimelineZoom = Mathf.Min(0, TimelineZoom);
                    //Debug.Log(Event.current.delta);
                    GUI.changed = true;

                }
            }
gloomy chasm
teal dagger
#

@gloomy chasm dude thank you so much :))))))

gloomy chasm
civic yoke
#

ok

finite cliff
#

I've been looking around online with none seeming to work, what is the correct way to display a GameObject Array in a custom editor?

peak bloom
#

is there a way to serialize the interface IList ? I'm generating the List<T> on runtime via MakeGenerics see below if my question wasn't clear (english isn't my 1st language!)

[System.Serializeable]
public class SomeClass
{
  IList value;
  Type dummy;
  Type createList = typeof(List<>);
  Type[] typeArgs = Array.Empty<Type>();

public SomeClass(VTypes listType)
{
  if(listType != VTypes.None)
  {
      if(listType == VTypes.String)
          typeArgs = new[]{ typeof(string) };
      else if(listType == VTypes.Integer)
          typeArgs = new[]{ typeof(int) };
      //some other types here ...
  }

  dummy = createList.MakeGenericType(typeArgs);
  value = (IList)Activator.CreateInstance(dummy);
}
}```
waxen sandal
waxen sandal
#

Unless you do your own ISerializationCallback implementation that is

peak bloom
finite cliff
#

tbf it was probably working for their case (not a gameobject array)

#

that is, the example I was reading

#

there are quite a few different ways apparently.. one of which was to "do it manually"

waxen sandal
#

Looks like that should work, ObjectField is the manual one which I wouldn't recommend

#

Post some actual code and that might say something more

finite cliff
#
foreach( GameObject go in myGameObjectArray )
{
    go = EditorGUILayout.ObjectField( go.name, go, typeof(                  GameObject ) );
}

so you would not recommend this one, I'm using it (ObjectFiled) for a single object and that did work so.. if all else fails

waxen sandal
#

If you care about resizing of your array or some other built in functionality or arrays, you won't get it by default with that solution

#

And they can be a pain to implement

#

(And you have to handle dirtying and undo yourself)

finite cliff
#

unfortunately doesn't in my case.. not sure what I'm doing wrong it could be the fact this editor is for a SO..

waxen sandal
#

Ah that probably explains

#

You should use this.serializedObject instead of creating your own

finite cliff
#

afk but I will definitely try this it would be a huge help.. thanks!

astral shadow
#

Hey yo!

If I want to replace ALL serialized field instances of a certain type on ALL serialized objects in a project with a new serialized field, how should I approach it?

For example, I have 50 different serialized objects (Scene, Prefab, Scriptable Object)
These have TestGradientField serialized properties.
I want to replace all of these with BetterGradientField and convert their serialized properties into the new structure.

Any ideas?

waxen sandal
#

If not, I'd write a one time utility to fix it

#

I.e. Load all scenes, for each scene find either known types with that field or all monobehaviours, fix them up using serializedProperties, save scene then load all scriptableObjects with that field

astral shadow
#

@waxen sandal
Formerly serialized may not work because I have a much different structure. Like subtypes
I think I have to write migration code

So yeah I'm doing the one time utility right now! Thanks!

waxen sandal
#

Ah yeah, then the one time thing is the best

#

I've done similar things in the past where I rewrote all monobehaviour references to reference scripts in Unity rather than in a DLL

waxen sandal
astral shadow
hexed kernel
#

Is it possible to check if the build setting contains a certain scene in an editor script?

peak bloom
#

int index = SceneUtility.GetBuildIndexByScenePath("Assets/Scenes/Scene1.unity");// path to your scenes

boreal tangle
#

Hey guys if I want to add images to my custom Editor whats the correct syntax? .GUILayout Image? or something like it?

gloomy chasm
#

If you want to set the size then you will need to use GUI.DrawTexture

tough cairn
#

what's the current method to get json from a server and download zip files from within the a unity editor window ? i am hoping to avoid installing extra libs

waxen sandal
#

HttpClient works, UnityWebRequest should also work

tough cairn
#

which one has wider support for older versions ?

peak bloom
#

I've got massive json file, and the smallest it can get is around 12mb it can get to 20+ mb sometimes. Trying to re-serialize it right before building via IPreprocessWithBuildReport.

public class VProcessBuild : IPreprocessBuildWithReport
{
      public int callbackOrder { get { return 0; } }
      public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) 
      {
          VVariableUtils.ReSerializeOnEditorPlayMode(true);
      }
}

The serialization would sometimes failed (inconsistently). Tried with a dummy file, around 2mb or less it worked consistently. Any idea why this is happening?

The serialization will ofcourse work as it should if it's NOT before build. Only right before building the scene it would failed inconsistently(by inconsistent here, sometimes it worked)

#

if that sounds weird let me know, english isn't my 1st language

waxen sandal
#

Show code

peak bloom
#
        public void StartSerializingVPool(VVariablePools variables, string vobjectGuid)
        {
            json =  string.Empty;
            string fileName = "VelvieR-" + vobjectGuid;
            object obj = variables;
            json = JsonConvert.SerializeObject(obj, Formatting.Indented);
            File.WriteAllText(path + fileName, json);

        }
#

standard serialization stuff, nothing much tbh

waxen sandal
#

Yeah that's weird, should be working just fine

#

Also no async going on so it can't be some weird race condition

peak bloom
#

yes, no async at all

#

do you think it's a bug?

waxen sandal
#

I guess but I wouldn't know in what

south beacon
#

Hi, is there a way to listen to Mouse Input (Mouse4 & Mouse5) in an Editor extension? I used "MenuItem"s and tried to rebind them in my Unity Shortcut Menu, but I can't bind mouse buttons there

tough cairn
#

how to get target for Property drawers ? the following always returns null for me

var target = ( MyClass ) fieldInfo.GetValue( property.serializedObject.targetObject );
visual stag
tough cairn
#

i use this as a single public field , its not a collection

#
class ClassA : Mono
{
  public ClassB field;
}
...
[CustomPropertyDrawer(typeof( ClassB ))]
public class Drawer : PropertyDrawer
{
  // ...
}
#

also tried :

var target_o = property.serializedObject.targetObject;

var target = target_o.GetType().GetField( property.name ).GetValue( target_o ) as ClassB ;
waxen sandal
#

@onyx harness Any chance you can add unity packages to your api versioner? e.g. TMP

shadow fractal
#

Hey,
I made a Unity Engine Toolbar but i am not able to put the prefab inside it.
i made a prefab by making a 3d shape then make a cube then put it in assets then it turned blue then i delete it from scene then add it there but it would still show none
if this is correct then i will give the code

waxen sandal
#

Show code

shadow fractal
#

okay

waxen sandal
#

Don't recreate your SerializedObject and store it in the EditorWindow instead of recreating it

#

Also, dispose of it when you're done with it

#

e.g. in the OnDisable

onyx harness
# waxen sandal <@264188849788289024> Any chance you can add unity packages to your api versione...

Hello there, there is an extremely low chance of me implementing packages.
These are the reason why Sabresaurus shut the door.
I already made a pre-research about them, and it sounds much more heavier and complexe (I'll explain complex below), since I have to make a parallel system commit-based instead of Unity-version-based.
Due to the potential sheer size, my personal database (100MB) might not have enough space for the packages (UI, TMP, and more?).
Since it is not making me any money, I am not encline to invest some to upgrade the DB. (beside the whole implementation complexity)

The main culprit is: I have to compile packages commit against every Unity versions due to... Preprocessor! 😁
And this single thing makes everything much more complex.

shadow fractal
#

pardon i am a student i just started unity

shadow fractal
#

GameObject?

shadow fractal
#

@waxen sandal ?

crude relic
#

@zenith estuary whenever you're on, wondering if you know anything about the compact int array format unity uses in its meta files. My code breaking skills are dumb and I don't understand what they're doing here

zenith estuary
crude relic
#

yeah, I got that far at least 😄

zenith estuary
#

There is a flag for serialized values internally called TransferHex64 too

#

("Transfer" is generally what Unity calls (de)serialization internally)

crude relic
#

hm

zenith estuary
#

I'm assuming it's quite literally just raw binary data in hex

crude relic
#

so it's just a bunch of fixed size hex values then

zenith estuary
#

Probably because indices can be in different formats

#

int16 and int32

crude relic
#

why would that matter for serialization

zenith estuary
#

It's just a more compact way to store it, I imagine

waxen sandal
#

^

#

Try storing a mesh in json or yaml sometime, it's fun

zenith estuary
#

Text compresses well, and there is a lot of repeating data there in sequence

crude relic
#

no, I get that the hex is more compact for serialization, I don't understand the part where you care if it's int16 or int32 when serializing it

zenith estuary
#

Whereas if it were an array, it'd be a lot of strings of varying length

zenith estuary
crude relic
#

hm

zenith estuary
#

it means that if the indices are 16-bit

#

each index is just FFFF

crude relic
#

I just figured that it was purely for compactness & compressability

zenith estuary
#

I imagine that's the case, yeah

crude relic
#

anyway, thanks for telling me I'm overthinking it 😄

waxen sandal
#

A bit yeah, Unity used to only support 16bit indices

#

And thus likely since the engine relied on 16bit, why not also do serialization the same

crude relic
#

remind me, that would be ... big endian?

waxen sandal
#

No? endianness is only about bit order

zenith estuary
#

byte order*

waxen sandal
#

Right yeah

zenith estuary
#

So yes, endianness matters here

crude relic
#

I'm talking about how the significant digits are on the left

#

I can never remember which is which (spot the high level programmer)

zenith estuary
#

That should be little endian

#

1B 00 00 00 is 27 in little endian

crude relic
#

time to go build a serializer 😄

#

thankfully I don't have to deserialize it

zenith estuary
#

If the indices are 16-bit, then it would be 1B 00 which would be 6192 in big-endian

#

or 27 again if still little-endian

#

both values seem possible, can't know for sure without actually seeing the mesh data lol

crude relic
#

I'm going to assume that it's 32 bit since the indices array is int

#

this is for sprites

zenith estuary
#

It's easy to verify anyway

#

just grab the indices in unity and print them

crude relic
#

yah

#

I was being lazy and not wanting to do any practical testing to figure this out 😄

#

also, I cannot believe I never knew about EditorJsonUtility, that thing is seriously magic for editor work

zenith estuary
#

It's a very handy tool when combined with proxy types

crude relic
#

yeah, I'm currently building out proxy types for TextureImporter

#

so I can import newly generated texture files (with sprites attached etc.) in one pass

#

thus the need to serialize a meta file by hand

solid root
#

How can I create an intfield with 3 ints next to eachother with their own labels? Identical to the position property on transforms

spiral trout
#

Is there any extension to show logs as warnings on Rider or VS ?

hybrid oar
#

Hi, how can i access functions like buttons do

hybrid oar
soft shadow
#

Hello, is it possible to have editor only persistent fields per component? Here's a minimal example of what I'm trying to do:

public class BuildArea : MonoBehaviour
{
    // This isn't used in the game. It only exists to display
    // things in the editor.
    public bool editor_draw_details = false;
}

[CustomEditor(typeof(BuildArea))]
public class BuildAreaEditor : Editor
{
    [DrawGizmo(GizmoType.NonSelected | GizmoType.Selected)]
    static void DrawSceneVisualisation(BuildArea build_area, GizmoType gizmoType)
    {
        if(build_area.editor_draw_details)
        {
            // draw more stuff
        }
    }
}

Is there a better way to achieve this? It would be nice not to have data in the component that isn't necessary during the game's runtime.

waxen sandal
#

I think you can technically wrap them in #if UNITYEDITOR but iirc it throws some warnings sometimes

#

Also you might still have the serialized data in the build

soft shadow
#

Thanks for the info. From searching around it seems there isn't a straightforward way to do it. I can leave the data in the MonoBehaviour for now.

brisk girder
#

Is there a way to make a label field show ellipsis (...) when the text is too long?

gloomy chasm
brisk girder
#

:/

#

Thanks for the info

gloomy chasm
#

I have an implementation if you want it 🙂

brisk girder
#

I'd love to, actually, it would make things much easier

gloomy chasm
#

I just ripped it out of the codebase that I created it for, so it might require a bit of editing, but should be pretty minor

brisk girder
#

Alright, thanks a lot!

gloomy chasm
#

Sure thing! It was a real pain to do, so happy to save someone else the pain too.

brazen tiger
#

I am facing an issue,
I have included " UnityEditor.EditorTools" namespace, but when trying to use ToolManager class I get error
"the name 'toolmanager' does not exist in the current context"
how to fix this?

#

Please.. can anyone help?

minor palm
#

Hello all, i apologize in advance if this is the wrong channel for this. I'm just diving into custom editors, this editor i made looks "normal" when viewed in the original scene and prefab it lives on. However when manually added to an object it become "squished" or misformatted. Any ideas? Both pictures are same script with same editor script.

waxen sandal
#

Is it an Editor or a PropertyDrawer?

glacial sail
#

Is there a way to detect Addressable changes in editor and run some code when it happens?

#

Specifically I'm trying to detect addressables being added/removed from a group.

#

I guess detecting changes on an .asset file could work too.

waxen sandal
#

IIRC there's a callback somewhere but I forget where

shadow fractal
#

Why is it not working 😦

#

cant put prefab

minor palm
waxen sandal
#

Probably a bug then

#

Try updating

lilac prawn
#

I have a question: I added a HelpBox (EditorGUILayout.HelpBox) to my custom inspector, but the message text is super small. Can I somehow increase it?

cosmic inlet
#

ok so

#

is there any way

#

I can publish a scene and all the models used in it

#

and then load it at runtime?

#

like, someone can publish a scene to my database and then load it in game

waxen sandal
#

Addressables is an option

#

Also wrong channel

ivory hearth
#

How do I add another editor extension which results in two assembly definition assets correctly?

#

This one also has its own Editor file aswell as the other one which has its own editor file too

#

this happens otherwise

ivory hearth
gloomy chasm
ivory hearth
gloomy chasm
ivory hearth
# gloomy chasm I'm sorry, can you try explaining the issue again in detail? What exactly are yo...

I am wanting add and use both TextMesh pro Effect and BrightAnimator which are both Editor extensions. However, upon adding both into the same project they seem to interfere with one another due to there being two files of unity tries to use.

This results in the UnityEditor.Buildplayer and numerous "couldnotbefound" errors. What should I do to have them both work simultaneously without errors?

#

Do I create a new editor file and only place what was in its editor files and what to do with two Unity Assembly definition assets?

gloomy chasm
#

It looks to me like the editor scripts are being included in the build which is resulting in the errors.

#

Does the BrightAnimator/Runtime/Editor folder have a assembly definition in it?

ivory hearth
gloomy chasm
ivory hearth
#

its to any platform

gloomy chasm
#

The assembly definition overrides the default behavior of putting scripts in any folder called Editor in their own assembly.

#

So if you have a assembly definition for only editor scripts, you need to set it as such

ivory hearth
#

this seems to have removed most of its files and given this message, its also blanked the two scripts and attachments left

#

over thousand errors

#

re import i go

#

could you maybe look into the extension for me? it could be very well that something is wrong with it on its own but am unsure

gloomy chasm
#

@ivory hearth I took a quick peek at the githib and your package is all messed up. It looks fine on github

ivory hearth