#↕️┃editor-extensions

1 messages · Page 106 of 1

patent pebble
#

then you'll probably need to use an EditorWindow instead of an Editor script

unkempt sparrow
#

ok

#

like so?

[MenuItem("Window/VRtex Studios")]
        public static void ShowWindow()
        {
            varLoaderEditor window = GetWindow<varLoaderEditor>("VRtex Studios");
            window.Show();
        }
patent pebble
#

yes check the documentation for EditorWindow

unkempt sparrow
#

ok

#

will do

patent pebble
#

but the data won't get serialized (saved) like it does with an Editor script
if you close and open the EditorWindow the data will reset to the default values

#

that's probably fine for some situations, it depends on what you're doing exactly

unkempt sparrow
#

ahhh i see yeah it will be open the entire time of use unless someone accidentally closes it

#

there is a save mid way though aswell but this was really annoying me haha

#

thank you very much

unkempt sparrow
#

why do all my sliders slide together?

patent pebble
#

probably because they are all using the same field

tardy pecan
#

Hey does anyone know why some scriptable objects are changing InstanceID? Like I'm trying to save UIElement.ObjectFields referencing a scriptable object as Json, but when I reload the project after a restart or something, their instance IDs have changed and loading them via the old value in the JSON leads to wrong objects being loaded

waxen sandal
#

InstanceIds aren't persistent and are reliant on what order assets are loaded in

#

You can use GUIDs instead perhaps

tardy pecan
#

yeah so I guess my system can't work this way, I took another approach and I now save my stuff in nested scriptable objects (that have correct references)

#

thanks for the help tho

unkempt sparrow
#

i had the script working just fine and turned on my pc today and now am getting this error

#
using System;
using UnityEngine;

namespace VRtexStudios
{
    public class VarLoader : MonoBehaviour
    {
        public GameObject avatar;
        public int BlendShapes()
        {
            SkinnedMeshRenderer mesh = avatar.GetComponent<SkinnedMeshRenderer>();
            Mesh currentMesh = mesh.sharedMesh;
            return currentMesh.blendShapeCount;
        }
        public Array getBlendShapeNames ()
        {
            SkinnedMeshRenderer mesh = avatar.GetComponent<SkinnedMeshRenderer>();
            Mesh m = mesh.sharedMesh;
            String[] arr = new string[]{};
            for (int i= 0; i < m.blendShapeCount; i++)
            {
                arr[i] = m.GetBlendShapeName(i);
            }
            return arr;
        }
    }
}
#

thats the current main script and i have no clue why its not assigning avatar. any ideas?

waxen sandal
unkempt sparrow
#

ok

unkempt sparrow
#

i make a slider for each blendshape and need them on seprate fields how do i do that?

#

i have them as all separately generated names but none move independently

#
for(int i = 1; i < totalShapes; i++)
            {
                scale = EditorGUILayout.Slider(Blendshapenames[i],scale, 0, 1);
            }
#

that is how i generate them

#

what is moves like

gloomy chasm
unkempt sparrow
#

so make a array of floats and assign it to them?

gloomy chasm
unkempt sparrow
#

each of them need to be customizable and i need to be able to save a current state of them all

gloomy chasm
#

Since you have a collection of blend shape names, I assume you are wanting to set the value of the blend shapes

unkempt sparrow
#

yes

gloomy chasm
#

So set the value of the blend shape then... no? If you want to just store the values, then yeah you will need a array/list of floats

unkempt sparrow
#

ok awesome thank you 🙂

#

@gloomy chasm you still here?

gloomy chasm
unkempt sparrow
#

sorry for the @

gloomy chasm
#

If ya have a question, ask and someone will answer. If it is about a previous conversation you can either at me or reply to my previous message. But please include the question in the message

unkempt sparrow
#

i have set up the array and i get no errors whether it be syntax or in unity but i am now unable to slide any of the sliders.

#

yeah thats why i @ you cause its about the same problem

#

my bad for not having the question in there

#

sorry

gloomy chasm
#

All good, now you know for the future 🙂

unkempt sparrow
#

thank you 🙂

gloomy chasm
unkempt sparrow
#

class definition method assignment

#
namespace VRtexStudios
{
    [CustomEditor(typeof(varLoader))]
    public class varLoaderEditor : Editor
    
    {
        public int totalShapes;
        public string [] blendShapeNames;
        public float [] blendShapeVal; //decleration
        private static float scale;

/*
        [MenuItem("Window/VRtex Studios")]
        public static void ShowWindow()
        {
            varLoaderEditor window = GetWindow<varLoaderEditor>("VRtex Studios");
            window.Show();
        }
*/
        public override void OnInspectorGUI()
        {
            varLoader mainWindow = (varLoader)target;
            if (GUILayout.Button("Collect Blendshapes"))
            {
                totalShapes = mainWindow.BlendShapes();
                blendShapeNames = mainWindow.getBlendShapeNames();
            }
            EditorGUILayout.IntField("Blendshapes", totalShapes); 
            blendShapeVal = new float[totalShapes]; //asignment
            for(int i = 1; i < totalShapes; i++)
            {
                blendShapeVal[i] = EditorGUILayout.Slider(blendShapeNames[i],scale, 0, 1);
            }
        }
    }
}
gloomy chasm
unkempt sparrow
#

ooo

#

that makes sense

gloomy chasm
#

Also note that since you are defining it in the Editor class, the values will not be saved to the component so when you select a different GameObject the values will be lost

unkempt sparrow
#

hmmmm

#

so if i define it in the script then use it in the editor would i be able to save the values?

unkempt sparrow
#

thank you 🙂

unkempt sparrow
# gloomy chasm You are reassigning it each update, that has the same effect as if you defined i...

so i have refactored it and all variables so there is no reassigning every update. However it still isnt working

namespace VRtexStudios
{
    [CustomEditor(typeof(varLoader))]
    public class varLoaderEditor : Editor
    
    {
        private static float scale;

 public override void OnInspectorGUI()
        {
            varLoader mainWindow = (varLoader)target;
            if (GUILayout.Button("Collect Blendshapes"))
            {
                mainWindow.Load();
            }
            EditorGUILayout.IntField("Blendshapes", mainWindow.totalShapes);
            for(int i = 1; i < mainWindow.totalShapes; i++)
            {
                mainWindow.blendShapeVal[i] = EditorGUILayout.Slider(mainWindow.blendShapeNames[i],scale, 0, 1);
            }
        }
    }
}
patent pebble
#

@unkempt sparrow you are reading the scale value on every the loop

#

of course it's never gonna change

#

your scale value is never changing because you are never assigning anything to it

#

but why are you still using a single float value to represent EVERY value of an array?

#

change scale for blendShapeVal[i]

unkempt sparrow
#

i thought where i had scale was the type of value used on the slider not the value itself

#

works fine now 🙂

patent pebble
#

this is the example in the Slider method documentation

scale = EditorGUILayout.Slider(scale, 1, 100);
#

you need to pay more attention to the docus examples

unkempt sparrow
#

yeah i looked at that specifically

#

i guess i do it also was 330 am when i was doing it haha

#

so makes sense

#

i need to sleep more running on like 3 hours today...... buuut first prototype it done!

idle tree
#

Im running this code to build a library of all the rooms in my game.
I was able to build and run this no problem before, but now im getting errors that AssetDatabase is only do-able in editor.

I dont know why it was building and working before or what changed to make it not, but how do I remove editor namespace dependancy on this code?

#

How do I build a dictionary of all the rooms in my project if I am not allowed to reference the project?

idle tree
unkempt sparrow
#

are you running it in unity?

idle tree
#

Yes

#

Do you mean the errors in console?

unkempt sparrow
#

yes click on one

idle tree
unkempt sparrow
#

and then copy paste the code underneath

idle tree
#

The build fails because I am trying to reference UnityEditor namespace in a build

#

which you can't do

#

but I don't know how to build my dictionary without it

unkempt sparrow
#

why do you need unityeditor namespeace?

idle tree
#

I need a way to do that same functionality, without using AssetDatabase

unkempt sparrow
#

lemme look at something real quick

idle tree
#

Okay

#

the dictionary is <string, GameObject> for reference

unkempt sparrow
#

thank you

idle tree
#

You can't serialize a Dictionary so I can't save it, I have to build it at runtime (to the best of my knowledge)

unkempt sparrow
#

do you have to use assetdatabase?

unkempt sparrow
#

nvm

#

assetdata base is thing you should use for this. i think

#

aight yeah if you make the script in the "Editor" folder and then use assetdatabase you should be fine just have it edit the script it should relate to.

#

this script must be in a folder called "Editor"

idle tree
#

You arent understanding

#

I need this dictionary at runtime, in my game, for my game to work

#

Dictionaries cannot be serialized

#

its fine though I thought about it, I can separate the code to build the list and the dictionary and pre-build only the list during Build I think

unkempt sparrow
#

you can declare the dictionary in the main script and then use them in the editor which will allow you to save them and have them at runtime

patent pebble
#

@idle tree for a simple approach most people just store two lists in a ScriptableObject and then at runtime they make a dictionary from the lists

#

you could also just implement your own serializable dictionary

unkempt sparrow
#

was i close?

patent pebble
#

nope, bunp's problem was because they are trying to read data from an asset at runtime in the build

#

they need to predefine the data somewhere (ie: in s ScriptableObject in the Resources folder) to be able to load it at runtime

#

this whole conversation should have been in other channels like #archived-code-general
this channel is for editor extensions and such

unkempt sparrow
#

ok would they be able to do that if they defined it in there script first and then used a editor to allow for the assetdatabase?

#

check me on this but is this channel for questions regarding custom editors and extensions?

patent pebble
#

yes, any topic related to making editor tools and extending Unity's functionality

unkempt sparrow
#

ok cool just making sure

patent pebble
#

it's important to keep questions and conversations on the topic of the channel

unkempt sparrow
#

will do

#

yeah i feel like i have done a alright job with that so far or would you say i need to improve a significant amount?

patent pebble
unkempt sparrow
#

very true

#

ill do better this is a very big project and i have a decent amount left to do so i will for sure be asking many more questions and hopefully answering questions better aswell.

patent pebble
unkempt sparrow
#

yup i have many times 🙂

#

thank you 🙂

remote yarrow
#

Dictionaries have been serializable for at least 5 years, but you have to use a special callback to do it EDIT: as MedLed linked to - but most of us have by now made this into re-usable code so we don't have to think about it any more) (and there's a wider automated solution Coming Real Soon (tm))

tepid shell
#

Hey there, maybe someone can point me in the right direction.

I have custom timeline track and clips that allow me to loop within a defined section of a timeline while a script is running. I've made it so it's possible to set the start time of the loop with an offset relative to the clip's start time (checkout the screenshot), and everything works quite well.
However at the present time there is no visual information that indicate when the loop will start on the timeline itself, the only information you have is the time offset, in seconds, that you can change manually in the clip's inspector.
Is it possible to add an icon, like an open square bracket for instance, on top of the custom clip's rectangle, in order to indicate when the loop begins? I know I can change the looks of the inspector, but I don't know if I can mess around with the looks of the timeline.

tough stream
#

Hi!
I'm searching for some kind of addon to make my nodal custom window. In the past, i tried making my own nodes, but... It didn't really work out 💀
I'd like to know if you guys know any extensions or package that allow me to create new nodes easily, i've got "XNodes" but idrk what it's worth

waxen sandal
tepid shell
patent pebble
#

this might be kind of a dumb question, but do I need to call SerializedObject.ApplyModifiedProperties if I'm using an EditorGUI.PropertyScope?

#

iirc there's no need for it, but asking just in case

#

can't find a concrete answer online

waxen sandal
#

Yeah you do

#

But most often you do it in a property drawer which handles it for you iirc

waxen sandal
gloomy chasm
#

(I mean that literally all it is)

patent pebble
#

i'm making a sort of generic property drawer base class and neither it nor the derived classes call ApplyModifiedProperties

#

so I was kind of freaking out about the values retaining the data correctly

#

yeah just tested on an EditorWindow, you do indeed need to apply the modifications

gloomy chasm
patent pebble
#

i'm trying to make more complete implementations now so I was going over everything to see how it worked

#

for example I was trying to do SerializedObject.Update() in my drawer which reset the values of all the previous fields to the default value

#

😅 silly me

pure siren
#

Is it possible to mark a serialized object properties as modified?

shadow violet
#

Just curios, is there a way to access the "Select Object" window that pops up when your assigning object fields by the inspector? Im wondering if its possible to make it show up on a button press or something that isnt specifically a ObjectField

gloomy chasm
gloomy chasm
shadow violet
#

Oh aawesome, thanks Mech

pure siren
# gloomy chasm What do you mean?

I'm calling a method with an InspectorGUI button on a MonoBehaviour script. That method reads in some values from a file on and modifies some of the properties. The scene is not showing as modified even though the properties are updated.

#

And if I reload the scene the changes are gone

