#↕️┃editor-extensions

1 messages · Page 110 of 1

old ravine
#

Then I run the game, and all the links disappear!

#

Even if I save before running the game.

visual stag
#

Presumably you are not dirtying the objects you make changes to

#

@old ravine

peak bloom
#

How can I get the center position of an active area of graphview, so I can get the center of it later on?

plain lake
#

For nested fields/props, how can I calculate the correct position for them?

 var initialPos = EditorGUI.PrefixLabel(position,label).x;

It only works for root fields

#
 var initialPos = (EditorGUI.PrefixLabel(position, label)).x - 15 * EditorGUI.indentLevel;

It solves the initial position of nested fields but width is wrong!

old ravine
gloomy chasm
#

Btw there is EditorGUI.IndentRect(..) for indenting the rects the proper amount. (Or maybe it is EditorGUIUtlity, I can't remember)

cosmic inlet
#

does anyone here happen to know how to use the currently experimental Graph View?

#

I created a system where for every variable in a node script with the attribute of [Port], a port will be created

#

it's currently really slow but the point is, it works

#

and I need to somehow link references using edges

visual stag
#

There's a tutorial on graph view pinned to this channel that's a good starting point

cosmic inlet
#

yeah but I don't know how to adapt them to my method of creating the links

#

the edges

#

I will check it out nontheless

#

oh

#

I already watched that one tho

short tiger
# cosmic inlet does anyone here happen to know how to use the currently experimental Graph View...

I use this higher-level library to create my own tools with GraphView. It's made by a Unity employee as a personal project.
https://github.com/alelievr/NodeGraphProcessor

GitHub

Node graph editor framework focused on data processing using Unity UIElements and C# 4.6 - GitHub - alelievr/NodeGraphProcessor: Node graph editor framework focused on data processing using Unity U...

cosmic inlet
#

oh wow I guess I'll use this one

#

it seems to be doing exactly what I want it to do, in the same method I made

#

thanks!

native stream
#

whats happing inspector not sees my project and unity can open project only if make new
and sends error of method axess team license

native stream
delicate pivot
#

hey, I have an EditorWindow with a ReorderableList

problem: as my items are Types (and therefore not serializable) I have to use the Type ctor and dont have access to ReorderableList.serializedProperty ```cs
m_list = new ReorderableList(m_managers, typeof(Type), true, true, false, false); //with m_managers = List<Type>

How can I reorder my m_managers after moving elements in list please?
visual stag
#

It will do that already, will it not?

delicate pivot
#

nope, unfortunately

visual stag
#

how's that implemented?

delicate pivot
visual stag
#

In the Unity version I'm testing in (2022.1) reorderable list modifies the list you pass in

#

If you reorder the list in the inspector, the original is modified. No copy was made.

delicate pivot
#

with non-serializable items?

visual stag
#

Yes

delicate pivot
#

i see

#

thx anyway :/

#

would you mind if I take a look at your code? (you cans send me a dm if you agree)

#

maybe i'll find what i did wrong xD

visual stag
#
public class Managers : EditorWindow
{
    [MenuItem("Window/Managers")]
    private static void ShowWindow()
    {
        var window = GetWindow<Managers>();
        window.titleContent = new GUIContent("Managers");
        window.Show();
    }

    private readonly List<string> m_managers = new();
    private ReorderableList _mList;

    private void OnEnable()
    {
        _mList = new ReorderableList(m_managers, typeof(string), true, true, true, true)
        {
            drawElementCallback = (rect, index, _, _) =>
                m_managers[index] = EditorGUI.TextField(rect, index.ToString(), m_managers[index])
        };
    }

    private void OnGUI()
    {
        _mList.DoLayoutList();
        if (GUILayout.Button("Test"))
        {
            foreach (string mManager in m_managers)
            {
                Debug.Log(mManager);
            }
        }
    }
}```
gloomy chasm
visual stag
#

it's not being serialized, and it wouldn't matter if it was

delicate pivot
#

ahhh i just wanna throw my computer by the window lmao

visual stag
delicate pivot
#

you mean when I fill the list?

visual stag
#

what's hidden here

delicate pivot
#

ahh

#
if (GUI.Button(new Rect(_rect.x + _rect.width / 2, _rect.y, _rect.width / 4, _rect.height), "Add",
                    EditorStyles.miniButtonLeft))
{
    //switch current manager style: dedicated object or common object, then process it
    switch (attr.m_style)
    {
        case ManagerStyle.COMMON:
            ProcessAddCommon(ref managersObject, manager);
            break;
        case ManagerStyle.DEDICATED:
            ProcessAddDedicated(manager, attr);
            break;
        default:
            throw new Exception("unsupported");
            break;
   }
   //mark scene as dirty
   EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
            
#

it's to add it in scene

visual stag
#

how does the window.m_managers list get modified here?

delicate pivot
#

it does not

visual stag
#

so why would the add button change the order of the list

delicate pivot
#

i fill it at beginning and never edit it manually

#

it's just that when i click the button it resets list order

visual stag
#

That's bizarre. Is the window being reloaded?

delicate pivot
#

nope

#

that's just.. weird

#

omg wait

#

hahaha found it

#

i forgot i called the init function in my 'OnHierarchyChange' i'm so dumb

plain lake
#

Now, it is OK. I set the indent level to zero and then revert back at the end.
My problem
Field labels do not have indent. (ip2 and ip3)

#

EditorGUI.LabelField has not been used. I do not know how they are rendered!

#
  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var height = position.height;
        var posY = position.y;
        var offset = height / 2f;
        //EditorGUI.LabelField(position, property.displayName);
        EditorGUI.BeginChangeCheck();
       
        var ipValue = (IPAddressV4)property.GetValue();
        var indentLevel = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;
        // render int fields
        EditorGUI.indentLevel = indentLevel;
flint hinge
#

Can anyone explain me how I can override the function of that add element button on a normal inspector list. I already made a custom editor for that script but now I don't know how to proceed...

vagrant stirrup
#

Hey, I'd like to query gameobjects in (unloaded!) unity scenes. I'd like to get the positions of all the gameobjects that have a collider component.
What I can do here is to parse the unity yaml file with YamlDotNet and resolve the transform hierarchy manually. I'm wondering if there is a better solution for this?

crude relic
#

what is your end goal?

#

@vagrant stirrup

vagrant stirrup
#

to have all the physics colliders loaded in my backend (I started with this manual loading because like this I could support hot reloading for local development)

#

Beyond physics objects, I'd like to also be able to define things using the unity world editor like placing monster spawners, defining player spawn points, points of interests, zone bounding volumes, etc.
^This is a no-brainer after I can query the boxcolliders, just writing this to give better context

vagrant stirrup
#

Btw @crude relic I successfully parsed the scene file but hit the roadblock with prefabs, it points to a guid and I can only resolve those with access to assetdatabase, so if I see it correctly, I'm unable to parse the scene file completely outside of Unity itself.

plain lake
#

EditorGUIUtility.editingTextField does not work correctly!
I would like to have a normal style when a text field is editing but when I click on a button and not focused, it should have another style.

#

After switching between windows and again click on a button, it would be OK

#

Also, there is a null error, it is destroyed (texture) unity editor after playing and close
Is it a standard way to solve it?

public class BackgroundStyle
{
    private static readonly GUIStyle Style = new GUIStyle();
    private static Texture2D _texture = new Texture2D(1, 1);
 
 
    public static GUIStyle Get(Color color)
    {
        if (_texture == null)  // here
        {
            _texture = new Texture2D(1, 1);
        }
        _texture.SetPixel(0, 0, color);
        _texture.Apply();
        Style.normal.background = _texture;
        return Style;
    }
}
gloomy chasm
wispy delta
#

Is it possible to use a fade group in a property drawer? I'm making a property drawer for a class that contains a list and I want the foldout to animate open to reveal the list instead of opening immediately. it seems this is not possible since property drawers don't use the layout system tho. can anyone confirm this?

nocturne geyser
#

if(Event.current.commandName == "ObjectSelectorUpdated") Object reference not set to an instance of an object

gloomy chasm
nocturne geyser
#

so no can do?

gloomy chasm
#

Correct-ish

#

It gets uglier from here 😛

#

What is it that you are wanting to do? Perhaps there is a better solution

#

(Just fyi, memes and such are not allowed in the server because they take up so much space and can clog up or derail conversations)

nocturne geyser
# gloomy chasm What is it that you are wanting to do? Perhaps there is a better solution

I wanted to create a MenuItem that would (essentially) do something similar to a UI Image (albeit with some differences that aren't necessary to the context). When you click it, a "Select Sprite" window would pop up (similar to what happens when you change the image on a UI Image). Once you select one, it would automatically make a UI Image with the selected sprite already assigned to the object along with it correct size.

nocturne geyser
#

I already know how to create the object and give it the same properties, what I dont know how to do is to display that "Select Sprite" window and assign it to the new image component.

gloomy chasm
#

Righto, so taking a look at the source code, it looks like you can do it using some reflection if you want.

#

As you can see @nocturne geyser it takes a Action<Object> onObjectSelectorClassed delegate as a param.

#

So it should be pretty easy to setup! No need for funky update loops or anything.

nocturne geyser
gloomy chasm
nocturne geyser
#

No

gloomy chasm
crude relic
#

you sure there isn't a public api for that? I swear I've used the object selector before w/out having to do reflection shenans

#

🤔

#

mb I'm just making stuff up

gloomy chasm
crude relic
#

ahhh that must be what I'm thinking of

peak bloom
# peak bloom How can I get the center position of an active area of graphview, so I can get t...

Managed to center newly spawned nodes into graphview, I bet there is an easy way to do this rather than rolling your own math

                    schedule.Execute(() => 
                    {
                        var graphView = vg._vviews.viewTransform.position;
                        var graphViewScale = vg._vviews.scale;
                        var editorWindow = vg.position;

                        vnode.SetPosition(new Rect((-graphView.x + (editorWindow.width/2)) / graphViewScale, (-graphView.y + (editorWindow.height/2)) / graphViewScale, editorWindow.width, editorWindow.height));
                        vnode.RefreshPorts();
                        vnode.RefreshExpandedState();
                    });
#

i'm open for suggestion

peak bloom
#

pretty sure xMin yMax do the same thing.. ugh

old ravine
#

I'm trying to create my own click & drag functionality in my EditorWindow script, but it seems I can't get the event for that, the built in "box select" behaviour overrides what I'm doing, and I don't get any more events until the mouse button is released and the built in blue selection box disappears.

This page seems to describe exactly my problem, and an apparent solution, but not quite what I want - he's clicking on some object he created. But I need to start clicking and dragging from any collision the user clicks on. Kind of like the way you click to drag select units in a 3D RTS. Wherever you click on the terrain, a box will drag out horizontally from that location.
https://stackoverflow.com/questions/63040319/unity-editor-capture-hold-mouse-down-and-move-event

craggy latch
#

I'm currently having an awful time trying to fight the scene camera. I have a level editor that runs in scene view. A part of that is scrolling to change the placed tile. As far as I can tell, there's no way to stop unity zooming on scrolling, so instead I have to set it back on Camera.onPreRender which will jitter half the time. I need to subscribe to that event though, which doesn't survive any sort of reload, so I need to run IntializeOnLoadMethod to reset it, but that only works for static methods, so I need a singleton to actually set it. I don't even know what's going on memory leak wise with the very dodgy subscribing and unsubscribing, but I don't imagine it's good.

Any advice? Some way to stop the zoom? A better place to set the camera size to avoid it jittering? Some way to make the event subscription not awful?

#

Also forgot an additional pain. You can't get the sceneview at InitializeOnLoadMethod. I don't even know how I had this working earlier. This is pain.

peak bloom
#

anybody knows how to show default inspector on top of uielements?

crude relic
#

make sure to call Event.current.Use()

old ravine
crude relic
#

@old ravine same applies to you lol

#

subscribe to beforeSceneGui

#

it allows to override default scene behavior

craggy latch
crude relic
#

np

old ravine
craggy latch
#

And I after I'm back at my PC. Let's hope this goes smoothely.

crude relic
#

you also need to manage GUIUtility.hotControl

#

if you don't register/set your own control id it won't override the default functionality

old ravine
#

@crude relic Also It's doing a weird thing where the DrawLine that I'm using smears across the screen and only refreshes the 3D view correctly at some kind of intervals that I can't determine, seems when I stop moving the mouse. Maybe your solution will help with that too.

crude relic
#

whenever you're doing mousedrag stuff in the scene, make sure to call SceneView.RepaintAllViews or whatever it is

#

so it repaints consistently

#

never run into smearing before tho

#

are you using Debug.DrawLine

craggy latch
crude relic
#

you should be using Handles.DrawLine

crude relic
#

cant guarantee I'll be online tho 😄

craggy latch
#

👍

old ravine
#

Works great for in-game

crude relic
#

yes, Debug.DrawLine is runtime-only

#

for editor you either want gizmos or handles

#

handles in this case

old ravine
#

Lifesaver man, it works perfectly 🙂

crude relic
#

it will behoove you to dig into the Handles and HandleUtility classes

#

they are necessary for sceneview editors

old ravine
#

Yes I'm compelled to do that now

near plover
#

I have an editor extension that opens a simple EditorWindow when I press a button. Is it possible to persist that EditorWindows location in unity's layout after I exit and re-open unity? Pressing 'save layout' doesn't seem to save the location of my extension's window.

crude relic
#

hmm

#

not sure it is possible to save positions of external windows

near plover
#

Usually the first thing I do is dock the window

#

It opens as a popup, but I want it to just be another panel

crude relic
#

it is possible to save the position of the panel if it's been docked

near plover
#

Oh, when I load the editor layout, I get this error: The editor layout could not be fully loaded, this can happen when the layout contains EditorWindows not available in this project

crude relic
#

yah makes sense

#

it can't find your window

#

make sure it's in a file that matches the class name

#

and isn't an inner class

near plover
#

It is not in a file matching the class name 🙂

crude relic
#

that would explain it then

near plover
#

I had to delete the layout, but it seems like that worked.

#

Thank you so much!

crude relic
#

👍

whole steppe
#

Hi everyone! I'd like to create a prefab that when dragged into the hierarchy, the user will be prompted to input an integer. Then that number of prefabs will be created as children of an empty game object. Is this possible with code? If prompts aren't possible, public variables in the inspector should be fine as well!

craggy latch
gloomy chasm
craggy latch
gloomy chasm
craggy latch
gloomy chasm
#

or

public class Example
{
    [InitializeOnLoadMethod]
    private static RunExample()
    {
// Sub
    }
}
craggy latch
#

Yes. You would need the instance of Example to sub to the event.

crude relic
#

No you don't

#

Just make the method you're subbing to static

crude relic
#

What are you trying to accomplish?

gloomy chasm
#

Anyone know if there is there a good way to serialize the value of a SerializedProperty?

crude relic
#

Uh

craggy latch
crude relic
#

It's a problem of your own making

#

Initialize on load is static

#

Event handler is static

#

Event delegate is also static

#

Everyone wins

crude relic
#

Bc the obvious answer is that it is already serialized

#

I don't think there's a way where you're not having a giant switch case

crude relic
#

That may appeal to your non-static sensibilities a bit more

#

And then you have a strict lifecycle since it's tied to having the tool enabled

craggy latch
#

Noted. Thanks.

craggy latch
#

@crude relic I've got this running and it works great.

private static void BeforeSceneGUI(SceneView sceneView) {
            Event guiEvent = Event.current;

            if (guiEvent.type == EventType.ScrollWheel) {
                if (!guiEvent.shift)
                    guiEvent.Use();
            }
        }

Small problem though, I need to use the scroll event for another script. You mentioned the hotcontrol thing for that, but I don't understand it. Could you give me some pointers? I could also just tell the other script to do it's thing from here, but want to learn what the hotcontrol thing is.

gloomy chasm
# crude relic I'm assuming you mean like, write the value to disk?

Haha yeah I mean write it to some sort of serialized format (bytes, json string, etc.).
Part of the problem is that I need it to be really generic, so it can handle any property value. The reason being is I basically need to be able to store the value of any given property and then restore the property to that value at another point in time.

whole steppe
slim vector
#

so im making a tool to make duplicating a lil bit easier. the duplicating of the object with its position, rotation and scale are working fine but im having issue with the preview mesh it is displaying. as seen in the video, the preview mesh itself has a different rotation than the actual mesh itself and im scratching my head for a fix, any idea on how to fix the preview mesh rotation issue?

#

the code for the preview mesh itself. i suspect the issue is with the Matrix, not sure...

if (inputInstances > 0 && Selection.gameObjects.Length == 1)
{
    GameObject go = Selection.gameObjects[0];
    MeshFilter[] meshFilter;

    // Get the existing MeshFilter component from the selected gameObject
    // If it doesn't exist, then get the MeshFilter component from the child gameObject(s) instead
    if (go.GetComponent<MeshFilter>() != null)
    {
        meshFilter = go.GetComponents<MeshFilter>();
    }
    else
    {
        meshFilter = go.GetComponentsInChildren<MeshFilter>();
    }

    if (meshFilter != null)
    {
        foreach (MeshFilter filter in meshFilter)
        {
            GameObject currGO = filter.gameObject;
            Mesh currMesh = filter.sharedMesh;

            for (int i = 1; i <= inputInstances; i++)
            {
                Vector3 finalPosition = CalculatePosition(currGO.transform.position.x, currGO.transform.position.y, currGO.transform.position.z, i);

                Quaternion finalRotation = currGO.transform.rotation * Quaternion.Euler(inputRotation.x * i, inputRotation.y * i, inputRotation.z * i);

                float scaleX = inputScale.x;
                float scaleY = inputScale.y;
                float scaleZ = inputScale.z;
                Vector3 finalScale = new Vector3(scaleX, scaleY, scaleZ);

                // Create a translation, rotation and scaling matrix
                Matrix4x4 matrix = Matrix4x4.TRS(finalPosition, finalRotation, finalScale);

                _previewMaterial.SetPass(0);
                Graphics.DrawMeshNow(currMesh, matrix);
            } 
        }
    }
}
wise yoke
#

does anyone know why AssetDatabase.Refresh doesnt refresh resources folder? I can only get it to refresh by recompiling my code

plain lake
#

After using var inputRect = EditorGUI.PrefixLabel(position, label);,
I see text value which is in the text field on the label overlapped!!!

gloomy chasm
gloomy chasm
crude relic
plain lake
#
   var inputRect =  EditorGUI.PrefixLabel(position, label);
        inputRect.x -= EditorGUI.indentLevel*15;
        inputRect.y += inputRect.height;
        inputRect.width -= 60;

        _input = EditorGUI.TextField(inputRect, _input, _style);
#

the first one is pattern and the second one is input rect

wise yoke
# gloomy chasm It should. What are you wanting and what are you seeing/not seeing?

I have an icon generator that makes pngs of items in my game, it runs in the editor, it generates and imports the icons just fine (saves them to resource folder) I call asset database refresh after that, but it never finds them until I force I manual recompilation of all scripts (by changing random code around or adding a comment etc)

whole steppe
gloomy chasm
wise yoke
#

After that code runs I want to assign the icons to the items, but resources.load never finds them

#

so I have to do a manual refresh for it to work

plain lake
#

EditorGUI.indentLevel*15

gloomy chasm
gloomy chasm
plain lake
#

The second text field should not have any label

wise yoke
#

I have an import preset and everything, they load in just fine, only thing that fixes it is me manually compiling the assemblies

crude relic
#

Assetsatabase.refresh won't import them, you need to import them

#

I can't remember the overload

#

Is it in assetdatabas

#

?

#

Something like assetdatabas importassets

gloomy chasm
#

AssetDatabase.ImportAsset(..)

crude relic
#

Yah

wise yoke
#

They get imported just fine, I can see them in the unity browser, just resources folder can't see them

wise yoke
crude relic
#

You should turn off automatic imports before and turn them on after

#

And then use the bulk import overload

#

Will make it much faster

#

Off automatic refresh actually I think it is

gloomy chasm
#

(@crude relic you have too much faith that people understand what they are doing!)

crude relic
#

I like to give the broadest solution and then work inward as necessary

#

Saves me effort and lets people draw their own conclusions. Better for learning! 😁

gloomy chasm
crude relic
#

Yah that's fine

wise yoke
#

I like to think I know what I'm doing 🥲

crude relic
#

You don't but its ok neither do any of us 👍

#

In the grand scheme of things

gloomy chasm
crude relic
#

Basically the opposite strategy of me 😂

gloomy chasm
#

LOL

wise yoke
#

I'm the same way when I help people as well

gloomy chasm
#

Is there a way to override a prefab property from script?

visual stag
#

Just change the instance?

crude relic
#

do you mean apply the override?

#

there's the PrefabUtility class

gloomy chasm
# visual stag Just change the instance?

I am trying to understand exactly how the prefab override system works. And I want to see if it is possible to override a generic property without overriding one of its fields.

#

So override _myClass but without overriding _myClass._fooFloat

visual stag
#

I don't understand what that even means, _myClass is not what it serialized if it contains children

#

so you cannot override it at all

crude relic
#

do you mean overriding what type _myClass is

visual stag
#

Is _myClass being serialized with SerializeReference or something?

gloomy chasm
#

Again, there is no 'end goal'. I am just trying to understand exactly how the system works so I can mirror it in my ScriptableObject Variants

#

I think I have figured it out, basically it just keeps track of which if any of its properties are overridden. And if any are, then it is too.

visual stag
#

I imagine that's the case, because _myClass has no member in the serialization hierarchy

#

it isn't present in the YAML at all

#

you cannot override its value in any sense, only the values of the serialized properties that are the lowest children

crude relic
#

SO variant is something that makes a lot of sense

#

surprised (not really) they haven't done that yet

wise yoke
#

@gloomy chasm @crude relic sorry for the incredible delay, but using assetdatabase.importasset doesnt work, any ideas why?

crude relic
#

nope, would need to get my hands on it

#

asset shenans are sometimes unintuitive

wise yoke
#

yeah and alot of it isnt well explained in the docs unfortunately

#

cant really share the project, it's for my job :/

crude relic
#

I wasn't suggesting that you should share it lol

visual stag
#

Good a time as any to get fired 🤷

wise yoke
#

fr

#

in all seriousness its not that big of a deal, im just an automation freak lol

visual stag
#

What's the setup with the Resources folder?

#

are you certain you're not just screwing up the call to Load

#

(like, does it work if you manually make the assets)

wise yoke
# visual stag What's the setup with the Resources folder?

editor script spawns prefab, positions it, takes icon screenshot, saves it to resources folder, i call assetdatabase.importasset, it cant find at all, but if i force a recompilation of the project, it can find it, so something is going wrong with the resource folder refresh

visual stag
#

If that's all good, try a AssetDatabase.Refresh perhaps?

wise yoke
#

thats what i was doing initially

#

it all works great if i manually compile the project (which i assume reloads resources)

#

but i cant get it to be automated

crude relic
#

what do you mean it can't find it at all

#

resources can't find it?

wise yoke
#

resources.load

#

returns null

visual stag
#

If you're running the load directly after creating the icon, are you using ImportAssetOptions.ForceSynchronousImport?

crude relic
#

^

wise yoke
#

no, ill try

#

didnt work

crude relic
#

@wise yoke if you're making a lot, use AssetDatabase.StartAssetEditing to queue up the calls also

#

and StopAssetEditing of course

wise yoke
#

i will, but what does that do?

visual stag
#

Well I think the answer is just to have a breakdown

crude relic
#

queues up imports so it can batch them

#

makes importing faster

#

when you're doing lots of it at once

visual stag
#

If you're making a load of assets a Start and Stop AssetEditing call will make it so there's one loading bar instead of a flickering mess of loading 😄

#

and it will be significantly faster

crude relic
#

on a tangential topic I'm designing an asset that may generate lots of textures, and I'm contemplating generating the meta files myself so I can avoid the initial import step 🤔

visual stag
#

I imagine the thing that takes time is messing with the Library, not the meta files

#

but I could be wrong

crude relic
#

you're correct, but the messing with the library is what I'm trying to avoid

#

if you write a png file to disk then it needs to import that

#

if you then want to immediately change the import settings via code you need to reimport it

#

if I just set up the meta file with the import settings I want then no reimport necessary

visual stag
#

If you StartAssetEditing it won't reimport until you're done modifying

crude relic
#

yah but I need to get the importer to change and serialize the import settings

visual stag
#

Ah I see

crude relic
#

the whole texture gen workflow is garbage lol

#

making the meta file by hand just sounds super janky though

#

so I'm hesitant

wise yoke
#

sounds like something easy to break

visual stag
#

I still am unsure whether having the meta file would skip you importing the asset before loading the importer

#

I would use a Preset over a meta file, but I'm unsure whether that helps the problem either

crude relic
#

if it were possible to write a png to disk and apply a preset to it on first import then I'd be all over that

wise yoke
#

presets as in?

visual stag
#

ye

crude relic
wise yoke
crude relic
#

if I write the meta file by hand, it becomes this:

write file & meta -> import

visual stag
#

Ah right, that makes sense, you don't need the importer if it's fine to begin with

crude relic
crude relic
#

but meta file is prone to breaking with version changes

#

so potentially lots of upkeep

#

maybe unity's serializer is robust to missing properties, so I can just write what I care about and let it fill out the rest lazily on some future re-import

#

I'd only need to do the manual part once, if the file already exists I'd just grab the importer

#

@wise yoke can you post the relevant snippet

#

tired of speculating w/out code

wise yoke
#

yeah sorry, cleaning it up so its easier to understand, 1 sec

crude relic
#

no worries

wise yoke
#

this should be all thats relevant

#

i do the try catch finally thing around this method

crude relic
#

you do have a double / in your path

#

not sure if it matters

visual stag
#

The leading forward slash seems odd too

crude relic
#

/Resources//UI/Icons/...

wise yoke
#

afaik

gloomy chasm
#

You don't even need to do Application.dataPath

crude relic
#

ImportAsset still needs the extension

gloomy chasm
crude relic
#

oh so it does

#

nvm

visual stag
#

The mixing and matching of string interpolation and concatenation is killing me 😄

crude relic
#

lol

#

yah it's not pretty

wise yoke
gloomy chasm
#

Is it possible that the AssetDatabase hasn't had time to update yet?

#

So Resources can't find it because it isn't there yet?

crude relic
#

Also, you don't need to use Resources Load

#

just load it via AssetDatabase

#

AssetDatabase.LoadAssetAtPath

visual stag
#

Yeah, that's what I would do. Already in an editor context

gloomy chasm
#

Hold up, what if it can't load it because you are trying to load it as a sprite and it isn't set to sprite?

visual stag
#

I think a preset was mentioned

#

I am not sure when presets applied to folders runs, which could certainly be the issue

wise yoke
#

yeah idk if the preset is messing it up

gloomy chasm
crude relic
#

and also try assetdatabase

gloomy chasm
#

(For testing I mean)

crude relic
#

yah there's a lot of ways to break this down and test this implementation that you can do

wise yoke
#

does loadassetatpath need file ext?

crude relic
#

yes

#

Resources is the odd man out, everything else wants extensions

visual stag
#

Use the same path you use for the ImportAsset

crude relic
#

as a rule

gloomy chasm
crude relic
#

because they're not files?

gloomy chasm
#

Yeah

crude relic
#

makes sense

gloomy chasm
#

I had to think of it within the context of builds to realize

visual stag
#

I enjoy never using the resources folder

crude relic
#

I just use it because it's stupid simple

#

I don't want to bother with enterprise tooling unless I have to

wise yoke
#

this works :D (the loadassetatpath method fixed it)

gloomy chasm
crude relic
#

yay

wise yoke
#

Thanks so much guys, ive automated some of my job now lol

visual stag
#

Hrm, that's interesting. I wonder if that means that it's the Resources folder that hasn't recalculated its index

crude relic
#

probably

#

but there's no public api to know that

#

interesting

visual stag
crude relic
#

anyway lesson is not to use resources in the editor

wise yoke
#

also, i fixed all the interpolation and concat mixing :)

crude relic
#

or at all, depending on how much you hate it

#

😄

#

you still have a double //

#

just saying

wise yoke
gloomy chasm
crude relic
#

when you concat everything together it will become /Resources//UI

visual stag
#

You have a mixed slash setup

#

this one should go, the others should exist

visual stag
#

like here

crude relic
#

👍

wise yoke
#

blame it on my lack of sleep lol

gloomy chasm
#

You can also get rid of the Application.dataPath

wise yoke
#

dont i need it? im using normal c# file.io, so shouldnt it not understand unity context?

visual stag
#

All the methods can just use the same "Assets/Resources/etc" path

crude relic
#

unity sets your cwd

#

of the process

gloomy chasm
crude relic
#

doesn't matter what type of file

#

it's all the same process

gloomy chasm
#

Its magic

visual stag
#

It's nice not having to create so many random paths 😄

crude relic
#

🪄 ✨

wise yoke
#

it doesnt seem to work without it

crude relic
#

rip

#

guess we all have egg on our heads

visual stag
#

Assets/Resources

crude relic
#

oh mb the leading slash

#

get rid of that

gloomy chasm
#

Not me, it works on my machine!

visual stag
#

It should be the same path as the others, not /Resources

crude relic
#

yah

wise yoke
#

very epic

gloomy chasm
#

I can't tell you how long I did some stupid Application.dataPath.Remove(Application.dataPath.Length - "Assets".Length) or whatever to get a project relative path before I learned I didn't need to... 🥲

visual stag
#

epic

crude relic
#

nice, very cool

wise yoke
#

this feels so good, i used to assign the generated icons by hand like a fkn cave man

crude relic
#

now you are a cave man with fire

visual stag
#

I am happy to have never known a world where I did dumb things with paths

wise yoke
#

now that we are getting exponentially more items in the game i cant do it that way anymore lol

gloomy chasm
#

@visual stag Just wanted to say thanks for the thing about SerializedProperties earlier being not able to be set because they are not saved to YAML. That helped it finish clicking in to place and change how I see the problem I was having! 🙂

#

Is there a way to convert a UnityEngine.Object reference to a string and then back by chance...?

#

Oh, GlobalObjectId will work I bet

#

Because of the change of how I am thinking about SPs a bit, it should also solve my problem I was having earlier about how to save SP values! This is great! 😄

crude relic
#

I like how all of the methods in GlobalObjectId are tagged as slow with no alternatives

gloomy chasm
#

Right!? Like... why even call them slow then? Maybe just so we will all know like "Hey, these are really slow..."

crude relic
#

I think that's why

gloomy chasm
#

Maybe they realized people be doing GameObject.Find(..) inside of an Update() loop and thought they should make it explicitly clear that this new API is slow.

#

That is all I can think of

zenith estuary
#

You can ToString that, then TryParse it back to a GlobalObjectId and use GlobalObjectIdToObjectSlow

#

The methods have "slow" in the name but that's only because (afaik) they will iterate over all objects in a scene to locate the target

#

That's why there are "batch" versions of them, since calling the single-object one repeatedly for a bunch of scene objects would add up in a large scene

#

As far as I know, the slowness doesn't apply to asset references, only scene references

crude relic
#

interesting

#

if only there was a way to limit it to assets

zenith estuary
#

That's not too hard

#

You can check the type

#

If it's a scene reference, remove it

#

or don't process it

crude relic
#

ooh I see

#

the type is encoded in the id

#

smart

#

so it never searches what it doesn't need to

zenith estuary
#

I used it to reimplement the internal SceneObjectIdentifier type

crude relic
#

nevermind, my comment is totally useless

#

😄

#

very cool

#

that's a part of the editor I've never touched

zenith estuary
#

Normally that type is only usable by Unity internally since the functions to use it are in C++

#

But GlobalObjectId is a superset of its functionality, so you can use that to reimplement it

#

Which I had to do in order to access objects stored in the LightingDataAsset

crude relic
#

interesting

#

that could potentially be useful for my importer...

#

I'm wondering about ways to orchestrate having a single asset import generate many files

#

and keeping those files' relationship with the root asset

zenith estuary
#

If you define a "fake" serializable version of an internal type, you can read/write it with EditorJsonUtility

#

The field name has to be the same as the class name

#

LightingDataAsset in this instance

crude relic
#

that is a clever way to do that

zenith estuary
#

it's trivial from there:

#

I used to use SerializedObject, but I had to use reflection to set its internal "inspectorMode" value

crude relic
#

I always have compiled lambdas to access internal stuff

#

though usually I'm calling methods

zenith estuary
#

But this approach doesn't need reflection and works better, so I ditched that

crude relic
#

I will definitely keep that technique in my back pocket

zenith estuary
#

There is a catch though

#

Since your field names has to match the names Unity uses in serialization, you will run into situations where the name you need to use isn't a valid identifier

crude relic
#

oh, bc of the identifier indices[4]

zenith estuary
#

indices[0] through indices[3] rather

#

public fixed int indices[4]; is just how I expose the value publicly so it's still seen as a fixed buffer

crude relic
#

oh I see

#

this is your code

zenith estuary
#

yeah

#

It's also annoying that Unity doesn't expose its Matrix3x4f type, only Matrix4x4f (as UnityEngine.Matrix4x4)

#

So I had to implement that too

crude relic
#

what does tetrahedron have to do with lighting probes

#

random question 😄

zenith estuary
#

It generates a tetrahedralization for more efficient light probe interpolation

crude relic
#

fascinating

zenith estuary
crude relic
#

I've always wanted to sit down and learn some of the guts of rendering

#

just never had the drive so far

zenith estuary
#

In my case this is driven by a need for it at work

#

Since we do a lot of custom lightmapping stuff

crude relic
#

makes sense

zenith estuary
#

(We can control the color, intensity, etc of baked lights)

crude relic
#

without rebaking

#

?

zenith estuary
#

yeah

#

all dynamic

crude relic
#

that's cool

#

isn't it baked into a texture?

#

so you're modifying the texture at runtime

zenith estuary
#

nope

#

it's still baked into a texture yes, but we don't modify the texture

#

It's very similar to how games like Thief or Quake did this in the 90s

crude relic
#

you modify how it's mixed into the scene

zenith estuary
#

Yeah

#

It's very cheap and lets us get really high quality lighting without paying the cost of dynamic lighting

crude relic
#

so all the lights are baked as white I'm assuming

zenith estuary
#

Yup

crude relic
#

gotcha

zenith estuary
#

The bake script stores their colors, sets them as white, and then bakes them

crude relic
#

it's just not GI which means you can't move the lights

zenith estuary
#

Yeah, I refer to it as "composited baked GI"

crude relic
#

cool

#

well thanks for sharing that was really illuminating

zenith estuary
#

lmao

crude relic
#

no pun intended initially

#

until I started typing it out

#

haha

zenith estuary
#

at some point I wanna do a writeup about how it works, since there's a lot of stuff involved

crude relic
#

no kidding

zenith estuary
#

unfortunately a lot of the work is actually because Unity's lightmapping API sucks

crude relic
#

I am definitely saving your tip of accessing internal data structures

zenith estuary
#

Very little is exposed, and the actual lightmapping process is hard to hook into

#

Most of the work involved was related to reverse engineering the engine lol

crude relic
#

doesn't help with my need for method calls, but sure it'll come in handy

#

it always is 😄

gloomy chasm
zenith estuary
#

EditorJsonUtility can modify native objects, JsonUtility only works on managed objects

#

i.e., EditorJsonUtility can modify anything SerializedObject can

#

JsonUtility can only really modify what reflection can modify

#

So EditorJsonUtility can change the internal m_LocalPosition value in a Transform for example, while JsonUtility wouldn't know what to do with one

crude relic
#

well in return for that juicy information here's a class that lets you create an importer platform-specific settings group with a default tab:

zenith estuary
#

EditorJsonUtility also skips validation when modifying the data, unlike SeralizedObject

#

Which I take advantage of

crude relic
#

if you ever find yourself in need of making a very slick and native-esque importer 😄

zenith estuary
crude relic
#

because for some reason the exposed method doesn't let you create a default tab 🤔

zenith estuary
#

Unity and not exposing useful APIs, name a more iconic combo

crude relic
#

anyway I'm wondering if I can leverage globalobjectid to maintain a parent-child relationship between my imported textures and the source asset 🤔

#

so that I can write to the files wherever they are even if people move them

crude relic
#

hm

zenith estuary
#

asset GUID doesn't work for scene objects

#

since they don't have a GUID

crude relic
#

wouldn't need to be for scene objects

zenith estuary
#

Then a GUID will work

crude relic
#

cool

zenith estuary
#

Well actually

#

GUID also won't work for sub assets

#

eg, if you have one asset, and the texture is a sub object of it

#

such as when you use AssetDatabase.AddObjectToAsset

crude relic
#

I think that should be ok

zenith estuary
#

but that's a very rare case

#

so yeah, probably not worth complicating over

crude relic
#

I'm generating images, so I'd just always refer to the base imported texture

old ravine
#

In my custom EditorWindow "BuildingCreator" I want to create a building prefab that I can then continue to tweak with a custom Inspector, to set its position and size, number of floors in the building etc.

What's the workflow for this? Instantiating prefabs seems to be done by dragging a link to a prefab into a public variable of a script component attached to a GameObject already in the scene, and then calling Instantiate using that variable as a parameter. Can my EditorWindow access that?

I made a new GameObject in the scene called "EditorInfo", attached a custom "EditorInfo" script, and made a "BuildingPrefab" variable to hold the prefab, dragged the "Building" prefab into the variable OK, and back in my EditorWindow script, I'm using this line to access it:
EditorInfo editorInfo = GameObject.FindObjectOfType<EditorInfo>();

But I'm getting the error: Assets/Editor/BuildingCreator.cs(28,9): error CS0120: An object reference is required for the non-static field, method, or property 'BuildingCreator.editorInfo'

gloomy chasm
#

Building Creator

heavy path
#

Anybody know if there's something or an asset store plugin that can convert an entire GameObject into a script?

#

So like say there was an empty GameObject with a few cubes and text inside it

#

Ah wait this is the wrong place isn't it

#

My bad

#

Actually I'll make it myself if I have to

#

Anyways so like I said if there was an empty GameObjects with a few cubes and text inside it

#

How could I convert everything in that empty GameObject

#

Into a script that builds it

#

If you kind of get what I mean

lime flicker
#

Not sure exactly what you mean. Drag the topmost gameobject it into one of your data folders to create a Prefab that you can instantiate repeatedly?
If you want to build it from script you'll just have to write the code to assemble the right parts according to whatever rules you want...

#

There are plugins to do procgen modelling according to a node graph though, would that suit?

gloomy chasm
#

I don't want to jump to conclusions... but I think I have found a bug...

#

So.... turns out

serializedObject.CopyFromSerializedProperty("_myList.Array.size");

works fine, but

serializedObject.CopyFromSerializedPropertyIfDifferent("_myList.Array.size");

will cause the above crash...

crude relic
#

so good news, you can indeed generate a minimal meta file and unity will happily fill it out with defaults for you

delicate pivot
#

Hey, Does anyone knows if it is possible to add a button in this bar to perform custom actions?

delicate pivot
#

(please ping me if you know, im going to bed i'll see tomorrow)

tired crane
#

Does anyone know how to enable unity debugger and snippets in visual studio code, this is really bugging me 😭

#

I have them installed and it says they're enabled but they dont seem to work

crude relic
delicate pivot
#

thanks man

#

👌

crude relic
#

np

delicate pivot
#

(how the f*** does this work 😰 )

crude relic
#

which part lol

#

I've never used this plugin

delicate pivot
#

how did he manage to extend it lmao

crude relic
#

iirc you can hook into the gui using shenanigans

delicate pivot
#

haha

#

dark magic

delicate pivot
#

haha i think i'm just too tried to try to understand now, i'll take a look tomorrow

crude relic
#

looks like it takes advantage of unity's UI being based around visualelements now

delicate pivot
#

mmh i see i see

wispy delta
#

I'm struggling to figure out how to record a full hierarchy undo when in the prefab editing context.
Does something look wrong with this function?

[ContextMenu("Apply Style")]
private void ApplyStyle()
{
    #if UNITY_EDITOR
    
    var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
    if (prefabStage != null)
        Undo.RegisterCompleteObjectUndo(prefabStage.prefabContentsRoot, "Apply Style");
    
    #endif
    
    bindings?.Apply(style); // changes a buncha properties on self and children that I'd like to be undoable
}
#

ah silly me. i wanted RegisterFullObjectHierarchyUndo not RegisterCompleteObjectUndo

barren moat
#

I'm trying to build a property drawer using UIElements but getting this error:

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;

namespace EffortStar {
  [CustomPropertyDrawer(typeof(AssetName))]
  public class AssetNameDrawer : PropertyDrawer
  {
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
      var container = new VisualElement();

      var foo = new Label("Foo!");
      container.Add(foo);

      return container;
    }
  }
}

Does anyone know how to address this?

wispy delta
old ravine
#

How do I "make an object" on the click of a custom editor button?

I found examples that do GameObject.CreatePrimitive, but I think what I want to do is spawn a Prefab

#

Or maybe create an empty and attach a component

crude relic
#

@old ravine well, which are you trying to do 😄

#

the method varies

#

depending on what you're doing

barren moat
#

Maybe NaughtyAttributes is taking control actually

old ravine
# crude relic <@!279870442569859073> well, which are you trying to do 😄

I'm not sure 😆
My goal is to create a "building entity" by clicking and dragging out a square on the ground that defines the size and placement of this building, a building pops up in that location and from there I can click on this building entity and customise its properties, like how many floors it has, etc.

#

So my question is: what should this bulding entity be in Unity terms. A Prefab?

crude relic
#

is this meant for you or is this going to be a public plugin

#

do you want to be able to edit properties after you finalize the parameters?

#

or do you just want to have it be a one-and-done kind of thing

old ravine
old ravine
crude relic
#

ok, I would just instantiate a prefab with a component

#

you can make the component editor only, so it'll get stripped out when you play

#

you can build the building in OnValidate but that's not super efficient, so I'd be more likely to use a custom inspector

#

and trigger the build there

#

the build code can still be in your component tho

#

and called from the inspector

#

use PrefabUtility to instantiate the prefab

#

check out the Undo class to help integrate undo support

old ravine
crude relic
#

you can use component.hideFlags = HideFlags.DontSaveInBuild;

old ravine
crude relic
#

yah, or you can detect changes and update it on the fly in your inspector

old ravine
#

Yes, I can do that but I assumed it might be slow for how I'm generating the building, but I will just do it and see how it performs

#

@crude relic Thanks man! Just needed some pointers, seems like there's a million ways I could go about this

crude relic
#

@old ravine can always make auto gen a toggle 😛

old ravine
crude relic
#

looks like my idea to write the meta file by hand works & cuts out a re-import cycle

#

🎊

barren moat
#

Is there any way to get mouse input event in editor, regardless of the focused unity window? I'd like to create some mouse shortcut macros.

#

(the shortcut editor doesn't support mouse buttons)

old ravine
barren moat
#

I'll try this one

#

Yeah, same issue. Requires scene view to be selected.

old ravine
#

Ah OK, it was worth a punt

peak bloom
barren moat
peak bloom
#

I'll skip mine too for now 😆 thanks for letting me know! 👍

long oak
#

Hey, has anyone made any experience implementing IPreprocessBuildWithReport on a monobehaviour?
Reasoning being I've created an additional sceneloader mb, which serializes the path & guid of the scene asset during editor time and also serializes it's buildIndex - but if the build order get's changed and the object isn't selected/loaded it wouldn't get notified.

long oak
#

so, if anyone is interested: you can implement it with some additional #ifdef but it seems to not have access to the proper instance of the mb at that time

crude relic
#

@barren moat you can do this if you hook into native windows functions and intercept mouse and keyboard

#

but you're outside of the unity ecosystem at that point

#

and obv it's not cross-platform

#

I implemented this ages ago to get better mouse wrapping behavior a la blender

light hearth
#

I'm having trouble with my property drawer extension. This is the error I'm getting every time i try to edit my scriptable object, and google isnt really helping me:
ArgumentException: Getting control 9's position in a group with only 9 controls when doing repaint
Anyone know what causes this, and how to solve it? I can share code if needed.

crude relic
#

@light hearth it means you're modifying something in between the layout and repaint pass

#

which is a no no for IMGUI

light hearth
#

Yeah thats what it says when i google it too. I just dont have any idea what it means lol

crude relic
#

which part dont you understand

#

specifically

light hearth
#

I dont understand what they layout pass is, nor the repaint pass, nor how Im modifying it between those passes, when this property script works for some scriptable objects but not others

#

I guess I have some reading to do

crude relic
#

@light hearth here's your two second overview:

the way that IMGUI's automatic layout works is that it calls your code multiple times to draw the final inspector

#

first it does the layout pass

#

which determines all of the rects it needs

#

this needs to be a separate pass because some layout notions can't be finalized until after the layout item has been created

light hearth
#

Hm I see.

crude relic
#

after that, it goes through again and draws everything to the screen, this time using the rects that it calculated

#

however, if you change something about what layout functions you're calling in between layout and repaint, the saved rects generated in the layout pass won't line up with the objects you're trying to draw

#

it panics and throws an error

#

in other words: if you change state in your drawer, that state needs to be consistent at least between the Layout pass and the Repaint pass

#

if you post your code here I may be able to tell you how that's happening

light hearth
#

Okay I understand that. So I need to specify which pass each instruction is in? Or repeat the instructions, once for the layout pass and then the repaint pass? This is my code: https://gdl.space/azuyunijin.cs

crude relic
#

usually these passes are taken care of automatically

#

but there are certain things you can do in the code that will cause a disconnect

#

ok, your issue is being caused by the fact that you're trying to use layout methods inside a property drawer

#

on lines 51 and 54

light hearth
#

Strange, because this works in some cases. But I believe you

crude relic
#

for property fields, it precalculates the layout size using GetPropertyHeight

#

once you're inside OnGUI in the property drawer you're no longer in a layout context and you can only use GUI methods

light hearth
#

Ahh i see

crude relic
#

that's what's registering the controls it doesn't expect, because OnGUI doesn't receive a layout pass at all

#

you can check this for yourself (for educational purposes) by logging Event.current.type in the property drawer

light hearth
#

That makes sense

crude relic
#

you'll never see a Layout event

light hearth
#

So OnGui is just being called in the repaint pass

crude relic
#

yes, and also the mouse and keyboard passes

#

your gui functions get called many times, for any event that happens in the editor

#

layout and repaint are just two of them

#

that's why it's so easy for imgui code to become so slow

light hearth
#

So I need to find the separate function that is called on the Layout pass and do my EditorGuiLayout things there?

crude relic
#

there is no easy way to do layout stuff in PropertyDrawer

#

I would advise you stick to non-layout methods

#

this just means you need to calculate the rects yourself, which isn't usually too big of a deal

light hearth
#

Hm thanks for the advice, i guess I have some reading up to do. I thought doing a simple "drop down" to display different variables would be simple.

crude relic
#

by drop down do you mean a field toggle?

#

like this?

#

dynamic height stuff is a pain in property drawers

#

not impossible but still a pain

light hearth
#

Hm maybe could work. I mean more like i have a drop down list. and when a specific drop-down entry is selected, a specific set of fields are displayed. And other drop down entries show another set of fields

crude relic
#

I see

light hearth
#

Thats sort of what my propertydrawer does now. But it doesnt work for some scriptable objects

crude relic
#

yeah, complex inspector stuff is outside the scope of propertydrawer

#

you would need to specify the heights each of your dropdown fields need to take up

#

in your getpropertyheight method

light hearth
#

Ah rip. Thought this was such a common problem that there would be some go-to solution that most people use

crude relic
#

most people use custom editors

light hearth
#

lmao i legit thought that was what property drawers were

crude relic
#

no, property drawers are for specific types or attributes

light hearth
#

But property drawers are more for individual fields

crude relic
#

to be drawn inside an editor

light hearth
#

or htat, yeha

crude relic
#

yes

light hearth
#

Well I appreciate the help, now I have a starting point of where to look.

crude relic
#

np

light hearth
crude relic
#

looks like that video uses a custom editor, rather than a property drawer

#

if you want your PassiveEffect drawer to be used in many different classes this won't work for you

light hearth
#

Oh yeah, thats correct. thanks for the heads up.

gloomy chasm
#

My mind is drawing blank, is there a way to only iterate the children of a serialized property besides comparing propertyPath?

crude relic
#

if you do Next( true ) it'll step into the children

#

what do you mean by "only"

gloomy chasm
#

I can do while (property.Next(true) && property.propertyPath.StartsWith(basePropertyPath))

#

But wondering if there was a nicer way

crude relic
#

use depth

#

that's what I did

gloomy chasm
#

ooh, good idea. I forgot it was a thing

crude relic
#

while( Next && depth > startDepth )```
haughty ruin
#

Hey, does anyone know of a page where I can find all the available EditorGui controls with screenshots? Sometimes I'm trying to find a specific thing, but I have to try a few because there are no screenshots of what it looks like anywhere

wispy delta
haughty ruin
#

maybe? I actually found what I needed luckily 🙂 (All I wanted was a menu to popup from a generic button, and that control is literally called GenericMenu hahaha)

#

who knew 🙂

wispy delta
#

I am trying to find all overridden properties on a prefab variant, as well as their original values on the source prefab so that I can revert the overrides whose values are unchanged. I've been fumbling around the PrefabUtility API all day and am struggling. Does this sound possible?

#

So as an example, if you have a prefab variant that changes an images color to white, but the source prefabs image color is also white, I wanna detect that and revert the redundant override

old ravine
#

How do I instantiate a Prefab from within an EditorWindow?
The only way I know to instantiate anything is by making a public variable on the object in the scene that holds a reference to the prefab, this variable is passed to the "Instantiate" function. But the EdtorWindow script doesn't exist in the scene so we can't set its public variables in this way.

wispy delta
old ravine
#

Hope someone helps with your question

gloomy chasm
#

It will give you an array of PropertyModification which contains a string for the value and a string for the property path

#

Also has an UnityEngine.Object field for object references

whole parcel
#

Hey! How so I have an enum of states and each of them has different values which works as intended, but how would I make a List above all this which would give the state enum dropdown list again?

#

Work around is adding the script multiple times like this:

cedar condor
whole parcel
#

so I have public struct HorrorData containing enum and some variables

#

then I have a class Horror with the list of HorrorData

cedar condor
#

So what's the issue?

whole parcel
#

and in my HorrorEditor I have this

#

this way it makes the list

#

but this part doesnt do anything

#

before I added the list it worked and filtered only the variables that I needed but now after I added the list this is completely ignored and it shows all the variables

cedar condor
#

Did your Horror class exist before this?

whole parcel
#

yes

#

but everything in the struct HorrorData was in the Class Horror

cedar condor
#

Could I see the entire HorrorData script?

whole parcel
#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;



public class Horror : MonoBehaviour
{
    public List<HorrorData> hor = new List<HorrorData>();
    

}

[System.Serializable]
public struct HorrorData
{
    public enum HorrorEvent
    {
        DisableAtStart,
        DisableMovement,
        MoveObject,
        Teleport,
        LightOnOff,
        Jumpscare,
        LookAt,
        PlaySound,
        DropObject,
        Levitate,
        ThrowObject,
        EnableOtherTrigger
    };

    public HorrorEvent state;

    private GameObject player;

    //Disable At Start
    public bool disableAtStart;

    //Disable Movement Settings
    public float delayBeforeMovingAgain;

    //Move Object Settings
    public MovableObject movableObject;
    public float delayMoveObject;

    //Teleport Object Settings
    public MovableObject teleportObject;

    //Lights ON/OFF Settings
    public bool lightsOnOff;
    //public List<Light> Lights = new List<Light>();

    //Jumpscare Settings
    public Image jumpSImage;
    public float stayOnScreenFor;

    //Look At Settings
    public GameObject camera;
    public Transform lookAt;
    public float lookAtDelay;
    public float damping;
    //private Vector3 lookPos = new Vector3();
    private bool startLook;

    //Play Sound Settings
    public string clipName;

    //Drop Object Settings
    public GameObject dropObject;

    //Levitate Objects Settings
    //public List<FallObject> LevitateObjects = new List<FallObject>();
    public float forceUp;
    public float forceDown;
    public float delay;

    //Throw Object Settings
    public FallObject throwObject;
    public float force;

    //Enable Other Trigger Settings
    public GameObject otherTrigger;
}
#

Lets say I move it back and comment out the list

public class Horror : MonoBehaviour
{
    //public List<HorrorData> hor = new List<HorrorData>();
    public enum HorrorEvent
    {
        DisableAtStart,
        DisableMovement,
        MoveObject,
        Teleport,
        LightOnOff,
        Jumpscare,
        LookAt,
        PlaySound,
        DropObject,
        Levitate,
        ThrowObject,
        EnableOtherTrigger
    };

    public HorrorEvent state;

    private GameObject player;

    //Disable At Start
    public bool disableAtStart;

    //Disable Movement Settings
    public float delayBeforeMovingAgain;

    //Move Object Settings
    public MovableObject movableObject;
    public float delayMoveObject;

    //Teleport Object Settings
    public MovableObject teleportObject;

    //Lights ON/OFF Settings
    public bool lightsOnOff;
    //public List<Light> Lights = new List<Light>();

    //Jumpscare Settings
    public Image jumpSImage;
    public float stayOnScreenFor;

    //Look At Settings
    public GameObject camera;
    public Transform lookAt;
    public float lookAtDelay;
    public float damping;
    //private Vector3 lookPos = new Vector3();
    private bool startLook;

    //Play Sound Settings
    public string clipName;

    //Drop Object Settings
    public GameObject dropObject;

    //Levitate Objects Settings
    //public List<FallObject> LevitateObjects = new List<FallObject>();
    public float forceUp;
    public float forceDown;
    public float delay;

    //Throw Object Settings
    public FallObject throwObject;
    public float force;

    //Enable Other Trigger Settings
    public GameObject otherTrigger;

}
cedar condor
#

I think I see the issue

whole parcel
#

this works as intended but I can only select one enum

whole parcel
cedar condor
#

You're drawing the properties of HorrorData with the custom editor

#

But since HorrorData is a struct and not a Monobehaviour instances of it only appear within the Horror data class, which doesn't have a custom editor

whole parcel
#

ooh I see

cedar condor
#

I think you have to draw the properties accessing them through the Horror class

#

Since there are no instances of the HorrorData struct outside of the Horror class

whole parcel
#

like move everything from HorrorData to Horror?

cedar condor
#

Not exactly

whole parcel
cedar condor
#

If you accessed the properties THROUGH your Horror class then it should work fine

#

I'll try to give an example

whole parcel
peak bloom
#

Will VisualElement.MarkDirtyRepaint also mark the children as dirty then repaint them all? I didn't see this mentioned in the docs anywhere

cedar condor
#

Still trying

whole parcel
#

no worries, take as much time as needed

#

I really appreciate the help

crude relic
#

@zenith estuary I just used your EditorJsonUtility trick for the first time -- thanks again for sharing that, it's great!

cedar condor
#

It might not be possible with the current system you have

#

Since you don't have access to the variables inside of HorrorData as SerializedProperties, it's impossible to custom draw them

whole parcel
#

right

cedar condor
#

The SerializedProperties for those variables are never created since that's not the object being inspected

whole parcel
#

oh okay I see

#

is there an other way I should go about this?

cedar condor
#

Not sure

#

I just recently started messing around with editor stuff a few weeks ago, and while I have learned a lot I'm definitely no expert at this stuff

whole parcel
#

Well I started 7 hours ago 😄

cedar condor
whole parcel
#

thank you for the help anyways I really appreciate it

cedar condor
#

I'm not sure if you could write a custom inspector for your HorrorData class

#

Change it to a class instead of a struct and you might be able to

whole parcel
#

I'll give it a try

#

How would I make a list out of the class tho?

cedar condor
#

Personally I would see if there's a way to make a custom inspector for you HorrorData class first

cedar condor
whole parcel
#

I haven't thought about that, that could be an option

cedar condor
#

Oh actually, you could potentially put your HorrorData class inside of the other one, and see if you have access to the vars that way

whole parcel
#

yeah it works that way

#

but how would I make a list of the Horror class now 😄

cedar condor
#

Exactly

#

That's the issue that we're struggling with

whole parcel
#

yeah

cedar condor
#

Try something like this:

public class Horror : MonoBehaviour
{
  public List<HorrorData> data = new List<HorrorData>();
  
  public class HorrorData
  {
    //Your data
  }
}
#

And then see if you're able to access the properties of HorrorData through the custom inspector

whole parcel
#

can't access them that way :/

cedar condor
#

Damn :/

#

I've only ever tried to do something similar once and I failed miserably 😦

whole parcel
#

wait I can

cedar condor
#

You can??

whole parcel
#

with System.Serializable

cedar condor
#

Try to access the SerializedProperties through the editor class though

whole parcel
#

weeeell yeah that doesnt work 😄

cedar condor
#

Try using Editor.CreateEditor on each of your HorrorData classes then try accessing the properties

#

I'm a bit out of what I know at this point

whole parcel
#

you have done more then enough, thanks a lot

#

I'll go and play with that documentation now hahha

cedar condor
#

Sounds good

#

Good luck with that

peak bloom
#

then instantiate the custom class as serializeobject as array
you don't even need customEditor for that

cedar condor
zenith estuary
crude relic
#

without it I'd need to build the conversion into the lambda

#

which is annoying

zenith estuary
#

Yeah, and SerializedObject is also a bunch of effort

crude relic
#

doesn't serializedobject only work on unity objects too

#

BuildPlatform is a POCO

zenith estuary
#

Yeah

#

If you wanted to use SerializedObject you'd have to use a wrapper ScriptableObject or something

crude relic
#

the platform specific settings methodology is really convoluted

#

I'm just digging into it in the reference source

#

they use a bunch of proxy objects and stuff

zenith estuary
#

Editor code is constantly a mess I swear lol

crude relic
#

all to make the editor experience smooth and limit what they need to serialize

#

it really is

cedar condor
#

Although I really don't know enough to be efficient with it anyway

misty igloo
#

Howdy Mech, tried doing a build using this library but there appears to be an issue with my version in "UHashSet" line 357,

Assets\_Assets\Scripts\Utilities\Runtime\UHashSet.cs(357,44): error CS0103: The name '_serializedItems' does not exist in the current context```
#

is there an issue with just changing this to "_serializedValues" as that appears to compile, or is _serializedItems a different form of object altogether and this shouldn't be happening?

gloomy chasm
misty igloo
turbid ruin
#

Anyone have experience with Playfab? Trying to see if its possible to send a password recovery email to someone given their username. I dont want users to have to login with email or type it in for recovery. Is it possible to find their email based on their username? I tried using GetAccountInfo but it says u need to be logged in to make the api call, which obviously user will not be since they need their password to login

waxen sandal
#

I doubt this is the rigth channel for that

turbid ruin
waxen sandal
#

This channel is for developing extensions

#

Not questions about random plugins

turbid ruin
waxen sandal
#

They probbaly have a forum or a discord themselves for questions

cosmic inlet
#

anyone know how to pass data from Port to Port in Graph View?

turbid ruin
jolly delta
#

I'm looking for a way to see the Scene as a node graph, to see the relations between every gameobjects and their monohabeviours

#

and add/remove relations between those behaviour properties using node links

#

anyone know something like that ?

shadow violet
#

If a script is in the Assets/Editor folder, shouldnt it automatically NOT compile with a build? Do you absolutely HAVE to encapsulate every Editor script in a Editor folder with #if UNITY_EDITOR for it to exclude from a build?

visual stag
shadow violet
shadow violet
peak bloom
#

not from/to Port but to Nodes specifically

#

if you required to have some function to detecting Ports for example then that depends on your implementation, but you can still use userData as a self-contained container

#

just to note, I said sorta 🙂 bcos the example is not for graphview, but it still applies

#

either way, you can do this without it, as filtering connected ports should do the job for most use cases

#

another example from my graphview's node

            //Associate VParentNode class upon creation
            vnode.userData = new VParentNode(vnode.VNodeId) as VParentNode;
cosmic inlet
#

I'm still struggling

#

ughhh

south beacon
#

Hi, I'm constantly forgetting to assign serialized Fields after creating/refactoring scripts. Since Unity doesn't seem to have a "require"-feature for fields (or does it?), I'm thinking about writing an extension that checks all serializefields in my scene/prefabs to not be null, unless i specifically annotate it to state otherwise in my code. Does somebody know if such an extension exists or how I would approach building my own? Maybe some kind of hook that's executed after the compile process, where I can iterate over all scripts in the Scene

crude relic
#

You would want to create a script that iterates over your objects, collects the fields, and checks if they're null

#

Excluding any that contains your attribute

#

You can do this using reflection

#

I would also cache your class types so you don't repeat work

#

@south beacon

south beacon
#

Okay, I'll give it a try. Thanks!

cosmic inlet
#

ok so I think I figured out a way to transfer ports-

#

how can I like

#

get the custom attribute of a variable

#
public string stringName;

void OnEnterNode()
{
  string = { variable from the Port attribute };
}```
#

something like this

#

I have the Port with a constructor

#

which takes in some variables

#

and then another variable that is assigned sometime else, outside of the constructor

zenith estuary
#

A simple example that would work for the above code:

cosmic inlet
#

oh?

zenith estuary
#
var attribute = GetType().GetField(nameof(stringName)).GetCustomAttribute<PortAttribute>();
#

Ideally you would want to cache this stuff somewhere, since you don't want to constantly be using reflection

#

For editor code, Unity also has a TypeCache class

#

You can do TypeCache.GetFieldsWithAttribute<PortAttribute>() to iterate over every field in your code with that attribute

hoary grove
#

I'm looking to have a Rightclick menu that creates a new Prefab based on an existing Prefab? Whats the best way to go about doing this?

cosmic inlet
#

yeah, this is a pain

#

I have to somehow get variables, when all I know is the port that corresponds to them, which is kept inside their attribute

#

I have literally no idea how to do such a thing-

peak bloom
#

the graphview is just a representation of your data, you can check which port connected to which...

#

literally just a graphical representation...

crude relic
#

What are you trying to do

#

Why do you care which port something is

cosmic inlet
#

yeah but the way I'm telling it to create ports is by making variables, assigning a custom attribute, and then get all of the variables with that custom attribute and run some logic to create the ports in a NodeView script

#

the issue however, is that I need to get the variables from an output port from Node A to the input one on Node B

#

it's really hard to explain-

#

uhh

#

variable has a custom attribute
custom attribute of that variable has a reference to it's corresponding port that gets assigned when I create it
and then I need to get the variables that correspond to those ports

#

the ports are store in the custom attribute of those variables

#

and I somehow need to get the variables

#

this is the function to create ports:

    {
        BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
        MemberInfo[] members = node.GetType().GetMembers(flags);

        foreach (MemberInfo member in members)
        {
            if (member.CustomAttributes.ToArray().Length > 0)
            {
                PortAttribute attribute = member.GetCustomAttribute<PortAttribute>();
                if (attribute != null)
                {
                    PortAttributeInfo info = new PortAttributeInfo(member, attribute);

                    Port newPort = InstantiatePort(Orientation.Horizontal, info.portAttribute.direction, info.portAttribute.capacity, info.portAttribute.dataType);
                    newPort.portName = "";
                    info.portAttribute.correspondingPort = newPort;
                    Debug.Log(info.portAttribute.correspondingPort.userData);
                    Debug.Log(info.portAttribute.correspondingPort);

                    if (attribute.direction == Direction.Input)
                    {
                        inputPorts.Add(newPort);
                        inputContainer.Add(newPort);
                    }
                    else
                    {
                        outputPorts.Add(newPort);
                        outputContainer.Add(newPort);
                    }
                }
            }
        }
    }```
#

it just takes in a Node, gets all the variables that have an attribute of PortAttribute, and creates a port based on the values from that attribute

#

This line is where I tell that variable which port corresponds to it
info.portAttribute.correspondingPort = newPort;

#

so now I have this function where o is the parent and c is the child Node

//Assign userData to parent first using the Ports
c.userData = o.userData;
AddElement(edge);```
zenith estuary
#

You can optimize that a bit by using TypeCache, which will avoid a lot of the work involved in scanning types for attributes etc

#

Though it depends on the Unity version you're on

cosmic inlet
#

2021.2

zenith estuary
#

You can use it then

cosmic inlet
#

yeah

zenith estuary
cosmic inlet
#

I will optimize it after

crude relic
#

I'm confused, why is there an issue

zenith estuary
#

Unfortunately there's no GetMembersWithAttribute, only fields and methods

crude relic
#

If you're building ports you already have the fields

zenith estuary
#

So there's nothing for properties

cosmic inlet
#

because I can't figure out how to get the variables that correspond to those ports

crude relic
#

Bc you're in the middle of doing the scanning

#

But the member is the variable...

cosmic inlet
#

because the ports are stored inside of the attribute corresponding to that variable

#

so I have 2 ports, start and end, which I need to assign data to

crude relic
#

The memberinfo contains the variable

#

Or describes it

cosmic inlet
#

this is where I keep the port reference for the variable

cosmic inlet
zenith estuary
#

So your PortAttribute describes the data that you want to receive in the stringToDebug field?

cosmic inlet
#

I can get the node from the start port and the end port

#

it describes the port that I assign the variable to

#

the correspondingPort variable is referenced in the CreatePort() function I posted earlier

zenith estuary
#

It's best to not store Port in the attribute itself

crude relic
#

Why would the port attribute know where the corresponding port.is

cosmic inlet
#

then where?

zenith estuary
#

Attributes are for "constant" data

crude relic
#

That makes no sense

zenith estuary
#

You would store it elsewhere, in a cache or some other location

#

A static dictionary could work

crude relic
#

Yeah, you should make a list of connections on your graph object

#

With start ports and end ports

#

Or something

#

Or a dictionarry

cosmic inlet
#

a dictionary might work

zenith estuary
#

Also, is DataType always supposed to be set to the field's type?

cosmic inlet
#

uhh

zenith estuary
#
[Port(...)]
public T Something;

should it always be typeof(T) in this example?

cosmic inlet
#

I didn't know how to do that

#

thanks

crude relic
#

You can just get the type from the firld

#

Field

#

Memberinfo

zenith estuary
#

Yeah that's what I was about to mention

#

But wanted to be sure that's what the data is meant to be

crude relic
#

Yah

#

Yeah you can't really write data to attributes

#

And if you can then you shouldn't

zenith estuary
#

The attribute should probably be:

#
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class PortAttribute : Attribute
{
    public Direction Direction { get; }

    public Capacity Capacity { get; }

    public PortAttribute(Direction direction, Capacity capacity)
    {
        Direction = direction;
        Capacity  = capacity;
    }
}
cosmic inlet
#

it is that now

#

ok but dictionaries are composed of multiple variables

zenith estuary
#

And then you can do:

foreach (FieldInfo field in TypeCache.GetFieldsWithAttribute<PortAttribute>())
{
    var attr = field.GetCustomAttribute<PortAttribute>();
    // set up the port for this field
}
cosmic inlet
#

ok my brain is just, fried

zenith estuary
#

Your dictionary could be Dictionary<FieldInfo, Port>

crude relic
#

Are you trying to serialize connections in your graph

cosmic inlet
#

I really don't know how to do any of this

#

I have variables with attributes, a script takes the attributes and creates the ports, and then I need to somehow make the variables in the second Node be equal to the ones in the first

#

like

crude relic
#

You only need to do that when you're executing the graph

cosmic inlet
cosmic inlet
#

and while it's running

#

I don't know how to tell it to take the variable from the port it's connected to

crude relic
#

That's what I said

cosmic inlet
#

because the code has no idea what ports correspond to which variables

crude relic
#

That's what your scanning code is supposed to be setting up

cosmic inlet
#

ok then in what way should I keep track of which ports correspond to which variables

crude relic
#

Make a port class that contains a memberinfo

#

Create a port for each port attribute

#

Assign all the relevant fields

#

Save it in a list or dictionary

#

Tada

#

You now have a list of ports corresponding to variables

cosmic inlet
#

sometimes I realize I am not very smart lmao

zenith estuary
#

(also it should be FieldInfo and not MemberInfo since you don't seem to be using this with properties or methods)

crude relic
#

Yes