#↕️┃editor-extensions
1 messages · Page 105 of 1
@patent pebble This produces exactly the same as having no property drawer:
public class BuildObjectPropertyDrawer : PropertyDrawer {
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
float height = EditorGUI.GetPropertyHeight(property);
return height;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
Rect labelPosition =
new Rect(position.x,
position.y - EditorGUIUtility.standardVerticalSpacing,
position.width,
EditorGUI.GetPropertyHeight(property, includeChildren: false));
EditorGUI.PropertyField(labelPosition, property, label);
float totalHeight = EditorGUIUtility.singleLineHeight;
if (property.isExpanded) {
foreach (SerializedProperty p in property) {
float height = EditorGUI.GetPropertyHeight(p);
float y = position.y + totalHeight;
Rect r = new Rect(position.x, y, position.width, height);
EditorGUI.PropertyField(r, p);
totalHeight += height + EditorGUIUtility.standardVerticalSpacing;
}
}
}
}
I haven't added the button yet
Very annoying that this has to be done 😦
@shadow moss does your PropertyDrawer have the [CustomPropertyDrawer] attribute?
@shadow moss have you tried using only this?
EditorGUI.PropertyField(position, property, label, true); //Draw property with children
ah, i thought you said you just wanted to add a button
Sorry, I misspoke. But really, your code helped me a lot
I have some conditionals that I need to add, so it's more complex
just to make sure your setup is correct, does it draw the PropertyDrawer when you use the PropertyField with the includeChildren set to true?
Yes it does
alright
well to exclude a property you can just check for its name
in your case you are looping over the child properties, so just skip the one that you cant by checking the name
if (string.Equals(childProperty.name, "_actionData")) {
...
}
yep, you can skip it, or replace it with a button, or whatever
Thank you
I am trying to get an EditorWindow menu GUILayout.Button to call a method in another script.
The GUI script is in the editor folder while the external method is in a script file in a separate asset folder.
I have these lines that resolve in Visual studio but in Unity the object type is not found.
I have not found any threads that reference this type of design.
void OnGUI()
{
m_MS = GameObject.FindObjectOfType(typeof(MethodScript)) as MethodScript;
if (GUILayout.Button("Execute an external method"))
m_MS.ExecuteThisMethod();
}```
m_MS == null
I think you may want to see if you could traverse the scene objects, then look for game objects with the component attached
You're doing this in non-play mode
I may be wrong, but that could be why
This property drawer has been a nightmare
I can't believe it took nearly all day
What are you trying to achieve? If you're writing editor code to setup some data in scene objects or prefabs, you would need to load prefab assets for editing or find and open scenes and then find your component to edit it. Of course pay attention to how editing in the Unity API works (setting things dirty by recording undo etc, loading prefab contents correctly first).
Noting to do with prefabs. The object I am trying to find is a script. I believe I need to make it serializable to get it onto the project database.
what's a useful editor extension i can use to show as an example for class?
just to show that i'm learning them
Do your own homework :X
Does anyone knowns how to get the CustomEditor type (or even better, the current instance) of a non Unity.Object type during runtime?
runtime in the editor? or in a build? (Editor stuff doesn't exist in builds)
Well, I know I could use reflection to get the type and create an instance, but I would like to get the one that would already exist to serialize properly
You answered your own question, in editor runtime
technically you answered my question 😛 but lets not get pedantic
anyway, no there's no easy way to do that (especially since more than one Editor instance can be active)
my best advice is to just store a list of all active editors in a static var
and you can compare the "target" field
the CustomEditor type of a non Unity.Object
@vestal mantle what do you mean? Aren't custom Editors only supposed to work with types that derive from UnityEngine.Object?
am I missing something here?
you can make a custom editor for anything
how?
aren't the target and SerializedObject properties of an Editor class only UnityEngine.Object types?
probably, but you can encapsulate your own object
well yes, but then you are not making an "Editor for anything"
you are making an Editor for your wrapper class
which has to be of UnityEngine.Object
To do that, I'd have to add it to the list when I create them, which means I'd have to access that code which is not an option for what I am trying to achieve
My case here is that you have a serializable class inside a MonoBehaviour for example
They have all the types (Also in an enum: propertyType, I beleive) and one is Generic, which is the other classes
that's a SerializedProperty, not a SerializedObject
Ah, yes, correct. Which is what I am using
I may have been looking in the wrong place due to this precision
Hi there, I want to add an automatic updater for a tool I work on. So far everything is going well except the end where I clean up by removing files that should not be existing anymore after an update.
Unity just keeps crashing when I try to delete assets. Does anyone have any ideas of why that could be? I can't find anything in the log files either
How can I make a manager like the one in this picture? I already have a script and I made a list to hold all the things I want to manage. How do I create these dropdowns?
if you're talking about the thing with the arrow those are EditorGUILayout.Foldout
Awesome, thanks. I’ll look into it
Is that actually some unity editor??
That's my UI but i mean to change sort by Editor but nvm figured it out by canvas
What is the method that opens up a popup with a view of assets (the circle with a dot)?
I'm aware of EditorUtility.OpenFilePanel
Found it. EditorGUIUtility.ShowObjectPicker
Are there any editor extensions that can go back and forward in the inspector?
As an example, if you click on an asset, then in the inspector, you click on a property. It would be nice to go back to the first asset via a keyboard shortcut (or better, a back button)
There was "Inspector Navigator", but it no longer exists
Just about every package that has this no longer exist
We still have one in our project but it's probably 10 years old too
I think it's just called backbutton
NG Nav Selection
I'll look for that
It's free
It works with a UI button, a window, or the mouse's buttons (Windows only)
You won't find it on the Asset Store, it is part of NG Tools Free :
https://assetstore.unity.com/packages/tools/utilities/ng-tools-free-80093
Thanks
Is there any way to change a docked window’s min size? Seems locked to 100 everywhere I put it
Also is it possible to get the whole unity editor window size/rect so I can position popup windows at the bottom?
Trying to split a rect for a PropertyDrawer
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var left = new Rect( position );
var right = new Rect( position );
left.width = position.width * 0.33f;
right.width = position.width * 0.66f;
right.x = position.width * 0.33f;
EditorGUI.PropertyField(left, property.FindPropertyRelative("hand"));
EditorGUI.PropertyField(right, property.FindPropertyRelative("button"));
}
but this is what i get
ah nvm i forgot a + sign
right.x += 1/3 width
perfection
EditorWindow.minSize ?
Unity is the ultimate game development platform. Use Unity to build high-quality 3D and 2D games, deploy them across mobile, desktop, VR/AR, consoles or the Web, and connect with loyal and enthusiastic players and customers.
anyone else having trouble with package manager ?
Hub 3.x has my acc , but not the editor no matter how many times i restart it
Nope
hey all, is there a way to open a new Properties window for a specific asset?
for example, I want to add a custom inspector button that will pop open a new floating Properties window for a ScriptableObject so I can quickly edit it without losing selection of my current gameobject.
Need to use reflection. This is what I have.
public static EditorWindow OpenPropertyEditor(Object obj)
{
if (_openPropertyWindowInfo == null)
{
Type propertyEditorType = typeof(EditorWindow).Assembly.GetType("UnityEditor.PropertyEditor");
_openPropertyWindowInfo = TypeAccessor.GetMethod(propertyEditorType, "OpenPropertyEditor", typeof(Object), typeof(bool));
}
return (EditorWindow)_openPropertyWindowInfo.Invoke(null, new object[] { obj, true });
}
thanks! where would I need to put that? in an Editor-derived script?
In any class that is in an Editor folder. It is static and almost completely self contained so it doesn't matter.
hmm, sorry but I don't really understand how to adapt this to my needs. would you mind explaining it a little?
what is "_openPropertyWindowInfo" for example?
Sure, _openPropertyWindowInfo is just a MethodInfo field used to cache the MethodInfo for the OpenPropertyEditor method because getting it is expensive.
ah OK so I need static MethodInfo _openPropertyWindowInfo; declared first?
TypeAccessor is just a utility class I made, it would be the same as the normal propertyEditorType.GetMethod(..)
Yup
Btw, look in #854851968446365696 to see how to mark/show text in Discord as code 🙂
OK I think I'm over my head a bit here. bit of a novice when it comes to editor windows and reflection.
so apologies for the many many questions.
All good! 😄
so the TypeAccessor.GetMethod() part should actually be propertyEditorType.GetMethod() in my case?
_openPropertyWindowInfo = propertyEditorType.GetMethod("OpenPropertyEditor", new object[] { typeof(Object), typeof(bool) }, BindingFlags.NonPublic | BindingFlags.Static);
It would be that, though the order of the parameters might be wrong, but your IDE should show you all of the overloads for the method
using UnityEditor;
using System.Reflection;
using System;
public class EditorTools : Editor
{
static MethodInfo _openPropertyWindowInfo;
public static EditorWindow OpenPropertyEditor(UnityEngine.Object obj)
{
if (_openPropertyWindowInfo == null)
{
System.Type propertyEditorType = typeof(EditorWindow).Assembly.GetType("UnityEditor.PropertyEditor");
_openPropertyWindowInfo = propertyEditorType.GetMethod(("OpenPropertyEditor", new object[] { typeof(Object), typeof(bool) }, BindingFlags.NonPublic | BindingFlags.Static));
}
return (EditorWindow)_openPropertyWindowInfo.Invoke(null, new object[] { obj, true });
}
}```
that's what I've got now. I have a problem with typeof(Object) though: ambiguous reference between 'UnityEngine.Object' and 'object'
am I using the correct namespaces?
That is because both UnityEngine and System namespaces have a class called Object. In this case we want the UnityEngine one. A neat thing you can do is up by the other usings you can do using Object = UnityEngine.Object; to tell it that Object refers to the UnityEngine.Object
Sure, you can actually have the name be 'anything', so like
using UnityObject = UnityEngine.Object;
Too many ( )
Docs explicitly state it’s not used when docked, and it doesn’t seem to be. UnityCsReference on GitHub doesn’t show anything for EditorWindow tho afaik
It’s weird tho because in 2021.2 I can now shrink all the default Unity windows down to nothing, which is really nice
Yeah, they changed the default behavior to that
But not for custom editors? 🤔
There’s also a weird bug where the minSize specified is a little bigger when the new window is first opened, then when I dock it and undock it again, it will use the real minSize
I'm trying to add a MenuItem to unity. I added a script to my Editor folder that looks like this: ```using UnityEngine;
using UnityEditor;
public class ConfigSelector : MonoBehaviour
{
[MenuItem("Window/blah/config")]
static void ConfigOptions() => Debug.Log("hello");
}```
I can see the Window/blah/config menu item in my editor, but it's always disabled. Do I have to do something to allow custom menu items? I tried adding a validator, but it doesn't seem to make a difference.
I just restarted the editor and now it works. Shrug. Guess I don't need help afterall.
@near plover MenuItems are weird sometimes
sometimes they don't update until you restart Unity
i face that problem a lot when I'm reordering them by changing their priority parameter
Good to know. At least I know how to work around it, and I don't expect to update the menu item itself very often.
Thank you!
@near plover another workaround I use is commenting out the entire script, saving, clicking on Unity so it recompiles, uncomment the script again, and go back to Unity
but be careful doing that with your MonoBehaviours because you'll lose data
Interesting
all of my MenuItems are just in editor-only scripts, so I don't need to worry about losing data
Same for me, but still a good thing to remember.
is it possible to use netbeans as code editor instead of visual studio?
You forgot a parameter?
forget what I said, it should work without as well
can you use a loop to make multiple foldouts for a list of objects?
great. now i'm wondering, if i have an editor script to make a custom inspector for an object, is there a way to access a member variable of that object in the editor script?
Like if I have a manager that holds a list of objects, what is the best way to access that list in the editor script
Using SerializedObject and SerializedProperty. You can see the pinned messages for resources on them
is there a way of getting the current InspectorWindow that is drawing an instance of Editor?
[CustomEditor(typeof(SomeMono))]
public class SomeMonoEditor : Editor
{
private void OnEnable()
{
// How do I get the InspectorWindow that is creating this Editor instance?
}
}
I'm making a tool that relies on knowing the InspectorWindow in which an Editor is being drawn in
I'm digging around in the source code but I haven't found anything to solve this
Yes
Let me find the code
Well shit, i dont have it
you can have a list of all the Inspectors, but not the currently drawing
The thing is, Editor is not related to a Inspector
It can be drawn from anywhere
Will this allow me to edit individual values of each object like in this image?
because right now i just have this
Yes, you will need to make a SerializedObject for each one you want to edit the properties of
so i'd want to get the list like i already did, make a for loop, and use the same process each time i iterate?
hmmm, shit...
I mean there has to be something internally that is keeping track of that info
i'll keep searching to see if I can figure something out
SerialzedObjects
Look for GUIView.current
@onyx harness there's the class ActiveEditorTracker but that only keeps track of the "main" Inspector window
What is it that you actually need this for?
i'll try that out
From it check window
making a tool to keep track of scrollbars in Inspector Windows
to check if they exist, what position they're in, etc
better to inject yourself and keep a list yourself
i had already gotten it functional, but it relied only on the "main" inspector window, doesn't support additional inspectors
I have high hope in GUIView.current.window
@onyx harness allright, I'll dig through there too and see if I can find anything useful
What Mikilo just posted will get you the window that was last repainted/draw iirc
not last repainted, but currently being drawn
hmmmm, with my current setup I would need to know the window when the Editor is instantiated
If I'm correct
@patent pebble how did it go?
still trying things out, haven't found a solution yet
I'll let you guys know when I do
I guess GUIView didnt worked out
i haven't tried that avenue yet, I'm still digging through PropertyEditor and InspectorWindow source trying things out
how can i save a list after the editor window is closed and then load it when its opened?
problem is that the list has the type InputActionReference
And what is it?
with EditorPref i can only save int, string, float,bool
a scriptable object
It gets more complex now
Either use a ScriptableObject to store the data, as it can easily save reference to Unity Object
Or you will have to implement a way to remember the "ID" of your InputActionReference
oh
If InputActionReference is an asset in the project, maybe use its GUID
If it is volatile, maybe use the InstanceID
I have absolutely no idea what is your context, so I just throw ideas
ty
Im trying to open the lighting tab from a custom Editor window button. is this possible?
I guess yes
EditorApplication.ExecuteMenuItem("Window/Rendering/Lighting Settings");
This just call the menu, which obviously opens your window
InspectorWindow & Editor instance
Thx, ill ty it out
uuuh so i've been trying to figure out why setting the background texture for a text area's style is bugging out. it would only draw with the texture when pressing my mouse down
on a whim i moved the unity window from my 4k monitor to a 1080 one and the problem went away?!
i attached a gif showing the problem. you can see the background switch to the intended dark texture when i press my mouse down
(excuse the lack of mouse in recording, sharex won't show it on a 4k monitor for some reason)
I'm assuming this should be reported as a bug, but figured I'd post in here for a quick sanity check
pretty straightforward code
EditableMessageStyle.normal.background =
EditableMessageStyle.hover.background =
EditableMessageStyle.active.background =
EditableMessageStyle.focused.background = background;
...
messageProperty.stringValue = EditorGUILayout.TextArea
(
messageProperty.stringValue,
EditableMessageStyle
);
anyone know why a UIElements TextField's TextInput would be white? The debug inspector doesn't show anything white colors applied to it, and none of the colors I edit change that part
It is most likely white because the default style is not being applied to it
I created a style with the proper background
And applying it didn't work?
nope
it works in the editor preview if I change it
and the uxml and uss is being updated in the editor view because I can change the layout and flow and other colors
Try to change the color in the UIToolkit debugger I guess just to make sure. You also use it to see if the style sheet is even present
stylesheet is present
background color changes the background color, but there's still the white box
I see
and the box is drawn on top of the text too
Sorry I'm not sure what to tell you
How can I make such a color selector for my character script in Inspector?
👍
thanks.. let me check
can anyone explain how it can done? I am really new to editor scripting and dont understand much from documentation.
@brazen tiger here's something to get you started
this is also a good introduction to the whole IMGUI system (one of the main ways of making editor tools)
https://docs.unity3d.com/Manual/GUIScriptingGuide.html
you can see all the different sections on the left of that docs page
The image you posted suggest that you're trying to make a color selector which picks from a set of four predefined color swatches (orange, blue, green, magenta). That is different from what MadLed suggested about using the ColorField control, which will open a color picker that lets you select RGB or HSV values via sliders etc. Which one are you trying to implement?
selecting color from predifined color swatches
ah, that's a good point
either way they're gonna have to learn how to use IMGUI
for selecting from predefined colors you would need to use some kind of combiation of GUI.Button and EditorGUI.DrawRect or something along those lines
or you could draw a ColorField and intercept mouse down events to prevent it from being clicked but allow the click to go through to a button that returns the color from the ColorField
Hey I was wondering why my inspector only displays this no matter how many characters I have. What is wrong with my code?https://pastebin.com/f1ZhWRmn
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
it should be able to edit more than just the name, and it should work for every character in the list of characters
When you right-click, you select the Asset
Or in the MenuItem you have the context provided in the argument
Well you don't have any selection, what path are you expecting?
Project window has a different selector system
They probably handle that internally
@stiff vine i don't think you can click the "background" of the project browser, it just selects the asset of whatever row you clicked
to get the asset you clicked you just use Selection.assetGUIDs or whatever it's called
ah wait there's an easier way
it gives you the GUID, from that you can get the path with AssetDatabase.PathToGUID or whatever
or what Mikilo said, you can just add a MenuItem to the Asset
@stiff vinewhat issues are you having? I've never had any problem with the default "Copy Path" menu in Unity
how are you able to click the empty space in the project view?
is this a version-specific thing in Unity?
for me it always select the asset in the row i click
if I click on the actual empty space below the "Packages" folder. I still get the right click Menu, but there asset-specific menu items are disabled
ooooh right the two column layout
i literally never used it 😅
i would use the two column layout if it had an option to still show the assets in the main column
i hate having to click around all the folders to see what's inside them
yeah it makes sense that you get the folder path if you click on the empty space of the area that shows the contents of said folder
Here's an example using the modern approach with UI Toolkit: https://controlc.com/21a33a27
using UnityEditor; using UnityEngine; using UnityEngine.UIElements; public class Colo - 21a33a27
Woah, never seen an ad big like this that you cant even close
Yea I didn't feel like creating an account or paying for Discord Nitro or a pastebin service without ads 😄 I miss the 90s where the internet was free.
@bitter barn can you share a screenshot of how your editor looks? I'm curious
Or maybe IMGUI (although I'm a fan of the new system)
[CustomEditor(typeof(ColorSource))]
public class ColorSourceEditor_IMGUI : Editor
{
public override void OnInspectorGUI()
{
Rect rect = EditorGUILayout.GetControlRect();
rect.width = EditorGUIUtility.labelWidth;
EditorGUI.LabelField(rect, "Color");
rect.x = rect.xMax;
rect.width = rect.height;
var source = (ColorSource)target;
for (int i = 0; i < ColorSource.Palette.Length; i++)
{
if (i == source.ColorIndex)
EditorGUI.DrawRect(rect, Color.white);
Rect swatchRect = rect;
swatchRect.xMin += 2;
swatchRect.xMax -= 2;
swatchRect.yMin += 2;
swatchRect.yMax -= 2;
EditorGUI.DrawRect(swatchRect, ColorSource.Palette[i]);
Event evt = Event.current;
if (rect.Contains(evt.mousePosition) &&
evt.type == EventType.MouseDown &&
evt.button == 0)
{
serializedObject.FindProperty("colorIndex").intValue = i;
serializedObject.ApplyModifiedProperties();
evt.Use();
}
rect.x = rect.xMax;
}
}
}
When doing IMGUI prefer PropertyDrawer in most cases
@bitter barn here's a similar implementation I have
it's encapsulated in its own method so it's easier to use
to use it I just call
_selectedColorIndex = LayoutControls.ColorSwatch("Color", _index, _swatchColors, ref _color);
and I have the option to change the swatch colors on right click
here's the code in case you want it
https://pastebin.com/Kwegw0jc
@patent pebble @bitter barn Thanks a lot
is there an easy way of getting some sort of global notification when ANY EditorWindow is closed?
I think yes
shit, i would swear there is some event somewhere
@onyx harness that one is called from EditorWindow.Close() through a call to UpdateWindowMenuListing()
is it possible to subscribe to reflected events?
i have no clue if or how I can do that 😅
yes
of course you can
good find
i had others
I think there are many indirect ways to try to know this event
what is ShortcutUtility?
on this line
DynamicMethod m = new DynamicMethod("DynamicEvent", typeof(void), arguments, typeof(ShortcutUtility));
just updated it
ah I see now, just CSharpMeta as the owner there
thanks!
yeah, it just needs a Type
any Type
Panel.AfterUpdaterChange
This might give a clue.
HostView.actualViewChanged
This one and other similar to it give a little minor hint
Do you need an realtime signal or delayed signal is ok?
delayed should be fine
just to give some context
i'm caching IMGUI control IDs so I can check them against an editor tool
so i need to do frequent cleanups on the cached IDs so they don't get mixed in when Unity re-does all the controls
i don't know if Unity reuses the same control IDs often or not
i'm just adding this as a safety check, seems like the sane thing to do
well, then get a Resources.Find of all the windows every then & now, and compare, and do your clean
yeah I'm doing something along those lines
but I just wanted to see if it was possible to get an event on editor window closes
i'm trying to register to the events using the example you shared by I always get errors
i don't know what I'm doing wrong 😓
CSharpMeta.ResolveEvent("UnityEngine.UIElements.Panel.AfterUpdaterChange").Add(MyTest);
CSharpMeta.ResolveEvent```
Type : internal class UnityEngine.UIElements.Panel
2019.1.0f2 ⟩ 2022.1.0b4
Field : internal static AfterUpdaterChange
2019.1.0f2 ⟩ 2020.2.0a13
GitHub Source
Well it exists between 2019.1 & 2020.2
You sure you are in between?
2020.3
i tried a bunch of other events, none of them work with the CSharpMeta class
this one for example
Exception: Event not found at UnityEditor.EditorWindow.s_UpdateWindowMenuListingOff with UnityEditor.EditorWindow.
CSharpMeta.ResolveEvent
when doing this ```cs
CSharpMeta.ResolveEvent("UnityEditor.EditorWindow.s_UpdateWindowMenuListingOff").Add(Test);
and I know that exists for sure
because I can subscribe to it with this
private static FieldInfo m = AccessedType.Field("s_UpdateWindowMenuListingOff");
public static Action UpdateWindowMenuListingOff
{
get { return (Action)m.GetValue(null); }
set { m.SetValue(null, value); }
}
but sadly that one doesn't get called consistently, it seems to only fire the first time a window is closed 😓
Strange, I will look at it tomorrow
alright! thanks anyways for your time!
s_UpdateWindowMenuListingOff is a delegate
AddEvent is for event
I need to implement delegate in their as well
ah
whoops
but it still doesn't work with UnityEngine.UIElements.Panel.AfterUpdaterChange
that's an actual event, right?
i'll do it tomorowx 🙂
alright I appreciate all the help ❤️ 🧙🏻♂️
you're welcome good sir!
night night
Check this one:
EditorWindowBackendManager.sRegisteredSystems
Object.OffsetOfInstanceIDInCPlusPlusObject
is quite interesting
It has been a while I haven't dig into the code
fun stuff I find
yeah I'm not very experienced with reflection and source code stuff
so I miss a lot of things 😅
trying to get better at it
dnSpy
& explore
simple as that
or or or
Get the root View
and collect all its children
might be much simpler than we think
Or just Resources.Find<EditorWindow> end of story
i'm out, cya
Or just Resources.Find<EditorWindow> end of story
right, the issue is I want to get a notification when an EditorWindo is closed
getting all the windows is not a problem
I'm glad I made those tools, it gives instant response to a lot of hard questions
You just need to compare to the previous list
@onyx harness yep i use your NGTools stuff pretty much every day
yeah i guess i can just do that on a set timer
yep should work well
yeah I understand that
quite the feat
one day, perhaps Unity will provide us some 🙂
or
lol yeah
time to submit to Unity's wishes... again... 😓
What you can do
Check for new EditorWindow
(same problem)
but hook into UIToolkit event when it closes
Might work
I'm really out this time
cya!
ah i figured out why the s_UpdateWindowMenuListingOff was only working once
it's because the hooked methods get overriden in this:
internal static void UpdateWindowMenuListing()
{
s_UpdateWindowMenuListingOff?.Invoke();
s_UpdateWindowMenuListingOff = EditorApplication.CallDelayed(BuildWindowMenuListing);
}
fixed it with a delay call and resubscribing
public static class IDCacheCleaner
{
[InitializeOnLoadMethod]
private static void Initialize()
{
EditorWindowAccessor.UpdateWindowMenuListingOff += AnyWindowClosedOrOpened;
}
private static void AnyWindowClosedOrOpened()
{
EditorApplication.delayCall += ClearCacheIDs;
EditorApplication.delayCall += ReSubscribe;
}
private static void ReSubscribe()
{
EditorWindowAccessor.UpdateWindowMenuListingOff += AnyWindowClosedOrOpened;
}
}
But does it give what you want? I don't think so
i mean, i get a notification any time any EditorWindow is opened or closed
which in this particular case is enough
it would be nice to get more detailed notifications tho
but at this point i'll take whatever i can get lol
i don't know if I have to cover more cases tho
because I don't know when Unity reconstructs internal UI data like the control IDs and such
so far it seems like covering any time the Selection changes and any time any EditorWindow is opened or closed seems to be enough
time will tell I guess 😅 if my tools break whenever something happens in the editor that triggers a rebuild of the internal UI data i'll notice
Now that you say that... I will myself too need a way to know when any window opens, to inject the tooltips system
another thing I just noticed about the delegate s_UpdateWindowMenuListingOff
it also gets raised when you enter playmode
in my case it's a benefit, but I can see some situations where it can become a detriment
if I find out any other way of getting a nice event when EditorWindows are open/closed i'll let you know
for now this approach seems to work
so... if it ain't broke, don't fix it 🙃
Probably because the interface is often recreated? Are you maximizing?
nope, just hitting play, no maximizing or anything
that delegate gets invoked when an EditorWindow is closed, when the EditorWindow constructor is called and when a DockArea is destroyed
so i guess any of those 3 situations happens when entering Play Mode?
can I extract the children that were added to a parent using AssetDatabase.AddObjectToAsset?
was there something like an attribute or something that let you specify which level of a game object's hierarchy you want selected when clicking on it in the editor? like for example if i have a root object with no mesh in it, with a child that contains the actual mesh - i want to select the root object when clicking on the child
yeah, thanks!
this happens the moment i select more than one of an object i have an editor script running on (the multiple object editing attribute is on), everything seems to be actually working fine but i have no idea to address this error since doubleclicking it doesn't take me anywhere and that info isn't very helpful
i'm also running odin inspector which might mess with those propertydrawers, i guess i'll just leave it be since everything seems to be working anyway
I have a strange bug, when i open the window, the name is correct, but when I add something to the list/field, it changes to the namespace name of the window editor script. Does someone know why?
Hi, I want to bind a key in Unity Editor (F12) to execute a method in one of my scriptable object, is that possible?
Put [MenuItem("CONTEXT/DoThatMethod F12")] above the method you want to call
https://docs.unity3d.com/ScriptReference/MenuItem.html
Wow thank you!!
I want also want to call a method every time a specific field in my scriptable object is changed, is that possible?
OnValidate will be called whenever any field changes, but you'll have to manually track if a field changed
Thanks! To track it, should I create a private field in the scriptable object and store that specific field's value every time OnValidate is called? Or is there a better way to do that?
Yeah that's how I would do it
Leave it private, or use [NonSerialized] if it's public (since you dont really care about it during runtime)
Thanks for the answer!
I'm trying to track changes of a string variable in a scriptable object. But the OnValidate method is called every time I hit a key to edit a string variable in my scriptable object, and it reads the current editing value of that string, not the final value (when I press Enter). How do I prevent this behavior and make it read only when I press Enter?
For example, my string variable's current value is "Hello", I want to execute a method when I change it to "Hello World", but the OnValidate function is called every key stroke I type in, so it reads:
"Hello "
"Hello W"
"Hello Wo"
...
(I have not pressed Enter yet)
@molten sierra are you making a custom Editor for the scriptable object?
I'm not, just using a normal scriptable object.
Or if there is a way to make a custom editor for it, but can display all the fields without having to give custom code for everything then I will make a custom editor for it (it has about 30 fields).
hmmm i know you can use delayed field in custom editors (they don't return the value until you press enter or the focus changes to another field)
i think there's an attribute to do that too for regular fields without custom Editor
can't remember the name
Oh nice! Thanks for the info, I will try to find it.
Sweet thanks!
This works great! But is there a way to make it the default thing? So I don't have to put in on every single variable in my classes?
i don't know if that's possible
what you can use is PropertyDrawers
Thanks!
as far as I know you can write a PropertyDrawer for example for the type "string" and every field of type string in your project will use it
you can use a delayed field in that PropertyDrawer to achieve what you want
Ohh that's interesting!
i've never used a drawer for default types like that, so I don't know if there's other considerations to take into account
but I assume it just works the same as PropertyDrawers for custom classes
Thank you, I will look into it.
Hi, is there a way to show a dropdown list of strings which fetches its values from a local string array, using PropertyDrawer?
For example:
public string[] options = { "a", "b", "c" };
[DropdownList(options)]
public string selection; // I want this show up in inspector as a dropdown list, showing values from "options" array.
I found this PropertyDrawer, it's close but it only takes static string values, not runtime string array: https://gist.github.com/ProGM/9cb9ae1f7c8c2a4bd3873e4df14a6687#file-stringinlistdrawer-cs
I can help, what have you done?
I tried to change its PropertyDrawerHelper to accept an array of strings, but it seems to only accept constant values.
Which is normal, C# nature of things
You have to give it a constant, so give it the name of the target field
Ohh I see, I see. Thanks for the suggestion!
But... if I only give it the name of the target field, how does it know which object to get the field from?
In the property drawer
you have many fields
You have the SerializedProperty from which you can access the Object
Get the object, and use the field name of extract your strings
Thanks! I will try that.
what would be the best way to run editor code for any new gameobjects added to the scene, either from the create menu, or dragged in as prefabs or whatever ...?
EditorWindow.OnHierarchyChange seems like the most promising place i can find for now except it looks like i would need to keep track of which objects are actually new in the scene manually which would be a pain and start incurring overhead when scenes grow large ...
MonoBehaviour.Reset is great but apparently only runs when the component is added to a gameobject, and not when the gameobject (in the form of a prefab) is added to a scene
How to either;
Go to asset in the Project window
Open the asset Properties (like right click Properties) so it opens a window
ok i figured step A. Preferable step B
?
to open the Properties window you need to use reflection
private static Type propertyEditorType = typeof(Editor).Assembly.GetType("UnityEditor.PropertyEditor");
private static MethodInfo methodInfo = propertyEditorType.GetMethod("OpenPropertyEditor",
BindingFlags.Static | BindingFlags.NonPublic,
null,
new Type[] { typeof(Object), typeof(bool) },
null);
public static EditorWindow OpenPropertyEditor(Object obj)
{
return (EditorWindow)methodInfo.Invoke(null, new object[] { obj, true });
}
and you use it like so
PropertyEditorAccessor.OpenPropertyEditor(someComponent);
you can pass any component type as the parameter for OpenPropertyEditor, like a Transform, a MonoBehaviour component, etc
here's an editor script showing an example of how it can be used
https://pastebin.com/QNDxnxCk
Perfect thank you :-) Suppose the alternative is make an editor window for my scriptable
yeah probably. Depends on what you want to do
if all you want is to literally open the Properties window like Unity does by default, use the code I shared
@sage oyster ah it seems like they exposed that method in recent versions of the engine
check if EditorUtility has the OpenPropertyEditor method
i'm in 2020.3, which doesn't have it
they added it in 2021.1
Hello, I have a gameObject with children gameObjects. I can't move the parent gameObject using the editor because when I select it, the first child is automatically selected. So I can only move the first child instead of moving the entire group. Is it normal ?
Im in 2022 so should be fine. Ill check it out
In the editor, when I move an object using the snapping, is it possible to add a "delta" ? I mean, I whould like to have the snapping at (0.5, 0.5, 0) or (1.5, 1.5, 0) or (2.5, 2.5, 0) instead of entire values (0, 0, 0) (1, 1, 0) (2, 2, 0).
I have tried to make an editor script but the OnSceneGUI is not called after a snapping move. I would like to adjust the position by myself after the move. Is it possible ?
@smoky jasper you can change the snapping increment values in the grid options if i remember correctly
https://docs.unity3d.com/Manual/GridSnapping.html scroll down to the section "Grid and Snap window" for the snapping settings
The problem is that I would like a snapping increment of 1 but starting at 0.5. That will give me values: 0.5, 1.5, 2.5, ... But with the settings I can have 0, 1, 2 or 0, 0.5, 1, 1.5, 2. I can't find a way to get what I would like
well then you're probably have to implement your own grid snapping to keep objects at the .5 values
Freya Holmer has an example of grid snapping tool
🔽 click for timestamps & info!
this was originally streamed as a course for students at http://futuregames.se/, who were super kind to let me both stream this live as well as upload it here! so massive thanks to the people at FutureGames!!
💖 Patreon ❱ https://www.patreon.com/acegikmo
🐦 Twitter ❱ https://twitter.com/FreyaHolmer
📺 Twitch ❱ http...
at the end of this video
and the beginning of part 2
Well I already have one CustomEditor and I works for everything except gameObject with children. I don't understand why, but the customeditor is not called if my gameobject contains children.
from the video it' not an auto snapping function
🤷♂️ no idea. If you share the code maybe someone can help
How Can I past source code here ?
All objects that contains a script inheriting from "Entity" should be impacted by this script
It works, but only if this gameObject, which have a script inheriting from "Entity", doesn't have a child gameObject
you mentioned previously you had problems selecting the parent, and that your clicks selected the child object
are you sure you actually have the parent object with the Entity component on it selected?
yes, now I use the Move Tool instead of the Rect Tool, so the parent is selected
Well... I just remove the scrip component and readd
and now it works...
I have a class, HexBoard, which handles the procedural generation of a board for my game.
There are several different shapes I can generate the board in. These shapes are stored in the enum GenerationType. Each enum corresponds to a function, but these do not all have the same function signature, because each shape is defined with different variables. In the given code, the two defined shapes are Hexagonal (defined by a radius) and Rectangular (defined by an x and y).
My desired way of controlling things is to have a window such as this one, where you may choose a Shape, and it will provide you with only the necessary fields, then a button that destroys the current board and generates a new one with the given data.
As shown in this image.
Given that each function has a different signature, how can I best define my variables? If I keep the variable scope local only to their enum processing, the fields will be erased as soon as I try to modify them
I currently have instead made those arguments class variables, as an array of 2 ints, and simply ignore the ints which are not relevant to that data type. This feels like a band-aid fix to me, is there a more appropriate way I can declare my IntFields?
This is my code. I've omitted the actual class declaration so I can cut out a tab, know that all of this is contained inside the class.
HexBoard board;
HexBoard.GenerationType genType;
int[] generationArgs = new int[2];
public override void OnInspectorGUI() {
HexBoard board = (HexBoard) target;
genType = (HexBoard.GenerationType) EditorGUILayout.EnumPopup("Generation Shape", genType);
GenerationFunction generate = () => {};
switch (genType) {
case HexBoard.GenerationType.Hexagonal:
generationArgs[0] = EditorGUILayout.IntField("Size", generationArgs[0]);
// generate = () => board.GenerateHexagonalTerrain(size);
generate = () => Debug.Log(string.Format("Pretending to generate a hexagon of size {0}", generationArgs[0]));
break;
case HexBoard.GenerationType.Rectangular:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Size");
generationArgs[0] = EditorGUILayout.IntField("X", generationArgs[0]);
generationArgs[1] = EditorGUILayout.IntField("Y", generationArgs[1]);
EditorGUILayout.EndHorizontal();
// generate = () => board.GenerateRectangularTerrain(x, y);
generate = () => Debug.Log(string.Format("Pretending to generate a rectangle of size {0}, {1}", generationArgs[0], generationArgs[1]));
break;
default:
Debug.LogError("Unrecognized Option");
break;
}
EditorGUILayout.Separator();
if (GUILayout.Button("Generate Board")) {
generate();
}
}```
Also my row is borked in Rectangular mode. I'm aware of this but it's not something I'm concerned with right now, I can figure that out on my own.
How would I go about making a "blueprint" system somewhat similar to bolt?
I want to be able to draw and drop If statements, strings and Save Variable statements.
Thanks, Please @ me if you respond to this.
With a lot of complex code. Basically it is one of those things that if you are asking, it is probably too advanced for you atm (This isn't meant as an insult to you to be clear!).
With that said, I will give you a brief overview.
You would need to decide if you want to use code snippets, or reflection for the logic. You would also need to pick what form of serialization to use depending on what option you choose. This doesn't even touch on the editor/UI side of things, only the backend.
Nope, this is basically how I would do it but with the addition of using [SerializeField] on genType and generationArgs so that they survive domain reloads (at least if memory serves Editors survive domain reloads)
Actually I would most likely have each variable stored separately for each type just so when switching types the fields will have proper values.
Also there is https://docs.unity3d.com/ScriptReference/EditorGUI.MultiIntField.html for the rectangle shape
Alright, that sanity check is a huge help, then. Thanks.
Yeah I totally get that. Sure thing!
What do you mean by reflection? Do you have any resources you may be able to point me to by any chance?
and yeah it's too complex for me, but I gotta learn some time xD
Not really, best bet tbh is to just google "C# reflection" or something like that.
Totally! If it is something you want to then for sure, just as long as you know it is a pretty advanced thing.
My goal is to try and create a framework that would allow for people to easily make branching narrative games
Ah, there are a good number of those on the asset store. Quite a few open source ones too, you might be able to learn from them.
Any in mind?
Not particularly, most (almost all) of them are node based, so maybe they would not be that applicable for you if that isn't what you are going for
I think node based may be what I'm looking for
Imma search the asset store for a bti
wait what? data in Editor instances survives Domain Reload?
I don't remember tbh
If you serialize it into the editor/editor window, yes. Otherwise windows would reset their state whenever you entered play mode
I'm trying to test that out and it doesn't for me... 😓
well, it does so 🤷
my data doesn't even survive inspector rebuild
[Serializable]
[CustomEditor(typeof(SomeMonoForDomainReload))]
public class SomeMonoForDomainReloadEditor : Editor
{
[SerializeField] private float _someFloatInEditor;
[SerializeField] private string _someStringInEditor;
private SerializedObject _editorSerObj;
private SerializedProperty _someFloatInEditorProp;
private SerializedProperty _someStringInEditorProp;
private void OnEnable()
{
_editorSerObj = new SerializedObject(this);
_someFloatInEditorProp = _editorSerObj.FindProperty("_someFloatInEditor");
_someStringInEditorProp = _editorSerObj.FindProperty("_someStringInEditor");
}
public override void OnInspectorGUI()
{
_editorSerObj.Update();
EditorGUILayout.PropertyField(_someFloatInEditorProp);
EditorGUILayout.PropertyField(_someStringInEditorProp);
_editorSerObj.ApplyModifiedProperties();
}
}
what is "inspector rebuild"
when I change selection
Well that's not gonna work
The instance is serializable but its lifetime is as long as it is open
it doesn't persist if you select other things or close/reopen windows
you shouldn't even need to do the whole ScriptableObject thing, Unity will handle that afaik
yeah i was just randomly testing
@visual stag they do reset when I enter play mode tho
Otherwise windows would reset their state whenever you entered play mode
this got me thinking they would survive entering play mode 😅
I am unsure whether Editors would work across playmode because what you have selected in play mode is not the same instance as in edit-mode. Maybe it would work with fast playmode switch
EditorWindows is where this is relevant to me personally
ah I see I see
makes sense
i have experienced situations when I'm inspecting an Editor in a separate window and sometimes they become a different instance from the actual editor in the Inspector window
i can't remember what caused this, but probably play mode or something like that
by "Editor in a separate window" I mean popping out the Properties window or re-creating the editor with Editor.CreateEditor
[CustomEditor(typeof(HexBoard))]
public class HexBoard_Inspector : Editor {
HexBoard board;
[SerializeField]
HexBoard.GenerationType genType;
[SerializeField]
int hexGenSize;
[SerializeField]
Vector2Int rectGenSize;
[SerializeField]
GameObject defaultTile;
delegate void GenerationFunction();
void OnEnable() {
board = (HexBoard) target;
defaultTile = (GameObject) base.serializedObject.FindProperty("defaultTile").objectReferenceValue;
}
public override void OnInspectorGUI() {
serializedObject.Update();
defaultTile = (GameObject) EditorGUILayout.ObjectField("Default Tile", defaultTile, typeof(GameObject), false);
EditorGUILayout.Separator();
genType = (HexBoard.GenerationType) EditorGUILayout.EnumPopup("Generation Shape", genType);
GenerationFunction generateBoard = () => {};
switch (genType) {
case HexBoard.GenerationType.Hexagonal:
hexGenSize = EditorGUILayout.IntField("Size", hexGenSize);
generateBoard = () => board.GenerateHexagonalTerrain(hexGenSize);
break;
case HexBoard.GenerationType.Rectangular:
rectGenSize = EditorGUILayout.Vector2IntField("Size", rectGenSize);
generateBoard = () =>
board.GenerateRectangularTerrain(rectGenSize.x, rectGenSize.y);
break;
default:
Debug.LogError("Unrecognized Option");
break;
}
EditorGUILayout.Separator();
if (GUILayout.Button("Generate Board")) {
generateBoard();
}
Debug.Log(serializedObject.ApplyModifiedProperties());
}
}```
Sorry if this is getting a little long
The key line here is the line where I set the defaultTile object
This is a Private, Serialized Field, which is meant to hold a reference to a GameObject
And sure enough, in the inspector, I have the correct field and can place a GameObject in it for instantiation
But whatever value I set in there gets totally erased when I switch to Play Mode
And even if I set it again, the reference is never actually received by the actual HexBoard GameObject
It has nothing to instantiate
I've found solutions, but they seem to rely on me making this defaultTile public, which shouldn't need to be the case given that the default inspector can handle this field just fine
I've been put under the impression that ApplyModifiedProperties is supposed to fix this, it never returns true and doesn't seem to do anything
you cannot combine non-SerializedObject/Property functions with ApplyModifiedProperties
if you are not going through the SO, ApplyModifiedProperties is just going to ignore your work.
Use Undo.RecordObject if you can't use SerializedProperty modifications to do the work
I don't understand, am I not using SerializedObject?
Right in OnEnable I set defaultTile = (GameObject) base.serializedObject.FindProperty("defaultTile").objectReferenceValue
No, that is not doing anything with the serialized property
except immediately discarding it
https://gist.github.com/Mikilo/8edbf562d7d3d39867bba1c4687240e5
I updated the class to handle delegate as well.
Call CSharpMeta.AddDelegate("UnityEditor.EditorWindow.s_UpdateWindowMenuListingOff", Test);
With Test being void Test(params object[] args)
aaaah thank you so much! 💙 🧙♂️
i'm about to hit the bed, but i'll try it out tomorrow
will let you know if I encounter any errors ⚔️
i dont understand why im getting this error for the line 155
There's nothing on line 155 and when exactly does the error happen and where does it say the line?
InvalidOperationException could be thrown by some SerializedObject that you're trying to iterate while not allowed. For example, when debugging and trying to expand SerializedProperty values in the debugger (at least it used to do that in the past, haven't seen the issue in a long time).
mb i made a value action with the control type any and it couldnt find it and create a instance
Does anyone have an idea how I can fix my issue with custom property drawers: I have a base drawer defined in a UPM package und a child drawer in the project's regular assembly. There base drawer has useForChildren: true, and the child drawer should override it. This normally works fine, but in my current setup it sometimes doesn't work. Meaning, on some machines, the child drawer is used, on others the base. Sometimes, when I recompile the drawer works, other times it doesn't. It feels like the order of compilation affects which of the two drawers Unity detects first and uses, although they should have a clear order. Is that some known issue or could there be anything I'm doing wrong? If I create the same setup of drawers in my main assembly, everything works fine.
Any chance it's only broken if you start Unity with compilation errors?
no
but it involves generics, so maybe that's tripping Unity up (but well not always, I'm seeing it working every once in a while...)
Do you guys know a reason why this line could not work?
ProjectWindowUtil.CreateScriptAssetFromTemplateFile(templateLocation, "NodeTemplate.cs");
I know for a fact that "templateLocation" is correct, since I tried doing a AssetDatabase.LoadAssetAtPath(templateLocation, typeof(Object)); and it did indeed fetch the asset. So I do not understand why the Script is not being created...
What's happening instead? Where do you call this line? It should create an asset and start name editing, so it needs to happing in a call that lets you do interactive stuff, like OnGUI in the editor. Also you need to have the project window open and maybe even not locked (not sure).
There are a couple of things which would lock the AssetDatabase and would prevent script file creation, e.g. AssetDatabase.StartAssetEditing.
Yes, this is happened, after I try to give a name to a folder
I want to create a folder, and then a script within it
Let me show you a little more
public class Foo : EndNameEditAction
{
public override void Action(int instanceId, string pathName, string resourceFile)
{
var folderPath = Path.GetDirectoryName(pathName);
var folderName = Path.GetFileName(pathName);
var folderGuid = AssetDatabase.CreateFolder(folderPath, folderName);
var folder = AssetDatabase.LoadAssetAtPath(pathName, typeof(Object));
ProjectWindowUtil.ShowCreatedAsset(folder);
var location = ConversaFolderLocator.GetFolderPath();
var templateLocation = $"{location}/Templates/NodeTemplate.cs.txt";
// This is just to prove that the asset exists
var foo = AssetDatabase.LoadAssetAtPath(templateLocation, typeof(Object));
Debug.Log(foo);
ProjectWindowUtil.CreateScriptAssetFromTemplateFile(templateLocation, "NodeTemplate.cs");
}
}
And what is happening instead is... nothing. The folder gets created, but it is empty
@west drum maybe you need to refresh the AssetDatabase before creating the script?
i've never had problems using CreateScriptAssetFromTemplateFile, but I call it from a MenuItem
unity gets the destination path from your current selection in the Project
so that may be another cause
make sure you select the folder you want the new script to be in
So, i need help with Universal RP for 2d lights
I want to make my character have a light in itself, but if i make it have shadows, the light desappears, since the light is inside him.
Please, help, what can i do??
image 1: shadow intensity = 0
image 2: shadow intensity = 1
do not crosspost
oh, sorry
@patent pebble In the end I did myself the File.Write
@onyx harness hey i've been trying your update to the CSharpMeta class and seems to work fine, however I have a couple of questions:
-
- How can I use it to hook to delegates that aren't of type Action<>, and Func<>? For example this one in
EditorApplication
- How can I use it to hook to delegates that aren't of type Action<>, and Func<>? For example this one in
internal static CallbackFunction globalEventHandler;
-
- How can I pass a parameter of Action, instead of Action<T>?
I see you've created method signatures with the typeAction<object[]> callbackas a parameter, but it would be nice to just useAction, because Unity has a bunch of those
- How can I pass a parameter of Action, instead of Action<T>?
I've tried tinkering around with the code but my knowledge of delegates is very poor, and this is a little bit out of my depth 😅
I saw you have this method there
private static void AddDelegate(object target, FieldInfo fieldInfo, Delegate callback, Type returnType, Type[] arguments)
I tried using it but I get errors with the Type[] arguments, i tried passing a null array, an array with length 0, and tried doing fieldInfo.FieldType.GenericTypeArguments;
but i couldn't make it work
hum... I have to try 😅
it would be super nice to just pass a method as the callback without having to do
private static void SomeMethod(params object[] args) // :(
and instead just have this
private static void SomeMethod() // :)
Yeah, I will handle those cases later 😄
public static void AddDelegate(string path, Action callback)
{
FieldHandler handler = CSharpMeta.ResolveField(path);
CSharpMeta.AddDelegate(handler.target, handler.memberInfo, callback);
}
private static void AddDelegate(object target, FieldInfo fieldInfo, Action callback)
{
Action @delegate = (Action)fieldInfo.GetValue(target);
@delegate += callback;
fieldInfo.SetValue(target, @delegate);
}
public static void AddDelegate(string path, Delegate callback)
{
FieldHandler handler = CSharpMeta.ResolveField(path);
CSharpMeta.AddDelegate(handler.target, handler.memberInfo, callback);
}
private static void AddDelegate(object target, FieldInfo fieldInfo, Delegate callback)
{
Delegate @delegate = (Delegate)fieldInfo.GetValue(target);
@delegate = Delegate.Combine(@delegate, callback);
fieldInfo.SetValue(target, @delegate);
}
after googling a little bit and trying to understand this stuff better, I managed to fumble this together and it seems to work
for Action, and Delegate types that don't have any return type and no parameters
i was already doing something similar from a copypasted code form your NGTools website, with the proxy reflection code your site generates @onyx harness
Hehehe glad someone used it :p
oh I use it ALL THE TIME when doing reflection stuff
it's a pretty awesome tool for people like me who aren't very experienced with reflection
right now I know how to make it so I could manage without your site, but it's just way easier to get a neat list of reflected members, methods, etc and just hit copypaste on the generated reflection code
I mentioned this elsewhere, but I've tried multiple times to make a Rider extension just to generate reflection. Never got past the point where I'm setting the basic extension shit up 😛
Hum... I got a API wrapper generator in C#... Maybe I can port it to JavaScript...
Hahaha, wonder why it is that much not that easy to make extension, tried to do stuff for VS, I aborted half way
To wrap not a single member, but a whole class and whatever you want in there
It doesn't help that I have to learn Kotlin or some shit
and that the UI and backend are two entirely separate services
Kotlin is their backend language?
There's a painful mix of languages and choices
@onyx harness another issue.
How can I get the actual argument values from the invoked callback? They all just return null
for example ```cs
CSharpMeta.AddDelegate("UnityEditor.EditorApplication.focusChanged", callbackFunction);
when my method is invoked, the args has the correct size, 1
which is supposed to be a bool, but it's just null
Here's the class
public static class ApplicationFocusChangeEvents
{
[InitializeOnLoadMethod]
private static void Initialize()
{
EditorApplicationAccessor.RegisterToFocusChanged(OnApplicationFocusChanged);
}
private static void OnApplicationFocusChanged(params object[] args)
{
Debug.Log($"args.Length: {args.Length}");
for (int i = 0; i < args.Length; i++)
{
if (args[i] == null)
{
Debug.Log($"args[{i}].GetType(): is null");
}
else
{
Debug.Log($"args[{i}].GetType(): {args[i].GetType()}");
}
}
}
}
Wait for me to implement it, maybe for Action or proxy delegate it doesn't work
I'm implementing the full class C# generator, then I will update CSharpMeta
@onyx harness ah! I see, i'll wait for it
thanks again for all the help!! 😋
@patent pebble Soon soon
Might not have the time to update CSharpMeta, this one is already taking time more than expected
it's fine, i'm not in a hurry
you've helped me a lot already I don't wanna stress you over it
How can I assign a struct to a SerializedProperty?
assign its contents to the sub properties 😄
hm
Trivial:
var fireAudio = weapon.FireAudio;
var fireAudioProperty = serializedAttack.FindProperty("_fireAudio");
var guidProperty = fireAudioProperty.FindPropertyRelative("Guid");
guidProperty.FindPropertyRelative("Data1").intValue = fireAudio.Guid.Data1;
guidProperty.FindPropertyRelative("Data2").intValue = fireAudio.Guid.Data1;
guidProperty.FindPropertyRelative("Data3").intValue = fireAudio.Guid.Data1;
guidProperty.FindPropertyRelative("Data3").intValue = fireAudio.Guid.Data1;
fireAudioProperty.FindPropertyRelative("Path").stringValue = fireAudio.Path;
lol
Maybe I should use a recursion
There's some enumeration built into SerializeProperty too right?
Maybe that'd simplify
Could 🤷
Ah well, looks like I've got it working now anyway. Next time!
Very far from good, because I don't have locally the exact member information.
So you have to cast yourself everything
oh my god
that's so nice
So you have to cast yourself everything
a small price to pay
If it gets more traction one day, I might bring the full data into NG UV, but it will suffice for now
i love how your site is slowly turning into an amazing toolkit for Unity API related stuff 🧙♂️
thanks for all the effort you put into it 💙
I'm off to bed, tomorrow CSharpMeta in the oven 😄
I don't know how well known this is, but you can get compile-time access to Unity's internal API if you name one of your assembly definitions one of these:
Unity.InternalAPIEditorBridge.001 - Unity.InternalAPIEditorBridge.024
Unity.InternalAPIEngineBridge.001 - Unity.InternalAPIEngineBridge.024
Unity.InternalAPIEditorBridgeDev.001 - Unity.InternalAPIEditorBridgeDev.005
Unity.InternalAPIEngineBridgeDev.001 - Unity.InternalAPIEngineBridgeDev.005
These assembly names are includes with all the InternalsVisibleTo assembly attributes defined in the Unity core dlls. I've seen Unity.InternalAPIEditorBridge.012 used by a Unity package, probably to access the internal API. The Dev ones presumably are meant to be used by devs, but it's not documented anywhere.
Here's the full list
The assembly name isn't pretty or descriptive, but compile-time, safe access to internals is very nice. You even get IntelliSense.
Yeah there were some other ones in the past as well
Is there a plugin or addon which can scan a project's scenes an d determine which assets within the project are NOT USED? I'd like to be able to cull out all the stuff I'm not using w/o doing it manually and inevitably making a mistake
Asking for a friend
Im guessing gotta fetch all assets, then check each scene, check each scene objects, materials etc
But also can look into the "select dependencies"(?) option see what it does?
There's AssetHunter and there might also be something in Mikilo's NGTools
Does anyone know if there is any performance difference between using .Next(..) and .FindReletiveProperty(..)? (Assuming that the property you want is the next one)
I don't know but next is probably ever so slightly faster
Depending on the implementation
That is kind of what I was thinking too
I wonder how iterating an array with Next compares to GetArrayElementAtIndex?
What do you mean?
One iterates, the other looks up
Easy, make an array of 100000, bench, you'll know pretty quickly
and I think we already know the answer
Right, but if you know the order of the properties, and call them in that order, then they have the same end result
FindRelativeProperty still have to parse & lookup a string
Was thinking of doing just that, most out of curiosity though than an actual need/use
Strings that you will have to extract somehow
Keep me posted please, i'm curious
Will do!
Unity already has a "Select Dependencies"
And Navi is right, AssetHunter is exactly what you need, but if I stand correct, it gives a result after a build isn't it?
NG Asset Finder can also precisely (exact paths) give you dependencies
But it can not state straight that this asset is not used in build
He just wants those unused assets (for the scene) be selected, so he can remove it
Oh, he wants to remove any asset used by a specific scene
I think so
Isn't Unity enough to get the dependencies?
Or you want additionally cross dependencies, to avoid mistake
I've started a graph map of the project years ago, but never finished unfortunately =X
Somehow I feel it would help a lot of people
We do that for asset bundles, it's useful but slow
Oh you manage to get a good graph? Nice
Good is subjective 😛
https://assetstore.unity.com/packages/tools/utilities/asset-hunter-pro-135296#reviews
Looking at it, from a user/publiser standpoint, having a 4* over > 50 reviews is not a good sign
I don't think Unity does half stars, so it's rounded down
Although the last review is worrisome
Yeah, 7h ago
(fyi I had good experiences in the past with it)
I'm sure the asset is good, something must have happen to go below 4.5*
@onyx harness It isn't even a competition (assuming I am not doing something dumb).
100,000 elements in List.
GetArrayElementAtIndex(..): ~2800ms
Next(..): ~130ms
No surprise
I didn't think it would be quite such a difference
Though not surprised that Next is vaster, just didn't think it would be that much faster
4.4 what? XD
Their rating
4.4035
Also, guessing you saw this @onyx harness but letting you know just in case #archived-unitytips message
Oh, hahaha! 😄
I got the ping from Twitter, didn't know he posted on other platforms
He is the only one posting feedbacks/bugs directly on my Discord :p
This guy is motivated
It is really handy, though if I am being honest the styling and some layout make it a bit harder to use/read (but also thanks for making it)
Please do tell, I'm all ears about UX/UI
Maybe not in this channel, either DM me or my Discord
I will DM you, yeah this channel isn't right for it haha
(I will in a bit actually, I gtg for a bit soon)
no worry
I will actually try out your back button thing since the one we're using now is probably 10 years old
I can give you the code if you want
Because using the mouse, is insanely more effective
And I want you to be more effective 🐙
But it's free... XD
NG Nav Selection is free
It's included in NG Tools Free and there is no Pro version of it
how can I alter the scale factor of an fbx model in an editor window
Is there an extension or something that auto sets sprites to Point (No Filter) among other settings? I always forget whenever I import a new sprite then spend a min complaining that it looks like shit.
Nice. This must be "New" as I used to have to have a import script.
Added in 2018.1
Yup. "New" lol
back in 2018 presets were broken
still some properties dont participate in them, and its not really automation
I didn't even know that the properties package was a thing, let along properties.ui... how long it been a thing for...?
Idk what Properties package even is yet, but I need to find some place to complain give feedback about this
well, I'd advise you to not just randomly start picking at things you haven't even used
That part just sounds like a parity with the Unity serializer
which is very sensible
I wouldn't just randomly do it, I would look in to it more first.
That is what I thought at first too, which I agree is sensible, but it isn't. It is public fields or members with the CreateProperty attribute, not [SerializeField] like you would think
well, seeing as it requires the IProperty interface, you would know that
It looks like it might have been originally created with DOTS, so the public field might be with structs in mind
My main thing is that Unity has a tendency to encourage the use of public fields in classes which is bad design and something the C# guidelines specifically says not to do.
But this is kind of off topic oops haha
Was doing performance testing with SerializedProperty, I feel like this test of a custom 'FindProperty' is slower than the built in one...
(build-in took about 1.5 seconds for 100k iterations, and this is test of a custom one is only 10k)
I see that the tool handle has 2 orientations by default: local and global.
I'm wondering if it's possible for me to change it to a new (custom) orientation?
@patent pebble I updated CSharpMeta to handle simple Action & Func<object>.
But unfortunately, I couldn't reproduce the bug you described.
I tested on Action, and a delegate of Action, both worked without me changing my code
Tomorrow I will check if I can easily implement strongly-typed delegate, I know it's doable, Jon Skeet did it (https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/):D
Does anyone know a workaround for this? https://issuetracker.unity3d.com/issues/monoscript-dot-getclass-returns-null-when-the-script-contains-a-struct-inside-a-namespace-or-an-interface-inside-a-namespace
How to reproduce: 1. Open the project "case_1218837-MonoScript.GetClass" 2. Select Tools -> Type Interface Check in the Menu Bar ...
oh nvm, I'm dumb. I had the wrong case in the filename!
Is it safe to use Resources.FindObjectsOfTypeAll in the editor to find all instances of components on prefabs?
hm, so I think I've found a bug? Or maybe I'm just confused.
var objects = Resources.FindObjectsOfTypeAll(scriptClass);
foreach (var obj in objects) {
if (PrefabUtility.IsPartOfPrefabAsset(obj)) {
var go = obj is Component
? (obj as Component).gameObject
: (GameObject) obj;
var prefab = go.transform.root.gameObject;
EditorUtility.SetDirty(prefab);
Debug.Log($"Set prefab {prefab} dirty!", prefab);
}
I'm using this method to mark prefabs dirty. But when I do it and resave they do not reserialize.
If I replace the "SetDirty" with an AssetDatabase.ForceReserialize it does reserialize.
What's the deal?
Answer to this is no! There is no guarantee that project objects are actually loaded in editor unfortunately.
You got it right, Resources looks into loaded object
You must load everything manually if you want to get everything
looking forward to that! 👀
But unfortunately, I couldn't reproduce the bug you described.
the bug was probably just me using the incorrect generic arguments and arguments 😅
errors... hate 'em, can't live without 'em
@deep plover copypasting the same message across mulitple channels is against the rules
when asking a question try to find the most suitable channel and only post your message there
@deep plover Don't cross-post. Also completely unrelated to this channel. Pick one relevant channel in #🔎┃find-a-channel
@stark geyser how long should i wait before i post the question on another channel so is not considered cross posting?
I was unsure whether everything is loaded in the editor.
As opposed to the build
But now I've learned
A horrible lesson
If you want assets, use AssetDatabase
I want to get all prefabs with an instance of a component somewhere in their hierarchy.
It's not that simple
Make a text search of the GUID
It does seem to work more than you'd expect though
or use the filter
Yeah I was considering that
Yeah that works nicely for SOs, but not for prefabs. I think a text search is likely the fastest method.
I guess you need it programmatically
How do I create a positionHandle with custom rotation and position?
(And attach it to an object when I need to?)
You will need to create a custom editor and in the OnSceneGUI method use Handles.PositionHandle(..)
is there a way of getting a SerializedProperty's actual height?
I want to get the actual height of the property and ignore the value that my PropertyDrawer returns in the GetPropertyHeight method
docs say this If the property has a custom PropertyDrawer, the function will return the height returned by that drawer.
Only way I know of is to iterate over every child property and add the standardLineHeight to an accumulated value
hmmmm, I'm trying to avoid that because I don't know if there's gonna be cases where the child properties have a height different than the standard line height
I guess there is arrays to think about too
yeah
there has to be a way of just getting the raw height, including all the children
You could look at how GetPropertyHeight works
see how it handles it if there is no property drawer
if there's no property drawer it just returns the single line value
i think i can use the PropertyHandler class to use an empty instance of it
Unity does this internally:
internal static PropertyHandler GetHandler(SerializedProperty property)
{
if (property == null)
return s_SharedNullHandler;
// Don't use custom drawers in debug mode
if (property.serializedObject.inspectorMode != InspectorMode.Normal)
return s_SharedNullHandler;
// If the drawer is cached, use the cached drawer
PropertyHandler handler = propertyHandlerCache.GetHandler(property);
if (handler != null)
return handler;
...
// Field has no CustomPropertyDrawer attribute with matching drawer so look for default drawer for field type
if (!handler.hasPropertyDrawer && propertyType != null)
handler.HandleDrawnType(property, propertyType, propertyType, field, null);
@patent pebble CSharpMeta done.
ah nice! I'll test it out later
i'll report any bugs i find
Yep yep.
Usage is simpler.
CSharpMeta.Add("path", callback);
with callback being either a variadic function or a matching delegate.
It automatically handles event & delegate.
And should work for both instance & static.
I experimented with every way I could find of doing this a while back. FindObjectOfType I hate because of the things it 'almost' does but then doesn't quite. I also tried AssetDatabase.Find( [text search] ) - note that I also use the undocumented (I filed bugs on this a year ago - still unfixed) parameters that you can find if you look in the Unity source code.
Eventually this workd for me:
string[] guids = AssetDatabase.FindAssets("t:Prefab a:assets" /** Undocumented feature, because Unity staff don't document the core APIs */ );
...and then loaded every one of them to do an 'if ( TryGetComponent<> )' on them
Which part is undocumented? a:assets?
Last time I checked (last week I think) yes
At least there you can just use the searchInFolders parameter
(someone else was trying something similar and getting stuck, and I dug out this code for them)
Behind the scenes the a: stuff gets converted into a properly typed class (which I've begged to be made public, because it's a lot less confusing and a lot elss error-prone than this 'magic acronym' stuff - but been rejected)
(e.g. I literally can't remember what a: does any more. It's so opaque and confusing. I will have to go digging in the source to re-understand it)
so ... if it was 'restrict-search-area:' that would be acceptable
that would be a pain in the ass to type in the search window
(I know it's single letter because it's intended for use in UI and no-one wnats to type long strings, since UnityEditor doesn't have auto-complete 😦 ... but that's no excuse for forcing scripts to use the same approach, when it's dangersous in code)
Anyway, it seems to work great, I've been using it a year or 2 for auto-upgrading prefabs in large projects, hasn't failed yet.
Any ideas how to go about generating collider surrounding all selected game objects ? Image as example.
Yes. Are you looking for ideas for the algorithm? Loop over all selected objects, find all meshes, loop through all vertices, if the vertex x position is greater than the largest known position, save it and so on. This way you construct an axis aligned bounding box.
If the collider has other requirements (like fitting more closely, or being a rotated box) then its more complicated, but first you would need to define your problem better 😉
Maybe state why you need the collider in the first place, maybe you want something different. There are so many ways, e.g. if you need a mesh collider that tightly fits the geometry, you could simply combine all meshes into one, but maybe you only want the convex hull (there's an algorithm for that), etc.
@bitter barn Thanks for the reply. Indeed I'm not sure what is best approach, but I'm looking to enable / disable objects meshrenderer and colliders upon player entering trigger. Each "trigger" area hold objects related to that room. Image attached as more visual explaining.
So my first idea was to somehow generate collider surrounding such areas, but maybe that is too complex and box colliders could work just as fine ? Opinions are very welcome on this matter.
Is that for performance optimization? Like a custom culling system? If the player leaves a room and can't see it, disable it? Because that would be something you could achieve with Unity occlusion culling. But if you want to manually have control over maybe playing animations and running scripts and also disable some parts of that, you could go with the trigger system.
However, these sorts of systems always have issues in places where multiple trigger boxes overlap or its unclear where the player could go/see. You might want to try placing manual trigger colliders only in the doorways first and see how it works.
But depending on what you're going for, it could make sense to generate a collider that follows the convex hull.
Indeed, poors man custom culling system.
Sometimes its faster to build a tool that helps you manually edit boxes because auto generation can become really difficult. Could always just take the selection, press a button, instantiate a new Transform in the middle of all pivots, add the collider in script and then start editing the box collider manually with Unity tools. Or maybe calculate the bounding box and spawn the box, but then activate Unitys edit tools from script and manually tweak the result. Just to speed up to the process.
t. Could always just take the selection, press a button, instantiate a new Transform in the middle of all pivotsThat actually sounds like best approach, did not think of center bounds. That approach should speed up collider creating enough as we are not talking about 100's rooms here. Thanks for the tip !
The ideal would be for it to accept flags or a list of types, not a string. But in any case it doesn't seem like that would find components attached to objects within prefabs. Maybe I could load all prefabs and then call Resources.FindObjectsOfType.
It's all a pain in the arse. Can't believe it doesn't have tab completion or fuzzy search for types.
@real ivy Hey I've been thinking about implementing a project cleaner in NG Tools, but then I looked up the store for such assets and found few.
They are all paid, is that what stopped you?
He was looking for a tool to determine if an asset is unused by the build
Yeah cool. Not the most ergonomic solution but you can also check the build log and diff it against the assets folder
I use it:
- Get all prefab-GameObjects (may be thousands of items)
- Iterate over all of them calling TryGetComponent<the one I want>
- This is lightning fast to date, haven't seen any perf problems. But I've not tried it on a huge project yet.
Oh nice!
Cool I should try it
I think ... if you hit significant performance problems with this approach ... then it would be worth submitting a bug report to Unity. This is a pretty common use-case, so they'd want to either fix/improve the performance of this approach, or create a new API route that's more optimized (but I think you'll be fine)
yeah it used to be a package called QuickSearch, they rebranded it as Search and they are trying to replace the basic search features with it
haven't tried it for like a year or two, it was a little bit cumbersome to use
but it was very promising
Yep yep saw it
" released in version 2021.1, Search has since become a core workflow for Unity users" -- but Unity 2021 isn't even released yet, it's still in beta no? 2020 LTS has been out less than a year.
Oh, OK, it has an 'experimental' version in 2020. But I thought we weren't supposed to use/trust experimental packages, that's why they got hidden away?
i.e. beta. Anyway ... some of those search features do look pretty cool, I look forward to them (in a production build of Unity :))
2021.2.8f1
it's starting to be a while now
maybe you could check what ReorderableList was clicked, hook to its onAddCallback delegate and manually set the last index as a new instance?
i do something similar for some of my tools but I don't remember if I implemented my own ReorderableList or if I hooked to the default ones
maybe someone here knows if there's an easier solution
but given that ReorderableList is an undocumented API, i wouldn't bet on it 😅
Almost all of the main APIs are documented. The new stuff - some teams especially (UIToolkit I'm glaring at you) - has a vast amount undocumented. But outside the specialist/niche APIs its pretty good.
(If you want to know what true documentation hell was like ... go look at Unity v2 and v3. That was pain. Endless pain)
yeah I feel like mostly everything is well documented
some examples do suck a little bit, and there's almost zero examples with images
but other than that, the only few undocumented features are mostly related to editor stuff
at least they maintain a public repository with the source code so we can browse through it if we need to
It is not
That is simply how adding elements to a SerializedProperty array works in Unity
yeah that's why I suggested that one of the most likely ways of doing that is to hook into the default ReorderableList callbacks
i was looking into the tests I did for that, and it's not too complicated
there's some things to take into consideration tho, for some of the ReorderableList delegates
some of them only call the default code when those delegates have no methods subscribed to them
for example onAddCallback & onRemoveCallback
Unity does this internally:
if (list.onAddCallback != null)
{
list.onAddCallback(list);
}
else
{
DoAddButton(list);
}
so if you hook a method to onAddCallback , you need to make sure you handle whatever you want to happen
this made me think somewhere down the line some built-in editor feature will affect those callbacks
while it's easy to just get every visible ReorderableList in the Unity editor, hook to their callbacks and call your own custom logic...
I don't know how safe it is, and if it will break some default feature 😅
Does URP have any support for Perspective-based decals? I want to project an image onto an object, but the URP decal system doesn't get larger the farther from the source you are.
things usually don't become larger the further away you are.......
I mean in the sense of a projector
I want objects to look 3d from a specific place, sort of like superliminal
I used to get compile time errors when trying to reference things from UnityEditor.iOS.Xcode or UnityEditor.iOS.Xcode.Extensions without having the iOS module installed.
The newer versions of Unity no longer have that problem. Does anyone know what/when it changed? I couldn't find anything in the changelog.
It's a bug that they give errors
I remember posting about that issue in the forum because it caused us lots of pain. Even the simple fast that we had to wrap our code into IF_SOMETHING_IOS causes stuff like refactorings to cause compile errors on other platforms etc. But I wonder how they would be able to fix this other than just including the code on every platform. Or maybe they found a way to only include empty shells for public API methods and nothing else.
We solved it by adding the ios platform to our docker build 😛
ohh.. it's a bugfix!
Well, shared pain is half the pain I guess. Still would love to figure out what changed even if it's just to know if it's coming back or not.
now, going back to old versions, I can't even reproduce it. 😅
how can I calculate the width and height of a GUI control, taking into account text wrapping?
is there something similar to GUIStyle.CalcSize() but that takes into account a maximum width constraint?
ah, nevermind I can just do this, made a simple extension method
public static Vector2 CalcSizeConstrained(this GUIStyle style, GUIContent content, float maxWidth)
{
Vector2 size = style.CalcSize(content);
if (size.x > maxWidth)
{
size.x = maxWidth;
size.y = style.CalcHeight(content, maxWidth);
}
return size;
}
I usually just use the max width in those cases even if the string could theoretically be shorter
yeah I usually don't bother with this, but in this case I wanted to display very tight text boxes
almost as a sort of "tags"
Ah right
I'm implementing validators for PropertyAttributes
and it's a lot more readable to have the valid types in their own boxes
😓 Discord loves introducing artifacts in my gifs for some reason
this one shows a little bit better the varying-size "grid"
i usually just do all of this on GUILayout/EditorGUILayout
but i needed to make this for PropertyDrawers
Hi, I'm currently trying to understand how Unity allows you to define an asset as a default value for newly created components.
To investigate this I'm using Unitys "Input System UI Input Module" as an example. If I create this component via the editor it automatically has the "Actions Asset"-field set to the "DefaultInputActions". How is Unity doing this and where is it defined? 'actionsAsset' is not defined anywhere in the MonoBehaviour, so I guess it has to be done somewhere in the InputSystemUIInputModuleEditor, but I can't figure it out 🤔
Isn't that done through default presets?
Or maybe a similar thing? I know that they store the default action asset in the Input package
i didnt really know where to ask this, but how can i change where in my cursor sprite is the point where the player clicks? because i have this image but the area where you click is top left instead of the center of the circle
hm... guys, the intellisense and debugging is not working for unity in visual studio. i checked to see if the external script editor is set to visual studio but i dont have any visual studio options in the dropdown. (not sure if im in the right chat)
mainWindow.totalShapes = EditorGUILayout.LabelField("totalShapes", varLoader.BlendShapes.ToString());
cannot source target type void to type int
BlendShapes returns a int any ideas?
@unkempt sparrowwhat are you trying to do?
a LabelField doesn't return anything
it's just text to display on the editor
you'll probably want to use an IntField
I am trying to make a editor that i can place a game object into and retrive the amount of blend shapes on that game object
public void OnGUI()
{
DrawDefaultInspector();
varLoader mainWindow = (varLoader)target;
EditorGUILayout.BeginHorizontal();
mainWindow.avatar = EditorGUILayout.ObjectField(varLoader.avatar, typeof(GameObject), true) as GameObject;
EditorGUILayout.EndHorizontal();
editorAvatar = mainWindow.avatar;
if (GUILayout.Button("Collect Blendshapes"))
{
totalShapes = mainWindow.BlendShapes(editorAvatar);
}
EditorGUILayout.IntField("Blendshapes", totalShapes);
}
thats my editor script right now
public class varLoader : MonoBehaviour
{
public GameObject avatar;
public int BlendShapes(GameObject avatar)
{
MeshFilter mesh = avatar.GetComponent<MeshFilter>();
Mesh currentMesh = mesh.sharedMesh;
Debug.Log(currentMesh.blendShapeCount);
return currentMesh.blendShapeCount;
}
this is my main script currently
it dosent have any errors but all it makes it this
no button or a int field with the current amount of blend shapes on the object
is your Editor class targetting the varLoader class?
public void OnGUI() don't do this
you need to override the OnInspectorGUI method
public override void OnInspectorGUI()```
i recommend checking the documentation carefully for this sort of stuff
the examples are pretty clear
when i had done this before it gave errors i thought it was just a different version of unity
im on 2019.4.29f1
nah, the errors are just your code
ok
what's in line 26 of your script?
it's telling you that you have a null object reference
yeah thats the object field
should it be inside the button so it only activates when its pressed?
OOOOO
why are you doing an ObjectField when you already have an exposed GameObject reference in your MonoBehaviour?
yep
still dosent get the right number but it looks right now
i am trying to grab a game object and pull it into that field this is for 3d models with armatures and fbx they are game objects in unity
well your currentMesh.blendShapeCount is probably 0
that's what you're getting from it
i was told not to use a skinned mesh render but i think that is what i should be using
it has 20 blendshapes though
this is the current error
same as before so i dont think its getting to the mesh yet
i don't know what's on that line
the object field
mainWindow.avatar = EditorGUILayout.ObjectField(varLoader.avatar, typeof(GameObject), true) as GameObject;
yes but you don't need an objectfield when you already have a public GameObject reference
you already have this
public GameObject avatar;
ok but that dosent have anything in it
i need to assign the game object to it correct?
i suppose so, you can't get data from an empty reference, can you? 😅
i'm telling you that you don't need to make an ObjectField
ok??? so just delete the line?
yes
OOOO
I GET It
since the script is on the object you dont need the object feild
ahhhh
i seeee
Unity automatically makes fields for your public fields
that's what you're telling Unity to do with the DrawDefaultInspector()
to make those automatic fields
the only issue with this is that it will eventually be a window not associated with a specific object