gloomy chasm
pure siren
#

I'm not modifying the properties with SerializedProperty, because I wanted the method to work at runtime and in Editor, but I'm guessing that's not possible

gloomy chasm
#

However that will not support Undo or prefab overrides

pure siren
patent pebble
#

hmmmm i'm struggling a little bit with PropertyDrawer heights

#

i'm getting different results depending on if the Inspector is docked or not

#

is there a way of getting the EditorWindow in which the current PropertyDrawer is being drawn?

#

i need to know in what window its being drawn to add an extra pixel to get the correct value

#

it's literally just a +1 when the Inspector window is floating not docked to anything

#

it's so annoying... UNITY WHY YOU DO THIS TO ME... 😓

patent pebble
# gloomy chasm Can you show?

sorry not at my computer right now, i can share all the code tomorrow and provide better gifs 😅
Basically i have a property drawer that draws a custom HelpBox that wraps the text.
At some point there's a discrepancy of 1 pixel between the actual WIDTH of the HelpBox and thw width of the inspector,
which makes the box wrap the text but the height gotten from the property drawer doesnt match
The weird bug is that it only happens when the inspector is docked, when it's floating the width and height match perfectly

#

I had shared that gif before

#

I dont know if this is caused by me using a custom GUIStyle with non standard padding values ( i've experienced situations where having odd padding values instead of even values would cause situations like this)
Or maybe it's a floating point inaccuracy issue

#

Or some other obscure internal bug with Unity

#

In that gif there was actual height errors caused by me setting incorrect values. But now i fixed everything, and it works correctly, except for that rogue pixel 😅

elfin robin
#

yo

#

does anyone know why when i parent an object to a bone it changes the anchor point of the bone?

patent pebble
#

@gloomy chasm here's the gif with the problem

#

as you can see, as soon as I undock the window, there's no issue

visual stag
#

welcome to the world of IMGUI

patent pebble
#

🙃

visual stag
#

where pain is pain and pain pain pain

gloomy chasm
#

Odd...

#

Just an idea, and could be wrong, but you could try rounding the x and width after getting them and before using them just incase something is happening there

patent pebble
#

done that already 😅

#

i was printing non-rounded float values, but rounding them didn't fix it

gloomy chasm
#

Can you share the code that calculates the property height?

patent pebble
#

yep, one sec

#
private static float Spacing => EditorGUIUtility.standardVerticalSpacing;
private static float InspectorWidth => EditorGUIUtility.currentViewWidth - EditorStyles.inspectorDefaultMargins.padding.horizontal;
//private static float InspectorWidth =>  EditorGUIUtility.currentViewWidth - EditorStyles.inspectorDefaultMargins.padding.horizontal - 1;

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
    if (ValidTargetType == false)
    {
        Vector2 errorBoxSize = GetErrorBoxSize(_errorContent);
        return Mathf.Round(errorBoxSize.y) + Spacing;
    }
    return base.GetPropertyHeight(property, label);
}

public static Vector2 GetErrorBoxSize(GUIContent errorContent)
{
    float width = InspectorWidth - EditorGUIUtility.labelWidth - Spacing;
    float height = ErrorBoxStyle.CalcHeight(errorContent, width);
    return new Vector2(width, height);
}

private static void SetUpStyle()
{
    ErrorBoxStyle = new GUIStyle(EditorStyles.helpBox);
    ErrorBoxStyle.fontSize = 12;
    ErrorBoxStyle.padding = new RectOffset(24, 5, 1, 2);
}
#

here's all the relevant code

#

i'm also suspicious of EditorGUIUtility.currentViewWidth

#

When docked

  • The point where the wrapping happens visually is at a EditorGUIUtility.currentViewWidth of 339
  • The point where the wrapping actually triggers the correct value is at 337
    When not docked
    -Both happen at 337 in sync
gloomy chasm
#

Okay

#

So it is probably a less than ideal solution

#

but you could get the rect in OnGUI and use its width instead

patent pebble
#

@gloomy chasm that might work. I wanted to avoid having to workarounds like that

#

but seems undocking the window doesn't affect the position Rect

#

while it offsets the EditorGUIUtility.currentViewWidth by 2 pixels

#

i guess Unity just adds 1 extra pixel on each side of the EditorWindow when it's undocked for some god damn reason

patent pebble
#

yah, that's my guess

#

i wonder who thought it was a good idea to do that 😅

gloomy chasm
#

Oooh

#

what are you doing in OnGUI

#

that is where the trouble would be (partly)

patent pebble
#

hmmm i do this

public static Rect DrawGenericError(Rect position, GUIContent labelContent, GUIContent errorContent, bool disableLabel = false)
{
    // Calculate rects
    Rect labelRect = CalculateErrorLabelRect(position);
    Rect errorBoxRect = CalculateErrorBoxRect(position, errorContent);
    Rect errorIconRect = CalculateErrorIconRect(position);

    // Draw label
    using (new EditorGUI.DisabledScope(disableLabel))
    {
        EditorGUI.LabelField(labelRect, labelContent);
    }

    // Draw error help box
    if (Event.current.type == EventType.Repaint)
    {
        ErrorBoxStyle.Draw(errorBoxRect, errorContent, false, false, false, false);
    }

    // Draw error icon
    GUI.DrawTexture(errorIconRect, PropertyDrawerGlobalCache.ErrorIcon);

    return errorBoxRect;
}
#
private static Rect CalculateErrorLabelRect(Rect position)
{
    Rect result = new Rect(position);
    result.x = position.x;
    result.width = EditorGUIUtility.labelWidth;
    result.height = EditorGUIUtility.singleLineHeight;
    return result;
}

private static Rect CalculateErrorBoxRect(Rect position, GUIContent errorContent)
{
    Rect result = new Rect(position);
    result.x = position.x + EditorGUIUtility.labelWidth + Spacing;
    result.width = position.width - result.x + EditorStyles.inspectorDefaultMargins.padding.left;
    result.height = PropertyDrawerErrors.ErrorBoxStyle.CalcHeight(errorContent, result.width);
    return result;
}

private static Rect CalculateErrorIconRect(Rect position)
{
    Rect result = new Rect(position);
    result.x = position.x + EditorGUIUtility.labelWidth + Spacing + PropertyDrawerErrors.ErrorIconLeftPadding;
    result.y += 2;
    result.width = PropertyDrawerErrors.ErrorIconSize;
    result.height = PropertyDrawerErrors.ErrorIconSize;
    return result;
}
#

so in the CalculateErrorBoxRect()
i get the width like:

result.width = position.width - result.x + EditorStyles.inspectorDefaultMargins.padding.left;

and in the method that gets the height for GetPropertyHeight() i do

float width = EditorGUIUtility.currentViewWidth - EditorStyles.inspectorDefaultMargins.padding.horizontal- EditorGUIUtility.labelWidth - Spacing;
#

i guess that's causing the discrepancy

gloomy chasm
#

Yeah you don't have the same logic in them

#

that would be doing it

patent pebble
#

yeah, i mean... one would guess using EditorGUIUtility.currentViewWidth for an editor window
would give a consistent, reliable value that I can use for all of my IMGUI needs!

#

HOW NAIVE OF ME 🙃

gloomy chasm
#

Well you shouldn't really be using that anyway

#

Because if the property is drawn in an editor window it could be very in consistent for what you actually want

patent pebble
#

hmmm yeah

#

what approach do you recommend for this sort of thing
just caching the Rect position from the OnGUI method and using it for the GetPropertyHeight method?

gloomy chasm
#

I think so

patent pebble
#

it seemed like a non-ideal approach since the drawer gets first the height and then draws the OnGUI

#

but eh, i guess it'll do

gloomy chasm
#

Yeah, it isn't ideal

#

My only concern really is that I don't remember how EditorGUI.GetPropertyHeight(..) works

#

Because if that calls the GetPropertyHeight method of the property drawer...

patent pebble
#

yes it does iirc

#

there's an internal method to get the height

#

i've used it a couple times

#

i used it for a PropertyDrawer where I needed to have some custom logic on GetPropertyHeight but then I actually needed to get the "raw" height in the OnGUI method

#
object nullHandler = ScriptAttributeUtilityAccessor.SharedNullHandler;
PropertyHandlerAccessor accessor = new PropertyHandlerAccessor(nullHandler);
propertyHeight = accessor.GetHeight(property, GUIContent.none, true);

by using an "empty" PropertyHandler

gloomy chasm
#

Really what it comes down to is that the property drawer system wasn't made for this sort of thing

patent pebble
#

NaughtyAttributes does that iirc

gloomy chasm
#

Yeah

#

it is the only choice for things like the Button attribute

#

I once helped a guy with some NaughtyAttribute stuff and that is when I learned that it was extremely inefficient

patent pebble
gloomy chasm
patent pebble
#

oh yeah

#

Naughtyattributes also likes to break your inspector under certain conditions

gloomy chasm
#

I think that case may be that they simply don't understand how IEnumerable works though (in the case of the reflection example)

patent pebble
#

yeh maybe

#

one time NaughtyAttributes locked my entire project because I had deleted a script and there was still fields of that type
so their Editor override was freaking out and not rendering anything

gloomy chasm
#

But overall I found the code kind of messy

patent pebble
#

there's also StackableDecorators, i digged around through their code and I think they do all of their stuff in actual PropertyDrawers and not overriding the Editor
and they do anything NaughtyAttributes can do

onyx harness
patent pebble
gloomy chasm
patent pebble
#

well I was about to try implementing a PropertyAttribute for adding a button to a method

#

so I guess I'll find out the hard way lmao

patent pebble
#

lol RIP

gloomy chasm
#

Actually, I wonder if you can inherit from it and use AttributeTargets.Method

patent pebble
#

only one way to find out

#

BRB

gloomy chasm
#

👍

patent pebble
#

nah it doesn't call the OnGUI method

onyx harness
#

You can always add the name of the method as an argument of the Decorator

#

But you will end up with static only

patent pebble
#

@onyx harness yeah but if you use a PropertyAttribute in a method the drawer doesn't call any of the methods

#

it just becomes useless

#

i wonder if there's some internal callback to hook up to Editor GUI updates

#

similar to EditorApplication.projectWindowItemOnGUI

onyx harness
#

You can't put a PropertyAttribute on a method O_o

patent pebble
#

i mean, unity lets you do it

#

it just doesn't do anything with it

minor knoll
#

Does anyone have an idea on how to automatically uncollapse the hierarchy when starting the game? I hate it that Unity automatically collapses the hierarchy upon entering play mode.

patent pebble
#

are you sure you don't have some tool or something that collapses your hierarchy

#

test if an empty project does the same thing

minor knoll
#

It's a multiplayer game with an extra scene for loading all the background stuff and I think once there is a dontdestroyonload in it, it automatically collapses everything

dull rune
#

Hello. I have 2 monitors. In monitor 1 I keep my visual studio in other the Unity editor. I would like that any time I press save in Visual Studio the editor compiles the changed scripts. Unfortunately its only happening when I move my cursor over the editor and focus it. This is very ineffective and I wonder if it can be tuned as I describe?

barren moat
#

I believe it would be possible to write a an editor script that does this, but you'd probably need to set up a file watcher and force a reimport when any file changes.

#

There may be an option for this I'm not aware of.

remote yarrow
dull rune
#

Like it read my mind orsmth

waxen sandal
dull rune
waxen sandal
#

A better ide than vs

warm valve
#

Hi, is it possible to change docked editorwindow width from the script?

gloomy chasm
warm valve
#

actually I want to change it without undocking.. Right now if I set EditorWindow position it automatically undocks. I want to prevent it.

#

I need to set the exact width of the docked window, just as I do it in UI

gloomy chasm
#

Ah, you will need to use quite a bit of reflection to do that

warm valve
#

trying to hack that right now.. thought maybe somebody already done it 🙂

gloomy chasm
#

Why are you trying to set the width in the first place?

warm valve
#

well, I need to render my scene view pixel perfect: so that all texels would be perfect squares. I thought maybe snapping the editor window size would be the easiest way to do it 😄

#

its not a problem for gameview, I can easily control that with camera rect (by adding small line so that all pixels are squares). But in scene view I cant change the camera rect.

#

well, I can, but it gets overwritten somewhere I think.. has no effect unfortunatly

dull rune
#

Hmm, not free.. cancel

obsidian skiff
teal timber
#

is the preview window some kind of scene or "place" i can put arbitrary things for previewing assets, or like if i want a 3d thing there do i need to actually just render it using a camera onto a rendertexture or whatever

#

an example close to what i'd actually like to do is create a preview for a scriptableobject asset which would display a UI element based on the strings and textures contained/referenced in the scriptableobject

waxen gate
#

is plasticscm down because it takes 2 minutes for me to preview my game and it gives the error message "the host closed the socket"

#

i just straight up cant playtest my game because every frame its trying to run this

iron wadi
#

Hi guys. I took this screenshot from a 3rd party asset and I wonder how I can implement my own buttons like this.

