#↕️┃editor-extensions
1 messages · Page 92 of 1
Oooh that's shiny
I like that
Yaaay figured it out.
Only thing left is text alignment
And text wrap, apparently
wordWrappedMiniLabel lol
Any tips/feedback on how I can make the list of edges less messy?
Can inline the "To" and "From" fields. Could remove the foldout and just have either a line or a space there. Remove the background from all of the Node items as it seems like it is redundant. If you want it a different color, do what the ReorderableList does have have a header, and a body.
Also when I say "inline", I mean put the two fields on the same line, and I would rename them to just "To" and "From", drop "Node"
Maybe remove the text saying what "Fix" does to save room. Could put it in a tooltip on the "Fix" button maybe.
I had that, but from is reserved
So it felt weird
reserved?
I'm not making those fields manually btw
Well no reason you can't 😉
Yea, from is a contextual keyword
The biggest reason is how much more work that is 😅
Every new field would require me to change the inspector
Could remove the foldout and just have either a line or a space there.
This is a good idea
Remove the background from all of the Node items as it seems like it is redundant. If you want it a different color, do what the ReorderableList does have have a header, and a body.
This I don't understand
True, but how many fields are you planning on doing. You could also make it a propertyDrawer to not have to do it in the editor itself.
Not that many I suppose 🤔 My biggets annoyance with the way it looks now is the alignment and the boxes
I'd like a "title" for edges. Like the inspector does it
You have
Actions
{
Edges
{
*nodes*
{
}
}
}
Each indent is a "HelpBox" grouping and it is adding a lot more visual noise, especially horizontally. "nodes" doesn't need a helpbox group since nothing else is inside of "Edges"
Likewise, I don't think "Edges" needs a helpbox either, but idk if you plan on putting other things inside of "Actions"
Yeah but then edges and nodes look the same
Which I thought looked pretty ugly
I do plan on adding more yeah. There will be events and node info
Do you have a screenshot of it the window with both edges and nodes, because the screenshot only shows nodes so it is hard to tell what to change to clean it up.
Ah no, I haven't built the rest yet
But:
This looks weird. I'd like Edges to look like components in the inspector
An actual bar, with a line, different color. An icon. I just don't know which style that is
iirc there is something to draw that in one of EditorGUI EditorGUIUtility EditorGUILayout.
The style is called "IN Title" I think.
alt + 5 is your friend.
IMGUI Debugger 🙂
I found a InspectorTitlebar() but it needs an actual target lol
I'll play around with that, thanks 😄
Oh damn that's useful
The shortcut actually works without having internal mode enabled?
Yup, they changed it in I think either 2019.3 or 2020.1 to be publicly available. It is in Window/Analysis/IMGUI Debugger too.
Internal mode? Where do you find that? I don't know what it is but I want to enable it 😛
Oh, that repainting thing is great! Also, 100% never would have figured that out lol.
I think I still don't fully understand .objectReferenceValue
if (node.needUnidirectionalFix.Contains(edgeProperty.objectReferenceValue))
It doesn't like this
Cannot cast expression of type 'UnityEngine.Object' to type 'Edge'
So you know for fields of int type public int foo, there is .intValue property right?
yeah
Well .objectReferenceValue is for fields of type UnityEngine.Object.
Which is Components, Textures, Assets, GameObjects.
They 'don't exist'.
All serializable classes are made up at some level by the supported types (ints, floats, strings, bools, etc).
Well, that's where it gets complicated with serializereference
Panic
But ya can't get a value from them still, only set.
Wellll
But yeah
You can with reflection
Well we aren't talking about reflection because you can do that regardless of if it is serializereference 😛
Haha yes, of course. I know things :p
There's a objectReferenceInstanceIDValue which is not documented it seems
I'm going to give the edges a generated uuid and use that instead
For what?
I made a tiny autofix tool that detects wrongly configured edges in the graph
That is literally just the same as .objectReferenceValue.GetInstanceID()
iirc
Inside of the nodes I maintain if there's a config mistake (bidirectional edge while the other node has its own edge)
So I want to check if the edge I'm showing is one of those poorly configured edges
Only in dev though so idc :p
IIRC we have a check that uses objectReferenceInstanceIDValue to check whether the reference has been deleted
So I think it still has a value even if objectReferenceValue would otherwise be null
(not in all cases of course)
Yeah, I think you are right, but I was just trying to illustrate that it isn't a 'free' value.
Because it is a method in the UnityEngine.Object class 😉
So then it's useless to me? :p
That is what I was saying 😛
Oh lol, sorry I'm a bit slow today
So a if dev with a uuid on the edge isn't weird then?
Works like a charm. A couple #if UNITY_EDITOR but that's fine.
Hallo, in a nightmare rn, is OnSceneGUI working to register events for others? Trying to implement some custom editor keybinds - in 2020.2.6f1
is there a syntax for adding a separator into a popup menu? Like if one of the options is 5 "-" or so
(Back to the whole attempting to replicate the UnityEvent dropdown functionality)
/?
ah nice
How does unity manage the type/field/method naming for the event popup?
It isn't NicifyVariableName thats used for inspector exposure, can't find anything for it
Which one?
Not even gonna ask about the disabled headers it looks like it uses the draw custom popup with separators method
but the combined item is type name + field name, and for methods is also the same guess i need to dig more tbh
but if you did that in reflection you get the system type rather than the primitive so it appears as Boolean, Int32, String
Of course I could just make some switch for it 
like the isStatic actually seems to return out as Get_is_Static and Set_is_Static due to the property even though im not specifying get/set property flags
dw, ill continue as I am
If you use GetProperties to find the property it should just be the property name and not get_is_static
Not sure about return type but it's likely just a simple conversion
Pals. Any1 knows why polybrush just refuses to work on my massive mesh? No errors, no nothing, it works on every other mesh in the scene.
I want to add options to the '+' button of my reorderable list, but I have no idea where to start.
I did find source code for the picture below, but cannot wrap my head around how it works.
Does anyone have experience with it?
I basically need to have 3 items in the dropdown and then fill in different values into the serialized struct when it's added to the list.
Now get the error 'SerializedProperty is null' and no clue what to do to fix it...
Made a forum post if someone can help https://forum.unity.com/threads/custom-inspector-null-error-serializedproperty.1135165/
Well, first off your audioContents list is not using hte struct you posted
can anyone tell me why did i open unity ( i left it pretty good just fine ) but now there is 15+ bugs out of nowhere ? and 230 unexpected asset states ???
I recently moved over to unity and i like to make games in my spare time. I can't seem to get a single IDE working for linux. I'm trying vscode and i get this error Attempted to update project that is not loaded: /home/adamsadeg/Welcome back/Unity.VisualStudio.Editor.csproj does anyone know how i can fix this? I have been googling for hours but can't find anything!
So i am making an editor window thing, and im trying to make it loop through a folder and find all the scriptable objects in that folder, and be able to read attributes of that scriptable object from the editor window. How would i do this?
Use AssetDatabase.Find, it has a parameter that takes path iirc.
You can use TypeCache.GetTypesWithAttribute (or something like that) to get the all the classes with the specified attribute.
And there is foo.GetType().GetCustomAttribute to get the specified attribute on the class of the foo type.
Sorry I have no idea how to help, have you already check the resources in #854851968446365696?
@onyx harness Wanted to thank you again for the suggestion of using elapsed time instead hard numbers for generating/loading previews. Just using the System.Diagnostics.StopWatch and it works really well and lets me better fine tune the performance! 😄
The code is a lot cleaner looking too which is nice! I also don't have to set limit for writing to files, and for regenerating previews now, just check the elapsed time!
Hehehe glad it is doing wonders ova there! 😁
Just keep in mind to not overflow in time.
Usually when you realize you passed the limit, well it is already too late, which result in less smoothness
Hi,
I just created a new project and when i run it in the editor i got this error, first time i have it and i don't really know how to fix it
Close the Collaborate window/tab
Why is it like that?
You're not setting the height of an element
How does that work?
Need more context
Should I explain what I'm trying to do?
More like what api you're using and what your code looks like
[System.Serializable]
public struct NoiseSettings
{
public NoiseTypes noiseType;
public int width;
public int height;
public float xOffset;
public float yOffset;
public float scale;
public float amplitude;
public bool invert;
}
[CustomPropertyDrawer(typeof(NoiseSettings))]
public class NoiseSettingsEditor : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
position.size = new Vector2(375, 50);
float w = position.width;
float h = position.height;
SerializedProperty noiseType = property.FindPropertyRelative("noiseType");
SerializedProperty width = property.FindPropertyRelative("width");
SerializedProperty height = property.FindPropertyRelative("height");
SerializedProperty invert = property.FindPropertyRelative("invert");
Rect noiseTypeRect = new Rect(position.x, position.y, w , h);
Rect invertRect = new Rect(position.x, position.y + h / 2, w, h);
noiseType.enumValueIndex = EditorGUI.Popup(noiseTypeRect, "Noise Type", noiseType.enumValueIndex, noiseType.enumDisplayNames);
invert.boolValue = EditorGUI.Toggle(invertRect, "Invert", invert.boolValue);
}
}
Override GetPropertyHeight and return the height of the area you're drawing
Like that? ```CSharp
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return EditorGUIUtility.singleLineHeight * 4; }
Missing override keyword
Also the height you're passing to your methods should probable editorguiutility. Singlelineheight
Show code
[System.Serializable]
public struct NoiseSettings
{
public NoiseTypes noiseType;
public int width;
public int height;
public float xOffset;
public float yOffset;
public float scale;
public float amplitude;
public bool invert;
}
[CustomPropertyDrawer(typeof(NoiseSettings))]
public class NoiseSettingsEditor : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
position.size = new Vector2(375, 35);
float w = position.width;
float h = position.height;
SerializedProperty noiseType = property.FindPropertyRelative("noiseType");
SerializedProperty width = property.FindPropertyRelative("width");
SerializedProperty height = property.FindPropertyRelative("height");
SerializedProperty invert = property.FindPropertyRelative("invert");
Rect noiseTypeRect = new Rect(position.x, position.y, w , h);
Rect invertRect = new Rect(position.x, position.y + h / 2, w, h);
noiseType.enumValueIndex = EditorGUI.Popup(noiseTypeRect, "Noise Type", noiseType.enumValueIndex, noiseType.enumDisplayNames);
invert.boolValue = EditorGUI.Toggle(invertRect, "Invert", invert.boolValue);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight * 4;
} ```
I'm using * 4 cuz it looks ok
@waxen sandal Did I do anything wrong?
Looks fine to me
You're doing some weird things with the size though that could be messing it up
should I just not change it?
Yes
Thanks ❤️
Does anyone know of good mesh manipulation editor extensions?
is there a way to create/add this curves from script?
is that what you are looking for?
similar to that, but directly adding a new curve property on that Curves list
i assume it should be done under AssetPostProcessor
Hmm i need to find a way to add a new AnimationCurve inside the Curves list in the ImportedModel
i know how to create a new AnimationCurves in general, but can't find a way to add a new one under that specific list
Finally found it. . .
https://docs.unity3d.com/ScriptReference/AnimationClip.SetCurve.html
been looking at the wrong direction 😅
ah well still failed though, can't access that specific field
Like... ProBuilder?
yeah, I didn't know if probuilder could be used on skinned meshes, granted I only read the intro to it
Is there a way to get a reorderable list in an editor extension?
I made a reorderable list from scratch using UnityEditorInternal, but I wondered if I could just get the current reorderable list and edit that instead of making one from scratch
Nope, you are doing it the way that you need to. There is ReorderableListWrapper which I believe is public which gets you closer to the default one.
Ah, ill look into that, thanks!
Do you have a link to the usecase/an example?
Idk if it is even public, so no 😛
It is what Unity uses internally to draw the default ReorderableLists for arrays and lists in the inspector.
You can look at the source to find out more
Okay, got it haha
Probably won't try to implement it since the deadline is tomorrow, but good to know for the future :P
Why inspector ignores height of my custom property drawer?
[CustomPropertyDrawer(typeof(ChildrenMaskInspectorView))]
public class ChildrenMaskEditor : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var cubeNetTree = AssetDatabase
.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/CubeNetTemplate.uxml")
.Instantiate();
return cubeNetTree;
}
}
Do you not have to override GetPropertyHeight with the new way of doing it?
https://docs.unity3d.com/ScriptReference/PropertyDrawer.GetPropertyHeight.html
It does not have any effect unfortunately
I am testing out dot product and it is not working if my target is at 0,0, but starts working if I move the target above 0,0
what about below 0,0?
@gloomy chasm to answer an earlier question, I've been messing with probuilder more, and, not sure if intended this way, but, was able to get it to do exactly what I was looking for
Is it possible to set a Non-Object Class property to another class?
ex. I have a List of Class A, and a List of ClassB, ClassB has 2 Variables of ClassA, both are non object class. I want to set a ClassA to 1 of ClassB's
but there not the same Instance, they only have the same variables values
Ok im having another weird bug... related to how unity's new RegisterValueChangedCallback works..
Idk how to describe this..
Basically i'm drawing an array of array
And in the inner for loop, i have a RegisterValueChangedCallback. Changing something in that field changes every thing in that same index of the outer loop
I guess im wondering how to BindProperty to nested arrays properly?
This is what im doing:
ObjectField bodyObject = new ObjectField("Default Item");
bodyObject.objectType = typeof(GameObject);
bodyObject.SetValueWithoutNotify(info.defaultItem);
bodyObject.RegisterValueChangedCallback(n =>
{
SerializedProperty entryProp = serSkill.FindProperty($"elementBodyInfo");
SerializedProperty arrayEntryProp = entryProp.GetArrayElementAtIndex(iClone).FindPropertyRelative($"bodyInfo");
SerializedProperty arrayEntryInfoProp = arrayEntryProp.GetArrayElementAtIndex(jClone).FindPropertyRelative("defaultItem");
arrayEntryInfoProp.objectReferenceValue = n.newValue as GameObject;
serSkill.ApplyModifiedProperties();
//serSkill.Update();
EditorUtility.SetDirty(elemental);
Debug.Log("Set to: " + iClone + " : " + jClone);
});
slotFold.Add(bodyObject);
My problem is different, it just doesnt save
I even checked Debug.Log(n.newValue.name + " : " + arrayEntryInfoProp.objectReferenceValue.name); and it prints the same name, so it's supposed to be changed?
Testing the same thing outside of any array whatsoever, works as expected
So.. is there something wrong with how i access/assign a field in some nested array entry?
I even tried to .BindProperty the ObjectField directly to the nested field path
bodyObject.objectType = typeof(GameObject);
SerializedProperty entryProp = serializedObject.FindProperty("elementBodyInfo");
SerializedProperty arrayEntryProp = entryProp.GetArrayElementAtIndex(i).FindPropertyRelative("bodyInfo");
SerializedProperty arrayEntryInfoProp = arrayEntryProp.GetArrayElementAtIndex(j).FindPropertyRelative("defaultItem");
bodyObject.BindProperty(arrayEntryInfoProp);```
And still not saving?
Hmm ok
If i change the inspector to Debug mode, and find a field in the nested array, then assign another object, it also doesn't change anything
So the problem is not with UI TK whatsoever, i guess
But... how can an array like this not able to change the value, even in debug mode?
Is it possible to drag an object from an ObjectField into another ObjectField? I can only find examples of dragging from the Project view to a custom editor, not copying within a custom editor
Nope
You could lock your inspectors and then select by clicking on it and dragging from project to the other inspector
@waxen sandal thanks 🙂
Hi! Let's imagine i have a custom editor extension for a script A and for a script B. Imagine i have an array of A inside B : How can i tell the editor to display as i told it in the script?
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = actionsList.serializedProperty.GetArrayElementAtIndex(index); // The element in the list
}```
Because i made a reorderableList<A> in B, right now
Do i have to copy the onInspectorGui of my A editor script?
it's kind of messing up with my brain 
(sorry if i respond tomorrow to your answer, i'm soon off of work)
EditorGUI.PropertyField(rect, element);
Thanks! But i'd like to not override anything i did in my other script 😅
(not the rect, for example)
and having a simple EditorGUILayout.PropertyField(element) takes the default editor layout
EditorGUI.PropertyField is the same as EditorGUILayout.PropertyField. The only difference is having to manually tell it how big the field is and where to position it.
Maybe I don't understand what you want? You want a field to draw using a PropertyDrawer, right?
yes! but the field i want to draw itself has a custom editor script. Here's what happens when i use the rect :
you see the elements are displaying, but the inspector of the element itself is trying to display (which is what i want)
what i could use is maybe a way to get the height of the displayed inspector, and add space between the lines? How?
You need to set the elementHeight in the ReorderableList
There is a callback, I don't remember the name, but it has 'height' in the name 😛
I think it is elementHeight thought.
Like that, but for element height. iirc the signature for the callback is float ElementHeight(int index)
okok, thanks!
float elementHeight(int index)
{
float height = EditorGUIUtility.singleLineHeight;
SerializedProperty element = actionsList.serializedProperty.GetArrayElementAtIndex(index); // The element in the list
return height;
}```
Wait, how can i access the variables of the element? i don't get it lol
i'd like to access variables and change height depending of their values
Well you have the serializedProperty of the element.
So you just get child properties of it. Or you can use EditorGUIUtlity.GetPropertyHeight(element) to do it automagically.
I don't believe in magic right now to be honest, but i'll try!
"EditorGUIUtlity doesn't contain a definition for GetPropertyHeight"
its EditorGUI, mb
magic kinda worked! i am astonished
Ah yeah, my bad. I forget which class some of these are in.
but my elements aren't drawn with the custom editor
dw lol
Is it ok for the editor scripts to be quite large or contain many vars? My tool is getting very sizeable, wondering if I should be offloading the vars to the scriptable object script
Not noticing a performance hit or anything yet, wondering about good practices
That is perfectly fine, and moving variables to another class just to make the current class take less lines is a bad idea (From a code readability and maintanablity and everything point of view)
Just use normal coding practices. Like if you have a large section of code that does it's own thing for the most part, then you can move that to it's own class.
Nice, fairly new to editor scripting and this is strange engine stuff 😄
Thanks!
Is it possible to align vertically centered all elements within a BeginHorizontal?
The red line is where I want the elements to go.
I've tried setting a fixed height of the horizontallayout and setting alignment = TextAnchor.MiddleCenter
I feel like there is a better way, but the best I can think of is to put each element inside of a vertical group and put a FlexLayout before and after each control within each of the vertical groups.
@gloomy chasm Thanks, that's at least a solution 🙂
where's collection on unity package manger ?
did they remove it ot am I missing something
yep thanks
Hi! i have a reorderable list here, and i would like to access the script on the corresponding element i have as a serializedProperty, but i don't know how lol
I'd need to have it as a serializedObject, is it possible to have it with the index?
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = actionsList.serializedProperty.GetArrayElementAtIndex(index); // The element in the list
EditorGUI.PropertyField(rect, element);
//(ActionSO)element.DrawRightMenu();
}```
(so i need to replace the second line inside here by the third)
Question, I have a button that instantiates a prefab, the issue is it spawns at (0, 0, 0). How can I make it spawn in the middle of my scene view?
is the button on the scene or in the inspector?
show me your instantiation method :)
real object
no, I want it to instantiate in the center of my scene view
oooh so in the middle of where you're looking in scene view?
yes
idk about this at all lol
Try in #archived-code-general maybe?
ok
still need help about my problem homies 👀
nevermind, all this is not gonna work... I need to find something else.
How can i tell my script to display this thing like my CustomEditorScript and not like the default inspector?
is no-one on, or are my question too blurry? ^^'
what i could use is some kind of element.DrawType(ActionSOEditor);, but i guess there's nothing inside serializedProperties for that
Oh my lord and savior, Navi, i beg you, come and help my lost soul amongst thy filthy editor extensions, may your guidance help me to find redemption and peace
What's element?
Like what's the type you're trying to draw in your list
i'm drawing by hand a reorderable list of ActionSO, it's a scriptableObject of mine
that has its own editorScript
Do i have to link it here?
Nah that's fine
So, what you want to do is use Editor.CreateEditor and then call OnInspectorGUI on that. However, you should not recreate this every frame, so you need to save it somewhere in your editor and then when you're done with it (i.e. ondestroy) you need to Destroy the editor as well
wait wait, what? I should call OnInspectorGUI by hand? I don't get it
in my DrawListItem?
with this overload?
and the Type is going to be my editor type, right?
Yes
Yes
But again, do not do this in your DrawListItem method, it'll create a ton of garbage and likely not work correctly
It needs to be created when your list is created and destroyed when your list is destroyed
so created onEnable, and destroyed "OnDisable", but does that even exists?
i don't destroy my list
and how can i create the editor with the element, if i don't put it in DrawListItem (which is what provides me the element)
Create a look up table somewhere
i'm sorry, i must've slept when they tought me about lookup tables...?
It's just a dictionary somewhere that you can use to "look up" some relevant data
So in this case, you can make a look up table (LUT) to lookup the instance of ActionSOEditor based on element.objectReferenceValue
oh okay, so i'd need a dictionnary that takes in serializableObjects as keys, and ActionSOEditor as values...?
ActionSO to ActionSOEditor

