#↕️┃editor-extensions
1 messages · Page 86 of 1
Consider a folder with 10 meshes that will be loaded into the database.
these meshes get loaded 1 by 1 and generate a preview for each.
these previews are generated into a Texture2D using a RenderTexture
those Texture2D are pushed into an array that has 4096/Texture2D.width elements
calling the packTextures method merges the array into a single Texture,
with 1 texture in the file the rect for that texture (thumbnail of mesh 1) is the full rect so [0,1,0,1]
after that a second mesh is loaded in, and pushed into that array,
that array overrides the atlas texture, and returns new rects,
the rect for the first element now becomes [0, 0.5, 0, 1] (the x rect of element one only takes up half the width of the texture, y remains the same)
the second rect becomes [0.5, 1, 0, 1] which will be correct until the 3rd element is created
the rects are in an array returned from the packtexture method, but only the new button that gets created will use an updated rect,
the previous rects remain the same and will show every element that was generated up to that point, because the rect is still the old value
@gloomy chasm the rect of the first element in this case still remains [0,1,0,1] but should be updated to be [0, 0.5, 0, 1]
because rects are a struct, and its copied by value (and even if it was by reference, it still wouldnt work because the array gets overriden)
Right, so what are you wanting to do? The only way to update them is to just loop through and update them.
that really is the only way then
i guess since the textures are packed into sets of 256 thats not all that bad, its sort of batched by itself in a sense
I mean, you could like maybe have an event that you register each button with maybe...?
good point, I dont know if there is something built in for that to handle some kind of eventtrigger on the VisualElement. I assume there is but I will need to look for it @gloomy chasm
No, you just make your own event.
@gloomy chasm the first thin i can come up with is this... but that feels like some really janky way of going about it
where that AddButton returns the whole collection of buttons belonging to the texture that was provided to it
which is stored in a bunch of arrays on the _ui object 🤔
Uh, you should read up more on UIElements. but to answer you question visualElements[i].Q<Image>().uv = rects[i];
I rly should, im mostly trying to get it functional for now and figure out the best approach doing some revisions
Is there a Unity class exposable in the property editor that allows the user to edit an EQ graph?
a little like the animation curve editor except with a defined duration and values fixed between 0 and 1
@gloomy chasm new plan, instead of having all the textures be cached in an atlas. I am going to try:
load mesh, write to jpg file,
then I check if the element would be able to render in the scene, if it can i grab the jpg and load it into the UI, otherwise I stop here
im hoping unity has the culling set up in a way that allows me to check if an object is visible in a scrollview or not, but I need to do some digging to figure out how this can be done
You were right Mech. Although that gives me some hesitation as to whether the Serializer is serializing recent changes
map.Count didn't work because while I "implemented" it, I didn't implement it correctly in my wrapper class
int Count { get; } vs int Count { get => list.Count; }
@gloomy chasm so now it seems to work, however I noticed while debugging that property.arraySize == map.Count - 1
Which is what makes me uncertain if the SP is actually serializing everything
It seems to since it increases when I click the "Add" button
But it's always 1 short of the count given by map.Count
Are you making sure to ApplyPropertyChanges()?
And like I said, don't mess with both SerializedProperty stuff and the direct C# classes/data at the same time.
help me please someone
it doesn't allow to assign anything to the fields via clicking and selecting or dragging anything in
You need to set the type when making the field. Are you doing EditorGUILayout.ObjectField?
ya
recipe.result = (Item)EditorGUI.ObjectField(new Rect(Screen.width / 6 * 5,Screen.height / 12 * 4,Screen.width / 12,Screen.width / 12),recipe.result,typeof(Item),true);
thats the line
recipe.result = (Item)EditorGUI.ObjectField(rect,recipe.result,typeof(Item),true);
i provided a type
I think I know what is happening but can you provide more of the code so I can be sure?
(I think that you are setting recipe.result multiple times/places which are overridding when you try to set it in the inspector)
no
the other ones are like this
recipe.ingredients[i] = (Item)EditorGUI.ObjectField(rect,recipe.ingredients[i],typeof(Item),true);
in a for loop
@gloomy chasm
@round hazel Well I still think you are setting it somewhere else. Try putting it in a change check and see if it triggers. That will tell you something at least.
a change check...
EdiotrGUI.BeginChangeCheck();
// Object field(s) here...
if (EditorGUI.EndChangeCheck())
{
Debug.Log("An object field did change!");
}
nothing happened
- it doesnt actually let me click the fields just hover over them and make them highlighted
Well that is something that would be nice to say to start off with. You need to show the full code to help you then. Use this site to share the code. https://paste.mod.gg/
should i send item and recipe script too?
No, they should not be needed. Just the editor.
k
it is very messy ik
please send a solution if possible as i have to sleep now gn
I'm not finding "ApplyPropertyChanges" anywhere in the docs
I found this though. Reeeaaaaaaaallly descriptive. I understand everything now.
And of course, the call seems to do a big fat nothing.
At least for my purposes.
Of course it could have just launched a nuclear missile in russia. Who knows.
@ivory fulcrum that function applies modifications to SerializedProperties on a SerializedObject
it saves the modifications you do to the properties
the most common use case is in custom Editors
So if I were modifiying things in the SerializedProperty, and then wanted the changes reflected in the underlying object, then I would use that?
you are basically required (with some exceptions) to use it whenever you are dealing with SerializedObject and SerializedProperty
can you share more context or your code?
read this
// In OnGUI():
if (GUIHelper.ColorControl(() => GUI.Button(headerButtonRectAdd, guiElements["AddIcon"]), null, null))
{
AddItem(property.FindPropertyRelative("list"));
}
// AddItem:
public void AddItem(SerializedProperty property)
{
map.Add(new CompositionMapItem());
numberOfItemsInMap = map.Count;
property.serializedObject.Update(); // Added to see if it changes the "one less" problem described below
Debug.Log($"Add: map.Count: {map.Count}\nAdd: property.arraySize: {property.arraySize}\nAdd: numberOfItemsInMap: {numberOfItemsInMap}");
// There is one thing that this debug log line exposed which is that property.arraySize is always one less than map.Count it seems.
// I'm not sure why and it makes me nervous that the serializer isn't serializing everything added except that it's consistently one less.
}
ok so in your AddItem method you aren't doing anything to the property
you are Updating the SerializedObject, basically reverting it to its previous state
you aren't performing any changes either
map.Add
map is the targetObject from SerializedObject
It's initialized the first time OnGUI is run
but then why are you using SerializedProperties if you are handling the changes directly in your classes?
is property.serializedObject and map supposed to point to the same Object?
Because everything I've seen tells me that SerializedProperty is how the data gets saved. And I've worked with custom editors where for some reason you make a bunch of changes and then update the script (even just adding a newline) and suddenly all of your data is gone
inexpclibly.
if you lose data it's because you aren't serializing it
by using Serialized Object/Property you are letting Unity handle that, which has some added benefits like default Undo system support
Right. That's what I'm trying to avoid and the fact that map.Count says that the array length is x, and property.arraySize is x - 1, that's what concerns me
@ivory fulcrum put that same debug line also before your serializedObject.Update();
you should see different output
I'm also trying to make sure that there's undo. But the problem is that if I try to modify the SP to add the element to the list, I get Unity's utterly braindead "copy the last object in the list" behaviour I wrote all this code to avoid
"copy the last object in the list" behaviour I wrote all this code to avoid
why is that an issue? just empty the value or set it to whatever defaul value you want it after adding a new element to the array
I'm also trying to make sure that there's undo.
then you either modify all the data through SerializedProperties or do it manually and register the changes to the Undo System manually
I'd be happy to use the Undo system
I suggest just not changing your data directly, just use SerializedProperties
so instead of
public void AddItem(SerializedProperty property)
{
map.Add(new CompositionMapItem());
numberOfItemsInMap = map.Count;
}
do
public void AddItem(SerializedProperty property)
{
//get the current "state" of the data
property.serializedObject.Update();
//add new element to your array property
property.InsertArrayElementAtIndex(lastIndex);
//get the last element of the array
SerializedProperty lastElementProperty = property.GetArrayElementAtIndex(lastIndex);
//modify that element
lastElementProperty.objectReferenceValue = new CompositionMapItem();
//apply the modifications to the data
property.serializedObject.ApplyModifiedProperties();
}
this last part is pseudo-code, but you get the gist
I can't remember if you also have to manually set the arraySize after doing property.InsertArrayElementAtIndex(lastIndex);
so keep an eye on that
Can't do it. CompositionMapItem is not a unity object
It's a plain object
And no, I can't derive CompositionMapItem from UnityEngine.Object
the devs made sure that wasn't a thing
That is the part he was saying is pseudo-code. If for some reason, it really is a problem that it copies the last one, go in and set the values to the default values. I already went over this with you and told you how.
well yeah, because (as far as I'm aware of) you can't construct custom class instances yourself when dealing with arrays and SerializedProperties, Unity handles that internally
what you can do is use SerializedProperties to use and modify the custom class's data like you can with types that derive from UnityEngine.Object
I should have been more clear in the pseudo-code
you can do something like
InitializeDefault(lastElementProperty);
private void InitializeDefault(SerializedProperty property)
{
property.FindPropertyRelative("_whateverStringField").stringValue = "Whatever default value";
property.FindPropertyRelative("_whateverIntField").intValue = 1234;
}
of course if your nested fields are also custom classes you have to handle it by doing the same but one level deeper
it can get dicey, specially if your custom classes are expected to change a lot in the future, because you are gonna have to manually adjust everything
but you get the idea
Here's a very dirty and quick example
[Serializable]
public class SomeCustomClass
{
[SerializeField] private string _someString;
}
public class SomeMono : MonoBehaviour
{
[SerializeField] private SomeCustomNonUnityObjectClass[] _customClassArray;
}
[CustomEditor(typeof(SomeMono))]
public class SomeMonoEditor : Editor
{
private SerializedProperty _customClassArrayProp;
private void OnEnable()
{
_customClassArrayProp= serializedObject.FindProperty("_customClassArray");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
int lastIndex = _customClassArrayProp.arraySize;
if (_customClassArrayProp.arraySize > 0)
{
lastIndex = _customClassArrayProp.arraySize - 1;
}
if (GUILayout.Button("Add new element")) { _customClassArrayProp.InsertArrayElementAtIndex(lastIndex); }
if (GUILayout.Button("Set last element to default value"))
{
SerializedProperty lastElementProp = _customClassArrayProp.GetArrayElementAtIndex(lastIndex);
lastElementProp.FindPropertyRelative("_someString").stringValue = "Some Default Value";
}
serializedObject.ApplyModifiedProperties();
}
}
@ivory fulcrum as you can see, I don't need to directly access my custom class at any moment
everything is handled by using SerializedProperties, thus having Undo support by default
this is obviously a very basic and unrealistic example, because real use cases will have more complexity than just a simple string, but the same principle applies
if this doesn't suit your needs, you can of course modify the data directly instead of using SerializedProperties, but you need to handle Undo yourself
(And if you do,** don't** touch SerializedProperties, the data will be out of sync!)
public override void OnInspectorGUI()
{
if (GUILayout.Button("Add empty element"))
{
//Do undo stuff
((SomeCustomClass)target).AddEmptyElement();
}
}
I've never dealt with modifying array data directly in this way so I don't know if there's any additional implications that you should take into account
and I'm a noob with the Undo system, so I don't know either if there's also things to consider with it when dealing with arrays
seems like dealing directly with the data would be a good approach if you need to make instances of non-UnityObject classes and you have to do stuff when calling the constructor or you need to modify their data in a specific way
(which seems to be your case)
otherwise, stick to SerializedProperties
@gloomy chasm I mean, as long as you update/apply the SerObject/SetProperty BEFORE modifying the data directly it should be fine, right?
I never mix the two, but technically it shouldn't cause any issues, correct?
public override void OnInspectorGUI()
{
if (GUILayout.Button("Change some stuff"))
{
serializedObject.Update();
// Do some changes to the serialized object
serializedObject.ApplyModifiedProperties();
((MyTargetType)target).SomeMethodThatChangesStuff();
}
}
My knowledge of Unity's internal serialization stuff is kinda shallow, so I tread carefully when making assumptions like this... 😅
Probably Mikilo, Navi or vertx know if this is a very bad idea or if it's fine and dandy 👀
I think so, but really, it just seems like bad practice to me to do that. More points for things to go wrong, and mixing two systems.
This is correct but kind of hacky
good to know
yeah, I mostly handle data through SerializedProperties only
I've only really done that in one case
any particular reason why?
for simplicity's sake? or what
check out EditorGUI/EditorGUILayout.CurveField
idk if you can "clamp" the values out of the box, but shouldn't be too hard
It's for a level debug tool, so it records runs and then groups them under a single parent, once a new level starts it raises an event with the data. I add that to the correct parent then I want to collapse all isExpanded properties of other elements.
So it's manually change normal data, SO.Update, find the correct serializedProperties and then change those
oh I see
I'm working on a quest system. I have a data structure called "stage" which contains a list of "objectives". This objective list has a custom property drawer.
When there is a list of stages, each with its own list of objectives with the custom drawer, the drawer is duplicated for each objective list, rather than giving each objective list its own drawer.
Does anyone know why this is?
@tardy sorrel post the code, easier for people to help
[System.Serializeable]
public class Mission
{
public List<Stage> stages = new List<Stage>();
}
[System.Serializeable]
public class Stage
{
public ObjectiveList objectives = new ObjectiveList();
}
[System.Serializeable]
public class ObjectiveList
{
public List<Objective> objectives = new List<Objective>();
}
[CustomPropertyDrawer(typeof(ObjectiveList))]
public class ObjectListDrawer : PropertyDrawer
{
//OnGUI stuff here.
}
Hm... did this from my phone and it didnt work well.
Basically anytime the ObjectiveListDrawer shows up, it shows the same one multiple times instead of multiple separate drawers.
use backquote (`), not apostrophe (') for codeblocks in Discord
When there is a list of stages, each with its own list of objectives with the custom drawer, the drawer is duplicated for each objective list, rather than giving each objective list its own drawer.
does this happen when you have a single Stage too?
or only when you have a list of Stages?
Sounds like your drawer is incorrect
If it's a single stage then there's only a single ObjectiveList, but that does make me wonder... I should try with multiple ObjectiveLists outside of a list and see what happens.
That's what I think too. But I don't know how nested lists behave with Drawers so idk
@tardy sorrel share your full ObjectListDrawer code so we can check if there's something wrong there
Alright, once I get back to my computer. I figured since I'm not using any static variables or the like, that the lists wouldn't affect each other.
I've cut out some of the noise. Here's the relevant stuff:
[CustomPropertyDrawer(typeof(ReferenceListWrapper), true)]
public class ReferenceListWrapperDrawer<T> : PropertyDrawer where T : class
{
[SerializeField]
ReorderableList list;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (!initialized)
Initialize(property);
if (initialized)
list.DoList(position);
}
protected void Initialize(SerializedProperty property)
{
SerializedProperty spList = property.FindPropertyRelative("_list");
List<SerializedProperty> elements = new List<SerializedProperty>();
for (int i = 0; i < spList.arraySize; ++i)
elements.Add(spList.GetArrayElementAtIndex(i));
list = new ReorderableList(elements, typeof(SerializedProperty), true, true, true, true);
}
}
Here's what it looks like in practice, with ObjectiveListDrawer just being a declaration of a type-specific version of the above.
As you can see, both Objectives lists are drawn identically despite being in separate entries. I'll try a couple of experiments tomorrow when I get time.
Yeah uhh using fields on a propertydrawer is not a good idea
It's cached between different fields
You can try to disable caching but I recently had issues with that
There's some method you can override to disable it
Chances are your reorderable list won't work properly either since it's being recreated
Depending on which Unity you're on, there's an attribute to make a list reorderable and then you can use a normal property drawer
@tardy sorrel Like Navi said, Unity Caches PropertyDrawers, so since you are only initializing the ReorderableList field once, it is using that for all of them. As mentioned, there is a method called CanCachieInspectorGUI that can disable this. Another option would be to store the ReorderableList in like a Dictionary, but since it is just the RL, disabling caching would be the best.
it doesn't allow to assign anything to the fields via clicking and selecting or dragging anything in
@waxen sandal @gloomy chasm Thanks for the insight. I'll see what my options are, then.
This is untested since I just wrote it in the browser, but try this. https://hatebin.com/qkiqoedthm
code generation in unity -- where do I look to use the latest version of unity's built-in code generation for templates?
What do you mean? The script templates are just strings written to a cs file. I assume you are referring to something else?
Sorry about that -- I meant I wanted to make my own codegen templates, but using Unity's code generation tooling, though I can't find any docs about it
The tool they use to generate scripts from Visual Script / DOTS templates and whatnot
Apparently there is one built in -- at least in the newer Unity versions, but I don't know where to look to find it or any docs about it
I don't think it is Visual Studio's T4 generator, but that's all I can find anything about
Ugh... let me try that again.... I've refactored down to this:
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (!propertyInit)
{
PropertyInit(property);
propertyInit = true;
}
if (SingleItemHeight <= 0 && property.FindPropertyRelative("list").arraySize > 0)
{
SingleItemHeight = EditorGUI.GetPropertyHeight(property.FindPropertyRelative("list").GetArrayElementAtIndexOrNull(0)) + 8;
}
// This is always re-updated every event because the undo system cannot undo the "add" method's update of the count.
numberOfItemsInMap = map.Count;
// Keep track of vertical position, with vertical padding.
currentVPosition = position.y + SpaceBefore;
left = position.x;
fullWidth = position.width;
// Dynamic Contents
itemsContent = CreateDynamicContent($"{numberOfItemsInMap} items", "SmallText", out numberOfItemsLabelWidth);
maxPagesContent = CreateDynamicContent($" / {NumberOfPages}", "LabelStyle", out maxPagesLabelWidth);
currentPageContent = CreateDynamicContent($" {pageNumber}", GUI.skin.textField, out currentPageTextWidth);
// Determine if paginated and use the correct drawing method.
if (isPaginated) DrawItems = DrawPaginatedItems;
else DrawItems = DrawAllItems;
// Draw CompositionMap title, total items, pagination controls, add button in a toolbar.
DrawToolbar(property);
NextLine();
// Column Headings
DrawHeader();
NextLine();
// Now draw the list items.
DrawItems(property.FindPropertyRelative("list"));
}
is there a way that I might determine if Unity is in the Avatar configuration inspector? I've heard I might be able to achieve this with reflection, but don't know anything more than that, or what to search for?
There is an easier way, give me a moment
public static bool IsInAvatarConfiguration()
{
Stage currentStage = StageUtility.GetCurrentStage();
if (currentStage != null && !string.IsNullOrEmpty(currentStage.assetPath))
return currentStage.GetType().Name == "AvatarConfigurationStage";
return false;
}```
I'll give that a go
adding using UnityEditor.SceneManagement; still gives compile error for Stage currentStage = StageUtility.GetCurrentStage(); am i using the wrong lib or something? the docs say it uses this one.
that's what i did
Hrm, weird then
i wonder if it's 2021 specific, i'm on 2019
docs don't show GetCurrentStage for 2019 docs
whelp
i'll dig into whether i can use GetCurrentStageHandle perhaps
it probably is private in 2019, you could reflect into it
would have to check whether it's there or not
I think stage handles are useless, but I could be wrong, didn't look that hard
i have no idea what i'm doing tbh
i don't know much about reflection, are you saying I could use it to call the private method?
yes
Though looks like the method didn't even exist
https://github.com/Unity-Technologies/UnityCsReference/blob/2019.4/Editor/Mono/SceneManagement/StageManager/StageUtility.cs
yeah
they changed the API a bunch, so I'm not sure if there's really an easy way of doing it, you just have to poke around and get a value from a property/field/method using reflection
can i use reflection to get the instance from StageUtility perhaps?
or rather implement StageNavigationManager.instance.currentStage;
yeah, if you can figure out what they have changed
as StageNavigationItem isn't a thing any more
so you have to hunt down what's in all that
StageNavigationManager is internal, i don't know if there's a way to find out whats in that
i don't think 2019 implements currentStage
Here's another alternative
public static bool IsInAvatarConfiguration() => ActiveEditorTracker.sharedTracker.activeEditors.Any(editor => editor.target is Avatar);```
that nearly works, however it only returns true when it's in the 2nd inspector, where it only shows the Configure Avatar button
the avatar inspector's kinda busted for me rn so I cannot test it properly
I'm assuming that it's based on the class editor.target is Avatar so will have to find out what class the config is
it's returning true for me when editing the avatar
ie, Avatar, so it'll be something like AvatarConfig
maybe this is another 2020+ difference lol
what function are you calling it in?
shouldn't matter, but I just have an editor window with OnGUI open
i just put it an update, as it didn't work when i made a button
it seems to only return true when i exit the config screen
I'm not really gonna look into it further because it's a 2019 thing and I've provided a lot of avenues to look at
unfortunately, if i want to put something on the asset store it has to be 2019 compatible
i guess i could put in a precompile to check for 2019 and just check for whether the character has the (Clone) suffix
and use the fn you came up with for 2020+
in any case, i'll look into the avenues. thank you for the help
The second method I provided would need a little extra check to make sure it's not just looking at the avatar inspector without having entered it in 2020+ too, but that'd probably be more reflection to figure out the state of that editor
I'm not sure what the deal is with 2019, but you can look at what the editor is when it's in the correct mode, and then construct your query based on that
Hey there. Is this the right channel to ask for help with editor windows? I'm currently trying to make a custom editorwindow and an error is driving me insane 😅
So I have a button in my editor window that just calls a function creating an empty gameobject with the name specified in the textfield above. But every click it creates 2 gameobjects in my scene.
what's the code?
Huh just tried posting it and it deleted the message
any formatting i should know about to post code?
you using '''cs for posting it
ok thanks let me try
failing that use hatebin.com or pastebin.com
Posted it on your behalfcs OnGUI(){ GUILayout.Label("Create new Empty Division"); string test = EditorGUILayout.TextField("Division Name: ", "put name here"); if (GUILayout.Button("New Division")) { CreateNewEmpty(rootLevelObject.transform.position, test); }
private void CreateNewEmpty(Vector3 pos, string name)
{
GameObject temp = Instantiate(new GameObject("===" + name + "==="), pos, Quaternion.identity);
temp.transform.parent = rootLevelObject.transform;
rootLevelObject = temp;
Undo.RegisterCreatedObjectUndo(temp, "");
}```
Ah thanks for posting
the issue is with Instantiate(new GameObject("===" + name + "==="), pos, Quaternion.identity);
Maybe to add to this: I have the same problem with a prefab. Everything I seem to be doing in this EditorWindow happens twice.
So instantiating a prefab instead of new GameObject()
with a PropertyDrawer? Just increase the height
Yup, I know about it, but it adds space after all of the elements
and not in between
and when increasing the height, it increases the height of all my group of fields, and not just one field
you can't easily add inter-space
You have to increase the height, and for the last not increase it
I can't do that since this is the same element being repeted (it's a list)
Trust me, you can do it 🙂
How then? that's my question lol
The hard work here is to define "who is the last element?"
issue is my last element could very much have the same value as an other element in the list
so i can't id it
The "ID" is in the propertyPath
hmm
{
return 25f;
}
This seems to get the job done
Well, that is what I suggested first X)
And then you argued it would add space at the very end
Which is true
By "height" I meant GetPropertyHeight
position = new Rect(position.x, position.y, position.width, position.height + 25f);
something like that
alright then 😄
thx for the help
Do you know any easy way
To get rid of this
within a property drawer?
or do I have to make a custom editor ?
You can't
okay that's what i thought xD
PropertyDrawers are applied at the element-level
not the list-level
unfortunately
It was list-level before Unity 4.2
And then they suddenly changed realizing their "mistake"
So yes you need a custom PropertyDrawer for a "list-container"
It was not supposed to be list-level 🙂
all right 🙂
thx again!
To make it clear, you need a class that contain your list and then draw the elements yourself
Which is a lot of work if you don't know where to look at
hmm yeah indeed i'm not even sure it's worth the effort
might be way easier to make a custom editor
extracting all of the elements of the list
same amount of work, and worse in my opinion
Most of the time PropertyDrawer is more convenient/suitable than Editor
Editor applies at Object-level (GameObject, Component, any asset, etc.)
PropertyDrawer is at field-level
Editor obliges to redraw everything yourself
Which is another amount of work
Not negligeable
but isn't it more convenient to be at object level if you want some really precise layout?
or if you want to juggle with all of the different datas ?
Most of the time you want a precise layout for a field, not a Component
and PropertyDrawer is reusable
and in your case, you want to adapt the list to your taste, not the whole Component
hm yup indeed
The bad point is your case is that it forces you to wrap the list in a container
(in order to make the PropertyDrawer)
so in which case is it better to use custom editor ? To make really heavy editors?
like maybe a branching dialogue editor or something like that?
(sorry i have a lot of questions 😆 )
Yes, heavy editor is where Editor might be more suitable
It's all fine
To give you an idea, I almost never used Editor in my entire tools programmer life
ooch okay
what do you think of plugins such as Odin or UIToolkit (haven't used any of them yet)
I dont use them, first Odin is a gas factory, makes a lot of thing easier, but it has its hands on Editor which in Unity Editor is not "sharable"
And I do most of my stuff myself
Odin has absolutely not advantage to me (including their serializer)
UIT is not mature enough.
On 2020/2021 maybe
But as a publisher I am stuck to their API on 2019
That's all
It's still good stuff, worth the penny I guess
If you have the list properly you can just use a for loop, arrayProp.arraySize, and arrayProp.GetArrayElementAtIndex
oh arraysize works on list too
Yep.
and from now on, you have the necessary information to know if you are on the last element 🙂
indeed ahaha
[System.Serializable]
public abstract class BaseItem
{
[SerializeField] protected int _id;
// other protected values...
// public geters etc...
}
Might be a silly question, but how do I make this class (and derived classes) show up in the inspector? [System.Serializable] and [SerializeField] do nothing. Do I need to make a custom editor?
Can't serialize abstract, and derived classes also need to have System.Serializable. Also Unity can't serialize polymorphic fields unless they have the [SerializeReference] attribute on them.
Thx, adding [SerializeReference] fixed all the problems I had! 😄
Just so you know, you don't need [SerializeField] if the field already has [SerializeReference].
After succeeding in making my drawer, I do think EditorGUI is a painful experience
That's all I wanted to say 😩
It is, if you don't know where you put your feet
Yeah maybe with more time spent on it I'll learn to like it
any way to add buttons without custom editor ?
Use a PropertyDrawer :p
On a fake field
It's one way to do it
Or google it, lot of solutions out there
alright 👌
When I use
string file= "E:/Dev/MyProject/Assets/Data/Data.actproject";
string filepath = EditorUtility.OpenFilePanelWithFilters("Load project", file, FileManager.FileFilters);```
The dialog is opening to the correct directory, but isn't automatically selecting the file that I pass in with file, ie Data.actproject
any ideas?
i don't think this is possible for an open file dialog is it.
I would like to make it more obvious when a field is not assigned. Is it possible to customize the drawer for any object reference? I'd like to draw the default inspector but put a big warning after it, or just tint it red.
You can make a property drawer for a property attribute that you apply to the fields
But not override the default property drawer?
I want to add an attribute too to disable it
So it's opt-out for optional
I assume you could override the drawer for Object, but I'm just not that much a fan of it
Understandably
That doesn't seem to work, just trying it now
using UnityEditor;
using UnityEngine;
namespace Feed.Editor {
[CustomPropertyDrawer(typeof(Object))]
public class ObjectFieldDrawer : PropertyDrawer {
public override void OnGUI(
Rect position, SerializedProperty property,
GUIContent label
) {
EditorGUI.LabelField(position, "FOO!");
// EditorGUI.PropertyField(position, property, label);
}
public override float GetPropertyHeight(
SerializedProperty property, GUIContent label
) {
return base.GetPropertyHeight(property, label);
}
}
}
you would need to
Choose a nicer red and 👌
The red I chose for the same purpose: 🙂
I've debated making my decorator drawer package have a callback that occurs after a property is drawn so you can reset
Unity's default decorators are so useless 😛
Didn't you just tell me that you don't like the idea of overriding the Object property drawer? Or did you use an attribute for this? @visual stag
That's a custom editor/drawer for something specific
Ah, cool. :-) I have no idea what would happen if two drawers are both applicable to the same field, but I don't think I'm likely to customize object fields further.
yeah, that's my worry, I think the more specific one would win, but it's not something I like to test
the reason I don't do it is that it affects all fields not just things I author, so unless it's a raw improvement to the field (like making something not suck) I try not to do it
I think Odin does global changes, but who knows how many edge cases they handle.
yeah, one of the reasons I do not use Odin
I remember chatting to a dude at IGDAM who had written his entire RPG using Odin dictionary inspectors and then discovered that a deep bug had prevented him from building his project.
That scared me off
Nightmare fuel

what is this ?
That's probably related to that quick search plugin
Can someone explain me the differences between these?
- Resources.Load
- AssetDatabase.LoadAssetAtPath
- EditorGUIUtility.Load
They all seem to do the same, and Im not sure when I should use which.
Resources is only in Resources folder
AssetDatabase is in the whole assetdatabase (Assets and Packages generally)
EditorguiUtility is in Assets/Editor Default Resources which also includes files that unity internally has in that directory
Think icons
Resources is also available outside of the editor while the others aren't
So that is the only difference? The location where the assets are?
If that is the case, doesnt "AssetDatabase" make the other 2 redundantly useless?
I'm actually not sure whether AssetDatabase can load those internal icons for example
And Resources is avialable at runtime so that's the difference, no need to use it in editor
So I can use Resources.Load during runtime, but not AssetDatabase?
Runtime being outside the editor (built projects)
But what are the advantages of AssetDatabase, over Resources.Load?
Being able to use it for all assets in your project rather than just in the Resources dir
It kinda seems like there should be a tool can combine both of those...
Aaahhh. I see
They have completely different purposes, there's 0 reason to combine them
Combining htem would only lead to confusion as somethings will work in editor but not in build
Ok. how about EditorGUIUtiliy? What are its pros, in comparasion with Resources and AssetDatabase?
This function will look in Assets/Editor Default Resources/ + path for the resource. If not there, it will try the built-in editor resources by name.
Literally the docs page
@west drum If you are not aware sticking stuff in a Resources folder will force the stuff to be included in your game build. So you don't want to use it for things you don't want in your build.
Literally not what I asked
Yeah, I guess the goal of Resources is to load during Runtime. Not sure what EditorGUIUtillity goal is
can anyone help me? my unity doesn't work and i just need to turn this package into a vrm
Well, Resources.Load is a lot easier to use, so use it if you can (even in the editor). The EditorGUIUtility method can load built in editor resources, other than that I'm not sure of the advantage.
AssetDatabase requires an exact file path to be used, but if you are loading editor only assets, I think it's the best method.
I think you will need to provide more details than that before someone can help you.
can you help me?
Resources is for any alive objects (alive = loaded in memory)
And assets in Resources folders of course
Resources can find Editor resources aswell, like open EditorWindows? Or am I misremembering?
Findobjectsoftypeall does that, but not normal load right?
Yep
Fair, I was comparing "normal" usage
It would have been more "logical" to have FindObject in Object instead of Resources
But I guess I am lacking of the reasons behind
Anyone aware of any assetbundle extractors on osx?
hey all im currently trying to do a command line build of ios but am recieving linker errors from arkit as the unityframework does not include the arkit package
any ideas im kind of blocked on this
would anyone be able to tell me why the MakeRow and Bind callbacks are not being executed here? https://github.com/torbenvanassche/AssetManager/blob/main/Assets/Scripts/InterfaceController.cs
consequence being that nothing is being rendered in the UTK listview 🤔
Shouldn't be needed, but try databaseViwer.Refresh() after setting itemsSource.
I am very close to cracking this damn puzzle xD
@steady crest Do you have the list style set to flex (Or a set height or something like that)?
If not, then that is your problem.
height is set to 100%, width to 80%
Open the UIT debugger and see if the ListView is actually taking up that room.
I did just now, its taking up the room, but its not populating any content inside the view
after attempting to load the content, it looks like this
Can you show what it looks like in the inspector when you hover over the ListView #DataContainer in the debugger?
@gloomy chasm viewport selected****
selecting the listview results in the same image
@steady crest Just for testing, can you remove any styling you have done if any to child elements of ListView #DataContainer, and set it's height to like 200px.
And if nothing shows up, set the width to 200px as well (just to make sure)
all the content inside the ListView is generated dynamically with inline styling. so there isnt any styling on them in the editor
(I also cant modify the styling of anything under the topmost component of the ListView)
Yes, I just meant any styling that you your self may have done.
Oh you 1000% can, just gotta do it through code as well(unless something changed in whatever version you are using).
ah yes, but im not modifying it in my code either. I mostly meant that you cant do it by accident in the editor
Ah, right, right. So did you set the ListView height and width?
its was set to 80% width 100% height, I just set everything to the default settings and still see nothing
No, I specifically mean to set the height at 200px (or more)
(tried with a 400px width as well to be sure, didnt make a difference)
hard setting the values in px doesnt appear to resolve it
@steady crest Is this runtime UI....?
well, yes. but for good measure I tried the same approach in the editor framework and it also doesnt work
@steady crest When you are testing to see if the items show up, are you by chance in playmode?
I am for the runtime version yes
@steady crest What I would say is to make a simple ListView all on it's own in its own editor window. Get that to work, then work backwards until you get this to work.
hmm, thats preobably a good idea
try to isolate the problem by downscaling
instead of repeatedly throwing myself at it until I figure out whats wrong
Remember that you will need to set the height of the list view and/or set flex grow.
@steady crest Btw for RegisterValueChangeCallback you can just do ```cs
sizeSlider.RegisterValueChangeCallback(evt =>
{
// Your code to run like normal here..
});
oh y, thats also true, Rider autocomplete xD
the height is specified at 100% of the parent, requesting that data at runtime gives me the correct value for that
Im just not sure why those callbacks arent firing, tho I also dont rly know how this component works underneath
I am almost 100% sure that the problem is height of the ListView. Try checking the debugger. The little boxes on the top right, can you select the ListView in the debugger, and show be the boxes on the top right?
well hello ther
im replacing the container
assigning new one, and not updating the ref
hmm
I'm having an issue with getting a list of classes (custom property drawers) to all expand (SerializedProperty.isExpanded = true) on a button press. When you click on them via an EditorGUI.Foldout, they expand fine, but iterating through the list from a custom inspector yields strange results:
What it does:
What it should do:
Code for expanding from a list:
@gloomy chasm ```cs
_dynamicList.Clear();
_dynamicList.AddRange(textures.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / _amountPerRow)
.Select(x => x.Select(v => v.Value).ToList())
.ToList());
databaseViewer.Refresh();
clearing the list instead of reassigning it
also, in the bind function giving it a placeholder texture until the async resolves and i get the actual texture
Did you set the content container to flex @steady crest
it's a different component than the list view
I have a working editor-time example, the only difference i found from editor<->runtime was the content container behaved differently
https://github.com/CoffeeVampir3/Graphify/blob/main/EditorOnly/Blackboard/NavigationBlackboard.cs#L33
Can someone please confirm me this? To submit a package to the asset store, it must support the UNDO functionality, otherwise it gets rejected?
Never heard that before but you should really do it
I read this in the submitting guidelines
So it quite shocked me... and I was wondering if it was a requirement to pass approval, or not
Unless you're doing massive structural changes it's not hard to support undo, so I would not really be shocked
I guess I will do it the brute way, and just store on every step my whole serialized object...
What's wrong with one of the multiple APIs Unity has?
There should not be a reason to write your own.
No, I will use them. What I mean is that, instead of making optimized operation records like "Move node to X,Y", or "Change property to XX", it will be easier to just make a single one "Update Object" with the whole object
It will not be very memory efficient, but my objects arent big anyway...
I don't really understand why, but I'm not sure I care to find out
You dont understand why what?
Why you wouldn't just record the steps. Recording complete objects in the undo system I've only seen done in a graph view thing where their entire object was just JSON
Unless your entire structure is serialized to Json, that's beside the point lol
I guess doing that would be simpler, than creating one command for every single possible operation
I was looking at the documentation of Undo to implement this:
https://docs.unity3d.com/ScriptReference/Undo.html?_ga=2.265815623.972428491.1618305783-260942605.1613898945
But it is kinda confusing to follow, just from the API docs. Does anyone know any article/video tutorial, that explains the basic principles of this API?
Are you using SetDirty to dirty your objects? Because if so, that's not how you're meant to do it, and is where you have gone wrong. It's the last resort for recording modifications
I dont set the asset dirty, until the user confirms that he wants to save the changes to the asset instance
You still have to mark it as dirty to get modifications to persist though, no?
Otherwise it didn't know anything changed
sure
SerializedObject and Undo are preferred, and they both record undo states.
Calling Undo.RecordObject on the UnityEngine.Object you're working with before you make a modification is all you need to do
But I have to manage the Undo callback somehow, no?
No
So I just have to set the Record, and Unity does all the magic?
You may have to tell it to repaint the graph in your case though because it's UIElements
yeah, so I will need some kind of callback, no?
Maybe this?
Undo.undoRedoPerformed += () => { Debug.Log("Repaint...?"); };
Yeh, rebuild the graph in there and that should hopefully do it. The persistence of UIElements is the biggest barrier to undo imo. If you're doing IMGUI editor stuff you don't even need to think to support it
But that will execute, even if the Undo operation has nothing to do with my extension, no?
Sure, but that doesn't really impact much
Ok, I will experiment a little.
I guess I could download some asset from the asset store, and see how they do it...
There should be several GraphView projects in Unity's repos too.
It would be optimal if it uses the GraphView API, of course. Even though most I have seen make their own Graph system
Anyone has a recommendation for a really simple one, that wont have very complex code? 😄
nvm, worked it out.
Hi! Does anyone know if there is a way to set the macOS CPU architecture through a script (I'm attempting to automate my builds)? Normally this setting is found in the build settings window... but I cannot find anything about accessing it through script. Specifically I want to set it to "Intel 64-bit"
In am trying to get some DragAndDrop working with a custom list treeview in UIT, but I have a problem where my MouseUpEvent is not being called after clicking on a foldout toggle because it is being consumed by it. Any ideas how to get around this?
If you're working off one asset you can literally have all your nodes be [SerializeReference] and just save the undo state, then just redraw the graph every time undo gets called. If that's not the case though, you basically have to hack the entire thing together. @west drum
I'd recommend setting up the graph asset in a simpler way so you can leverage the built-in undo system, as if you're undoing more than one asset it absolutely doesn't work.
Here's my hacked impl for reference
https://github.com/CoffeeVampir3/Graphify/blob/main/EditorOnly/BaseGraph/GraphifyView.cs#L753
@civic river Yeah, that is that I am going to have to do. But I am gonna have to change a lot of how the graph works, and capture a lot of new events 😦
Does anyone know, in GraphView API, what Callback I should register to, to find out if a node has been changed?
I have tried GeometryChanged, but that is fire in every single frame, which is not what I want. Only when the node is dropped.
I also tried MouseUp, but for some reason that event is not firing... even though MouseDown does work :/
There is the this.graphChanged callback 😉 (At least in 2019.3)
SceneView.RepaintAll() However, I think something else may be happening there maybe? How are you going about putting that text there?
Hello, I have question about editor scripting, property drawers...
I'm trying to make a property drawer for a custom class I made, I want to use the EditorGUI.Foldout but I don't understand how to go down a line after the foldout so I tried to use EditorGUILayout.Foldout but it draws the foldout and all the stuff at the bottom of the component.
https://hatebin.com/jmqyzebyll
as you see here
You shouldn't use GUILayout in property drawers
You need to manually calculate the rects you want
Ahhh
Also you need the GetPropertyHeight method
Thank you very much
Hello, I'm trying to understand how to draw stuff on different lines but it doesn't work
https://hatebin.com/umowzhmgrh
it looks like when I open the foldout it gives the middle position instead of the top left
How can I solve that?
is there a way to specify which process i want to attach to in the vscode debugger, instead of having to pick from a list?
https://hatebin.com/wjurqodqji
I found how to fix the issue but it's not perfect, I don't understand how to draw down a line perfectly
as you see the spacing between the lines is not perfect
What you are looking for is EditorGUIUtility.standaredVerticalSpacing.
ahh thank you
I have a problem, I have a boolean that when set to true, the editor window is constrained to a certain size. When you first open the window, its set to false, and you can scale the window to any size. When set to true, it constraints, but once its set back to false, it's still constrained, why?
wait, nevermind, I think I fixed it.
yup, fixed it. False Alarm
Has anyone ever written a script which combines the functionality of EditorApplication.playModeStateChanged and IPreprocessBuildWithReport? It seems like the former requires the class to be static, but then it can't implement the interface. Is there perhaps a similar interface for the play mode state changed event?
I could always just write little classes for each that just poke a common processor but I'm wondering if there is a cleaner solution.
is there placeholder text for TextField from UIElements?
Nope, need to do it your self unfortunately.
SerializedObject of Sprite gives ArgumentException
but Sprite will be sometimes null/none in code
and add if(spr !=null) will just hide it without giving ability to change it
any ideas how to make SerializedObject out of Sprite?
Context?
displaying Sprite field in Editor Window that using UIElements
it needs to be displayed by ObjectField that need SerializableObject
You sure you need a SO and not a serializedproperty?
anyway to have a update-like event in edit mode?
sure, depends on what object you want to have it on
problem with execute always is that Update is called only when the scene is changed
EditorWindow update would mean that i have to make a custom editor window in order for an update to work?
you can use this function to force Unity to always update
https://docs.unity3d.com/ScriptReference/EditorApplication.QueuePlayerLoopUpdate.html
basically in your Update function of your ExecuteAlways script you just execute QueuePlayerLoopUpdate at the end of it, so it triggers the Update again
this is fine for a personal project, but otherwise I'd recommend making a custom editor
yeah this is for testing mainly ^^
okay this seemed to do the trick - ish
what's really odd it it only seemed to call it 16 times
then stopped
well guess it doesn't work anymore
🤷♂️
guess you can try this https://forum.unity.com/threads/solved-how-to-force-update-in-edit-mode.561436/#post-5110952
it works more or less, but it's only called when i move the mouse or do something
not really consistant it seems?
thanks for trying to help me btw
well yeah the cleanest way is using an Editor
I used OnGUI before, seemed pretty straight forward. But now I need to show a simple label and I just can't get it to work!
I am using 2020.3.1.
My script inherits from a class that inherits from MonoBehavior. I tried the following code both on the current script and the inheriting one.
private void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button"))
{
print("You clicked the button!");
}
}
This is example from the docs.
And it doesn't show. No matter what.
I tried all the aspect settings as well.
Hey guys, does anyone know of how to get an actual script reference from a VolumeComponentEditor?
For context, trying to work in a Transform as a parameter on my custom post-process volume and there seems to be no builtin support for a transform parameter - tried using ObjectParameter<Transform> but that nulls out immediately
public class TextFieldWithPlaceholder : TextField
{
Label placeholder;
public TextFieldWithPlaceholder(string placeholderText)
{
placeholder = new Label(placeholderText);
this.Q("unity-text-input").contentContainer.Add(placeholder);
this.RegisterValueChangedCallback(x =>
{
placeholder.visible = x.newValue.Length < 1;
});
placeholder.name = "placeholder";
}
public override void SetValueWithoutNotify(string newValue)
{
base.SetValueWithoutNotify(newValue);
if (placeholder != null)
{
placeholder.visible = newValue.Length < 1;
}
}
}
simple and dirty TextFieldWithPlaceholder
Howdy! Do you folks know an editor extension that shows reference as lines? Overlay on top of hierarchy
I am drawing some GUILayout.Button and I want to use them like toggles. I have everything setup, I just need a quick way of setting the GUIStyle.active state to show them depressed.
Looking at the GUIStyleState class, it has a backgroundImage property, do I really need to make my own image via code and assign it there? Or are there already preset ones I can access through one of the GUI or GUIEditor classes?
Maybe use Toggle with button style instead of Button with custom styles
Bingo! Thanks man!
I just started using 2020.4. What did they do to the UI Tookit debugger!? Why are the properties alphabetical?! This is horrible to use! It went from being a very convenient, and easy to use way to debug and mess around with styles, to being legitimately frustrating to use!
Don't you like having every border color be in a completely random seperate place? x.x
Is there a way I can add a custom field to the texture importer with a custom script?
CustomEditor can target textureimporters iirc
Thanks!
Hey, i have this error Library\PackageCache\com.unity.timeline@1.5.4\Runtime\Animation\AnimationPreviewUpdateCallback.cs(15,14): error CS0246: The type or namespace name 'IAnimationWindowPreview' could not be found (are you missing a using directive or an assembly reference?) been looking into it for ages but cant seem to get anywhere, i am working on a collaborate with a friend and it seems to be working fine his end but not the same for me and not a clue why, any help is much appreciated
Not the right channel but try deleting the package cache in appdata and in your library
oh my apologies, any idea which channel i should go to? also tried what you suggested and the errors still there
#archived-code-general or forums
thankyou
Forums is your best bet tbh
ive found a forum which literally talks about this but there hasnt been any answer for it in 8 months haha
Is anyone aware of any information on building low level uielement controls?
I need to implement a rich text control
Like what are you looking for specifically?
Api docs ,guides, anything really. I've found little to no information on low level custom controls that need to control drawing
You don't handle drawing your self, ever. It is always done via styles.
Generally speaking yes, but this is a case where that isn't enough
Well what is id that you want control over that can't be done with styles?
I need to have text rendering with the ability to style words and provide words and strings of words with interaction while maintaining layout control
Right now the only way I can acco.plish this completely is by making every word a label and its hell on the layout engine
So I need to go lower level
Best is to go look at the source
Ah, well at least in 2020.1+ that is done with internal stuff
there's some things there last I checked
The methods that appear responsible are overrideable but I was hoping to find some documentation a little better than source
I already made some naive attempts that way and got nowhere
That is what is used my UIElements to generate all of the text
Man thats right I have to maintain 2 versions of this solution
I wish the api didn't massively change
They're pulling tmp into uitk soon right?
In 2020 it looks like it already supports rich text just fyi.
Uhg that might mean 3 versions
Oh really?
Then the newer version might actually be fairly easy
I hope so, that would mean I only have to build legacy support
For context I have built a. Markdown renderer for uitk based upon markdig
In case it helps here is the actual VisualElement that is responsible for all text https://github.com/Unity-Technologies/UnityCsReference/blob/master/External/MirroredPackageSources/com.unity.ui/Core/TextElement.cs
Should be TextureImporter not TextureImporterSettings
Do you know what the rich text tenement is that handles this?
You make me afraid to click that link lol
(706 is where it actually doe stuff with rich text)
Wow that method is gigantic
Only like 2000 lines...
Maybe I won't take inspiration from unity...
The whole file is 5660 lines....
Well they are using TextCore which is basically the core of TMP.
I wonder if ill be able to do that In 2018, I hope I can just use their rich text in 2020+
Little of this probably translates well to 2018
If you want to do it in 2018 I think your best bet is to use IMGUI for it
Nope, I refuse
Why? The only other real option is to do a label per word...
I will never go back, I've finally setup a workflwo that let's me use uitk wherever I need
I can still setup a low level renderer, it will just be a lot of work
👋 Hey all, I've been trying out writing an editor extension with UI Toolkit for the first time and I'm running into this error
error CS1061: 'Texture2D' does not contain a definition for 'texture' and no accessible extension method 'texture' accepting a first argument of type 'Texture2D' could be found (are you missing a using directive or an assembly reference?)
Is there some other syntax for texture? I have a feeling I just have some inconsistencies between my uxml, uss, and cs scripts but I can't find anything.
The included samples in editor also aren't consistent with what I'm seeing in this tutorial.
I was following along and then adapting this official Unity tutorial:
https://youtu.be/mTjYA3gC1hA
But is that really worth it for a feature that is already present in new versions? You could spend days on it, or just spend like 30 minutes. Sure it is not as nice, but you won't even use it in 2020, and it will be more stable.
It would mean rewriting my entire markdown renderer
So itd be the same cost, and the result would be a worse, less controllable, less extensible result
Would need to see the code.
Downstream projects would be exceptionally limited by the choice
How so? Are you doing some rendering stuff your self?
And there is already an imgui markdown renderer, no reason to solve the same problem
Its a direct implementation
Is RenderBase a class from Unity?
I believe that is a markdig class
yes, it is
this is the method I'm trying to get rid of, which causes the layout engine to cry when you resize windows and what not
its really only a problem in the context of layout updates, otherwise it performs quite well. This method does cause it to take a lot longer than is ideal to parse the document.
Would a GeometryChangedEvent help with that?
Or the OnPanelAttachEvent?
I'm not capable of answering that WRT to geometrychanged
the parsing only occurs once though, the existence of 5000 labels in a moderately sized document however is the issue
my working assumption is if that can become one control you loose all that overhead
I am confused, why do you have 5000 labels in a document? Is it because you are doing 1 word == 1 label?
thats correct
its the only way I could find to get the layouting to work correctly and consistently, and its far far far from ideal
it introduces a number of gotchas
Wouldn't just doing this basically be a drop in replacement for having a label per word?
public class RichLabel : VisualElement, ITextElement
{
public string text { get; set; }
public RichLabel()
{
var container = new IMGUIContainer(() => GUILayout.Label(text));
Add(container);
}
}
is there an easy way in all versions of UITK to propogate USS styles to it?
The only styles that wouldn't be applied would be text specific styles.
This is my cs script and I have my stylesheet hatebin: https://hatebin.com/yokgqwbniv
I will add my uxml here because hatebin doesn't like it for some reason
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:engine="UnityEngine.UIElements"
xmlns:editor="UnityEditor.UIElements"
xsi:noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd"
>
<engine:ListView name="time-keys-list"/>
<engine:Box name="light-profile">
<engine:Image name="preview"/>
<engine:ScrollView name ="light-profile-info-scroll">
<engine:Box name="light-profile-info"/>
</engine:ScrollView>
</engine:Box>
</engine:UXML>
I'd have to translate the rich text
No, GUILayout.Label already handles richtext
yeah, but it has a format
which isn't markdown
So I'd need to modify the text to support that
thats not a big deal
Yeah, exactly
You wouldn't have to modify anything...
HTML != markdown?
I'm not sure why you think there is no translation that needs to occur, but it definitely needs to occur
Ah, sorry I misread.
Normally if you double click the error it will take you to the line causing the error. Does it for you?
so this is in theory a viable approach, its probably a better approach than the one I'm using as it could incur fewer issues. the question is can I have link tags. I think the answer to this is no, which means I'm back to square 1
link tags?
"hyperlinks"
I use quotes because my MD implementation actually implements extensible Scheme support
I'm honestly guessing on this, but have you considered having the paramter for LoadLightProfileImage be a Texture2d instead of a Texture? I don't think it should make a difference, but maybe it does
sorry yes
the error has to do with the use of texture on lines 70 and 73
here I've numbered it out
59 --- while (lightProfileProperty.NextVisible(false))
60 --- {
... skip to later
67 ---
68 --- if (lightProfileProperty.name == "lightProfileImage")
69 --- {
70 --- prop.RegisterCallback<ChangeEvent<UnityEngine.Object>>((changeEvt) => LoadLightProfileImage(lightProfile.lightProfileImage.texture));
71 --- }
72 --- }
73 --- LoadLightProfileImage(lightProfile.lightProfileImage.texture);
tried that already and it's the same error
Texture2D does not contain a definition for that either
The problem is with LoadLightProfileImage(lightProfile.lightProfileImage.texture);
IS this a compile time or runtime exception?
I assume that lightProfileImage is in fact a Texture
yeah
So you are trying to get a texture from a Texture
I'd expect that its an Image
Following along with the video and no errors were thrown
when they do it
let me grab timestamp
Show the class for lightProfile
If It were me, what I would personally do is assume I didn't copy somethign correctly and rewatch the video, checking each thing he goes over in my code and do my best to avoid making an assumption that my stuff is the same
Also may want to verify you're working against the same version of unity, since that could make all the difference
did all that already
I changed the name of the original script to LightProfileData.cs since it seemed like that was was it needed to reference. I remember having this naming earlier and no error being thrown. It is a scriptable object
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FG
{
[CreateAssetMenuAttribute(fileName="New_LightProfileData", menuName = "Light Profile")]
public class LightProfileData : ScriptableObject
{
public Texture2D lightProfileImage;
public Vector2 timeKey;
public AnimationCurve blendCurve;
public Vector3 lightRotation;
public Color lightColor;
public float lightIntensity;
public float indirectMultiplier;
}
}
You're right Mech
See, look lightProfileImage is a texture...
so just removing .texture should be all you need to do
yes I know it is a texture - that's the naming used in the Unity video where they access the texture as an image?
why is that? curious
lightProfileImage is a texture already
you're trying to access a property that isn't defined on the type
which is why I was asking if the error was compile time or runtime
I think you are getting confused. There is a UnityEngine.UIElements.Image which is a UI VisualElement for displaying a texture and there is UnityEngine.Texture, which is a representation of a texture file, like a .png.
I'd suggest renaming lightProfileImage to lightProfileTexture to clarify the code a bit
even though the uxml is <engine:Image />?
unrelated the Image is a UIElement, which renders a piece of graphics, provided to it in the form of a Texture2D
I thought they had to match
Look at the xml xmlns:engine="UnityEngine.UIElements" So <engine:Image /> is the same as <UnityEngine.UIElements:Image />
but all 2d images in Unity are a Texture2D at some level
On a side note, in general unity doesn't use any magic naming where names need to match
the single exception I can think of is the value you place inside binding-path in UXML, where the value should match the path to a property (this might be slightly inaccurate)
I assumed it was type matching
ah nope
these are two different types which solve 2 different problems
Texture2D solves the problem of managing 2d graphics assets, and providing a common interface to interpret 2d graphics assets
Image solves the problem of displaying those kinds of assets on screen in a stylable control
ah okay. Right, I have to think about this like css. Are there any display types in uxml that just aren't compatible (won't display) whatever properties properly?
I'm not quite sure what your asking, the question doesn't provoke any thoughts about uss/uxml compatibility issues
for example wouldn't I get an error if I tried to display a Texture2D within a text field?
If you found some way to try and cause that to happen sure, but I don't see any way that you could cause that to happen without causing a Compile time error
okay so it would cause a compile error
which I believe is what you ran into, this is a fundamental programming issue however, your syntax was invalid
is a type mismatch != invalid syntax?
you didn't encounter a type mismatch
right that's what I ran into here.
Maybe it's just semantics but I thought if you tried to display a type in a way that will cause a compile error then that is a type mismatch between whatever variable and the USS/UXML field
I thought the UXML and USS define the field I am displaying
I moved on from my issue. I'm talking about generally, I know what happened with my issue now thanks to you two
No I understand what happened with my code, I then pivoted to asking a more generalized question but didn't make that clear enough 😅
the essence of my question is closer to "How do I know what will cause a compile error with this syntax?" Learning this has been pretty discombobulating
Nothing you do in UXML or USS will cause a compile error.
Because compile errors only happen when compiling C# code.
Wait so what do you call the errors that I got?
I said "compile error" because after reading Twiner's message I thought that was the only type of error that could occur from trying to display something incorrectly would be a compile error
Sorry 😓
I know that's not what my issue was - I wasn't talking about the problem I encountered anymore
This what Twiner was talking about. You don't understand what the error actually was. I am not trying to be mean or harsh at all, but going and learning some more c# would be very good.
public class ClassA
{
public bool foo;
}
public class ClassB
{
public void RunTest()
{
ClassA instanceA = new ClassA();
instanceA.bar = 5;
}
}
This will give you the exact same error.
The problem is that you are trying to get something called bar from ClassA. But ClassA doesn't have anything called bar.
Anymore on this topic should be moved to #💻┃code-beginner since it has nothing to do with extending the editor.
No sorry I understand my issue was purely a c# issue. I moved on from that. My questions were trying to figure out if I can cause an error based on how my USS/UXML is written.
That's all
My more general questions aren't related to the issue I encountered
I gave the example of displaying a texture within a text field as an example I assumed would cause an error (because you would never try to display a texture in a text field)
Are you talking about from within UXML? Or from C#?
You define the field to display within UXML right?
Then you write the structure of the editor extension in C#?
or is UXML only associated with USS?
So this was close to my understanding based on the documentation prior to this
UXML - template that defines the logical structure of the user interface
↓
C# - load template to build interface
USS - determines styling of each VisualElement in C# script
If I have something wrong with my UXML or USS it won't throw an error - it just won't look how I intended?
If something is wrong with one of your USS or UXML files I think unity will give you an error or warning. But that is a different type of message that a error from C#.
Okay 👌 . Sorry for being a bit of a headache. I typically write more shader code than C# so apologies for mixing up some terms on different types of errors
hey all anyone here have experience turning on arkit using the unity-xr-plugin-managment api?
Can you set UI elements picking mode via USS?
Only in UXML afaik
pickingMode = PickingMode.Ignore;
scrollView.pickingMode = PickingMode.Ignore;
scrollView.contentContainer.pickingMode = PickingMode.Ignore;
This feels really bad lol, but thanks vertx
I hated it too. The fact that tons of things are just pickable by default without having any behaviour is also annoying to me. I just mutter "better than UGUI" to make myself feel better.
Aye, it's quirky but mostly makes up for it by not being UGUI 🤣
I'm trying to draw labels in the sceneview to help with some design/debug stuff. For some reason the labels tend to appear BEHIND the objects. Is there any way to always draw text on top/last in the scene view?
Would like the "TEST" label to appear in front
hello is there any specific extension that shows this? i am fairly new with vs and unity and i see everyone has this
Fellas, does someone know how to reload the asset from the persisted file? I have tried AssetDatabase.Import but I keep having the same values, which are different to the ones in disk...
This kinda works... but only if I execute it twice. Not sure why...
Destroy the in memory instance and recreate?
@waxen sandal How to do that?
What are you actually doing, how did the file on disk change while the in memory one is different?
Are you editing the file outside of Unity?
Just override the variable with a new instance from LoadAsset?
How and where are you drawing it?
@gloomy chasm Drawing the labels in OnDrawGizmos()
Basically a check to see if the object is visible via simple culling (world -> screen pos).. then using GUI.Label() (also tried using Handles.Label). Feeding the position of the object in question.
hey anyone here have success in adding arkit within a ci/cd?
You may have more success asking in #🤯┃augmented-reality maybe. If not, then try the forums. 🙂
Is there a way in UITK to save values when the editor reloads? Like expanded states and the such?
Hmm... I don't quite get it. So like what persist when using it...?
Man, I am going to have look at the source how builtin controls use it and also make a test window simply to test how it works... :/
I will ping you with my results. 🙂
@severe python Welp... You can't add custom serialized data... -_-
It does save serialized fields. However it seems you need to call the internal method SaveViewData(). On there is an internal method OnViewDataReady() which can be overridden which I think is a way to move elements around and stuff based on the values that have been saved.
Also worth noting that ViewDataKey does not apply recursively.
What do you mean?
Ah, but that should have the exact same result as setting the viewDataKey property in C#
I'm writing code for window within the Scene view.
Everything is going along great. But there is an annoying thing about it is when I click anywhere inside the window that is not an input element, as a result it clicks "through" the window and deselect the object in the hierarchy.
Is there an option I can use to have the clicks stop at the window and not go through?
Oh nevermind, I figured it out by sheer accident lol. Just slap a GUI.DrawWindow() at the end of the WindowFunc parameter of GUILayout.Window.
entering playmode even in empty scene is taking long time how to fix this
Close windows
Looking through the documentation and I'm having trouble finding what USS comment syntax is. I tried the CSS /* comment */ but that didn't work. anyone know?
also is there any way to get syntax highlighting for USS and UXML in vscode?
turns out that the UXML generated by UI Builder is initially seen as plain text and not uxml. if you edit the file extension, then change it back to uxml, syntax highlighting will appear
Sounds like an IDE issue, should report a bug
No one asked a question in this channel today, what is happening? Did they all become gurus? 😄
No, you just spoke too soon 😛
This should fire the event right...?
var basicEvt = new Event()
{
delta = new Vector2(0, 100),
type = EventType.ScrollWheel
};
using (WheelEvent wheelEvent = WheelEvent.GetPooled(basicEvt))
{
list.Q<ScrollView>().SendEvent(wheelEvent);
}
It is not triggering the list.Q<ScrollView>().verticalScroller.valueChanged event.
I'm trying to make a card editor like in unity's example. So far I got the list view working where i can select scriptable objects. Now I want to display the sprite of that object in the custom editor. In Unity's video they query for an "Image" and simply apply the texture there, however there is no way for me to add in an image for the UI builder.
No problem, I can just use a visual element and set the background image of that to achieve the same effect. However, I can't seem to access this through C#? I went through the API for visual elements and didn't find anything on this. If anyone could tell me how to set the background image of a visual element through C# that would be great!
Alright I found it, just use a visual element and access the style, feels a bit dirty but it works
private void LoadCardImage(Sprite sprite)
{
VisualElement cardImage = rootVisualElement.Q<VisualElement>("card-image");
cardImage.style.backgroundImage = new StyleBackground(sprite);
}
I know there is implicit conversions for most style types, such as int element.style.width = 250. I know Texture can be implicitly converted to backgroundImage, so I think Sprite should be able to as well.
My editor adds a custom component to the game object, however unity doesn't detect this as an actual change, so when Unity changes to a different scene, ie like the avatar inspector, it doesn't display a message asking for a save to the current scene. Is there a way that I can cause unity to register the change and prompt with the save dialog?
the docs describe EditorApplication.SaveScene however this is Obsolete, has this been replaced with something else perhaps?
Type : public sealed class UnityEditor.SceneManagement.EditorSceneManager
5.3.0f4 ⟩ 2021.2.0a15
Unity Doc
Method : public static SaveScene()
5.3.0f4 ⟩ 2021.2.0a15
Unity Doc
GitHub Source
I've also tried that, however it seems to do nothing, no dialog shows up and neither is the scene saved
When you apply a change to a scene. If the * does not appear
it means Unity did not see it
Just dirty it
(the scene)
thank you, that works great.
once I mark the scene dirty, Is it really necessary to manually call SaveCurrentModifiedScenesIfUserWantsTo, as Unity asks that anyway if the scene is changed.
or perhaps, do you think I should call the save dialog when my editor adds the component
You should leave it to the user to save the project/scene
i guess i'll get feedback if people don't like that it doesn't prompt to save immediately when the component is added
when the editor is closed, it removes the component, would that be a just cause to prompt a save dialog perhaps?
the component isn't a runtime component
Unity alraedy prompt the user if a scene is invalid
You add a MB that is not suppose to be at runtime?
MB?
MonoBehaviour
of course
i'm adding a component, so that I may draw gizmo's on the game object
but it's an editor only editor, not meant for runtime
is there anything wrong with that?
i also don't know of any other way to draw gizmo overlay on a gameobject
plus, adding a component allows me to uniquely identify the scene instance of the game object
a game object is instanced each time unity loads a scene, so i can't rely on GetInstanceID. someone mentioned a github repo that allowed gameobjects to be uniquely reference, however it does this by adding a component and stores an id ref as a variable in the component
Why not an editor with OnSceneGUI?
I think i tried that, but can't remember why i went for a MB with gizmos.
I'm wanting to draw basically lines and either GreeMoveHandle or Sphere's, is they all possible in OnSceneGUI?
are Handles selectable by the user in the scene editor window?
Yes
however, I think I'd still have to add a component to the gameobject if only for being able to reference the same go when the scene changes
Thank you for the assistance
I'm using an EditorWindow which doesn't have OnSceneGUI(), is there an equivalent for use in an EditorWindow?
SceneView.onSceneView
Anyone use Rider here? It keeps doing this to me:
If I select that first fix, the errors all go away for awhile. But it adds nothing to the file because UnityEditor is already imported. A little while later the errors will reappear and repeat. Unity never has any complaints about the script, so I'm not sure what its issue is
I have not seen that before 🤷
Darn, I though you were actually most likely to know 🙂
It's only a mild irritation so I guess I'll live with it
haha
(This error does not hurt me)
I have a feeling it's got something to do with the assemblies being different for an editor script, but I don't have enough experience to know what to do
Yeah, i get the IDE error thing semi-regularly.
Although about half of them are "Your Plastic Repo is busy, try again in a moment" if it polls while Unity is polling.
Just make sure the Rider package is up to date in UPM... uh...
crying might fix it 🤷
Yeah! So, I figured out that my "Unity is hanging when doing domain reloads" was actually Rider's doing. It only happened when I was attached to Unity with it. If I detached before a domain reload was needed it never hung.
And then I noticed yesterday that while teh latest 'Verified' version of the Rider plugin was like, 2.something, there's actually been like a dozen updates since then and it's at like, 3.something now. They're just not "Verified" so it wasn't offering them automatically
when debugging 2019.4 I had regular hangs, mostly when I left Unity and Rider to do something else for a bit
SO FAR I haven't had a problem after upgrading the plugin
If the "Verified" badge means "This might be so old that it's broken" I don't know what its value is supposed to be 😛
Is it possible to add an animation preview to the "Select AnimationClip" window like in the image? Posted on the Unity forum as well as a feature request https://forum.unity.com/threads/please-add-animation-previews-to-the-select-animationclip-window.1101244/
So, I have this "Wizard" script to create and initially configure a new thing in my scene. It does this from a Prefab which I made for this purpose, and said prefab will never itself be used at runtime, only by this editor script thing. Is there an editor-only way for me to locate a reference to the prefab so I don't need to drag it to my wizard every time? Most solutions are talking about sticking it in Resources, and I don't want or need to do that I don't think.
Perfect!
how do i draw a selectable handle within the scene view?
for an editorwindow inspector
any links someone can point me to, so i can look into perhaps?
There's an event in SceneView that oyu can subscribe toand then use handles
How to make GraphElement Copyable?
the whole logic is there
but it is marked as internal
so i can't test it or fix it
doesn't let me check myself if data i correct or if i can fix it
any ideas how to make it copyable or give me ability to do it manually?
omg this is a channel
Does ANYONE know how to make the inspector have like, colored backgrounds in it
Yes, but you need to be more specific on what you are actually wanting to do because there are a number of different ways to do it depending on what you are trying to achieve exactly.
i have an example let me find the pic real quick
the red green blue areas, basically, i may have other components inside i'm not trying to replicate this specificly
It is either GUI.color or GUI.backgroundColor I don't remember which.
You can also do EditorGUI.DrawRect
i tried the draw rect, failed
i'm actaully extremely new at the editor extensions, so i'm not even sure i'm doing it correctly, do all editor extensions need to be in root assets/Editor/
It should work, you probably did something wrong which is not too hard to do if you are new 🙂
not new a unity or on gui though, just editor stuff, but i just released an asset that alot of people are seeming to want, and i'm trying me best to make it look as good as it performs ha
No, they don't. They just need to be in a folder called Editor. You can have multiple folders called Editor and they can be anywhere in your project.
i searched far and wide across google and github and i couldn't find a single set of sauce that demonstrated this in any basic sort of way, which is how i would normally figure this stuff out
maybe you editor buff's know of some resources?
thank you thats good, since i can contain it to my assets folder
You can check the pinned messages in this channel. Also the docs are pretty good on some of the higher level stuff.
ill take a look, thank you, there's gotta like, be a section on this though right? that was my issue, i found bits and pieces of documentaion on setting background color, i would hope using the gui.backgroundColor would work, because using drawRect is kinda hacky (i think)
in the most simplistic implementation, if i am deriving from : Editor, this would work ? ```
public override void OnInspectorGUI()
{
GUI.backgroundColor = Color.green;
//My custom controls here? or can i set GUI background color and then let unity handle the rest?
}```
Yes, you can do base.OnInspectorGUI() after GUI.backgroundColor = Color.green, or do your own controls. Or both.
ah, gotcha ha, sorry i totally forgot about overriding and calling base there!
No problem, I figured as much.
wish me luck, studies have shown assets with colored inspector controls are 50% more better than those without
and thank you!
i feel like at a base functionality, i owe it to the next me to make a little github repo for it
Uh.... sure... Good luck.
You can also use a GUIStyle if you wanted and make a 1x1 texture and color it, then set it as the background for it.
is that related to the, .IsProSkin thing? I saw that while trying to figure this out by looking through an asset with dnspy, i figured it was some kind of home rolled drm or somethign ha
No. The .isProSkin is just a bool if the editor is using the light theme or the dark(pro) theme
ohhhhh, is that why i had to flip a bit with a hex editor to get the dark theme a while ago, it was a unity pro feature only
Correct, but from 2019.4+ it was made a free feature for everyone (YAY!)
@wintry frigate this is what I was talking about for using a style.
// In an init method...
Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
GUIStyle style = new GUIStyle();
style.normal.background = texture;
// In ONInspectorGUI...
GUILayout.BeginVertical(style);
forgive my extreme lack of knowledge in this department, as i am terrible with graphics, i do code much better, but i cant throw code at everything anymore with unity now can i lol....would you suggest taking the approach in this post as opposed to mine in order to achieve similar results to that example pic i posted?
No problem, I get it. If GUI.backgroundColor works, then use that. Otherwise I would use the style approach.
"studies" 😄
Feel free to ask if you are not sure how to do something or to see if you are doing it right (Just don't forget to test and google things yourself)
oh trust me i google. i'm a firm believer than even as programmer, writing code is just a symptom of bad googlin
(I actually generally dislike when people do colors like in the screenshot you showed. But you of course may do as you like)
i will add you to my scientific study, then , one for the nays lol
Nah color is fine, helps separate parts, but the header
please don't
This is the one of the worst habit an editor scripter can have
is this why you guys keep the inspector color UI code locked away then huh
if i get it to work and apply it to my asset, ill report back here to make sure that "just because i can, didn't mean i should"
Oh, I hate this in assets. It is so ugly, takes up valuable screen space, and generally looks less professional to me.
You got it
what do you guys think about that example i posted, because that has got to be the best inspector tool i've ever used (more for the functionality of being able to select your bitcost for netcode than color) but still, i thought it very well done
It's like ,I bought your assets, I know it is yours. Who is this for?!
The best? Long way to go 🙂
Revisiting the Inspector (Poke me to join the future open beta of NG Flow Inspector)
#madewithunity #indiedev @AssetStore #unity3d #gamedev #ngtools https://t.co/gB74rQwqqE
whoaa. since when could we get lil icon bookmarks
You can't just keep posting that one gif if you aren't going to do any other updates! (jk, jk 😛 )
Since never, I never released it
XDDDD
imma allow it, its really nice lol
You got me
i do the same thing too lol
when i started getting into netcode, i kinda like, lost sight of my game and now i have this game with amazing netcode, and no point to it, but on the plus side, releasing this asset
I did a quick prototype for searching properties in the inspector this morning https://streamable.com/j8l5d7
perks of doing tool around a game
This is great until it's just 8 C# scripts
Oh ho looks like i'm not alone anymore 🙂
looks cool though
I've seen many prototype of Inspector
i got a softball question also, is the reason my game crawls in the editor because i serializefield/public wayyyy to many things
Most demanded feature: filter
Serializing is a factor you need to take into account when you register it (for the undo system), load it, save it
Most likely not. You can run the profiler in the editor to see some more detailed info.
If you feel it is laggy, it likely means you draw too much GUI
and yeah the profiler helps
i usually switch to the profiler since it's in the same group as my inspector to make it get my frames back lol
Sounds like too much drawing to me.
....in the inspector?
Is it only lagging when an object is selected? How about only when with a specific component?
any GUI can become pretty heavy if you are not careful
Time to switch to UIT! 😛
it lags tough on my playerprefab, as it has a criminal amount of scripts on it, nothing fancy editor stuff, i do use odin tho
I like it! And it lets you mess around sooo much with the built in windows (see inspector window)
Yeah, it is trying to draw too many things at once I bet.
It's great in that aspect, but the current unending mixing of UIT and IMGUI means there's no way to properly switch
is odin helping or hurting me you think?
both