I am experienced on developing editor extensions but I have no idea about how to do this.

Any idea how to start?

gloomy chasm
patent pebble
# iron wadi Hi guys. I took this screenshot from a 3rd party asset and I wonder how I can im...

for a regular EditorWindow that you make, you can do this to add buttons to the top bar and generic menus to the three dots menu

public class EditorWindowTopBarButtons : EditorWindow, IHasCustomMenu
{
    private GUIStyle _lockButtonStyle => "IN LockButton";
    private bool _locked = false;

    [MenuItem("Test/Top Bar Buttons")]
    public static void MakeWindow()
    {
        EditorWindow.GetWindow<EditorWindowTopBarButtons>();
    }

    // Add generic menus to the three dots button
    void IHasCustomMenu.AddItemsToMenu(GenericMenu menu)
    {
        menu.AddItem(new GUIContent("Lock"), _locked, FlipLock);
        menu.AddItem(new GUIContent("Button"), false, DoButton);
    }

    // Magic method which Unity detects automatically.
    private void ShowButton(Rect position)
    {
        // Drawing a toggle
        _locked = GUI.Toggle(position, _locked, GUIContent.none, _lockButtonStyle);

        // Drawing a button
        position.x -= position.width;
        if (GUI.Button(position, ""))
        {
            DoButton();
        }
    }

    private void FlipLock()
    {
        _locked = !_locked;
    }

    private void DoButton()
    {
        Debug.Log("Button pressed");
    }
}
#

but the screenshot you shared is probably doing something different

onyx harness
#

It probably uses exactly ShowButton

patent pebble
#

or can you use ShowButton to add to the Unity default windows?

onyx harness
#

ShowButton is not clipped

#

that's the trick

patent pebble
onyx harness
#

You can overdraw out of the given Rect

patent pebble
#

ah lol

onyx harness
#

Try it with a Button or a DrawRect

patent pebble
#

so you think they're creating a mock editorwindow and using the ShowButton from there?

#

to add it to the Project browser window?

onyx harness
#

Oh you are right, I forgot it was in Project window

#

Well probably injected I would say

patent pebble
#

yeh that was my guess

#

maybe you could just gett the total Rect of the Project browser window and draw the buttons on the top right

#

but i guess they are doing something else since they also inject the star button for the favorites thing on the top left

onyx harness
#

Oh I thought the star was from recent Unity

patent pebble
#

no idea, looks like a custom thing

#

but i don't know

gloomy chasm
#

So basically.. what I said to start with 😛

iron wadi
#

Thanks guys for detailed info. I checked what Harmony is. It looks like an interesting library but I won't go to that length (like injecting code to Unity editor) just to be able to add a button to project window. I'll see what I can do with UIToolkit.

#

@gloomy chasm I developed IMGUI extensions for Unity but I haven't experienced UIToolkit yet. Even if I implement my own window with UIToolkit, how am I supped to inject a button into an existing window? Like querying for the project window in a DOM like object structure?

gloomy chasm
iron wadi
#

Thank you. I'll check that.

Also, I have this checkbox implemented before with the help of a library called UnityToolbarExtender.
https://github.com/marijnz/unity-toolbar-extender

Now I checked the source code of this library and saw that it's doing its job with reflection and by looking for a VisualElement in a Root object. This root object is in a scriptable object called "UnityEditor.Toolbar" and loaded by Resources.FindObjectsOfTypeAll method. Interesting stuff...

That's the same way you showed in your example. Thank you!

#

One last question. How would I know the value of projectBrowserType ?

onyx harness
#

By cleverly searching it

iron wadi
#

Ok

#

Thank you guys

onyx harness
#

Project is trickier than the rest

#

as its type name is not following the "normal convention"

#

UnityEditor.ProjectBrowser is what you want

iron wadi
#

Awesome. Thank you!

onyx harness
#

"ProjectBrowser" does not follow the common "Window" suffix

waxen sandal
#

Anyone knows where the gradle external tool settings are located in the source? I find references to IPreferenceWindowExtension and HasExternalApplications but no gradle implementation of that exists

#

Or what the editorpref is called that lets you use a non bundled gradle?

waxen sandal
#

Foudn it btw, GradleUseEmbedded

gloomy chasm
#

Anyone know how you get an object field to show the "Missing (..)" text?

patent pebble
#

and if you passed a non-valid InstanceID it would show that

#

but can't remember

gloomy chasm
patent pebble
#
private void OnEnable()
{
    _go = new GameObject();
    DestroyImmediate(_go);
}

private void OnGUI()
{
    string missingString2 = EditorGUIUtility.ObjectContent(_go, typeof(GameObject)).text;
    EditorGUILayout.LabelField($"missingString2: {missingString2}");
}
#

what's the name of the style to get the "Missing" thing? I'm curious

gloomy chasm
patent pebble
gloomy chasm
patent pebble
#

ah they just manually do it

patent pebble
#

@gloomy chasm ah digging around on my reflection examples found this one

public class EditorGUIUtilityAccessor
{
    private static MethodInfo MI_ObjectContent = typeof(EditorGUIUtility).Method("ObjectContent", new Type[] { typeof(Object), typeof(Type), typeof(int) });

    public static GUIContent ObjectContent(Object obj, Type type, int instanceID)
    {
        return (GUIContent)MI_ObjectContent.Invoke(null, new object[] { obj, type, instanceID });
    }
}
#
GUIContent missingString = EditorGUIUtilityAccessor.ObjectContent(null, typeof(Material), -1);
EditorGUILayout.LabelField(missingString);

GUIContent noneString = EditorGUIUtilityAccessor.ObjectContent(null, typeof(Material), 0);
EditorGUILayout.LabelField(noneString);
#

if you pass an instance ID of -1 it gives you the "Missing" content
and 0 for "None" content

onyx harness
#

Maybe you can create a fake missing Object

#

by assigning its InstanceID to -1

patent pebble
#

@onyx harness is there a way to change the instance ID of an object?

onyx harness
#

Reflection

#

Or serialization

patent pebble
#

ah, right

onyx harness
#

Dont do that on existing object though

#

probably not good idea

#

But if you want to fetch any object, you can create an empty Object, reassign its InstanceID and serialize it, you will have all its content fetched naturally

gloomy chasm
#

I mean, that all could work, but also just drawing the style seems like a much more stable and performant solution

onyx harness
#

I would prefer drawing the style too

#

But if you prefer to stay consistent in using an Object, creating a fake object does not cost anything

patent pebble
#

ah, note for the reflection approach
using the internal EditorGUIUtility.ObjectContent() causes problems because it caches the content in this field

private static readonly GUIContent s_ObjectContent;

so if you do this

  • Call ObjectContent to get a "Missing" content
  • Call ObjectContent to get a "None" content
    -Draw with EditorStyles.objectField.Draw using the missing content
    -Draw with EditorStyles.objectField.Draw using the none content

both of your draws will get the "None" appearance

#

you can instead just use this other internal method to get the "Missing" GUIContent

private static extern string GetTypeNameWithInfo(string typeName, int instanceID);
#

it's what they use internally

internal static GUIContent ObjectContent(UnityObject obj, Type type, int instanceID)
{
    if (obj)
    {
        s_ObjectContent.text = GetObjectNameWithInfo(obj);
        s_ObjectContent.image = AssetPreview.GetMiniThumbnail(obj);
    }
    else if (type != null)
    {
        s_ObjectContent.text = GetTypeNameWithInfo(type.Name, instanceID); <-------
        s_ObjectContent.image = AssetPreview.GetMiniTypeThumbnail(type);
    }
    else
    {
        s_ObjectContent.text = "<no type>";
        s_ObjectContent.image = null;
    }
    return s_ObjectContent;
}
#

pass instanceID of -1 to get "Missing" and instanceID of 0 to get "None"

#

I don't know if Unity ever uses the instanceIDs -1 and 0 for internal stuff tho
haven't seen it so far, but who knows 😅

onyx harness
#

0 is by default a none existing object

#

So pretty sure it is widely used in their codebase

patent pebble
#

i mean if they only use it for a non-existing object it should be fine

onyx harness
#

We use -1 for a natural non-used ID, but perhaps 1, 2, 3, etc. are also missing ones 🙂

patent pebble
#

seems safe enough then

#

if it ever makes my Unity explode i'll share the cautionary tale 🙃

eternal surge
onyx harness
#

Nice job, but wrong channel @eternal surge

eternal surge
#

What would be the fitting channel? It may fit asset-store-advertising, but I didn't put it on the asset store but only GitHub

stark geyser
eternal surge
#

ah, makes sense. thank you very much

visual yacht
#

Hello 🙂
I would like to understand how to implement undo in the editor
I want to replace GameObjects from the scene with prefabs

I have a editor script with this sequence within a method:

foreach ( GameObject sceneGameObject in selectedObjectsInScene){
  PrefabGameObject = GameObject.Instantiate(GameObjectReplacement) as GameObject;
  Undo.RegisterCreatedObjectUndo(PrefabGameObject, "created object");

  PrefabGameObject.transform.position   = sceneGameObject.transform.position;
  PrefabGameObject.transform.rotation   = sceneGameObject.transform.rotation;
  PrefabGameObject.transform.localScale = sceneGameObject.transform.localScale;
  PrefabGameObject.transform.parent = sceneGameObject.transform.parent;  

  Undo.DestroyObjectImmediate(sceneGameObject);
}

Everthying works as intended, but Unity crashes when hitting ctrl+z after running the script.
It seems the problem comes when calling Undo.RegisterCreatedObjectUndo(..) as when I comment it out, unity does not crash anymore

any ideas?
I am not sure the explanations on in the manual can help me ( https://docs.unity3d.com/ScriptReference/Undo.html)

gloomy chasm
# visual yacht Hello 🙂 I would like to understand how to implement undo in the editor I want ...

I think it looks okay... Simply for a readability thing I would change PrefabGameObject to be defined where it is instatiated, so GameObject prefabInstance = (GameObject)GameObject.Instantiate(GameObjectReplacement);

You also want to combine all of the undo operations in to one so that when you perform an undo/redo all of the gameobjects will be destroyed and created in the same operations

int undoGroup = Undo.GetCurrentGroup();

// foreach loop here...

Undo.CollapseUndoOperations(undoGroup);
patent pebble
#

just a random guess, your Editor may be crashing because you are destroying an object that is part of the undo operation?

#

try to do the PrefabGameObject.transform.position, etc lines before the RegisterCreatedObjectUndo and see what happens

visual yacht
visual yacht
patent pebble
#

i actually had no idea if that was the problem, just a random guess 😅

#

glad it's working

gloomy chasm
#

I am trying to find a way to not use harmony for this thing I am doing. And I almost have found a way....
Not for the first time I have wished I could inherit from an internal class 😢

gloomy chasm
patent pebble
#

sounds like one of those things that seems simple enough but then Unity does a 360 on you

#

"pls unity stop being unity"

#

😢 ...

onyx harness
#

Harmony in an asset in the Asset Store is dangerous, hope you will go through

gloomy chasm
#

There is a VisualTreeUpdater that takes a list of IVisualTreeUpdater and does exactly what I want... if I could implement IVisualTreeUpdater in a class

patent pebble
gloomy chasm
#

I know some assets use it. Like the Needle guys just released an asset that uses it I know

remote yarrow
# visual yacht Hello 🙂 I would like to understand how to implement undo in the editor I want ...
  1. There are magic methods you're supposed to use (that aren't mentioned in the main API docs - you have to know they exst before you can discover they exist ;)) instead of core methods if you want Undo to work correctly. There are replacements for (off the top of my head): .position, .rotation, .transform.parent, and AddComponent <-- the parent one is important and the addcomponent one is slightly important. You don't have to use them (apart from the parent one - not using that one causes actual problems) but they are worth using. Almost no-one knows about these, but then ... Undo doesn't work correctly for most assets so that's not a surprise 🙂
  2. Unity wrote a one-class utility that makes Undo much easier to get right, and auto-compiles-itself-out of non-Editor builds. It's called "UndoBlock". It's here: https://docs.unity3d.com/Packages/com.unity.reflect@1.0/api/Unity.Labs.Utils.UndoBlock.html - you can get the source from their repo IIRC.
  3. ...UndoBlock is missing some features/API calls required to fully implement Undo in Unity, so I use an extended version of that class (which I sent back to Unity, the changes might (?) have been incorporated), and now it's easy to make Undo work in new assets/projects.

I've been filing bugs on Unity's Undo implementation since approx 2014. I consider it an embarassment that it was never really tested or designed.

gloomy chasm
# remote yarrow 1. There are magic methods you're supposed to use (that aren't mentioned in the ...

What magic methods do you mean...? As far as I know there are no 'undo alternatives' for setting the position or rotation.

Undo doesn't work correctly for most assets
What do you mean? Do you mean that most assets don't implement it properly, or that Undo doesn't allow functionality that would support most assets?