this is getting out of hand 
How do i create this LUT? I don't get how i can put every single ActionSOEditor that can possibly exists inside a dictionnary
You don't have to, just when you create the list for your array you also create that dictionary and fill it with editors for the items in the array
Then when an item is removed or added from your list you destroy or create it
When the whole thing is destroyed (because the object is deselected or something) then you destroy all editors

Don't worry, it becomes more fun
ok so when i create the list, i create the dictionnary, and fill it with all ActionSOEditors that are needed in my list of ActionSOs?
Yes
please 
and... 🥁
How?
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.
called L45
So, in OnEnable you iterate over all LeafActions elements and create the editor for those items and add them to your LUT
Then in DrawListItems, you try to get the item from the dictionary using objectReferenceValue. If it's there you draw it
Then LeavesInEditor should implement OnDestroy, where you loop through all items in your LUT and destroys all instances of ActionSOEditor
ok, but i mean how do i - OOOOOOOH
You mean i create the editor in a foreach
Yes
The bot doesn't like excessive spaces
LUT.Add(LeafActions.GetArrayElementAtIndex(i), CreateEditor(LeafActions.GetArrayElementAtIndex(i).objectReferenceValue, typeof(ActionSOEditor)));
mb
but it doesn't manage to convert a few things, wait
What
first arg: can't convert a serialized property to an ActionSO (seems fair)
second: can't convert Editor to ActionSOEditor
seems kinda fair too
okok! brb
sheeeesh that works:
LUT.Add((ActionSO)LeafActions.GetArrayElementAtIndex(i).objectReferenceValue, (ActionSOEditor)CreateEditor(LeafActions.GetArrayElementAtIndex(i).objectReferenceValue, typeof(ActionSOEditor)));
WAIT I CAN EVEN-
i can access this function:
oh nvm i need oninspector
anyways, added this:
private void OnDisable()
{
foreach(ActionSO key in LUT.Keys)
{
Destroy(LUT[key]);
LUT.Remove(key);
}
}```
That's what you meant?
hummm they said my list isn't defined now? Do i miss something? https://pastebin.com/ZR7P2Z0U
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.
(error is when i called the DoLayoutList method)
You never create your dictionary
you didn't see anything 👀
I have a bunch of fixes to do, i hope i won't be back lol
Thanks so much, you truly are my lord and savior 
if your script inherits for Editor, then probably, yeah :)
I am in mac and my unity tools dont work
i mean
there is no suggestions and color text
Wrong channel 😛 #854851968446365696 has guides on how to set up your ide
Otherwise ask in #archived-code-general or #💻┃unity-talk
ok
Navi my console is getting crazy 🥺
https://pastebin.com/mxbipTdF
Modified a few things
Are you creating editors for objects that are null?
nope
There's some other exception that's preventing the creation of your reorderablelist
I did all the steps right and it doesnt work ;-;
visual studio doesn't link with unity? is that it?
well this is not the right channel
oh ok
Not sure atm, going for lunch
okok! see you! (i hope)
ok i'm back, so basically, i've got a few probs:
- sometimes i get a nullref saying something is not defined
- I'd need the elements' inspectors to be inside the list, below their own element, and not below the whole list:
(My script:https://pastebin.com/zwAryUtx)
oh s**t, forgot to summon Navi without pinging
Oh my lord and savior, Navi, i beg you, come and help my lost soul amongst thy filthy editor extensions, may your guidance help me to find redemption and peace
You'll likely want to wrap the oninspectorgui call in an area block https://docs.unity3d.com/ScriptReference/GUILayout.BeginArea.html
Idk about the null ref, could be a null element in your array?
well it's as soon as i add an element to the array
but the element isn't null at its creation, because it clones the latest element
and the latest element isn't null
and why?
Your editor uses guilayout which is not supported in reorder able lists, begin area defines an area that supports guilayout in a non guilayout context
okok! But where should i put the begin/End area calls though? Because i can't put it in element, and shouldn't wrap the whole DoLayoutList();, should i?
around line 75
okay, so around each elements, right?
yES
Show code
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = actionsList.serializedProperty.GetArrayElementAtIndex(index); // The element in the list
//EditorGUI.PropertyField(rect, element);
//(ActionSO)element.DrawRightMenu();
//element.DrawType(ActionSOEditor);
GUILayout.BeginArea(rect);
if(LUT.TryGetValue((ActionSO)element.objectReferenceValue, out ActionSOEditor editorToDraw))
{
editorToDraw.OnInspectorGUI();
}
GUILayout.EndArea();
}
probs bc of the rect
but idk what to put
You sure your lut has anything in it?
Also you should have a higher height for each element
https://pastebin.com/jAJCfPCv
well yeah, shouldn't i be?
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.
Idk, probably? I can't debug your code os I don't know
Also use the imgui debugger to verify whether there are actually elements in there but just not drawn
That first screenshot just shows that your dictionary is not null, nothing about actual items
yeah, mb: LUT.Keys.Count:
Use the imgui debugger to see whether the elements are drawn and where
oh mb, i thought you where talking about the debug mode on the inspector, what's imgui?
like the visual studio debugger?
No, it's under window > analysis > imgui debugger
well that's scary! i found one of my things, but it doesn't show anything
i found this for the array
LeafActions' the array
There's the draw option at the top, change that unified
done! then? I should finf leafAction again?
i found the begin area
but not the endarea though
that might be it?
Uhh not sure if it should show up
More importantly, are there children in that begin area element
yup!
Hmm, maybe this trick doesn't work after all
ig lol

Did i find Navi's Edge...? 😳
The edge of knowledge itself
seriously though, ill be testing things out randomly from now on, wish me luck
gl
I can't remember, where do ya store preferences SO?
(mind telling me where you got this cute cat? 🥺 )
It's from another discord I'm in
private as really private? 🥺
I mean you can just open the url and save the image
thanks! hehe
Any ideas how you get an icon/thumbnail for a ScriptableObject given only a System.Type (no instance of the SO)?
AssetPreview.GetMiniTypeThumbnail() just returns the DefaultAsset icon.
Not sure if it helps but you can easily create an instance to work with - SriptableObject.CreateInstance(someType); - though I'm not sure what a preview of an SO should look like?
I am making a dropdown menu to select a System.Type that inherits from UnityEngine.Object, and want to show the icon for the type. So for a ScriptableObject, it would just be the normal icon you see in the project browser.
But it seems that even ObjectField doesn't support doing what I want, shame.
(I could make instances, but that could be a lot of unneeded garbage)
this help?
I could set it manually, but that feels like maybe more worth than it is worth. Thank you for the suggestions though! 🙂
This is what I am doing (Will be a dropdown)
Hey y'all! I need some help. I am trying to get the asset names that contains a certain string like AssetDatabase.FindAssets("Base_", "APath/AnotherPath") but its returning the guid. I need the names of those files, not the guid.. and i am stuck
i use it but it gives.. the assetpath
lets say i used it, but then how do i remove the rest of the path?
Use System.IO.path.GetFileNameWithoutExtention
would that search files like AssetDatabase.FindAssets does?
oh wait
i think i understood what you meant
okay let me try it
Works like a charm!!
Or you can also use normal string methods like LastIndexOf and SubString
god i love this community
Seriously tho, this community helps a lot! (btw i am making a custom script generator with parameters, i will use those names as extents)
Evening,
I have a question for everyone here. Has anyone ever encountered an issue where copy pasting timeline elements becomes impossible, and when trying to copy it shows an error?
ive been working around it by closing and reopening the project
but this is getting a bit annoying.
You'll probably have better luck on the forums or another channel
I really didn't know where to ask this question.
Where do you think I could ask this?
Hi! I'm trying to do a FindRelative to have a property, but it doesn't seem to find it:
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = actionsList.serializedProperty.GetArrayElementAtIndex(index); // The element in the list
EditorGUI.PropertyField(rect, element);
ActionSO so = (ActionSO)element.objectReferenceValue;
if (so.actionType == ActionType.Dialog)
{
SerializedProperty dialog = element.FindPropertyRelative("dialogLines"); //
EditorGUI.PropertyField(dialog.rectValue, dialog);
}
//(ActionSO)element.DrawRightMenu();
//element.DrawType(ActionSOEditor);
//enviedecaner();
}```
even though my element is an "ActionSO" (which i created), and you can see the code here: https://pastebin.com/3ic5mj6G
You cannot FindPropertyRelative on an ObjectReferenceValue property as it is an entirely different serialized object
you would need to create a SerializedObject out of the value and do a FindReference on that. But it's rife for performance issues so you tend to need to cache it all carefully.
oh... That's unconvenient
well it's an editor script, if it has minor performance issues, i don't really care
which way is the best in terms of caching that value?
because it's an element of a reorderable list i'm recreating
i'm starting to think more and more that this was a bad idea to begin with lol
I tend to make a dictionary using the object value as a key to the serialized object
like a lookup table?
To cache and look up the SerializedObjects, yes
Hi! (Yeah it's me again)
I'm currently trying to do a custom window.
What happens is that i have this little button, that opens my window:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class ScenarioEditorCW : ExtendedEditorWindows
{
SerializedObject soTarget;
[MenuItem("Window/SCOL/ScenarioEditor")]
public static void ShowWindow()
{
GetWindow(typeof(ScenarioEditorCW));
}
public static void Open(ScenarioTree treee)
{
ScenarioEditorCW window = GetWindow<ScenarioEditorCW>("Scenario Editor");
//soTarget = new SerializedObject(treee);
}
public void OnEnable()
{
}
private void OnGUI()
{
//DrawProperties(currentProperty, true);
}
}
but then i don't really know how to get a reference of the object i put on target, since apparently i need to keep the method on static
Hey. in figure 1, I introduced a c# property with get and set. then tried to use it in propertydrawer OnGui and I got a NullReferenceException... Why?
any workaround ?
This is a struct by the way
and this is the whole struct, if anyone needed to see
Just make a property on the window and set it in your open method
You can't serialize C# properties, only fields
what do you mean...?
thanks, I copy-pasted the c# property in the Editor file ... that's a hardcoded way though, i wish there was a better approach
Just private ScenarioTree target; window.target = treee
ayy i missed the "window.", thanks!
i'm sorry, i may unintentionnaly spam this chan again, but i'd want the "open" method to open when i click on the object, like the inspector basically
(instead of my buttons)
Check Selection.objects and Selection.SelectionChanged
i'll check this out, thanks!
public void OnEnable()
{
if(Selection.objects.Length == 1)
{
if(Selection.objects[0] is GameObject)
{
GameObject sel = (GameObject)Selection.objects[0];
if (sel.TryGetComponent(out ScenarioTree selectedTree))
{
tree = selectedTree;
}
}
}
}```
i've done this, but it doesn't seem to work at all
i've put it in OnGUI, i'm tired lol, at least it works, but i'm tired of optimizing
Should use selectionchanged tbh
(i did, didn't wanted to spam here anymore, but yeah lol
EditorWindow has its own void for that, doesn't even need events)
At least this channel would be used then 😉
I made a folder field! Only accepts folders, shows the full path name, and truncates the start if it, and getting all the folders is async, and there is a little spinny wheel while it is getting them!
Yeah, same. I am using the Directory class to do it, but still.
I am using System.Task for it, but maybe I don't understand how to use it/what it does because I feel like it takes longer than doing it on the main thread.
TAP?
Since you can't really await things since you won't complete the frame
Tasks
Task based asynchronous programming
Ah, got it.
System.Task has a callback for when when it completes which is nice.
I will go back later and see if I can make it faster. But I think it is okay how it is for the first version.
You should really be awaiting it and not using htat event
Why is that?
Idk where/how I would await it since everything is just in the OnEnable method. I admittedly don't have a lot of experience with multi threading or async stuff.
You can make OnEnable async 😉
If you're not awaiting it then you're not using it correctly
And there's no real using to use it then instead of using callbacks
I really need to read up on async... I don't really get what it does (Not that I have tried that hard to understand)
Oh hot dang! That was easy...
async void OnEnable()
{
var task = new Task(....);
task.Start();
await task;
// Make tree and stuff....
}
Am I doing something dumb there or is it really that easy...?
Nono, just make a method that returns a Task<T> and then await method()
Ehh? But isn't it the same thing? (Also I take it I don't need Start()...)
I did not do it correctly, It now never completes...
async void OnEnable()
{
// Setup stuff...
IList<BTreeViewItem> rootItems = await Build();
Debug.Log("Finished working"); // never called...
}
private Task<IList<BTreeViewItem>> Build()
{
_dataPath = Application.dataPath;
return new Task<IList<BTreeViewItem>>(CreateTree);
}
What's the rest of your code
Doing task.Start(); return task; in the build method did the trick... I guess ya do gotta start it...

Hello there,
Does anyone know if there's a way to get the Playable Behaviour from the ScriptPlayable<T> without knowing the exact Generic T Type?
My use case:
Iterate through playables which could be any type and run some custom code on the behaviours.
Annoyingly I can take the playable type from the playable, with Playable.GetPlayableType() but to be able to call GetBehaviour I need to cast the playable to ((ScriptPlayable<T>)playable).GetBehaviour() but passing any of the base types throws a cast exception
As all of the Playables are structs they don't retain the original typing. So even if I create the playable in this way
ScriptPlayable<AbstractBehaviour> playable = ScriptPlayable<AbstractBehaviour>.Create(graph, new T());
Casting the Playable returned in from timeline to ScriptPlayable<AbstractBehaviour> is not allowed :/.
Anyone knows some magic to help with this?
There is no way to do exactly what you are asking. What is the end result you are wanting?
I'm trying to create a bit more "generic" mixer for the timeline that would allow to call specific methods on the clip behaviours. More of a way to not have to create a lot of specific mixers mostly.
Has anyone rotated prefabs via editor script? Trying to make objects rotate 90' on keypress, it will do it once, then not rotate anymore;
tile.transform.rotation = Quaternion.Euler(0, tile.transform.rotation.y + 90f, 0);
rotation is a quaternion not a Vector3, so rotation.y is not the same as Vector3.y
Just use transform.Rotate(...). Further discussion would be better suited to #archived-code-general 🙂
Cheers, thought it might be another strange editor script thing but OK 👍
I have a struct: public struct ConvexHullGenerationParameters : IEquatable<ConvexHullGenerationParameters> which sits as a private serializable field in a component.
I wish to overwrite it via serializedObject.FindProperty, however I can't figure out how to this proper.
I was able to extract data from it like so:
convexHullGeometry = new ConvexHullGenerationParameters
{
BevelRadius = serializedObject.FindProperty(propertyName + ".m_BevelRadius").floatValue,
MinimumAngle = serializedObject.FindProperty(propertyName + ".m_MinimumAngle").floatValue,
SimplificationTolerance = serializedObject
.FindProperty(propertyName + ".m_SimplificationTolerance").floatValue
};
^ And perhaps there is an easier way.
I used to just use serializedProperty.objectReferenceValue, however in this case it is not applicable because this struct, well is a struct doesn't inherit from Unity Object class.
I tried to write to it like so:
var serializedObject = new UnityEditor.SerializedObject(component);
var propertyName = "m_ConvexHullGenerationParameters";
serializedObject.FindProperty(propertyName + ".m_BevelRadius").floatValue =
convexHullGeometry.BevelRadius;
serializedObject.FindProperty(propertyName + ".m_MinimumAngle").floatValue =
convexHullGeometry.MinimumAngle;
serializedObject.FindProperty(propertyName + ".m_SimplificationTolerance").floatValue =
convexHullGeometry.SimplificationTolerance;
serializedObject.ApplyModifiedProperties();
Didn't work.
So what is the question?
I wish to overwrite it via serializedObject.FindProperty, however I can't figure out how to this proper. Line 2
What is wrong with the way you are doing it right now?
I don't know. I can confirm that the extraction worked proper and the data carries over, but it is when I write to it, it doesn't write. So I'm here asking what I'm doing wrong? 🙂
Top code shows extract, and bottom shows write.
I'm thinking that is it possible that the struct is not initialized? on the component since it's a fresh AddComponent operation. However it is struct that can't be null...so I assume I can just write directly to it's open fields.
Looking at it, it looks like it should work. Could test doing it on an existing component (not one from a new AddComponent operation) and see if it works.
It's a fairly complex component that Unity wrote, I'm thinking it might be some internal operation going on that is resetting the values. I just needed to be sure here that I wrote my write back correctly. If you said I did correctly, I'll trust that and go with investigating their component editor logic.
If it is because it is a brand new component it is possible though unlikely that unity is deserializing it and apply default values that are overriding yours.
Hey bravo! I just did a simple Task.Delay(500), and after it added, the numbers updated proper! It's a cheap workaround, but it's a rare edge case, so I'll keep it like this for now. Thanks man for giving me the proper push 😉
Well glad you got it working! 😄
And this is a good speculation, however I can tell you that it's not the case because a few lines above this one, I do a similar thing to another part of the component data field, and it works off the bat.
Well good to know, I figured that it most likely wasn't the case but thought I would speculate anyways.
I would guess then that OnEnable/Awake/etc. the component is setting that data.
What's the correct way to do custom editor and change values inside SO that gets saved, that DOESNT use SerializedProperty/Object ?
I'm just picking up an old project and this is what i did because...i had to i think.
I think bcoz i had to make a SO sub asset on the fly, then the serialized path is not known or something like that
Now i'm having the classic problem of "values can change, but when recompile it's not saved! Onoz!"..
A, nevermind now it works again. Just a matter of putting the .SaveAssets and .Refresh in the wrong order
Altho im kinda curious what exactly is the problem with modifying actual objects vs serialized
What kinda problem can happen? Is it a predictable kinda problem? Or the kinda obscure problem where it "bugs only sometimes" ?
Downsides are having to manually support Undo/Redo, if it is not an asset, then it won't support prefab overrides, and if you create an SO of the object and don't call serializedObject.Update() at the start, your changes won't be applied to the SO that you made in your manual edit.
Also need to make sure to SetDirty the object otherwise it will not be saved.
Hi! I've got a little problem: I made a custom window, to edit objects of mine:```cs
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Scenario Key ID :");
EditorGUILayout.TextField(ScenarioTreeKeyID);
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("Save Changes"))
{
pScenarioTreeKeyID.stringValue = ScenarioTreeKeyID;
}```
as you can see, i've got a save button, trying to hardset the value of the variable inside the object, but it doesn't seem to work... I guess i'm missing something?
Apply?
if (GUILayout.Button("Save Changes"))
{
EditorGUI.BeginChangeCheck();
pScenarioTreeKeyID.stringValue = ScenarioTreeKeyID;
if (EditorGUI.EndChangeCheck())
{
soTarget.ApplyModifiedProperties();
}
}```
Tried this : nothing :/
Idk if i'm doing it right though
ChangeCheck is only for gui elements
Not for anything
You should jsut compare stringValue to ScenarioTreeKeyID if you care about checkingi t
what do you mean? I should just check if they're different, and if they are: soTarget.ApplyModifiedProperties(); ?
Yes
but they're not linked at all
I mean- look:
- L59: i set the value of my field to be the value of the property
Then the user can modify it, but it doesn't change the property, since it just took it's value
Then, line 93, on button pressed, i just do the opposite trade, and feed the string value with my modified string value
if (GUILayout.Button("Save Changes"))
{
pScenarioTreeKeyID.stringValue = ScenarioTreeKeyID;
soTarget.ApplyModifiedProperties();
}```
Just like that?
It's still not saving anything
where are you actually changing ScenarioTreeKeyID in this window
because that text field is doing nothing but drawing it
EditorGUILayout.TextField(ScenarioTreeKeyID); needs to set the return value to ScenarioTreeKeyID
Just like that toggle
oh wait
again, exactly what Navi said, you never set that value to anything, so the text area is doing nothing
ScenarioTreeKeyID = EditorGUILayout.TextField(ScenarioTreeKeyID);
like this
working like a charm! thanks guys
https://pastebin.com/V4tiYT2H
Sorry to be back so soon for a problem that has nothing to do with my previous one, but i have a Reorderable list that is causing me errors, and have no idea why.
Apparently it's not set to an instance of an object, but i'm setting it L61 i believe?
The only thing i changed from the other times i did this is that i'm doing it through a list directly, and not a serialized property of a list
it's an editor script, so after recompiling yeah
(it breaks at onGUI, when i hover it with my mouse)
Full error is too long, pastebin coming
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.
SerializedProperty element = leavesList.serializedProperty.GetArrayElementAtIndex(index);
._.
does your leavesList even use serializedProperties?
Are you sure...? I got a label here, it's in OnGUI(), it tells me the tree's name
it's initialised via a list you have
you should either be using one, or the other
not both. Either it's serialized properties, or a manually controlled list
oh, so i can't do list.serializedProperties
okok! thanks!
use the ReorderableList constructor with serialized property in it
Don't mix and match things like that
but if i want to FindProperty on the window itself (because i want a serialised property of the Leaves list that is in this script), i need to have a serializedObject of this window, right?
So that i can do soWindow.FindProperty("Leaves"); ?
okok! easy lol
Thanks!
Though I'm not sure why you want that, is it just to not directly operate on the target tree?
I think they want a save button to apply the actually changes rather than directly editing it
Which you could still theoretically do but iirc Reorderablelists are very eager to apply your changes
Yeah, basically i want to be sure that the user is not doing anything "illegal" with my architecture lol
UM
I THINK I-
That's weird 👀
Even more weird this is that i'm trying to display an empty Leave list.
(forgot to clear my list everytime i changed object)
void AddLeaf(ReorderableList list)
{
CheckWholePath();
GameObject go = new GameObject();
GameObject leaf = PrefabUtility.SaveAsPrefabAsset(go, pathToLeaves + "/Leaves" + ".prefab");
DestroyImmediate(go);
ScenarioLeaf newLeaf = leaf.AddComponent<ScenarioLeaf>();
//Add leaf to list
}```
Hi again lol
I've added this function to the OnAddCallback of my reorderable list:
Basically, i don't want the user to be able to just add an empty element: i want the added element to already have a new element i create.
But strangely, there aren't any obvious methods to do so, like list.Add() (which is the primary point of a list?)
Because it depends on what your backing data is
You should probably just get the array serializedproperty and insert it into that
yeah? Okok, i'll try this, thanks!-
Wait, how...?
oh, but the element inserted is empty
ok, i can surely work that out now...
Right... that's why you cahnge it after
yeah, i had that part, but i can't seem to find the correct method
oh, objectReferenceValue then?
Yes
but i can't do indexes on the objectReferenceValue...
sorry for being annoying lol
can't wrap my head around this. There isn't any single property in SerializedProperty that makes me access the last element of the property, idk how to do this
Getarrayitematindex or something
combo'd with .arraySize - 1
pLeavesWindow.GetArrayElementAtIndex(pLeavesWindow.arraySize-1) = newLeaf;
this doesn't work, sadly
i guess this is just to get the element, and not set it
you cannot set SerializedProperties you can only set their values
ooooooooooooh
if it's an objectReferenceValue you will have to set that property
I think i might be missunderstanding the documentation of SerializedProperty.FindPropertyRelative()...
I have a serializedproperty, element, that displays an element of my List<ScenarioLeaf>. My lists have 4 things, including a gameObject field, name CharacterShowingPrefab. I want to show this field in the array, so i simply do this:
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = leavesList.serializedProperty.GetArrayElementAtIndex(index);
SerializedProperty chara = element.FindPropertyRelative("CharacterShowingPrefab");
//EditorGUI.PropertyField(rect, chara);
}
Inside of the callback to draw items. I commented the third line, cuz it gives me nullrefs
What's ScenarioLeaf
a script of mine, doesn't really matter: what really matter is that it has a property called CharacterShowingPrefab and it's the type of my list
no, just a script
What does that mean
inherits from monobehavior*, sorry
So it's a UnityEngine.Object, we've been over this, you can only access UnityEngine.Objects through a SerializedObject, so you need to get the objectReferenceValue and create a SerializedObject from it and then find the right property based on that
ooh, okay
Would work for structs, for example? The tutorial i'm seeing does it
Yes
UnityEngine.Objects are references while structs and classes are really copies, hence the difference
ok! thanks, i feel like progressing somehow lol
@timber herald
https://docs.unity3d.com/ScriptReference/Editor.OnSceneGUI.html
Or not in an Editor:
https://docs.unity3d.com/ScriptReference/SceneView-duringSceneGui.html
Gives you a scope to draw stuff in/on the scene view.
Am on those right now and currently am confused, how to use Editor scripts because apparently I can't use them on gameobjects haha
Editor is for inspectors for custom components / scriptable objects
those derive from Editor, dont they?
inherit*
shouldn't OnSceneGUI handle that though?
I copied this script https://docs.unity3d.com/Manual/gui-Basics.html and it worked but only in the game view. Switchted to Editor instead of MonoBehaviour to use the OnSceneGUI function, now it's not compiling because it's not on a gameobject and I'm wondering how editor scripts compile when they are not in the scene?
followed multiple tutorials but OnSceneGui still not working
It should work fine if you have a component on a gameobject that is selected, and an editor for that component.
that's what I thought too
also have the editor script in the Editor folder
any idea how to debug this?
using UnityEditor;
using UnityEngine;
public class Test : MonoBehaviour { }
[CustomEditor(typeof(Test))]
public class TestInspector : Editor
{
private string textValue;
private void OnSceneGUI()
{
Handles.BeginGUI();
textValue = EditorGUI.TextField(new Rect(10, 10, 200, 20), "Value", textValue);
Handles.EndGUI();
}
}```
did everything the same
except I have two seperate files and the Editor one in the Editor folder in my assets
you're missing the Handles.BeginGUI and EndGUI
wtf
thanks
it works now
no tutorial mentioned them
or i was just blind
now it is only showing when the gameobject is selected, how do I make it visible permanent?
you probably want to use the delegate then
duringGUI?
yes
You can subscribe to it on launch https://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html
Doing it right now. I can't set a reference to my monobehaviour class I want the script to work on, in a static function though. What function should I use then?
you could FindObjectOfType, or have a button that starts and stops a class on the editor for the object that subscribes to the scene view delegate instead of doing it on startup. There are lots of ways, you'll just have to find what works best for the UX you want. While noting that you may need to ensure you unsubscribe from the delegate as to not have multiple of the same thing subscribed
damn this is a hell lot more complicated than I first thought
how is OnGUI so easy and OnSceneGUI an absoulute hell lol
if I wanted to build a permanent visible UI tool element like progrids for example, how would I go about it?
Like a separate window or in sceneview?
in sceneview
What vertx just told you
weirdly I cannot access instances this way though
I got to admit I have very little experience with this and can't see the bigger picture. Still confused why Handles affect GUI operations in OnSceneGUI
I'm trying to write an animation preview window, this code worked once and now it won't work at all, it throws a null ref exception
public class AnimPreview : EditorWindow
{
Motion PreviewClip;
Editor clipEditor;
bool showPreview = false;
[MenuItem("Window/Preview")]
static void ShowWindow()
{
AnimPreview window = EditorWindow.GetWindow<AnimPreview>();
window.Show();
}
private void OnGUI()
{
PreviewClip = (Motion)EditorGUILayout.ObjectField(PreviewClip, typeof(Motion), true);
if (GUILayout.Button("Show Preview"))
{
showPreview = !showPreview;
if(showPreview)
{
clipEditor = Editor.CreateEditor(PreviewClip);
clipEditor.HasPreviewGUI();
}
}
if(showPreview)
{
GUIStyle bgColour = new GUIStyle();
bgColour.normal.background = EditorGUIUtility.whiteTexture;
if(PreviewClip != null)
{
if (clipEditor != null)
{
//This line throws a null ref exception
clipEditor.OnInteractivePreviewGUI(GUILayoutUtility.GetRect(256, 256), bgColour);
}
}
}
}
}```
You really need to provide more context...
or do I do this on a separate class and subscribe to it with my editorscript? Gonna give this a shot
well this https://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html suggests using a static constructor, if I was using it in the Editor script I can only use static functions
Yes? There's plenty of way to get an instance of th ings
From FindObjectOfType to Selection
Even finding things by name works just fine
the problem is I can't in a static class, at least that's what visual studio is telling me
Show your code
I've seen some of these stupid methods rely on a certain state, usually you can find it by looking at the reference source
it's still this and the static constructor from the unity documentation
my current approach is to make a static event on update and subscribe to it from the editor class
There's no error in that code
any idea what this line means? "The default implementation is a no-op." with reference to either of these docs? https://docs.unity3d.com/ScriptReference/Editor.OnPreviewGUI.html & https://docs.unity3d.com/ScriptReference/Editor.OnInteractivePreviewGUI.html
how would you go about calling a function of another class in this update? https://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html
You find the object you want to call your method on using one of the ways I described above, and then just call the method
Means if you don't implement it then it does not do anything aka no-operation
E.g. FindObjectOfType<Test>().SuperCoolMethod();
Or (Selection.activeObject as Test).SuperCoolMethod()
what you said about it relying on a source, might that be related to the Note section that either of those docs have perhaps?
I don't have the note plugin
i get the same message over and over again that I cannot use non-static objects within a static class
if you make SuperCoolMethod() static, it'll work
Sorry Object.FindObjectOfType<Test>().SuperCoolMethod();
made it work with the event now it says I can only call GUI functions with a OnGUI function or OnSceneGUI lmao
anyone got a ui element foldout sample?
I'm assuming it works different, right now im creating a list view with elements bound to a list; open binding, if theres a sub list of one of those elements I want it to make a foldout.
@lofty sphinxPlease don't cross post, you question isn't even relevant in this channel
I have confused the channel
Hi! I've got a little problem:
I'm creating some SO's via a button in editor (here's the function:)
private LeafRequirementSO CreateNewReq()
{
//Creates an ActionSO.cs at Assets/Scenarios
CheckWholePath();
LeafRequirementSO newReq = CreateInstance<LeafRequirementSO>();
AssetDatabase.CreateAsset(newReq, pathToReq + "/NewReq.asset");
AssetDatabase.SaveAssets();
return newReq;
}
And i am then trying to put this new SO inside my array, Req, that is serialized:
if (GUI.Button(new Rect(rect.x, rect.y + EditorGUI.GetPropertyHeight(chara) + (2*EditorGUIUtility.singleLineHeight), rect.width, EditorGUIUtility.singleLineHeight), "Create a new requirement"))
{
Req.arraySize += 1;
Req.GetArrayElementAtIndex(Req.arraySize - 1).objectReferenceValue = CreateNewReq();
}```
but it doesn't seem to be affecting any values inside this
i'm trying to draw this array in a readonly way, with a foldout:
showReq = EditorGUI.Foldout(new Rect(rect.x, rect.y + EditorGUI.GetPropertyHeight(chara) + 10, rect.width, EditorGUIUtility.singleLineHeight),showReq, "Requirements");
if(showReq)
{
if(Req.arraySize != 0)
{
//EditorGUI.LabelField(new Rect(rect.x, rect.y + EditorGUI.GetPropertyHeight(chara) + 20, rect.width, EditorGUIUtility.singleLineHeight), "The requirements are:");
EditorGUI.indentLevel++;
for (int i = 0; i < Req.arraySize; i++)
{
Debug.Log("cc lol"+i);
EditorGUI.LabelField(new Rect(rect.x, (rect.y + EditorGUI.GetPropertyHeight(chara) + EditorGUIUtility.singleLineHeight)+((i+1)*EditorGUIUtility.singleLineHeight), rect.width, EditorGUIUtility.singleLineHeight), ((LeafRequirementSO)(Req.GetArrayElementAtIndex(i).objectReferenceValue)).ToString());
}
EditorGUI.indentLevel--;
}
else
{
EditorGUI.LabelField(new Rect(rect.x, rect.y + EditorGUI.GetPropertyHeight(chara) + 20, rect.width, EditorGUIUtility.singleLineHeight), "There are no requirements for this leaf.");
}```
But it keeps drawing me the "There are no requirements for this leaf." label even when i click on the button.
i doubt this problem comes from the displaying part, but i'm puttin it here just in case, it's the first time i'm trying foldout so it might have a thing not working or so
oh, i forgot again...
Oh my lord and savior, Navi, i beg you, come and help my lost soul amongst thy filthy editor extensions, may your guidance help me to find redemption and peace
try de-inlining some of your statements, they are grossly unreadable
Totally agreed
ie EditorGUI.LabelField(new Rect(rect.x, (rect.y + EditorGUI.GetPropertyHeight(chara) + EditorGUIUtility.singleLineHeight)+((i+1)*EditorGUIUtility.singleLineHeight), rect.width, EditorGUIUtility.singleLineHeight), ((LeafRequirementSO)(Req.GetArrayElementAtIndex(i).objectReferenceValue)).ToString());
create a variable for each element you will pass into things, assign the variable, then just pass the vars into the functions.
that will help you debug also, as you will be able to inspect each value in debug mode
atm, there's no possible way to inspect the result of (Req.GetArrayElementAtIndex(i).objectReferenceValue)).ToString()) to see what is returned and passed to ToString()
when you are debugging something, inlining statements really isn't your friend
well, considering i'm not even passing through " if(Req.arraySize != 0)", and straight going to hell else, that's kinda useless for now?
that was just an example, the rest of your code is the same
declaring rects to a variable makes things easier to read, it adds a lot of noise to the function you are debugging, making it difficult to read
yup
back to the example i posted earlier, where does the Rect start and where does it finish? you have to expend energy to work that out when reading it
Yup, totally agree
I made two different methods:
Rect FoldoutRect = new Rect(rect.x, rect.y + EditorGUI.GetPropertyHeight(chara) + 10, rect.width, EditorGUIUtility.singleLineHeight);
showReq = EditorGUI.Foldout(FoldoutRect,showReq, "Requirements");
if(showReq)
{
if(Req.arraySize != 0)
{
EditorGUI.indentLevel++;
for (int i = 0; i < Req.arraySize; i++)
{
Rect LabelRect = new Rect(rect.x,
(rect.y + EditorGUI.GetPropertyHeight(chara) + EditorGUIUtility.singleLineHeight) + ((i + 1) * EditorGUIUtility.singleLineHeight),
rect.width, EditorGUIUtility.singleLineHeight);
Debug.Log("cc lol"+i);
EditorGUI.LabelField(LabelRect,((LeafRequirementSO)(Req.GetArrayElementAtIndex(i).objectReferenceValue)).ToString());
}
EditorGUI.indentLevel--;
}
else
{
EditorGUI.LabelField(new Rect(
rect.x,
rect.y + EditorGUI.GetPropertyHeight(chara) + 20, rect.width,
EditorGUIUtility.singleLineHeight),
"There are no requirements for this leaf.");
}```
for the last one, for ex, i just returned to each argument
For the rest, simply created a variable
This code below is 1000% easier to read than yours
var myRect = new Rect(SomeGuff);
var lfSo = (Req.GetArrayElementAtIndex(i).objectReferenceValue)).ToString()
EditorGUI.LabelField(myRect, lfSo);```
you mean the upgraded one i just sent or...?
Yup, mb, ```cs
if(Req.arraySize != 0)
{
EditorGUI.indentLevel++;
for (int i = 0; i < Req.arraySize; i++)
{
Rect LabelRect = new Rect(rect.x,
(rect.y + EditorGUI.GetPropertyHeight(chara) + EditorGUIUtility.singleLineHeight) + ((i + 1) * EditorGUIUtility.singleLineHeight),
rect.width, EditorGUIUtility.singleLineHeight);
Debug.Log("cc lol"+i);
LeafRequirementSO req = ((LeafRequirementSO)(Req.GetArrayElementAtIndex(i).objectReferenceValue));
EditorGUI.LabelField(LabelRect, req.ToString());
}
EditorGUI.indentLevel--;
}
var lfso = (LeafRequirementSO)Req.GetArrayElementAtIndex(i).objectReferenceValue;
var lfsoStr = lfso.ToString();```
nearly there
separate the ToString to a variable also, then you can inspect the variable before it gets passed to ToString
yep, mb:```cs
LeafRequirementSO req = ((LeafRequirementSO)(Req.GetArrayElementAtIndex(i).objectReferenceValue));
string reqStr = req.ToString();
EditorGUI.LabelField(LabelRect, reqStr);
do that with the rest and you'll find it's shit loads more readable
and debuggable
Inline statements are a curse to debugging
at the end of the day, the compiler inlines stuff where it can, so it's not explicitly required or any more optimal to do so. The only real gain is that inlining looks cool, but in reality, it sucks most of the time and is just painful to read and debug
got it, thanks! :)
when you write a function, you decompose and compartmentalise how it works. Other people don't have that understanding and must form it. In 6 months when you look back at that code, you won't have it anymore either.
always try to write your code so that it's readable to a simpleton
If you get to the point where you are answering questions on any of these channels, you'll realise that a significant number of questions can simply be solved by people decoupling their code into individual statements and just debug & inspecting the variables to find the answer.
https://pastebin.com/PC2VZRTA
Is that good enough? 👀
So, my problem is that my button on L35 of this pastebin doesn't seem to be doing anything at all
that's much better
Oh
Didn't see it's almost my time to go now lol
Should've posted here sooner :/
line 39, you set arraySpace, then immediately overwrite it in line 40
well i got confused: Thing is the things i put in array space is the empty space of the array i got.
i wanted to encapsulate it like you told be, but looks like there was mistakes along the road i guess?
what's the Req definition?
(and then toAdd is the element i need to add in this array)
Array Req = new Array(): perhaps?
it's a serialized object of mine, do i need to show it?
it would help
i don't think so, no
i have :
- A serialized array of Reqs
- A req i need to add in
I did this @L234, works perfectly well
except it's for a prefab, but yknow
And i don't see how it would help since i'm not touching to any of it's properties?
SerializedProperty Req = elementSo.FindProperty("requirements"); is what i was after, i didn't know what type it was, so difficult to know what you are trying to do with it
Oh, ok
well i need to draw a RequirementSO[], and i wanted to do it on a custom readonly way with my tostring and labels
basically
I'm not very familiar with SerializedProperties, I'm guessing you need to find the index where to add toAdd to, then set it with arraySpace[i] = toAdd;
serialized properties, however, don't work this simple
But i've got to go now though, thanks for all this
If someone knows the answer while i'm gone, i'll take it lol
actually, you want to add it to Req don't you. atm, both arraySpace & toAdd are unused
at a guess Req[Req.count] = arraySpace
or some variation of count to get the array size
Anyone know where I might information on how to use a PreviewRenderUtility to dispaly an animation clip?
How can I make something like that in a custom editor (its supposed to display a texture instead of a material)
You use BeginPreview and EndPreview and just add a GameObject with a animator that you want to play the clip of, iirc that is.
Override OnPreview in the custom Editor.
Thanks I'll try that
@gloomy chasmhow do i tell PreviewRenderUtility what to render?
the only information i can find is how to render a texture
I tried using AddSingleGO(..) but got a blank screen with some errors
previewRenderUtil.AddSingleGO(go), or InstantiatePrefabInScene
Ya gotta position the camera/go
i can use hideflags to create the go in scene to make it not visible in the hierarchy can't i?
No need if you are adding it to the previewRender scene.
do i need to create a specific scene for this, i don't want to use the current one
No
Idk how advanced you are or are not, but the source code may help you understand it https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/PreviewRenderUtility.cs
It isn't too bad to at least get the broad strokes of what it does.
maybe, a lot of the unity code goes over my head tbh. I'll take a look
If it doesn't help and you are still having problems, you can show me what you are doing and I can see if I can help you.
i tried a couple a bunch of stuff, but i'll give it another go, if i can't get it working, your assistance would be very appreciated
Could someone explain "This visualElement is not my child"
Get jerry springer on this one
What do you mean...?
Attempting to remove a child of a visual element provided by bind item
right... confusingly enough doing Add will also reparent it, but the original still gets drawn
you should ask billy jean
@gloomy chasmI have this code, it shows nothing. Also, it screws up xbot.fbx, i need to reimport it after opening the window https://hastebin.com/subibatozo.csharp
Firstly, use the renderUtil.Render() method.
still doesn't do anything. Should I perhaps use a model from the Hierarchy as the GO?
No that won't do anything. Firstly EndPreview() returns a texture, you need to draw the texture.
I've got this, but it displays just a white screen and i'm still not handling the DefaultHuman correctly. https://hastebin.com/uwiyaweyem.csharp
Hey MechWarrior99, Is there a way to save a Texture2D into a prefab file in some way?
like not as a game object but as metadata?
Googling Subasset will give you what you want 🙂
Can I save text data with it too?
If it can be an asset then it can be a subasset.
hmmm
AssetDatabase.AddObjectToAsset(objectToAddAsASubasset, asset path) or something like that.
You can use hideflags if you don't want the subasset to show up in the project browser
Ok.
@gloomy chasmyou had any thoughts on how to get the previewRenderUtil with a human character? I'm at a total loss
the paste i did earlier, if a cube is used in place of a DefaultHuman, it shows the cube, ie
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
outputTexture = CreateTexture(obj);```
So the cube works?
yes, very basic, but it works
Then the camera may be too close to see the DefaultHuman.
And is there a way to hook into saving assets?
Like.. AssetDatabase.Save()...?
Kinda, like, when anything saves the asset, run this function as well?
moving camera further away has no change
Yes, there are several, look up asset postprocess. Or just goggle for a event when assets are saved.
ok thanks!
Eh... you could use a bit of reflection and just use the class that unity uses for the animation clip editor...?
i'm less optimistic i could get that working
I've been looking through some of the animancer code and that uses a renderpreview window, however that passes the animation via it's own custom playable wrapper, making it difficult to extract what it does
What I'm thinking of doing, is saving the thumbnail into the asset metadata, and then if that's there and the last saved date I attach to that subasset is newer than the asset being saved, then it skips trying to generate a new thumbnail and just uses what's there, otherwise it generates a new one. The other thing is to create a single scene to render the thumbnails without closing that one or opening a new one, and then close it when there are no new thumbnails to generate or the editor closes
So use a sort of resource pool
@snow bone When you add the human are you instantiating it or just adding single? It is a prefab so you should be instantiating it
I'm hoping that fixes the "too many scenes" issue
I'm also working on reserializing the texture assets after moving them.
....So you want to mimic unity's thumbnail generation?
AssetDatabase.MoveAsset() and AssetDatabase.ForceReserializeAssets()
Yes, because it always fails to generate coherent thumbnails for these prefabs
it either leaves it the default icon or generates an empty box
The thumbnail generation works when I close and reopen the editor, but then after a time they turn into black squares
@gloomy chasmDude, that works!
But also all the trimming I did to the sprites resets when I close and reopen the editor
But the positions are persisted
any idea how to animate it with an anim?
@ivory fulcrum I spent like 4 or 5 days making a thumbnail system that generates thumbnails, caches them to file and caches them to temp memory in a pool, and regenerates when the asset is dirty, and does it all async as to not lag the editor.
animator.Play(0, 0, normalizedTime), and animator.Update(deltaTime)
I would love to see that code. Currently my code is synchronous.
The secret is to put the code in to the EditorApplication.update callback.
wait a minute.... I broke one of my rules by moving it in the asset database.
shoot
can I prevent the reimport of an asset?
i'm assuming that i need to attach an animation controller ie a mechanim thing to the animator first?
on application load
You basically have a list of 'requests' that gets added to anytime you need to generate or load a texture, then in the update you start a stopwatch and go through each request in the list and fulfill it. But before fulfilling each request you check to see if the time in the stopwatch is greater than the max allowed time, if it is you return.
Not that I know of.
do you know if I can substitute the animator for a PlayableGraph, so i can pass my anim clip to that instead?
Looks like what unity does is to make a AnimatorController and a AnimatorState and assign them to the component of the model thing
Ehh, I don't remember what a PlayableGraph is, so I don't know 😛
disregard the playablegraph, i'm thinking too far ahead of myself. I should just get it working with animator first before i try anything fancy
where are you reading about the AnimatorController & animatorState?
@gloomy chasmcan you link where you read about the AnimatorController and a AnimatorState please
Like how to use them? Or where I was saying that that is what Unity is doing?
thank you, I'll have a read through and see what I can understand, then quiz you with the bits I don't
Line 486+ will also be of use to you.
Sure thing! No promises though.
@gloomy chasmis the animation clip editor the inspector that shows when an anim clip is selected?
Yes. It is the Editor (Inspector view) for a AnimationClip.
So the OnPreview... whatever is the preview that is shown in the bottom of the inspector.
is has a lot of reference to the AvatarPreview, is the AvatarPreview the dockable window that shows the animation?
OnPreviewSettings() just makes a call to AvatarPreview.DoPreviewSettings
I meant OnInteractivePreview()
is it using the AvatarPreview to show the window using the PreviewRenderUtility ?
Ehh... no...?
Or... yes?
I'm not sure what you are asking exactly.
there's no calls toe the PreviewRenderUtility in AnimationClipEditor , but there is some in AvatarPreview
Ah, yeah the AvatarPreview has an instance of the PreviewRenderUtility that it uses.
i didn't know there were keyboard shortcuts to use in the preview window
AnimationClipEditor.OnInteractivePreviewGUI() makes a call to AvatarPreview.DoAvatarPreview, it calls the previewUtility.EndAndDrawPreview();
@gloomy chasm Thank you for your help. There's a lot of useful information in them two classes that will help me a ton
Your welcome, glad that they were able to help you.
I've been at this for over 14 hours today! I'm going to see if i can get it animating, then call it a night
Oof, well good luck! 😄
The AnimatorController they use is an internal derived from RuntimeAnimatorController. they don't like to make it easy for us
Hahaha, you can say that again.
Any ideas for a multi line text field with wrapping but no new lines?
Text fields aren't wrapping?
i meant textAreas anyway
The only possible thing i see is to create a TextAreaIsh GUI yourself i guess? Don't know how that works at all
I don't want to deal with TextEditor (you've seen how much it sucks) 😛
totally 💀
if i may borrow you for a sec, because there appears to be something i really don't get 👀
https://pastebin.com/YMZ0QJ3Q
L210 is a button supposed to add the toAdd ScriptableObject in the Req Serialized Property, which is an array that's the same type as toAdd, but i can't wrap my head around that
when i click, the array really doesn't change
You're reassigning a local variable
Req.GetArrayElementAtIndex(Req.arraySize - 1).objectReferenceValue = toadd is what you want
well that's what i did before someone tells me how i should get my code more readable instead of just trying to answer my problem yesterday 👀
(Was just the rects that were too long for him after all, nothing i could change)
thanks, Navi, i'm trying that right now
doesn't work :/
How can i be sure that the function returns the LeafRequirementSO like i want it to?
char chr = Event.current.character;
if ( (chr < 'a' || chr > 'z') && (chr < 'A' || chr > 'Z') && (chr < '0' || chr > '9') ) {
Event.current.character = '\0';
}```
Apparently this works for filtering text input
oooooh 👀
I'm back again! 🥴
RequirementCW.Open((ScenarioLeaf)pLeavesWindow.GetArrayElementAtIndex(index).objectReferenceValue);
Everything begins with this: i'm opening the Custom Window (CW for short) to see more correctly all the "LeafRequirementSO" (that i call Req for short) that are on my ScenarioLeaf (Leaf for short). I pass on the leaf i want to inspect in my window, and the machine is on:
public static void Open(ScenarioLeaf leaf)
{
RequirementCW window = GetWindow<RequirementCW>("RequirementsCustomWindow");
window.soTarget = new SerializedObject(leaf);
window.leaf = leaf;
}
private void OnEnable()
{
reqSp = soTarget.FindProperty("requirements");
for (int i = 0; i < reqSp.arraySize; i++)
{
reqSos.Add((LeafRequirementSO)reqSp.GetArrayElementAtIndex(i).objectReferenceValue);
}
reqDisplay = new SerializedObject(this).FindProperty("reqSos");
}
public void OnGUI()
{
if(leaf != null)
{
EditorGUILayout.LabelField(leaf.ToString(), GUILayout.ExpandHeight(true));
}
}
There we go. I open my window, setting the soTarget and the leaf values, that are respectively of types "SerializedObject" and "ScenarioLeaf".
And then, nothing. I try to get the reqSp (SerializedProperty): nothing, nullref.
Pastebin of my ScenarioLeaf program:
https://pastebin.com/NLsy8WeC
I thought it was the leaf, at first, but no: the ToString() works like a charm: it is the correct one.
snap, i forgot my incantation again!
Oh my lord and savior, Navi, i beg you, come and help my lost soul amongst thy filthy editor extensions, may your guidance help me to find redemption and peace
HEY!
LISTEN!
uninstall all of your editor extensions and then reinstall them one by one
Also watch out for the wallmaster
the... What...?
Enemy from Ocarina of Time
ayyy (only zelda i havent played)
Get a 3DS, or Citra, and play it!
in an order in particular?
I got a 3ds AND the game lol
what i don't have is time 🥵
done, still the same errors
No. I just wanted to give you a response that seemed to fit your problem that might sound like something Navi might say
Of course preceded by "Hey! Listen!"
Hey, can you tell me if there is a way to create custom array without using FindProperty?
oh, lord
Which get's to be REALLY annoying when you're on cleanup through the game and she's telling you to go to the temple of time
(this was the navi i was talking about 👀 )
Nope, hes using it
wave = serializedObject.FindProperty("wave");
.... OHHHHHHHHHH
But i mean, it could've been it: editor extensions are really ducked up
literally, a guy nicked "Navi"
DonTomas: There are definitely some problems that I wish Unity devs would solve but...
oh, mb, well... First off, why? And then, you can make a foldout with custom fields inside (textAreas, etc)
Yeah lol
since i don't wanna ping them, i just pray to them and hope they'll respond lol
LOL
Well ay, i mean it worked sometimes
I mean, I want something like this, but for array:
ObjectPosition script = (ObjectPosition)target;
var position = script.position;
script.position = (ObjectPosition) EditorGUILayout.EnumPopup("Position", position);
I find that playing video games for a few days helps me get my mind off of the problem I'm trying to solve when I'm stuck programming, and then when I approach the code again, I get a fresh perspective of it and usually think of new ways to approach the problem
But I can't find anything for arrays in editorGUILayout
i've been doing editor extension for 2-3 weeks straight, monday to friday
And i have no idea of what this is
Well, for me, it's the list i sent you
It's kinda old and kinda sucks, cuz you have to use rects, but is really short, complete
you can easily create a lot of things with this.
I mean... a LOT.
Hm, ok.
Thats not exactly what i want, but thanks 🙂 I'll check it
aaaah, i'd love to do that so much, except i can't play on my working hours lmao
(Problem of mine still unanswered, please don't mind answering it 🥲)
Found this too: https://catlikecoding.com/unity/tutorials/editor/custom-list/
uses serialized properties too, but seems more recent i guess
as i said, you can always use foldouts and everything
with a get/set to the size of the array
The joys of being a hobbyist
Ok, thank you
yeah lol right
I don't follow what the problem is exactly.
"And then, nothing. I try to get the reqSp (SerializedProperty): nothing, nullref."
It shouldn't
on the reqSp
:/
What is the exact name of the field you are trying to get with SerializedProperty?
it's in the pastebin, in my leaf script: "requirements".
an Editor has a target, is there an equivalent for an EditorWindow?
So do be clear, reqSP is null, not GetElementAtIndex?
wait, i have a problem, one of my script stopped working, i have to pretend to do something so it works again 👀
(unity just crashed 👀 )
(my window now doesn't open, restarting unity 👀 )
still nothing, window doesn't open
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.
i haven't changed anything
unity editor is really getting on my nerves
working through the AnimationClipEditor is a nasty rabit hole ><
"working through the AnimationClipEditor is a nasty rabit hole ><"* here king, fixed it for you
they seem to have written a multi-purpose time ruler for animations, so it can have ticks and text or can just be like the vertical line shown when previewing an anim
can i display an editor inside an editorwindow?
Yes, Editor.CreateEditor, then just call DefaultInspector or OnInspectorGUI or whatever to draw it. Make sure to cache the editor so it isn't regenerated each frame, and clean it up in OnDisable.
thank you
EditorGUILayout.ObjectField really should have a generic version instead of relying on typeof()
@gloomy chasmsay i have my own custom editor, how do I call that from Editor.CreateEditor?
Create Editor takes an instance of a UnityEngine.Object and will create an editor for, it uses a custom editor if one is defined.
can i just do myEditor = new MyEditor(); to create it?
Editor inherits from ScriptableObject, so no. You could do Object.CreateInstance<MyEditor>() but I don't believe there is a way to set the target. And anyway it is the same result.
There is an overload that takes an editor type if you want that.
this seems to work, but TestEditor is an empty class
test = CreateInstance<TestEditor>();
What do you mean empty?
public class TestEditor:Editor{}
That's fine.
Editor isn't abstract anyway.
it seems to work on the editor i'm working on, so I'll accept that.
Thanks
I hope someone is paying you to code for them, you know your stuff.
Haha, well thank you. I get a bit of freelance work now and then, otherwise just work on my own projects.
I did realize recently that at some point I think I became smart, and actually know stuff? 😛
I much prefer working on my own projects, I've had a string of really abusive employers in my past
my last job, i was let go, while the person who was shit and causing underlying issues, which were tripping me up, who I actually had to teach how to do stuff like basic source control, was given a raise.
@gloomy chasmIf i want to set some variables in the editor that is returned from Editor.CreateEditor(.), is it ok to cast it and pass the vars through a function?
Yup, you can do anything you want to it that you would do to a ScriptableObject, and you can do almost anything to an SO that you would do to a normal C# class.
nice, thanks again
do you think it'd be better to pass a reference to the EditorWindow class to the editor that it is creating, then refer back to the variables that I need? That would technically be a circular reference
probably much of muchness to be fair
I think it depends on what you are wanting to do, but that is a perfectly fine thing to do, if maybe a bit messy. Also means that it may not work right showing in the Inspector unless you can give it the inspector window.
Just something to keep in mind.
i'm not intending for it be shown outside the editorwindow. I think either approaches should work fine
if i made it dockable, that's probably not going to work is it?
i think i'll set a function, i can deal with it being dockable another time
Ehh? What wouldn't work? Should work fine... what are you doing that would make it not work?