Man that Unity.Labs package has so many handy utilities! Too mad it is not on github 😦
The undo block is pretty basic right? Just a get and collapse the undo group, no?

remote yarrow
#

IME: Most assets don't implement Undo correctly. You can undo some actions but not all, or you can undo 'everything' or 'nothing' but not 'the actual steps I performed, in reverse order'. etc.

#

The undo block is circa 300 lines of code, so I guess basic yes?

gloomy chasm
remote yarrow
#

No, it's not how it's designed, sadly

#

That simply won't work a lot of the time

#

It's things like: do you remember to never do "transform.parent = X" and instead do "Undo.SetTransformParent( X )"?

#

Simple cases today mostly work (although one bug I filed a few years back was "create a cube, rotate it once, move it with the mouse, hit ctrl-z, and undo breaks" with core UnityEditor 😄 )

gloomy chasm
gloomy chasm
#

Can you give an example of where undo won't work?

remote yarrow
#

If it were designed simply then we wouldn't need most of the API, we'd only need a couple of method calls, they would work in all situations, and there'd be no excuse for any asset to be missing full Undo support

#

In practice it's: do it simply, discover the MANY cases that break in-editor, play whack-a-mole trying different combinations of API calls to try and force the Editor to honour the API, play whack-a-mole some more re-writing your code in ways that should make no difference but do make the Editor Undo system work / stop working ... etc

#

(and, of course, every method call has to be #if UNITY_EDITOR because none of the API calls are allowed in runtime code)

#

TL;DR: it's a mess

gloomy chasm
#

If you are trying to use undo in runtime classes (like components) you are using undo and editor scripting wrong...

remote yarrow
#

Any change to any data that can be triggered from inside the editor needs to be wrapped in undo logic. If your editor menu does something that uses your runtime components/code/etc ... and you don't insert/wrap all the Undo cases ... it will screw up. The code will run fine in runtime and Editor, but Editor will fail to Undo (sometimes you get 'nothing happens', but about 1/3 the time you get 'Unity corrupts the scene' by making weird random changes to MonoBehaviour data)

#

(corruption that - of course - can't be undone using ctrl-z; it's 'git checkout --' time again)

gloomy chasm
#

When editor scripting you should almost never need to use #if UNITY_EDITOR

remote yarrow
remote yarrow
gloomy chasm
gloomy chasm
#

In general if you are changing properties of a runtime object, you should be using SerializedObject to do it not calling the APIs.

remote yarrow
#

Gizmos have no meaning at runtime. But Unity requires the (editor-only) code for gizmos to go inside runtime classes. If you constrain yourself to the crappy/ugly Unity-3.x era editor extensions then, sure, you'll be OK. But if you want to do anything particularly valuable/interactive it usually means interacting with Editor APIs sooner or later.

gloomy chasm
remote yarrow
#

I tried that approach. It's insane. It will kill you. The amount of code duplication is incredible (I recently refactored an 8 year old editor extension that was built that way - So. Many. Bugs! due to code duplication).

#

Or: I have an extension that was originally editor-only, but users required it to be also available at runtime. That was painful to change.

gloomy chasm
#

It depends on what you are doing, but there should be that much duplication. Either way, that is the way that Unity designed it to work.
If you don't like doing it that way that is fine, but it isn't fair to say that something like Undo doesn't work well when you are not using it as intended.

#

Not saying the design is perfect, but it does function well and covers any use-case as long as you are using UnityEngine.Objects

#

Editor code should basically be treated like the view and controller in an MVC (assuming I remember the MVC properly)
Where the runtime stuff is the model

gloomy chasm
#

Is there a decent way to get the folder for your asset?
Right now I am doing this and it feels really dirty

internal class EditorAssetsFolderLocator : ScriptableObject
{
  /// <summary>
  /// Reterns the project reletive path to the "MyAsset/Editor" folder in the assets folder.
  /// </summary>
  public static string GetFolderPath()
  {
     var locator = CreateInstance<EditorAssetsFolderLocator>();
     var script = MonoScript.FromScriptableObject(locator);

     string path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(script));
     if (Path.DirectorySeparatorChar != '/')
        path = path.Replace(Path.DirectorySeparatorChar, '/');

     DestroyImmediate(locator);
     return path;
   }
}
patent pebble
#

@gloomy chasm you can use the [CallerFilePath] attribute or a StackTrace

private static string GetFolderPath1(bool projectRelative = true, [CallerFilePath] string filePath = "")
{
    filePath = Path.GetDirectoryName(filePath);
    filePath = MakePathUnityStyle(filePath);

    if (projectRelative)
    {
        filePath = MakePathRelative(filePath);
    }

    return filePath;
}

private static string GetFolderPath2(bool projectRelative = true)
{
    string filePath = new StackTrace(true).GetFrame(0).GetFileName();
    filePath = Path.GetDirectoryName(filePath);
    filePath = MakePathUnityStyle(filePath);

    if (projectRelative)
    {
        filePath = MakePathRelative(filePath);
    }

    return filePath;
}
#
private static string MakePathUnityStyle(string path)
{
    return path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
}

private static string MakePathRelative(string path)
{
    return path.Replace(Application.dataPath, "").Insert(0, "Assets");
}
onyx harness
#

works for AsmDef, which might link to Library, crap

patent pebble
#

yeh

#
D:\Unity\MyProject\Library\ScriptAssemblies\MyAssembly.dll
onyx harness
#

Which basically uses your trick, but has fallbacks

gloomy chasm
#

So basically, there isn't really a nicer way to do it :/

onyx harness
#

But my utility is mainly to extract GUID & LocalID

#

If

#

If you rely on "C# Type must match its filename"

#

You can use this:

static class PrintAssembliesSources
{
    [MenuItem(Constants.PackageTitle + " Internal/Print Assemblies Sources")]
    public static void Print()
    {
        var    list = Client.List(
#if UNITY_2018_1_OR_NEWER
            true
#endif
        );

        while (list.IsCompleted == false);

        foreach (var item in list.Result)
            NGDebug.Snapshot(item, item.packageId);

        Assembly[]        playerAssemblies = CompilationPipeline.GetAssemblies();
        StringBuilder    buffer = Utility.GetBuffer();

        foreach (Assembly assembly in playerAssemblies)
        {
            NGDebug.Snapshot(assembly, assembly.name);

            buffer.Length = 0;

            for (int i = 0, max = assembly.sourceFiles.Length; i < max; i++)
                buffer.AppendLine(assembly.sourceFiles[i]);

            Debug.Log(buffer.ToString());
        }
    }
}
#

Which gives you the the .cs for any Asm

#

Not very reliable

#

I mean, you can't handle duplicate

#

I know there is another way to get scripts, but I forgot, someone mention another way on the publisher Discord or the forum, I don't recall

onyx harness
patent pebble
#

i can't say how reliable it is because I'm not super experienced in this topic
but so far for me it has been working fine, and it's relatively clean

#

using the [CallerFilePath] works fine too, but you have to wrap the method in another method or you will get a different path if the method with the attribute is called from an external script

#

so

public static string GetFolderPath(bool projectRelative = true)
{
    return GetFolderPath(projectRelative);
}

private static string GetFolderPath(bool projectRelative, [CallerFilePath] string filePath = "")
{
    filePath = Path.GetDirectoryName(filePath);
    filePath = MakePathUnityStyle(filePath);

    if (projectRelative)
    {
        filePath = MakePathRelative(filePath);
    }

    return filePath;
}
#

which is kinda boilerplate-ish

#

i just keep both examples just in case one of them doesn't work for some reason

onyx harness
#

StackTrace is pretty reliable, we all rely on it when writing a console

gloomy chasm
#

Yeah, seems like StackTrace might be a good idea. I will give it a try, thanks Madled

onyx harness
#

Don't forget to cache to keep it efficient

gloomy chasm
#

@onyx harness well... it took ~5 hours but I finally managed to remove harmony! 😄

#

Trying to follow the code for how Unity handles it was such a pain. You know how it is, both trying to understand the implementation and also look to see how you can hook in to it

#

Such a pain

remote yarrow
#

The MonoScript was broken in 2020 (they only just fixed it today), so we moved over to using the Assembly trick. However it requires a bit more work than just grabbing the Assembly - you need to handle special cases of "am I in a local Package? (because file locations there aren't writeable, and you usually need to know that!)", and "am I in a DLL? (because I got slightly different results on this one - but there's a Unity API for working around this specifically)"

#

Manually copying from other machine (IDE on this machine doesn't have that checked out):

var asm = Assembly.GetAssembly(GetType)).GetName().Name;
var asmDef = CompilationPipeline.GetAsssmeblyDefinitionFilePathFromAssemblyName(asm);
var asmDLL = CompilationPipeline.GetPrecompiledAssebmlyPathFromAssemblyName(asm);
if( asmDLL == null ) asmDLL = CompilationPipeline.GetPrecompiledAssebmlyPathFromAssemblyName(asm+".dll"); // yes, really - Unity's API a bit wonky here
var pathForAssembly = asmDef ?? asmDLL;

... which gives you a reliable root position, and then you can navigate relatively

gloomy chasm
patent pebble
honest crater
#

oh sorry didnt realize

gloomy chasm
#

When deleting an asset, you get a prompt like this.
Does anyone know of a way to show my own prompt instead?

patent pebble
#

@gloomy chasm yes! i've made a similar prompt for an asset processor

#

gimme a sec

#

ah whoops

#

misread

#

i don't know how to override the default prompt

#

😓 ...

gloomy chasm
#

ooh 😦

#

Shoot... I don't think there is a way without using Harmony, but I just got rid of it!

#

Maybe I can try intercepting the key down event in the project browser?

#

Its not perfect...

#

It's so silly. Getting SO variants to actually function has taken the least hacking (meaning none) while adding all this 'extra' stuff has taken so much xD

patent pebble
#

the devil is in the details

#

i get super bogged down by so many little menial things like that too

gloomy chasm
#

Getting sidebars to work took less hacking than this

#

Well.. no that's not really true since it is almost 100% reflection... but still!

onyx harness
#

What are you trying to do?

gloomy chasm
#

But for scriptableObject variants of course

onyx harness
#

Sounds tricky & dificult 🙂

drifting summit
#

im trying to impliment the ReadOnly attribute, and it works for classes inside the editor script, but my other normal scripts dont recognize it. I have the editor script in the Editor folder. Am i missing a step?

eager shale
#

so there's the EditorGUILayout.FloatField() and for other types as well, but where is the boolean version of it?

#

nvm it's .Toggle()

gloomy chasm
drifting summit
gloomy chasm
#

You have public class ReadOnlyAttribute : PropertyAttribute { }

#

And that does not go in the editor folder

drifting summit
#

i see

gloomy chasm
#

your class that inherits from DecoratorDrawer does go in the editor folder

drifting summit
gloomy chasm
#

LOL, I was trying out the new Splines tool and learned that the property drawer uses a naive implementation to get the value of a serialized property just using the property path
That means you can't have a Spline field in another class or list xD

tired basalt
#

Is there anyways to update nested prefab but do not trigger reimport of father prefab?

#

Or at least, reimport later

tired basalt
#

I figured it out. AssetDatabase.StartAssetEditing() + AssetDatabase.StopAssetEditing();

crystal vale
#

How to build a project with editor script without deleting?

patent pebble
#

any scripts you put inside an "Editor" folder won't be included in the build

#

@crystal vale

crystal vale
lethal sage
#

So I am making an extension for my game that procedurally generates a roof made of convex sections based on some control points (child gameobjects). I'm using handles to allow easily moving the points. Moving the handle updates the point's position and regenerates the roof. How do I solve the following issues?:

  1. An undo operation should only be made when the point begins being moved, not every frame while it is moving (currently I'm storing last saved time and checking if it's been more than a second).
  2. Undoing/redoing a control point movement should regenerate the roof.
patent pebble
#

when accessed through a SerializedProperty, why is this class considered a Generic and not an ObjectReference?

[Serializable]
public class SomeClass {}
gloomy chasm
patent pebble
#

makes sense

#

stupid me 💀

gloomy chasm
#

All good. I've been there

patent pebble
#

is it safe to use UNICODE characters in Unity?
such as this (U+27F6)

#

i have been scared of using them because I don't know if they will display inconsistently or if they will break under certain conditions

twin dawn
#

Using them where?

patent pebble
#

in the Editor UI

#

such as the inspector panel or any EditorWindow

gloomy chasm
terse hazel
#
[Serializable]
public sealed class SceneRef
{
    [field: SerializeField] public string ScenePath  { get; private set; }
    [field: SerializeField] public int    BuildIndex { get; private set; }
    
    public static implicit operator string (SceneRef reference) => reference.ScenePath;
    public static implicit operator int    (SceneRef reference) => reference.BuildIndex;
    
    #if UNITY_EDITOR
    [CustomPropertyDrawer(type: typeof(SceneRef))]
    public class SceneRefDrawer : PropertyDrawer
    {
        private const string _SCENE_PATH  = nameof(ScenePath);
        private const string _BUILD_INDEX = nameof(BuildIndex);
        
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            SerializedProperty _scenePathProperty  = property.FindPropertyRelative(relativePropertyPath: _SCENE_PATH);
            SerializedProperty _buildIndexProperty = property.FindPropertyRelative(relativePropertyPath: _BUILD_INDEX);
```Any reason why `_scenePathProperty` and `_buildIndexProperty`  are null?

Can **property**.Find**Property**Relative not find properties?
gloomy chasm
#

And no, FindPropertyReletive some what paradoxically cannot find c# properties. Only public fields and private fields with the [SerializeReference] attribute since those are the only field types that Unity serializes

visual stag
#

$"<{nameof(ScenePath)}>k__BackingField" would be how to get the serialized backing field from a property

#

it's not nice, so it's best to just serialize backing fields

uneven pebble
#

I was wondering if I can have a bunch of CreateCustomGameObject in a separate static class(es). Of course with different method names, as long as the [MenuItem()] directive made the editor recognise those methods?

#

Is that possible? Or do I need to keep them in the Monobehaviour derived classes?

supple willow
#

hey. how can i set some Editor local method to be called right after load ?

#

I want to subscribe to onHierarchyChanged as soon as possible

EditorApplication.hierarchyChanged += onHierarchyChanged;```
#

but the soonest thing I know is OnEnable, which is not good, because its only called when someone clicks on the gameobject with that script

honest bramble
#

I'm trying to learn about ScriptedImporter as I have a file with a unique extension that contains data for various meshes. In my OnImportAsset(AssetImportContext ctx) method I'm able to make children and components (MeshFilter and MeshRenderer for exmaple) to the object, but for some reason no matter how I make Meshes and assign them to the MeshFilter.mesh property, the file never shows the meshes. When I attempt to use the example code on the API it does properly show a primitive cube for the GameObject though. Any help appreciated. Thanks!

#
    [ScriptedImporter(1, "XPR")]
    public class XPRImporter : ScriptedImporter {
        public Mesh[] meshes;

        public override void OnImportAsset(AssetImportContext ctx) {
            GameObject root = ObjectFactory.CreateGameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));
            root.transform.position = new Vector3(0, 0, 0);
            GameObject meshRoot = ObjectFactory.CreateGameObject("MDL");
            meshRoot.transform.position = new Vector3(0, 0, 0);
            meshRoot.transform.SetParent(root.transform);

            GameObject mesh = ObjectFactory.CreateGameObject("OBJ");
            mesh.transform.position = new Vector3(0, 0, 0);
            mesh.transform.SetParent(meshRoot.transform);
            MeshFilter meshFilter = ObjectFactory.AddComponent<MeshFilter>(mesh);
            MeshRenderer meshRenderer = ObjectFactory.AddComponent<MeshRenderer>(mesh);();

            meshes = new Mesh[1];
            meshes[0] = new Mesh();
            meshes[0].Clear();
            meshes[0].vertices = new Vector3[] {
                new Vector3(0, 0, 0),
                new Vector3(0, 0, 1),
                new Vector3(1, 0, 0)
            };
            meshes[0].triangles = new int[] { 0, 1, 2 };
            meshFilter.mesh = meshes[0];
            ctx.AddObjectToAsset("main", root);
            ctx.SetMainObject(root);
        }
    }
waxen sandal
#

You probably need to dirty the meshfilter

terse hazel
honest bramble
gloomy chasm
gloomy chasm
uneven pebble
#

There or anywhere else for that matter

honest bramble
honest bramble
#

Also I get the following error on import if I have public Mesh[] meshes; Line in the class like in Ln3 of my example. I don't understand why, even if I don't do anything with it:

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.PropertyHandler.IsArrayReorderable (UnityEditor.SerializedProperty property)
snow bone
#

Anyone know how or if it's possible to draw gizmos within the PreviewRenderUtility please?

mossy wren
#

How can I tell when a hotkey is used when I am in the UnityEditor

primal steeple
#

Anyone know whether to use PreviewRenderUtility over GUI.DrawTextureWithTexCoords when trying to make an editor that's similar to the animation window?

patent pebble
#

you can access the information of a KeyDown and KeyUp using that

#

it also has this one, to check if a shortcut is triggered

internal static Func<bool> doPressedKeysTriggerAnyShortcut;
patent pebble
#

here's an example on how to use them

public static class GlobalKeyEvents
{
    // Exposed delegates to hook up your methods to them.
    public static event Action<KeyCode, EventModifiers> GlobalKeyDown;
    public static event Action<KeyCode, EventModifiers> GlobalKeyUp;
    public static event Action AnyShortcutTriggered;

    [InitializeOnLoadMethod]
    private static void EditorInit()
    {
        RegisterToGlobalEventHandler();
        RegisterToTriggeredAnyShortcut();
    }

    private static void RegisterToGlobalEventHandler()
    {
        FieldInfo info = typeof(EditorApplication).GetField("globalEventHandler", BindingFlags.Static | BindingFlags.NonPublic);
        EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue(null);
        value += OnGlobalKeyPressed;
        info.SetValue(null, value);
    }

    private static void RegisterToTriggeredAnyShortcut()
    {
        FieldInfo info = typeof(EditorApplication).GetField("doPressedKeysTriggerAnyShortcut", BindingFlags.Static | BindingFlags.NonPublic);
        Func<bool> value = (Func<bool>)info.GetValue(null);
        value += OnAnyShortcutTriggered;
        info.SetValue(null, value);
    }

    private static void OnGlobalKeyPressed()
    {
        if (Event.current.type == EventType.KeyDown)
        {
            GlobalKeyDown?.Invoke(Event.current.keyCode, Event.current.modifiers);
        }
        else if (Event.current.type == EventType.KeyUp)
        {
            GlobalKeyUp?.Invoke(Event.current.keyCode, Event.current.modifiers);
        }
    }

    private static bool OnAnyShortcutTriggered()
    {
        AnyShortcutTriggered?.Invoke();
        return true;
    }
}

however, the doPressedKeysTriggerAnyShortcut delegate seems like it doesn't trigger for EVERY shortcut, like for example Ctrl + R or Ctrl + C don't trigger it
so you probably want to rely more on the globalEventHandler to manually check for your key combinations

cinder relic
#

Is there a way I can add a MenuItem without using the attribute?

outer kraken
mossy wren
patent pebble
#

with the "using" directives like

using System;
using UnityEngine;
etc...
#

if you press "CTRL + ." while the caret (cursor) is on top of those errors in Visual Studio it should give you a list of recommended fixes

#

one of them will be to import the namespaces

north sphinx
#

Any idea whether you can make editor window top part to be windows style? not this one that snaps only inside unity

#

just like main unity window

#

like that

harsh hull
#

Good question, I’d like to know too. I doubt it though

patent pebble
#

@north sphinx @harsh hull yes, search the documentation for EditorWindow, it has multiple ''Show...'' methods to show the window in different ways

#

Normal, utility, etc

#

I don't think you can change the style of the default windows like the scene, inspector, etc

#

Or at least i dont know how

#

But you can show your own windows however you like

north sphinx
#

that sucks

#

I'm only interested in vanilla windows

waxen sandal
#

There's the Wizard thing that has the normal windows bar

patent pebble
#

ah I'm stupid, you actually can show the default windows however you like too

#

you can't change the already existing ones, you have to create a new instance

#

@north sphinx but you will lose the functionality that comes with the top bar buttons like the lock and the context menus

north sphinx
#

to open window as separate window

patent pebble
#

no, i mean with the other styles like the ShowUtility, you will lose those top bar buttons

#

to open the windows as extra instances with the different styles you need to use CreateInstance

#

one sec, i'll share example

#
using System.Linq;
using System;
using UnityEditor;
using UnityEngine;

public class ShowsWithDefaultWindows : EditorWindow
{
    private EditorWindow[] _foundWindows;

    private int _selectedIndex;
    private string[] _popupOptions;

    [MenuItem("Something/Default windows Show test")]
    public static void MakeWindow()
    {
        GetWindow<ShowsWithDefaultWindows>();
    }

    private void OnGUI()
    {
        // Get all windows
        if (GUILayout.Button("Get all open windows"))
        {
            _foundWindows = EditorWindowUtility.GetAllWindows();
            _popupOptions = _foundWindows.Select(window => window.GetType().Name).ToArray();
        }

        // Draw popup, button and labels
        if (_foundWindows != null && _foundWindows.Length != 0)
        {
            _selectedIndex = EditorGUILayout.Popup(_selectedIndex, _popupOptions);

            if (GUILayout.Button($"Call ShowUtility on: {_popupOptions[_selectedIndex]}"))
            {
                EditorWindow newInstance = CreateInstance(_foundWindows[_selectedIndex].GetType()) as EditorWindow;
                newInstance.ShowUtility();
            }

            for (int i = 0; i < _foundWindows.Length; i++)
            {
                EditorGUILayout.LabelField(_foundWindows[i].titleContent.text, $"Type: {_foundWindows[i].GetType()}");
            }
        }
        else
        {
            EditorGUILayout.LabelField("No found windows");
        }
    }
}
#

i have no idea if there's unintended consequences of showing the default windows in that manner...
because Unity... you know 🙃
so use at your own risk

#

ah forgot to share the utility method

public static class EditorWindowUtility
{
    public static EditorWindow[] GetAllWindows()
    {
        return Resources.FindObjectsOfTypeAll<EditorWindow>();
    }
}
north sphinx
#

wow, thanks

#

let's see how it works

#

yep, it is indeed opened in windows style window

#

but, is it possible to do it with exactly this style?

#

that has minimize/maximize

#

and x to close

#

like main Unity window

#

Mainly I want that because unity own windows are not snapping to screen

patent pebble
#

maybe someone else knows

patent pebble
#

when I click "maximize" on mine they snap to the edges of the screen

north sphinx
#

it just goes above, like unity window

patent pebble
#

@north sphinx i don't know what you mean exactly, both my main Unity window and the EditorWindows snap by default when doing maximize

#

EditorWindows don't snap by dragging like the main window does tho

#

🤷‍♀️

north sphinx
#

kinda that's what I mean, I dragged window partially into top side of screen and if I stop holding mouse, screen will maximize itself

#

editor windows don't do that

#

and that's what I aim for

slender jetty
#

Hi 🙂 I am looking for a bit of help/insight in setting up my ability system. One of the things I would like to be able to do is create them as scriptable objects and edit them in the inspector, rather than having to program each of them individually. What I am considering right now is having a custom editable list of steps to happen when the ability hits (abstract class AbilityStep). Would it be possible to make a list like this, but with an abstract object type, rather than one all incompassing class with all the values needed for all of them?

#

I had this in a previous project, but I just don't find it very configurable/changable

gloomy chasm
slender jetty
#

Does it work smoothly for saving and reloading them?

#

If I have a list of objects that all inherit from the same type?

gloomy chasm
slender jetty
#

Cool 🙂 Thanks

slender jetty
#

On a SerializedProperty, is there a way to see all available children?

namespace Abilities.Steps
{
    [Serializable]
    public class AbilityStepList
    {
        public List<AbilityStep> Steps;
    }

    [Serializable]
    public abstract class AbilityStep
    {
        public abstract bool DoStep();
    }
}

When I am making my propertyDrawer for this, I can't access Steps? I also can't get it to work with SerializeReference?

#
[CustomPropertyDrawer(typeof(AbilityStepList))]
public class AbilityStepListDrawer : PropertyDrawer
{
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        var list = property.FindPropertyRelative("Steps");
        return Mathf.Max(list.arraySize, 1) * 90 + 50;
    }
}

List is null in this case?

#

I would like to see if it can't find the property, or if the referenced property is null?

#

Oh, I got it working - SerializeReference on Steps, rather than on the class that has a AbilityStepList

slender jetty
#

In the above example AbilityStep is an abstract class - how can I add implementations of it to a reorderablelist that draws it?

brazen willow
#

what kind of extention do i need to make a ui like this and make it work in edit mode?
(image taken from another engine)

mossy wren
brazen willow
gloomy chasm
# brazen willow which one?

I guess I will break it down for you really quick.
Unity has two UI systems which you can use to create editor windows and inspectors.
Immediate Mode GUI (IMGUI)
This is the original way of make UI, it uses methods to draw the UI each frame much like an Update method in a component.

UI Toolkit (formerly UIElements)
This is the newer way and what will be used more and more as time goes on, it is a retained mode GUI (if you know what that means). It is based/inspired by web design so it uses USS and UXML files to define the structure and style of the UI.

brazen willow
#

sounds like IMGUI is more for me this time

gloomy chasm
brazen willow
#

i did as it shows in unity document
but nothing popped up on the screen

mossy wren
#

Is there a (using UnityEditor;) function that lets me know if the project code base has changed since last compile?
Like... I want to know if it can be refreshed or not

gloomy chasm
mossy wren
#

Right. Thats what I did. Now I can change code and bounce between editor several times and not have to needlessly recompile every time

#

it saves about an hour of dev time a day.

#

Never mind, found a work around

slender jetty
#

When I try to open Amount here, it crashes with this description:

0x00007ff7aaf0714f (Unity) GetFieldIdentifierForEnum
0x00007ff7abe7399f (Unity) SerializedObject::GetPopupMenuData
0x00007ff7abe74de0 (Unity) SerializedProperty::GetSerializedPropertyType
0x00007ff7aa5f16ec (Unity) SerializedProperty_CUSTOM_GetSerializedPropertyTypeInternal
0x000001375b699ab1 (Mono JIT Code) (wrapper managed-to-native)```

+ a lot longer callstack. Anyone have an idea what the problem might be?
analog grove
#

Hi everyone, I'm kind of recreating the editor's mask field, and I'm using the EditorStyles.popup.Draw, but it causes this to happen

#

~Any ideas?~ Found it, I only needed to do EditorGUI.LabelStuff only when event is repaint

outer ether
#

How can I edit the values shown in the inspector for a managed plugin .dll with a script?

#

I want to change the scripting defines of some DLLs with a script

#

Found it, PluginImporter

devout oracle
#

Hi, is there a command or the like to select previous asset, essentially a command that functions like a back button?

#

So I'm inspecting a material then click on a prefab. Is there a built in command to get back to the material I was originally inspecting?

waxen sandal
#

No but there extensions that do that mikilo's NG tools have one iirc

terse marsh
#

Had a question earlier that I deleted, I'll try to rephrase it: We're making an Isometric game using Tilemaps and I'm having issues with sorting layers so that the player is properly rendered in front of/behind objects like walls and pillars that they can be expected to both be behind and in front of

#

Instances like this, I can stand behind this wall but I want it to render properly when you're in front of it too

#

right now, that looks like this

#

Would there be a way to dynamically solve this in code? Like, checking whether or not the player is in front of or behind specific parts of the Tilemap? I know you're able to do that when referring specifically to singular objects with singular Sprites but since the Tilemap object isnt just a single square thats not going to work

terse marsh
#

That if I put everything on the same layer, itll dynamically sort itself out

#

is this the only way to solve it? Feels like itd lead to issues later

snow bone
#

is it possible to create a property drawer for an editor class and not a monobehaviour?

#

would i need to perhaps serialize the editor window class. I'm using a custom editor that I want to display something in, which is what the property drawer would be for displaying; a property in the custom editor window.

#

Should I perhaps create a serialized container class for stuff I want to be display in the property draw?

valid wharf
#

is there way to search for all animator controller in the AssetDatabase?

#

kinda like "t:Script"

snow bone
#

what about FindAssets?

valid wharf
#

I just want to use the filter mode

snow bone
#

you should be able to use the filter to search for classes of the animationcontroller

#

yeah, the docs don't give much info on how to use the filters

valid wharf
#

yes, that's why I asked lmao XD

snow bone
#

@valid wharfDid that work?

snow bone
#

code-advanced is probably a better channel

timber vapor
#

thanks

snow bone
#

@gloomy chasmi'm trying to have a docked previewRenderUtility window at the bottom of my editor, but don't know how to dock it, so considered making a property drawer to display it. Ie, the Cube window in the image below would show a previewRenderUtility window of what's in the Fbx Model field

#

that's a cut & paste, I don't know how to make the docked cube window thing at the bottom attach to my editor. This is what I want it to be.

#

I have the previewRenderUtility code to display what I want, but it's in it's own window

#

this is what have

honest bramble
#

Anyone know how to add an Apply and Revert buttons to the inspector of a ScriptedImporter, I have booleans in the Editor Window but I have to Right-click > Reimport every time, instead of doing an Apply like an FBX importer.

honest bramble
#

Much appreciated

#

@patent pebble sadly, even after adding a protected override bool needsApplyRevert => true; and in the protected override void OnInspectorGUI() { } I add the ApplyRevertGUI(); call, neither button shows.

honest bramble
supple willow
waxen sandal
#

OnEnable is called right after an editor instance is loaded

onyx harness
waxen sandal
#

Oh cool

worldly echo
#

Heyllo people, How may I display an int value in the custom editor of a ScriptableObject ?

barren moat
#

You'll also need to make sure the pivot point of your sprites is at bottom center as that's the position that is considered when sorting.

#

@terse marsh

north sphinx
#

How to run code on Update in editor only?
Basically, I'm making my own custom renderer for niche cases and I need to create a preview in scene view to adjust colliders/scale/positions
Which is pepega hard without any view.
So I simply want to run some code on Update

#

but only for editor

waxen sandal
#

EditorApplication.Update?

north sphinx
#

I have no idea

#

I need it to run from mono behaviour

waxen sandal
#

ExecuteAlways/ExecuteInEditor?

north sphinx
#

hmm, maybe it is

#

yeeep that is it

#

thank you

#

hmmm

#

what about isolated view in Prefab editor?

#

for some reason in prefab editor my code is not running

#

I do it in update()

pine geyser
#

I have tried to make a custom unity inspector for a thing I made and I am overriding the regular rendering to have it drawn as a grid of toggles(images actually but still toggles) but seems like any changes I make don't get saved to the disk. only in memory

#

so I have a Scriptable object containing an array of booleans and not sure how I am supposed to modify it so it gets saved

waxen sandal
#

Use SerializedObjects instead of direct object access

pine geyser
#

something like?
var myThing = (MyObjectType) serializedObject.targetObject;

#

it gets my data, I modify it but how do I save it?

#

serializedObject.ApplyModifiedProperties(); doesn't seem to do anything

#

and I do Markdity on the target object

waxen sandal
#

You have to use the serializedobejct to modify it

#

rather than using targetobject

pine geyser
#

sorry but idk how to use it

waxen sandal
#

that's why there's google

pine geyser
#

I don't have good google skills

waxen sandal
#

you better learn then

#

If you google Unity Serialized Object, you probably find an example of eactly what you want

pine geyser
#
var array = ((UnitRange) serializedObject.targetObject).grid;
array[3] = true;

EditorUtility.SetDirty(_property.serializedObject.targetObject);
_property.serializedObject.ApplyModifiedProperties();
#

that's rougly what I do rn

#

seems like it's saving the stuff but only when I hit save on the scene

#

Kinda works but kinda sucks I need to hit ctrl save after hitting the save button in my editor

pine geyser
#

Thanks both of you

#

now it works

analog grove
#

Hi everyone, quick question, I am currently using EditorGUI.ToggleLeft, is it possible to make it have this state?

#

Or what sort of toggle should I use/should I cheese it by drawing that on top of the inactive toggle

visual stag
rocky vapor
#

Hello so I am working on an Editor Themes asset that lets you change the default look of unity. However I have a bit of trouble changing the color of buttons. I can change almost anything using an uss just buttons don't work ```css
.button
{
background-color: #000000;
}

outer ether
#

I'm trying to setup a progress bar but this only goes to 2/5 th of the loading bar, the rest after "Iter_2" stays in the same place. Any ideas why?

 EditorUtility.DisplayProgressBar("ProgressBarTest", "Iter_1", 1f / 5f);
 Thread.Sleep(1000);
 EditorUtility.DisplayProgressBar("ProgressBarTest", "Iter_2", 2f / 5f);
 Thread.Sleep(1000);
 EditorUtility.DisplayProgressBar("ProgressBarTest", "Iter_3", 3f / 5f);
 Thread.Sleep(1000);
 EditorUtility.DisplayProgressBar("ProgressBarTest", "Iter_4", 4f / 5f);
 Thread.Sleep(1000);
 EditorUtility.DisplayProgressBar("ProgressBarTest", "Iter_5", 5f / 5f);
 Thread.Sleep(1000);
 EditorUtility.ClearProgressBar();
waxen sandal
#

Thread.sleep is not a good way to test that, wouldn't surprise me if that's causing issues

outer ether
#

updated the script to use x / 100f based values, after the reload it worked correctly, second time it got stuck again. So. yeah probably thread sleep

hearty basin
#

Hi everyone,

One my project growth, I need to better manage my project's assets. One solution i'm exploring is having two project : One for asset integration, and one for the project. To setup a functional pipeline using this method, I would like to develop a tool able to export UnityPackage from the "Asset only project" and automatically import it in the real game project. This will allow us to just add what we use in our project, but also have a nice way to update content without directly modifying source file.

But I need for this tool a script able to run a script from another project :
Export Package From "Asset project" -> Import Package in "Game Project". I've never seen a script able to communicate with another unity instance.
So my question is : Do you know if this is possible ? If yes, how would you do something like this ?

This is an experimental reflexion, and maybe there are some better way to handle this issue. So if you have any recommandation i would be happy to hear them.

Thank you !

bright nova
#

Hey folks,

Can anybody here firstly put up with my venting on how much I hate the fuzzy undefined behaviour of serialising unity assets and secondly please help me with fixing said flaky undefined behaviour. I'm going mad with deadline-looming but unitys-making-no-effing-sense crunchitis here.

keen coral
bright nova
#

Sure, I'm creating materials and setting properties - essentially creating a copy of a material but using a slightly different shader with similar parameters.
If I create the materials one by one, it works OK but if I create them altogether it sometimes misbehaves and all the input textures to the material are set to 'none'.
I print out the contents of the material after creation each time and the values look fine but seeing it in unity: nothing.
I'm saving the asset, I'm calling 'AssetDatabase.Refresh();' like some sort of ritual against bad spirits but still this weird empty material behaviour.

keen coral
#

Do you tag the newly configured materials as dirty?

bright nova
#

yup

#

The trouble is, I have no idea when unity is doing anything and no control over it either.

keen coral
#

Can I see the code your are using?

bright nova
#

it's all a black box and that black box isn't doing what I expect it to

#

sure, one sec

#
public Material CreateMaterialCopy(Material sourceMaterial, string newMaterialPath, Shader newShader)
{
    if (newShader != null)
    {                    
                var mat = new Material(newShader);
                var dir = Directory.GetParent(newMaterialPath).FullName;
                EnsureDirectory(dir);
                AssetDatabase.CreateAsset(mat, newMaterialPath);
                AssetDatabase.Refresh();
                Debug.Log("Creating material: " + newMaterialPath);
                var dirName = Path.GetDirectoryName(newMaterialPath);
                var sourceShader = sourceMaterial.shader;
                int propCount = newShader.GetPropertyCount();
                AssetDatabase.Refresh();

                for (var i = 0; i< gTextureMergeSpecs.Length; ++i)
                {
                    var mspec = gTextureMergeSpecs[i];
                    if (mat.HasProperty(mspec.materialPropName))
                    {
                        var fname = dirName + "/" + mspec.mergedFileName;
                        AssetDatabase.Refresh();
                        Texture newTexture = CreateMergedTextureFromMaterial(sourceMaterial, fname, mspec.subChannelMapNames, false);                        
                        mat.SetTexture(mspec.materialPropName, newTexture);
                        AssetDatabase.Refresh();
                    }
                }      ```
#
     AssetDatabase.Refresh();
                //yield return new WaitForSeconds(2);
                for (var i = 0; i < propCount; ++i)
                {
                    var propName = newShader.GetPropertyName(i);
                    var sourcePropIdx = sourceShader.FindPropertyIndex(propName);
                    if (sourcePropIdx != -1)
                    {
                        CopyMaterialProperty(sourceMaterial, sourcePropIdx, mat, i);
                    }
                }
                //do this last, attempting to give asset database time to catch up
                AssetDatabase.Refresh();
                for (var i = 0; i < gTextureMergeSpecs.Length; ++i)
                {
                    var mspec = gTextureMergeSpecs[i];
                    if (mat.HasProperty(mspec.materialPropName))
                    {
                        var fname = dirName + "/" + mspec.mergedFileName;                                                
                        Texture newTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(fname, typeof(Texture2D));
                        if (newTexture != null)
                            mat.SetTexture(mspec.materialPropName, newTexture);
                        else
                            Debug.Log("failed to set merged textured:" + mspec.materialPropName);
                    }
                }
                AssetDatabase.Refresh();
                EditorUtility.SetDirty(mat);
                Debug.Log(PrintMaterialContents(mat));
                AssetDatabase.Refresh();

                return mat;
            }
            else
            {
                return new Material(sourceMaterial);
            }
        }
keen coral
#

gimme a second to read that

#

You may want to put that CreateAsset at the end of your code.

#

I'm not 100% sure that CreateAsset links your attribute "mat" to the newly created asset.

#

From memory, I think you create the asset, and then you load it to deal with the actual asset (or you create the asset at the end).

#

You can safely discard most of those AssetDatabase Refresh ^.^ but I don't think they will cause any harm.

bright nova
#

Sorry, it's a bit long and there's some things in there that are hacky desperations around simply not understanding why the thing is doing what it's doing

keen coral
#

Sure, no problem.

bright nova
#

like ideally the second iteration through the 'gTextureMergeSpec' stuff shouldn't be necessary but that was me thinking that perhaps some late processing on the textures was resetting them, causing them to be nulled in the material later? No idea, it's all a black box.

keen coral
#

Try to load your material after creating it, instead of keeping the initial "mat" reference.

#

I think it's your best bet.

bright nova
#

ah, that's a trick I've used with textures

#

one sec

keen coral
#

From my own experience, when you start handling material assets, the usual problem is how to avoid them from saving things permanently, no the other way around 😁

bright nova
#

ha, well it could do with being clearer. Sometimes with this I feel less like I'm programming, more like I'm doing weird incantations and goat sacrifices to get the machine god to behave itself (n.b. have not actually hurt any goats)

keen coral
#

Also and this one is in case you are super tired, if for some reason the code goes through the "else" but you are super convinced that it doesn't, it obviously won't save anything.

bright nova
#

yeah, that's also a possibility, been doing late nights on this sprint. Holidays next week and they want it all working.

keen coral
#

Yeah Asset management in Unity is a bit related to dark voodoo, but it's not supposed to be blocking since the API is really small.

bright nova
#

I'd rather a REST style callback thingy when things are done.

keen coral
#

As long as you modify an asset, it should be fairly easy, so you should probably make 2-3 calls to assess what kind of instance you are handling.

bright nova
#

ohh, that sounds interesting - what are the different types of instance?

#

btw, that worked! Thank you - I should have guessed, like I said I had that idea with textures earlier but somehow didn't think to apply that lesson to materials.

keen coral
#

Ah great!

#

Well there are in-memory instances and asset instances, and that's about it.

#

One is just a temporary variable, and the other is linked to the disk.

#

Meshes, materials, etc. can be found in both types, depending of what you are doing.

bright nova
#

Ok, that's good to know. I knew that in memory assets were kinda temporary but must remember to reload them once saved.

keen coral
#

Yeah in the documentation it's not explained.

#

There are a fairly large number of holes on technicalities in Unity doc.

#

If they only added that in the doc, it would suddenly make a lot of sense ^.^

#

I'm guessing that if you tried to check the asset path of "mat" (before loading), you would have noticed that the path was empty 🤔

#

I'm not sure how to distinguish assets from instances except by knowing that they are 😁 but there must be a way.

bright nova
#

It would really help if they pointed just that little thing out, wouldn't it?

gloomy chasm
#

@bright nova @keen coral
Right-o, it seems like yall got it figured out, but I will go over a few things to try and make things clearer in the future.

Doing something like New Material(), new Texture(), and CreateInstance<ScriptableObject>() creates an instance of the class in memory.

You use AssetDatabase.CreateAsset(..) to serialize that instance in to a new file on disk.

AssetDatabase.Refresh() is used to update the UnityEngine.Object assets in the project from the serialized files.

AssetDatabase.SaveAssets() saves/serializes any changed UnityEngine.Object to file if they are dirty.
You use EditorUtility.SetDirty(..) to mark a UnityEngine.Object as dirty so that it will be saved.

Assets cannot contain (serialize) references to non-asset UnityEngine.Object as the way that it serializes the reference is using the GUID of the asset, of course non instances don't have a asset GUID.

#

Also you can use AssetDatabase.Contains(..) to know if an object is an asset or not.

manic sandal
#

Hey sorry I'm new here so feel free to let me know if this is asked wrong but I'm trying to override the way that a class is shown in inspector and haven't had any luck online. The goal is to show a class, for example a FancyInt differently when it is shown in inspector.

public class FanycInt : Monobehaviour
{
  public int fancyInt; // We'll do cool stuff to this later.
}

I can write a custom inspector so that when you add a FancyInt component to an object it show differently, but what I want is for the FancyInt to show up differently when another class is using it, for example

public class FancyIntContainer : Monobehavior
{
  public FancyInt myFancyInt = new FancyInt(); // I want to use a custom inspector for this!
}
``` 
I hope that makes sense, thanks in advance!
gloomy chasm
manic sandal
#

Yes

gloomy chasm
manic sandal
#

Ah, awesome, didn't know how to look this up properly, thanks!

gloomy chasm
south fox
#

Is this channel only about ui stuff? I want to do something when a scene gets opened in the editor (load another scene). I want to know if its possible and if so how to do it.

slender jetty
waxen sandal
#

You got some code to show?

slender jetty
#

Sure, I can try doing a minimum. Is there a good place to put it?

waxen sandal
#

Hastebin or something similar

slender jetty
#

Forgot to include the actual class being drawn:

[Serializable]
public class AbilityStepList
{
    [SerializeReference]
    public List<AbilityStep> Steps;
}```
gloomy chasm
# slender jetty https://www.toptal.com/developers/hastebin/ugumepuvez.csharp <- Here. Note that ...

Okay, so I will just go over the things I see since I don't see anything obviously wrong off the bat.
You have a struct Damage and class Damage : AbilityStep this makes it very confusing when looking at the code and much harder to follow. I would rename the class to something like DamageStep for clarity.
Your field naming is also inconsistent which again makes it harder to follow what is going on (plus just looks messy).
You add an ability using direct access to the instance instead of using SerializedProperty. This will make it so it won't support prefab overrides or undo also the change may not be saved since it doesn't dirty the object.

This would be the proper way to do it.

property.arraySize++;
property.GetArrayElementAtIndex(property.arraySize - 1).managedReferenceValue = new Abilities.Steps.Damage();
slender jetty
gloomy chasm
slender jetty
#

Then it doesn't crash

#

It can also show stats

gloomy chasm
#

Comment out DamageType type in DamageLine

#

I am pretty sure that is it given the log you posted

slender jetty
#

Yup, it works when that one is not there

gloomy chasm
slender jetty
#

Same namespace as the Damage and DamageLines

    public enum DamageType
    {
        Magic,
        Physical
    }
slender jetty
#

It's just an enum

analog grove
#

Heyo, had a couple of questions. I'm trying to create a selector that uses a popup. don't know how to send the values back to the serialized propery, I tried using a callback when OnClosed but said the property had already been disposed of.

analog grove
#

I'll add some info in case someone knows how to do this. Unity seems to do this using a reference to the GUIView and events but this is not accessible. any idea on how to do something similar?

onyx harness
#

Send an event to the parent Window

#

@analog grove

#

window.SendEvent(new Event() { commandName = "mypopup", button = 123 });

outer ether
#

Any idea why unity on macos and linux lacks the full PATH environment value of my system?

On windows you get this: C:\Python310\Scripts;C:\Python310;C:\Program Files\PlasticSCM5\server;C:\Program Files\PlasticSCM5\client;C:\Windows\system32;...
Everything defined under the windows' PATH settings are available

On macOS this is all that gets returned by
Environment.GetEnvironmentVariable("PATH")
PATH = /usr/bin:/bin:/usr/sbin:/sbin

onyx harness
#

Define "lack"

slim vector
#

so i've copied this editor script from here (https://docs.unity3d.com/ScriptReference/PrefabUtility.html) to create prefab for me automatically without needing to drag each mesh into the Project folder manually but the resulting prefab created using this tool have a different icon (blue box with grey side). i believe it is a prefab variant(?) and i was wondering if it is possible to create the prefab with the fully blue box instead?

outer ether
# onyx harness Define "lack"

Things that are the default such as /usr/local/bin not available in Unity.
macOS defines its PATH var from /etc/paths

waxen sandal
outer ether
#

nothing user installed can be accessed via Process.Start with the Unity provided PATH

slim vector
waxen sandal
slim vector
#

a prefab and prefab variant are pretty much the same right?

waxen sandal
#

Also, you can start user installed apps but they should be available from the commandline as well, which is generally what /usr/local/bin//usr/bin is used for

waxen sandal
outer ether
#
ehakan@mbp ~ % cat /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

That's my issue, the PATH should have /usr/local/bin if it actually used the macOS defaults

outer ether
#

/usr/local/opt/openjdk@11/bin:/Users/ehakan/grpc:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS:/Users/ehakan/.cargo/bin

slim vector
#

how can i make it a prefab instead of a prefab variant though?

outer ether
#

I only defined the first two items in my .zshrc, the rest are "system"

slim vector
#

kinda ocd about the different icons in my prefabs folder

outer ether
#

as in it just gets embedded with every terminal instance

waxen sandal
waxen sandal
slim vector
#

alright will try

outer ether
# waxen sandal My path doesn't have /usr/local/bin by default, my shell is adding it

Thanks for the heads up. I found out about /usr/libexec/path_helper, it's apparently what builds the PATH value for shells, invoked in /etc/profile. Bodged this together

        public static void LoadMacOSDefaultShellPaths()
        {
            using (var process = new Process())
            {
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.FileName = "/usr/libexec/path_helper";
                process.StartInfo.Arguments = "-c";
                process.StartInfo.RedirectStandardOutput = true;

                process.Start();
                var stdout = process.StandardOutput.ReadToEnd();
                process.WaitForExit(30000);

                if (!process.HasExited)
                {
                    Debug.LogError($"'/usr/libexec/path_helper -c' timed out, killing the process");
                    process.Kill();
                    return;
                }

                if (process.ExitCode != 0)
                {
                    Debug.LogError($"'/usr/libexec/path_helper -c` failed with exit code {process.ExitCode}");
                }
                
                Debug.Log($"/usr/libexec/path_helper output = {stdout}");
                
                // assert if the output is of expected format 'setenv PATH "...."'
                var args = stdout.Split(' ');
                if (args.Length != 3)
                {
                    throw new Exception("Outputs incorrect");
                }

                var paths = args[2]
                    .TrimStart(new char[] {'"'})
                    .TrimEnd(new char[] {';'})
                    .TrimEnd(new char[] {'"'});
                
                Environment.SetEnvironmentVariable("PATH", paths);
            } 
        }
tough stream
#

Hi! how can i do a "CreateAssetMenu" that creates a class inheriting from another class of mine? (ie i've got an ActionBase class, and i want a button in assets/create/New Action to create a new action script inheriting for ActionBase by default?
The little things)

waxen sandal
#

CreateAssetMenu is just a MenuItem that creates a SO for you, so you can just create your own static method with MenuItem that makes an SO at some location

waxen sandal
#

I'm not sure what exact source is but there's probably a bunch of examples online

#

It won't give the exact same functionality but it's similar

waxen sandal
tough stream
waxen sandal
#

ProjectWindowUtil.CreateAsset(asset, assetPath);

#

I should've etold you about this one before probably

tough stream
#

thanks!

tough stream
#

what if i want to load all the scriptables inside a folder (that i've got the path too)?

#

AssetDatabase.LoadMainAssetAtPath doesn't seem to be working

gloomy chasm
tough stream
#

to load all the scriptables inside a folder (that i've got the path to)

gloomy chasm
#

Assets can have sub-assets, that is what it refers to when it says "MainAsset"

tough stream
#

yeah, like sprites right

#

so what if i want to load all the scriptables inside a folder (that i've got the path to)?

gloomy chasm
#

note that all System.IO methods take a full path and not one relative to the project. Likewise, all of Unity's AssetDatabase methods require a path relative to the project

tough stream
#

bruh
But i can get the unity path to asset with someething right? Like assetdatabase.ProjectPath?

gloomy chasm
gloomy chasm
onyx harness
#

if I ask for Directory.GetFiles('.') it works

gloomy chasm
onyx harness
#

You can't, because the current Directory is set on the projecct path, so it would accept "Assets", "Library", "Temp", etc.

#

You are making me doubt, but I am 99% sure it is

gloomy chasm
onyx harness
#

And now that I am think about it, I'm 100% sure

#

it takes whatever you give it

#

be it absolute, relative, network

gloomy chasm
slim vector
#

i assume it is? it's a mesh

gloomy chasm
#

That way if the mesh changes it will update as well

slim vector
#

how can i make it an original prefab though?

#

hmmm

#

when i drag the mesh into the folder, i get an option to either make it an orginal prefab or a prefab variant

#

how does unity make it into an original prefab from there?

#

instead of a variant

gloomy chasm
#

I should say that unless you have a specific reason for doing this, the recommendation is to make it a variant of the model instead

slim vector
#

alright

slim vector
#

one more thing, is it a must for the editor script to inherit from Editor? i remember watching some videos regarding creating custom tools and some of their script(s) doesn't inherit from Editor at all

gloomy chasm
slim vector
#

i see i see

#

cause currently i am inheriting from Editor but the script itself isn't for a custom inspector, rather it is for a menu item instead

gloomy chasm
#

Yep, no need for it then

slim vector
#

what if i'm inheriting from Editor just so i can use DestroyImmediate?

#

right now once i create the prefab(s), i want to delete the selected gameobject(s) from the scene

gloomy chasm
#

No need, DestoryImmediate is a static method

#

Object.DestoryImmediate(yourObjectInstance);

slim vector
#

ahhhhhhh right

#

thanks a lot

mossy wren
#

https://pastebin.com/tAwaLeae 0.48 KB

//I can't save my scene particle effects into the project if I do this. It unlinks the Particle->Renderer->Material to null
//How would I be able to save my scene particle effect into my project properly if I want to change the material on runtime?

#

I think I need to write an editor extension to make new materials maybe on the fly?

#

A better question is: If I instantiated something in UNITY play, how do I save the result as an asset into my Project Assets?

gloomy chasm
#

However I could be wrong on this one, I don't remember for sure

mossy wren
#

yup

#

AssetDatabase.CreateAsset for non game objects

#

this is awezome!

analog grove
#

heyo, just a quick question, is there a better way to get the window in which the propertydrawer is being drawn on, other than getting the focused window?

gloomy chasm
analog grove
analog grove
gloomy chasm
analog grove
#

oh okey, yeah i can just have a failsafe and it should be okey. Guess I'll learn some reflection then

onyx harness
#

Go learn go learn little padawan

rocky vapor
tough stream
#

hi! how do i know if an .asset exists at some path?

#

do i need to do like a try catch maybe?

#

cuz i just tried this:

ScriptableCharacterList CharList = ScriptableObject.CreateInstance<ScriptableCharacterList>();
            try {
                list = AssetDatabase.LoadAssetAtPath<ScriptableCharacterList>("Assets/SCOLAssets/CharacterScriptables/CharacterList.asset");
            } catch {
                AssetDatabase.CreateAsset(CharList,"Assets/SCOLAssets/CharacterScriptables/CharacterList.asset");
                list = AssetDatabase.LoadAssetAtPath<ScriptableCharacterList>("Assets/SCOLAssets/CharacterScriptables/CharacterList.asset");
            }```
And somehow it's not creating anything
(my class doing this is editor only and static)
#

(well, the class itself isn't static, but all the other things in it are (including this "list" variable))

tough stream
#

Help me i feel like i'm doing totally illegal things

ScriptableCharacterList CharList = ScriptableObject.CreateInstance<ScriptableCharacterList>();
            try {
//If the list already exists, we just say it's THE list
                ScriptableCharacterList.Instance = AssetDatabase.LoadAssetAtPath<ScriptableCharacterList>("Assets/SCOLAssets/CharacterList.asset");
            } catch {
//If it doesn't, create it... And tell it's THE list
                AssetDatabase.CreateAsset(CharList,"Assets/SCOLAssets/CharacterList.asset");
                ScriptableCharacterList.Instance = AssetDatabase.LoadAssetAtPath<ScriptableCharacterList>("Assets/SCOLAssets/CharacterList.asset");
            }```
(That is trying to turn a scriptable object into a singleton ![skull](https://cdn.discordapp.com/emojis/932677808994521138.webp?size=128 "skull") )
outer ether
#

How can access the "Validate References" field of a .dll through an editor script? I get the PluginImporter for the asset but I'm not sure on how to set the "validate references" field?

waxen sandal
tough stream
#

oh, yeah
when i createAsset(), right?

waxen sandal
#

After it

waxen sandal
tough stream
smoky plover
#

is it possible to get serialized property on MonoBehaviour OnValidate method?

waxen sandal
#

Probably

#

But why

smoky plover
#

I had a bug overriding OnInpectorGUI and wanted to use another way to access my ExposedReference

#

but I solved

rocky vapor
smoky plover
#

SerializedObjectNotCreatableException: Object at index 0 is null
happen on line _assetProperty = this.serializedObject.FindProperty("asset");
of this script every time i enter in playmode

public class TableReferenceEditor : UnityEditor.Editor
{
    private SerializedProperty _assetProperty;
    private SerializedObject _assetObject;

    private void OnEnable()
    {
        if (serializedObject != null)
        {
            _assetProperty = this.serializedObject.FindProperty("asset");
            SetAssetSo();   
        }
    }

there is a workaround?

smoky plover
#

SerializedObjectNotCreatableException Error in Unity ( Solved ) | Serialized Object Not Creatable

For Advance Unity Tutorials and Live sessions you can Join Our Channel.
http://bit.ly/2N54fgc

👇👇👇👇👇👇👇👇
Learn Unity Game Development with deep concept with US -
https://www.youtube.com/channel/UCXKkwWoBY_sK6LtIFFmB46Q

👇👇👇👇👇👇👇👇
Ask any question on...

▶ Play video
smoky plover
#

is it possible to fire event on collection change?

#

I mean when add and remove item from an array

#

in a CustomEditor

worthy mist
#

Hey guys! I'm creating an editor tool that will create a bunch of assets using AssetDatabase.CreateAsset and also prefabs. Problem is that operation is taking way too long... I've tried using AssetDatabase.DisallowAutoRefresh(); but to no avail... Is there anything else I can do?

#
AssetDatabase.CreateAsset(material, Path.Combine(meshPath, $"{filter.gameObject.name}.mat"));
                 AssetDatabase.CreateAsset(filter.mesh, Path.Combine(meshPath, $"{filter.gameObject.name}.asset"));
                 var partPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(meshPath, $"{filter.gameObject.name}.prefab"));
                 PrefabUtility.SaveAsPrefabAssetAndConnect(filter.gameObject, partPath, InteractionMode.UserAction);
worthy mist
#

Found a solution... AssetDatabase.StartAssetEditing(); and AssetDatabase.StopAssetEditing(); will do the trick

sharp rune
#

Hey can someone help me? I've never written anything for the editor, so I'm a little lost on where to begin.
I'm trying to write some code that will let me change the colors for: selected polygon colliders, awake polygon colliders, selected box colliders, awake box colliders

#

I want these 4 things to be different colors so I can quickly tell what I have selected, and what the other colliders in my scene window are without clicking through the hierarchy

#

I can enable always show colliders in the project settings, but the problem with that is, everything is the same color, even colliders I have selected, so I cant tell what it is I'm editing

whole steppe
#

I'm currently trying to create an instance of a custom editor script via CreateEditor(object, type). However, this function only seems to create the base "Editor" class, and trying to cast it to my custom editor type fails. I've double checked all the necessary attributes and inheritance setup, but have had no luck. Has anyone else encountered this problem before?

whole steppe
#

is it possible to add custom game objects context menu item?

#
    [MenuItem("GameObject/HelloWorld", false, 10)]
    public static void CreateTextArea()
    {
        GameObject go = new GameObject("Name");
    }
#

alright based

gilded onyx
#

Guys I need your help. I have an assignment to get a job.
I need to setup a connection with this thing:
https://github.com/PokemonTCG/pokemon-tcg-sdk-csharp
an just make a game with it.

My Visual studio 2019 whenever i try to install the package:

Could not install package 'PokemonTcgSdk 1.1.1'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.7.1', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

So I downloaded the 1.1.0 version

My new error is that now that I have the new classes etc when I try to test em in Unity I get this error: (Only in Unity not in the VS console)

Assets/GameManager.cs(4,7): error CS0246: The type or namespace name 'PokemonTcgSdk' could not be found (are you missing a using directive or an assembly reference?)

I suspect that it is the SDK version but I cant locate where to select the one I use plus I think my VS is buggy all along.

P.s I use Mac

GitHub

Pokemon TCG SDK - C#. Contribute to PokemonTCG/pokemon-tcg-sdk-csharp development by creating an account on GitHub.

gilded onyx
#

Help please

viscid gulch
# gilded onyx Help please

I really don't know how everything works on mac, i'm using endeavourOs and I had some similar problems when installing from different repos, f.e. vsCode installed from flathub wouldn't be able to locate .Net. from aur. This is probably unrelated, just trying to help.

analog grove
#

hi people, I've been trying to figure out how this is done but I'm not really finding a way. I basically want to make a search bar. The code works, but I would like to make it 1. prettier and 2. a bit more functional by having a search icon and when text is present have a cross to delete, sort of like the hierarchy tab. Does anyone know how to add these icons to the text field?

devout oracle
#

Hi, is there a way to step thru the code the unity editor executes at certain times? I'm specifically try to go through the asset (model/fbx specifically) import process to get a better idea how to customize I. I find the unity docs concerning it to be pretty vague on a lot of things, at least to a unity young'en like myself

vague herald
#

so... I have very little property drawer experience, but I was working on a SmartEnum implementation for Unity with a property. Recently was playing with it and realized that it didn't work in the case that fieldinfo was a List.

        {
            //Begin Property
            EditorGUI.BeginProperty(position, label, property);

            //Get Current Value
            var smartEnum = (SmartEnum)fieldInfo.GetValue(property.serializedObject.targetObject);

            //Get All Other Possible Values
            var enumList = SmartEnum.GetValues(smartEnum);

            //Get Current Index
            var i = enumList.IndexOf(enumList.FirstOrDefault(x => x.Equals(smartEnum)));
            i = (i < 0) ? 0 : i;

            //Make Possible Values into List
            string[] options = enumList.Select(x => x.ToString()).ToArray();

            //Do a Popup and Get Selection
            var j = EditorGUI.Popup(position, property.displayName, i, options);

            //Set Value to Current Selection
            fieldInfo.SetValue(property.serializedObject.targetObject, enumList[j]);

            //End Property
            EditorGUI.EndProperty();
        }

Was wondering if anyone could give me some ideas or help on making this Array or List Compatible?

waxen sandal
#

What exactly is not working?

vague herald
#

It is not Array Compatible, when I make a List<SmartEnum> it breaks

waxen sandal
#

🤦‍♂️

#

What breaks

#

How does it break

#

any error?

vague herald
#

The Specified Cast at

            var smartEnum = (SmartEnum)fieldInfo.GetValue(property.serializedObject.targetObject);``` 
is invalid
#

it is a List<SmartEnum>

That is the problem. I want it to work within Lists.

#

(or other serializable array types)

#

oh shit, I think I figured it out

#

was [CustomPropertyDrawer(typeof(SmartEnum), true)], that true shouldn't be there
Wait nvm, that just breaks the styling

vagrant zinc
#

Hi,
i have a script that introduces own fields in the inspector, by using [SerializeField] private Material glowMaterial;

The inspector then takes "glowMaterial" word and forms the field name of it, resulting in "Glow Material".

How could i set the field name in the inspector to a different name, i.e. "Material" only?

gloomy chasm
vague herald
#

I am not sure what the alternative ought to be, that is the issue and getting information on this stuff is archaic

gloomy chasm
#

Basically you have to split the path of the property and get the value of the field of each property in the path

vague herald
#

nice, going to add it as a package dependency, as it is lightweight enough

gloomy chasm
#

I will say, idk what the structure of SmartEnum is, but I don't think you need to do it the way you are

vague herald
#

A SmartEnum is a pattern for Enums, wherein it looks like this:

{
    public static readonly TestEnum One = new TestEnum(nameof(One), 1);
    public static readonly TestEnum Two = new TestEnum(nameof(Two), 2);
    public static readonly TestEnum Three = new TestEnum(nameof(Three), 3);

    private TestEnum(string name, int value) : base(name, value)
    {
    }
}```
#

It allows for certain benefits. Such as Injectability, attaching values, and preventing extension

gloomy chasm
vague herald
#

until unity enforces its own standard for git packages, this seems to be one of the most popular versions to do versioning...

Ugh, Unity devs, if you can hear me, please just integrate whatever this guy did into your package system by default.

gloomy chasm
#

The reason being that Unity serializes everything as a value and not a reference.

#

So doing myTestEnumField == TestEnum.One would be false

#

I think

vague herald
#

I overwrite the == function

#

SmartEnum is direvative of IEquatable<SmartEnum>

#

I just check if value is equal

gloomy chasm
#

Oh, got it

#

It would be best if you could recreate the assignment logic using SerializedProperty as assigning values using FieldInfo has a number of drawbacks.
Doesn't dirty the object(may not save unless something else changes), doesn't support undo, doesn't support prefab overrides.

gloomy chasm
vague herald
#

Unity is Unity, there is a ton of stuff that I wish it had built in so I wouldn't have to hack to get around it.

#

And of course, there is the whole problem of developing a solution and then someone out there rediscovers your problem and can't solve it, because you aren't at the top of search results

#

anyway, none of this is relevant to this channel so I am going to stop

#

thx for help

vagrant zinc
gloomy chasm
vagrant zinc
gloomy chasm
vagrant zinc
#

ohh ok 😕

#

Ok atleast i now know there is no way to achieve this, i was stuck on this for an hour about and finally can move on. But i think i will place this as feature request at unity's

#

@gloomy chasm Thank you for your help ✌️

patent pebble
#

I'm having issues with handling selective click events in a property drawer

I'm making a PropertyDrawer that is an object field, but it has extra height for drawing other fields below.
I want to consume the event selectively if I click on the area that is not the object field

#

as you see in the GIF, the object field's context menu appears when clicking in any area of the entire drawer (that doesn't have another field)

#

so I basically want to consume the event and not show the context menu when I right click on the area highlighted in red