#↕️┃editor-extensions
1 messages · Page 83 of 1
Well, I have no idea what he is willing to do with it :D
Is the issue that if you change it during playmode it persists?
He just wanna lose data on playmode
Non serialized fields are still saved, on enable is not called @onyx harness
it's because the new playmode options don't reload the domain
none of the 5 callbacks listen on the scriptable object page get called when playmode starts or end
Oh, with domain reload disabled
yeah, I'm not sure how you're supposed to support this option -,-"
Domain reload disabled implies that you have to do all the reset stuff yourself
I read that in the early documentation of this feature, which makes sense
This kind of codeflow design puts a high pressure on dev, it forces them to code correctly 🙂
I have one list to clear, but I can't find anything that gets called at the right time
unity seems to have put the onus on the dev to clean things up but gave no tools to do so 🤔
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
https://docs.unity3d.com/Manual/DomainReloading.html
The example is quite explicit
I guess the documentation is just incorrect
it says the callbacks get called like normal
https://docs.unity3d.com/Manual/ConfigurableEnterPlayModeDetails.html
Maybe the graph might help you
yeah I've read all this before, the documentation seems to imply the callbacks should still trigger, unless they meant only MonoBehaviours
There is not a single callback being called when entering playmode? 😳
not for any scriptable objects reliably
OnEnable gets called after recompiling
that's about it
So what Unity did is select a big block of code and wrapped it in an if and called it a feature
And no attribute works? Unfortunately I never worked with disable DR, only read about it
But I doubt none work, even for non-MB
The static callbacks still get called, but I only want to reset a non-serialized value on an instance of a SO
it seems like a really unnecesarily complicated way to reset an object
I would have to register a static callback and collect up the game objects using find or something
Type : public static class UnityEditor.AssemblyReloadEvents
4.0.0f7 ⟩ 2021.2.0a8
Unity Doc
Event : public static afterAssemblyReload { add; remove; }
2017.1.0f3 ⟩ 2021.2.0a8
Unity Doc
GitHub Source
and this one?
You also got EditorApplication.playModeStateChanged
https://ngtools.tech/uv/UnityEditor.EditorApplication/playModeStateChanged-/
Type : public sealed class UnityEditor.EditorApplication
3.4.0f5 ⟩ 2021.2.0a8
Unity Doc
Event : public static playModeStateChanged { add; remove; }
2017.2.0f1 ⟩ 2021.2.0a8
Unity Doc
GitHub Source
Those look promising, I wasn't aware you could use them on non-static calls
Which one works?
Would have expected the first to fail
private void OnEnable()
{
EditorApplication.playModeStateChanged += ResetSO;
}
private void OnDisable()
{
EditorApplication.playModeStateChanged -= ResetSO;
}
private void ResetSO(PlayModeStateChange pmsc)
{
if (pmsc != PlayModeStateChange.EnteredPlayMode)
return;
currentVirtualGraphIndex = int.MinValue;
Debug.Log("Reset.");
}
bit of a hack but what can you do
Looks fine to me
Hey, so I am trying to save changes to a SO made in the editor and support Undo/Redo. Right now I make a change then set the SO dirty. Seems to work fine, but when I tried to add undo support, it breaks.
I do Undo.RegisterCompleteObjectUndo(...) before my change, but if I do a second register undo on the object, the first change is removed. I assume this is because it is not properly saving the first change. Do I have to do AssetDatabase.SaveAssets() every time I make a change?
guys how come my Hierarchy does not update instantly when I do PrefabUtility.InstantiatePrefab. It does not show this new prefab
it needs like 1 more action in the inspector or in the Hierarchy to show the new instantiated game object (like when I click on other objects)
I even call this EditorApplication.RepaintHierarchyWindow() but it does not work
@gloomy chasm I had better success using Undo.RecordObject for registering single changes, you can also use Undo.IncrementCurrentGroup(); which should seperate the undos as they seem to be grouped by name, so if you add 3 undo's in a row named "myChange" they all get undone at once if you don't increment the group
Ah! That seems to have done the trick! Thank you! 😄
Hi all. I cant seem to use Gizmos.DrawCube and DrawLine to draw it on top of any mesh renderer
Is this possible?
You mean you want the gizmo to draw over/in front of the mesh?
Yeah
How can I "update" a GUI field which value was changed from code while the user still has keyboard focus on it?
I think I've come across this before, but I forgot how I dealt with it... 😓
private void OnGUI()
{
if (Event.current.type == EventType.Repaint)
{
if (_needControlRefresh && _guiLoopsWaited >= 1)
{
HandleKBControlRefresh();
}
else
{
_guiLoopsWaited++;
}
}
if (GUILayout.Button("Change value"))
{
_someFieldValue = 0;
TriggerControlRefresh();
}
}
private void TriggerControlRefresh()
{
_previousKeyboardControl = GUIUtility.keyboardControl;
GUIUtility.keyboardControl = 0;
_needControlRefresh = true;
}
private void HandleControlRefresh()
{
GUIUtility.keyboardControl = _previousKeyboardControl;
_guiLoopsWaited = 0;
_needControlRefresh = false;
}
So far this seems to be working... but feels really dirty and unreliable
Is there a better way of "refreshing" fields?
it feels weird to use, sometimes the refresh happens instantly, other times it has some delay
call Repaint()
tried repainting when the trigger happens, still has delay some times
You can try TextEditor editor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
Or try RecycledTextEditor like such:
using System;
using System.Reflection;
namespace NGToolsEditor.NGGameConsole
{
public class RecycledTextEditorProxy
{
public object instance;
private static Type type = Type.GetType("UnityEditor.EditorGUI+RecycledTextEditor, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
private static PropertyInfo textProperty = RecycledTextEditorProxy.type.GetProperty("text", BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
public String text
{
get { return (String)textProperty.GetValue(this.instance, null); }
set { textProperty.SetValue(this.instance, value, null); }
}
private static MethodInfo MoveTextEndMethod = RecycledTextEditorProxy.type.GetMethod("MoveTextEnd", BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
public void MoveTextEnd()
{
RecycledTextEditorProxy.MoveTextEndMethod.Invoke(this.instance, new object[] { });
}
}
}
To use with:
namespace NGToolsEditor.NGGameConsole
{
public class EditorGUIProxy
{
public object instance;
private static Type type = Type.GetType("UnityEditor.EditorGUI, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
private static FieldInfo s_RecycledEditorField = EditorGUIProxy.type.GetField("s_RecycledEditor", BindingFlags.Static | BindingFlags.NonPublic);
public static object s_RecycledEditor
{
get { return (object)s_RecycledEditorField.GetValue(null); }
set { s_RecycledEditorField.SetValue(null, value); }
}
}
}
Looks like that:
[NonSerialized]
private RecycledTextEditorProxy textEditor = new RecycledTextEditorProxy();
...
this.textEditor.instance = EditorGUIProxy.s_RecycledEditor;
this.textEditor.text = "bla bla bla";
this.textEditor.MoveTextEnd();
@onyx harness oooh that's very neat. Thanks for sharing! 😊
oh also, doing cyclic repaint on this seems to "fix" it
if (Event.current.type == EventType.Repaint)
{
if (_needControlRefresh && _guiLoopsWaited >= 1)
{
HandleControlRefresh();
}
else
{
_guiLoopsWaited++;
Repaint();
}
}
but it still feels kinda dirty. I'm gonna have a go with what you shared, seems more reliable
TextEditor is pretty unknown to the community, but it is supposed to handle text input manipulation
I think a while ago I tried to create my own text controls to expand the functionality of TextField and TextArea and make a couple more
and iirc i used TextEditor stuff
but I didn't finish it, left it kinda hanging
maybe it's finally time to come back to that 👀
ive got 2 classes, Stat, and RandomStat which inherits Stat, and i wanna use a different drawer for each but this doesnt seem to work
im thinking its to do with the fact that the RandomStat is referred as a Stat in the code but is there any way around this?
What do you mean?
well there are Stat and RandomStat classes stored in an array of type Stat**
and i want it to show the correct drawer for each but im assuming this cannot be done
Are you using the [SerializeReference] attribute on that list? If not then all you really have is a list of Stat not Stat and RandomStat.
Sure thing! I would read the docs on it though since there are some oddities to using it.
it does seem a bit of an out there solution but definetly works in this case
has managed to break some other bits but im sure ill get them sorted
SerializeReference should allow for circular references right?
Sure does!
Cool, can you explain the memory leak I get when I do that?
Nope, sure can't! Sorry.
Glad to know it should work at least, thanks
is
AssetDatabase.ForceReserializeAssets()
the same as doing
EditorUtility.SerDirty() + AssetDatabase.SaveAssets()
? 🤔
I found this on the forums, but it dates back to 2017, so I don't know if it's still accurate
The new ForceReserializeAssets API makes Unity load and re-save the assets you request, so that any changes in data format or upgraders etc can be flushed to disk for you to commit to VCS immediately.
Well I ran the method to see how it behaved and it basically changed every meta file in my project...
it removed the "timeCreated" line in most of them
it also changed some values on a couple of scenes like this one:
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
to this
m_IndirectSpecularColor: {r: 0.37311953, g: 0.38074014, b: 0.3587274, a: 1}
now I have to go over hundreds of changes to see what it did to my assets 😅 fun stuff
it also screwed some rotation stuff on a couple of prefabs I guess it's messing with Euler and Quaternions because some rotations have switched values like: X to W, Y to X, Z to Y and W to Z
hey all 🙂 Does anyone know the editor style for the play/pause/frame buttons up top? Adding to that bar and the default is a lighter grey than expected
(worth mentioning that editorstyle.toolbarbutton is destroying my button sizing, but im figuring that out now :P)
"AppCommandLeft", or more general "AppCommand"
Here is the source for it if you want to take a look your self. https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/UIServiceEditor/UnityMainToolbar.cs#L127
anyone knows how to download packages into the assets folder ?
Trying to edit some scripts but its seems to be locked
Packages/com.unity.physics/Unity.Physics/ECS/Base/Systems/StepPhysicsWorld.cs
and
Asset Packages/com.unity.physics/Unity.Physics/PhysicsSettings.cs has no meta file, but it's in an immutable folder. The asset will be ignored.
yeh packages are locked. I've moved a package into assets before (i copied them out, uninstalled the package, then into Assets), but that was a git repo. Not sure if it would work with the official unity modules
Doubt: If I have a List<Node> in my ScriptableObject, is there a way to set a constructor, to execute everytime I press "+" in the inspector?
ISerializationCallbackReceiver
Ok, let me see the docs...
This callback is called on any object
Since you want to "construct", this is the best way
As constructor you can't use it
But when the callback is invoked... how do I know what the new object is?
I just assume is the last one?
You don't
But then, how do I know what object I have to pre-populate?
Let's talk with precision, because I feel we are getting a bit offplan
ok
You want to construct the Node whenever you add one
I have a list of "nodes". I want that when I press "+", the field "ID" of the node gets populated with a random unique ID
If I have this...
Try putting ISerializeCallback on Node and use the Deserialization() one
Not sure it will work
And then press +
I get another item... but with the same ID
Which, of course, it is not optimal
Because Unity clones the last one
Yeah, that is what I want to avoid
ok, let me see
It sounds like you want more control, and the control comes from the parent
which is your SO
ISerializeCallback? Or ISerializeCallbackReceiver?
You probably mean ISerializationCallbackReceiver
Ok, yes, I have added the interface to the node
Done
When I have a list of 1, and I add another one, it runs twice
One for each element
"OnBeforeSerialize" ran about 1 million times. I had to remove the "Debug.Log"
Put the interface on your SO
The issue here is we dont have a lot of control on how Editor is gonna execute
Yeah, exactly
We can only "seek"
So, everytime that "AfterDeserialize" runs, I have to go through the list, and "seek" those entries that duplicate an ID?
The last one yeah
But it better to check the whole list
Because you can dupplicate any entry on an array in Inspector
"AfterDeserialize" also run, for instance, when reordering the list
Because you need to understand how Unity manages its business
Whenever you do any operation, the serializer will copy, or add, or remove
It does not seem a very convenient method... Isn't there a way to just disable the "+" button?
Have no idea, never worked with the "recent" versions
If not, I guess I might as well just hide the List on the inspector
Oh, well. Then I guess I will have to just hide it
Thanks anyway
anyone knows how to add a custom prefab here?
if you have a property with getters / setters, how do you access the value in a CustomDrawer with something like FindPropertyRelative?
this does not seem to work
would it work if i use findPropertyRelative("_isRandom")?
but just wouldnt have the functionality of the getters / setters
Yes, if the field is serialized
ok sure thanks
does anyone know how to get IntelliSense working for the C# extension on vscode?
Is it me, or does EditorUtility.SetDirty doesnt work properly with ScriptableObject that contain lists?
can you share some code?
what do you mean by "doesnt work properly"? Is it not serializing the list? is not serializing the scriptable object?
what types are in the list?
@patent pebble I solved it, by adding AssetDatabase.SaveAssets(); after SetDirty
Thanks!
Dumb error
well yeah. You need to save the changes you make to your scriptable object 🙃
I dont know why, I was sure in my head that setting as dirty would automatically save them
duh...
SetDirty just "marks" the object as having "dirty" data, which means it has changes that need to be saved to disk
Yeah, makes sense
either from the main menu in Unity or in code with SaveAssets()
Not sure why one uses "EditorUtility" and the other "AssetsDatabase", though
Seems rather unintuitive
iirc SetDirty is not exclusive for assets
i may be mistaken, but I think you can for example set scene objects and prefab instances as dirty
(which in turn sets the Scene itself as dirty too)
take that with a grain of salt, i'm not 100% on that
no problem. Here's a refresher about how Unity handles saving, in case you want to give it a read https://docs.unity3d.com/Manual/Saving.html
Ill take a look for sure! Thanks!
Can you setup default editors for custom assets...
er
Can I make Unity open a markdown file with Visual studio instead of notepad for example
yeah, sorry that was confusing to write
Not sure if Unity handles that, give a look to your OS
I know unity has some control, but thats a good point I should check my assoc
I'm glad I know how this shit works... I dont know of a simple way to check associations
well, changes the os association does make that work, but it doesn't use the existing vs instance unfortunately :/
Ah I could do that, but it isn't really what I wanted. It looks like the specific solution I'm looking for is adding the md extension to Project Settings / C# Project Generation / Additional Extensions to Include
once I do that it works as expected and overrides the windows file association to use the specified external editor
Thanks yall
On a completely unrelated note, is there any interest in a Markdown element for UIToolkit?
I made one based off of Markdig, its not a great implementation since its a direct rendering into objects, and Unity doesn't have any kind of Rich text element so to accomplish the results every word is a label
Which works surprisingly well, obviously not perfectly well, and it doesn't scale for large documents
though I'm considering trying to seriously tackle the problem and make a markdown element that can actually be consistently performant
when using AssetDatabase.CreateAsset to create a scriptable object, it's fine, but I get this error in Console which doesn't look so nice:
MonoScriptImporterInspector.OnEnable must call base.OnEnable to avoid unexpected behaviour.
UnityEditor.AssetImporters.AssetImporterEditor:OnDisable ()
i mean everything works fine, but i dont know what this error is
does it mean i have to have a custom inspector for it, and use OnEnable?
hmm there is no base.OnEnable in the custom inspector
Do you have a custom editor for your SO?
Nope but i fixed it (somehow)
Does anyone know how to fix the enumfields? There are so weird can't seem to get them to a normal size
Using UI builder package
I can't aya specifically but I would use the ui debugger to see what's happening
Ive encountered similar problems you need to apply the uss to the right elements
I see ok ok, its difficult to work with this system so much weird things happening haha.
Got another question, now that I'm using a enumfield it takes a enum as argument.
I receive a string[], im used to doing it likes this
index = EditorGUILayout.Popup(index, Localization.knownLanguages);
is there a alternative ?
if (Localization.knownLanguages != null)
{
}
I tried to create a enum dynamically but that seems a bit overkill
Does anyone know a way to work with Texture2D data via SerializedObject/SerializedProperty. Specifically, I am creating a Texture2D pragmatically and then would like to save it to a field on a ScriptableObject. I tried setting SerializedProperty.objectReferenceValue but that does not seem to work, my textures appear white.
This is just a guess, but you may have to save it as an asset? Again, just a guess on my part.
You might be right, but I hope not!
If it is the case, you can save it as a sub-asset of the ScriptableObject and set the hide flag so it will not be visible at least.
That's a good idea, I will look into it, thanks!
isn't that design a little bit confusing? why would you want to have an assignable field on a ScriptableObject to hold invisible assets?
I would at least make the field non-editable if you only assign that texture field through code
I'm not a big fan of "hidden" assets in my project, unless they are temporary and don't need to persist sessions
The idea was to hold small 16 x 16 textures for use in editor windows, to avoid having to recreate them endlessly. These textures are generated from solid user adjustable colors, so having fixed assets doesn't work. The user would not be able to assign assets to these fields, they would purely be generated by my editor code behind the scenes. It's not that big of a deal, I am instead just going to generate the textures on the fly when the editor windows are created. The idea of saving the textures to the ScriptableObject asset was a whim.
Don't save them to disk
Keep them as base64 texture in code
And do as you did, create them on the fly on creation
is there an event when something an editorWindow changes, such as when I drop a gameObject into an objectField?
I want to call an update fn when the user drops a gameobject into an objectField, but can't find anything on the docs and have tried a bunch of events
Is this your own window?
yes
ChangeCheck
that works for built in controls, i have my own control, how would i manually set this event, any ideas?
nvm, found it, GUI.changed = true; this seems to work for me
@waxen sandal Thank you.
I have a drag drop window, however when i drag anything into the window and not even the drag drop area, it returns null. https://pastebin.com/Kni17y5x
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.
any ideas how to stop this please?
Nvm, i fixed it
Return obj instead of default on line 18?
yeah, that's what I did, thanks.
@onyx harness hey , do you know how to make custom preview nodes in shader graph - i want to have logarithmic view / change the draw range and the color space ?
Unfortunately I do not, I never touch Shader Graph, I made my own XD
that's a bold statment lol
do you mean you created an asset or something or just a personal tool ?
Wasn't sure it would handle >10k nodes
personal tool
But it is very far from complete, and kinda abandonned
i wouldn't dare doing something like this on my own
it is just showing rectangle & stuff cleverly
i mean , there is an ever growing needs to support render pipelines and different versioning of hlsl code
How do I change a property in a PropertyDrawer from a GenerMenu context menu without applying changes to the serialized object?
lol
Sounds like a paradox
PropertyDrawer is working from a SerO
if you apply from it, it will reapply on the SO
Hu? It works fine technically to do that. But obviously it isn't good to do so.
My guess is that when the ShowAsContext is called and the time an item is selected, the SerializedProperty changes in some way so the one passed to the menu is some how different than the one currently being used to draw.
I'm not sure how to get around that though.
That would mean that I would need to manually go and find the SerializedProperty though... unless I am misunderstanding.
Exactly
Which is not an issue here
FindRelativeProperty(property.propertyPath)
It is that simple
How the heck did I never realize that it takes a path not just a field name... The parameter is literally called "propertyPath"... -_-
But thanks, that worked. Do you normally just make your own SerializedObjects?
Do not think SerializedObject as Unity's own internal tool
It can be useful & powerful into your hands
Oh for sure! And I have before. Just not done it with a PropertyDrawer before. Do you store them in a dictionary by propertyPath, or do you do something else?
I often use them ephemerally
I almost never store them
Except when doing Editor stuff
Oh you were talking about SerializedProperty & proeprtyPath
Yeah use a dictionary if you want
It's all up to you
As long as the path is not dynamic (array & nested stuff), it should be fine
Yeah, not sure if there is a better way to handle it. Disable caching the property drawer maybe?
if it works, it works
I decided to end up just using EditorGUI.Popup instead. Made things a bit simpler (honestly don't know why I didn't think of it sooner). Thanks for the help.
Hahaha as long as it works 🙂
Is there another way to change the editor cursor than: EditorGUIUtility.AddCursorRect ?
It seems I can only change between the ones already in the enum MouseCursor? I'm just trying to change to the colorpick cursor.
How do I enable auto complete?
I know I need to install unity tools in the VSC tools section, but I can't find the tools section
all the online tutorials say that the tools section should be on top.
Not sure, you could take a look at the source for the Colorpicker to see how it does it though.
I would, but I'm not at that level. The code I see make no sense to me and I don't know how to trace it down. End up here and I'm totally lost:
public Color color
{
get
{
Color ret;
this.get_color_Injected(out ret);
return ret;
}
set => this.set_color_Injected(ref value);
}```
in the spriterenderer
Does anyone know of a way to override the way the editor calculates "Center" for a gameobject?
In this case I have a spline. None of the points are objects, its all just pure code (tm). When pivot mode is set to center I want the transform gizmos to be at the averaged center of the points and ideally I dont want to override all the transform gizmo code...
Then I don't know, check the source for that property and see what it's doing?
Always a good idea. Looks like I can use reflection to leverage LockHandlePosition. Thanks 🙂
The pivot of a GameObject is wherever its Transform dictates it to be. It's the result of applying the transformations from every Transform in the hierarchy leading up to and including that object's own Transform
So really... You should be setting the Transform position I'd say
Is there anyway to get an EditorWindow to render to a renderTexture or something similar, rather than to a Rect on the screen?
Details/goal: I’m hoping to make a script where I can copy the graphical contents of a ShaderGraph window- to an appropriately sized texture- and save it. Similar to a screen shot, but the final image would potentially be larger than the screen resolution. [Determining the “appropriate size” will be my next step- though I’m not even sure if it will be possible; might require user input for that part.]
I want this script because, as it stands now, trying to show a shadergraph in discord is a pain, and for large ones - usually leads to blurry/unreadable results- or multiple screen-shots.
This is interesting, but I do not have the answer.
oh! just found this: https://github.com/advancedfx/afx-unity-srp/blob/advancedfx/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs I think this is the type of window I need.. reading it now.
^ that guy has a member, that is a VisualElement derived class GraphEditorView : VisualElement, to do the drawing... but I'm not sure this actually helps at all. 😦
InternalEditorUtility.ReadScreenPixel
or UnityEditor.ScreenShots
are both relevant APIs
(both internal)
but I really doubt it would screenshot culled areas
Actually, InternalEditorUtility is not
I do not think
it won't
but you can move the view
and combine the content
especially seeing as ReadScreenPixel returns a color array, it'd be p easy to combine
One trick I would use would be to :
- create (or undock) an EditorWindow
- hide it off-screen
- make it giant (or the size you want)
- takes the screenshot
- restore.
ReadScreenPixels implies to handle the position and size, which is not a big issue, but it is something to do
this is great stuff guys! ya lost me with the "hide-it/take a screenshot" part... how would I screenshot a hidden area?
oh with this? "ReadScreenPixels implies to handle the position and size"
UnityEditor.ScreenShots contains many stuff to handily take screenshots
I'd make this myself if Kink isn't typing "we're adding this feature to shadergraph tomorrow"
Who Kink is?
never mind 😛
@keen pumice Without those tricks, I don't you think you can do it.
I've never seen IMGUI writing to any buffer, at least not in C#, because it has to do it at some point of course
hmm I can't see to find this guy... I found the ScreenCapture class- is that what you meant?
No, it may be 2020 only though - it's internal.
Type : internal class UnityEditor.ScreenShots
4.2.0f4 ⟩ 2021.2.0a9
Not sure ScreenCapture would help
When I think about it, I'm not sure you can screenshot something off screen
Well, you can still do like vertx said and do it over your main screen
It is very easy to test, just move a window half off screen, take the screenshot using the API
@keen pumice On the right, you have (C# Reflection Generator)
Which is a little helper to access internal stuff using Reflection
oh! move it around in the script.. and tiles the multiple images..I get it now.. great idea!
that's pretty sweet. I've wanted to make something like that for Rider for a while
seeing as Rider knows the API exists and you cannot reach it
it'd be great if I could just alt-enter and generate the access
That would be handy
I made a "nice to have" request years ago 😛
I looked into making it but was scared off by their API
where do we see the source for those internal guys-- so we know what functions we can call via reflection?
pinned to this channel
Type : internal class UnityEditor.ScreenShots
4.2.0f4 ⟩ 2021.2.0a9
Method : public static Screenshot()
4.2.0f4 ⟩ 2021.2.0a9
Unity Doc
Example of Reflection snippet I provide @keen pumice
The API is internal, you need Reflection for any method
Man Mikilo, I love your style, I can tell your really passionate about your projects
You mean the color?
Oh
Hahaha I was going "well dont be too harsh on me, I'm colorblind" XD
.> that explains certain things
Thx ma man, it is really kind, it makes my heart full of joy 🦋
understood, I mean how do you know what string goes into the GetMethod function?
@keen pumice I handed it to you already
ah.. got it-- I was derping
Or check that
Since I've moved from working on my package as a folder in my Assets folder to having it in its own folder that I use "Install from disk" in the package manager to import into the project, I'm stuck with either not getting full syntax recognition or in my VS Solution I get no folders in any of the projects
like this...
is that normal?
No idea, Rider is superior
Rider costs money and Jetbrains burned me last time I paid them money :/
Perhaps checks the .csproj if things are correctly recognized
I suppose I could just modify them a whole bunch, I tried regenerating them
this is what you get in Rider
thats what I used to get, well not the asset/packages seperateor
this is how the unity project explorer looks
Assets is totally fine though, its just the packages
using symbolic links to make them embedded packages in the Packages folder seems to work just fine, I'll just use that as a work around
though unity doesn't seem to trust me: "Packages/com.passivepicasso.thunderkit is a symbolic link. Using symlinks in Unity projects may cause your project to become corrupted if you create multiple references to the same asset, use recursive symlinks or use symlinks to share assets between projects used with different versions of Unity. Make sure you know what you are doing."
But do you know?
I had one pretty big issue back in 2017 using symlinks.
Was running parallel projects linked to one shared folder, and every single time I focused the other Unity, it would trigger a code change. Very annoying.
Ah yeah I wouldn't use it for a longer term solution
Mostly use it to test packages and stuff, temporary things
I'm trying to create a custom editor for the following Data class:
public class Data : ScriptableObject
{
public List<BaseNode> _nodes;
}
[Serializable]
public class BaseNode { }
[Serializable]
public class SubNodeA : BaseNode
{
public int _someNumber;
}
[Serializable]
public class SubNodeB : BaseNode
{
public string _someText;
}
i want to show all nodes that are in the _nodes list with their specific default inspector
so one item in the list could be a SubNodeA and will serialize the int field and another item in the list could be SubNodeB and will serialize the string field
also i want this to work with subclasses i might add in the future, without rewriting the editor code every time
any ideas how to do this?
SerializeReference
SerializeReference doesn't really give me this result
actually it doesn't change anything at all
What did you change
nevermind, if i actually add subclass objects to the _nodes, then it works
now i only need a dropdown where u can select any subclass of BaseNode and a button that will add a new instance of that sublass to the _nodes list
trying to do this via reflection but i don't know how i can add a node object to my _nodes list from the editor
var node = (BaseNode) Activator.CreateInstance(selectedNodeType);
_nodes.InsertArrayElementAtIndex(_nodes.arraySize);
//_nodes.SetArrayElementAtIndex ??
_nodes is the Data._nodes as a SerializedProperty
There's a get element at indenx or somthing
yea but how can i assign a custom class value then?
i managed to do this now via this
Data _data;
void OnEnable()
{
_data = target as Data;
}
...
var node = (BaseNode) Activator.CreateInstance(selectedNodeType);
_data._nodes.Add(node);
I actually tried setting that, but that gave me an error in the console
What was the error?
it just told me that i was trying to set the managedreferencevalue to something
but doesn't matter, as i said i found some other way to do it
Alright, glad to hear it. Just so you know, at least in 2019.4, SerializeReference with types referencing the same type (like a node, with a list of child nodes) doesn't play well with prefab variants.
I have a gameobject that references a scriptable object. I then use a static [MenuItem()] command that calls AssetDatabase.CreateAsset(), which updates the .asset file. When I press play, the gameobject reference becomes None. Is this a bug, or is there a way to inform the inspector that the asset has been updated? I have a minimal working example if someone can use it.
I have tried using EditorUtility.SetDirty(foo); to no avail.
Can someone explain this?
private float MyCustomDrawerInstance(float value, GUIContent label)
{
return EditorGUILayout.Slider(label, value, this.From, this.To);
}
This is an example from odin's doc. How can Odin use EditorGUILayout in PropertyDrawer? Can you define the position before EditorGUILayout get called?
I'm having some trouble overriding AssetImporter.SupportsRemappedAssetType(Type type), sometimes the passed value in the parameter is null (with types that derive from ScriptableObject mainly, but some others too)
Why are all of the entries of my Type[] array correctly populated but some of them are null when I pass them as a parameter to SupportsRemappedAssetType() ?
Here's the code https://pastebin.com/wM2vSWqu
all I want to do is get a list of all the types that derive from UnityEngine.Object and then pass them into the SupportsRemappedAssetType method, but seems my lack of programming expertise is showing here 😅
what happens if you put a log after the if?
the debug behaves as normal even after the if
the type is still there
it's only null in the AssetImporter.SupportsRemappedAssetType(Type type)
is there something I'm missing about the Type class?
show me some logs
the file with the editor logs?
yep
ok gimme a sec, because it's 200mb, gonna trim it to only keep the stuff related to this issue
it didn't let me add a regular breakpoint, tried with a Function breakpoint and it says "always break"
Here's some logs anyways
I still don't understand what's happening. How can a Type be fine at one point and then be null when passed as a parameter for a method
It's probably something super basic, but I'm at a loss here
for example the null problem happens with these classes
https://ngtools.tech/uv/UnityEditorInternal.Transition/ (obsolete class)
https://ngtools.tech/uv/UnityEngine.StateMachineBehaviour/ (abstract class)
and also with every class that derives from ScriptableObject
between lines 549 and 617 you can see the logs for the StateMachineBehaviour issue in the logs I just shared
It is weird to me as well
But I also had the feeling you didnt tell me everything
I don't know if there's anything else I can share
i think I shared all the relevant code
Show me all the code please
Because it looks like there is a call in between
I guess I know why
AssetImporter.SupportsRemappedAssetType is not virtual
It makes you think it is,but it is not
So I guess you just need to take that into account
"new" is the key
wait, where's that?
from ScriptedImporter
namespace UnityEditor.AssetImporters
{
[ExtensionOfNativeClass]
[MovedFrom("UnityEditor.Experimental.AssetImporters")]
[Preserve]
[UsedByNativeCode]
public abstract class ScriptedImporter : AssetImporter
{
protected ScriptedImporter();
public abstract void OnImportAsset(AssetImportContext ctx);
public virtual bool SupportsRemappedAssetType(Type type);
}
}
here's what I see when I go to the definition
Here's my full code:
https://pastebin.com/4GWm2zuG ExternalObjectRemapping.cs
https://pastebin.com/y4Fdxnni ExampleImporter.cs
Sorry no need anymore X)
do you want also the Example, ExampleEditor and ExampleImporterEditor classes?
oh k
You just need to take that into your code
that you are not calling it, someone else does
Therefore you have to deal with the null
I use dnSpy
any clues on how should I go about that? I'm sincerely very lost in this particular case as to what to do
or any topics I should read on?
about what exactly?
If null you return false XD
Because it might mean Unity is doing handling it behind
Or whatever you are doing
hmm... but that's what I don't understand. If I pass a Type of ScriptableObject, why do I get it as null in the SupportsRemappedAssetType() method?
that makes it impossible for me to use that type
or if you wanna go super ugly you use a static set by yourself just before
Unfortunately, the code is C++ side
I mean all I can guess is that it has to do with type instantiation and I somehow need to do extra handling to fix this
all I wanted was to see every type of supported asset for remapping in a particular importer... one would think Unity would provide that by default 🙃
Unity being Unity i guess...
i'll do a request for this. But it can be years (if ever) before it gets implemented
😅
You can, but I wouldn't count on it
If you feel it is a bug
report it
it is a good habit
I'm not sure it's a bug, but it's definitely weird unexpected behavior. I'll report it anyways
is there a built in gui editor thing for a key: value display?
like a text input but the value is just a display
so a label + value? I just can't find it
Label?
Wait is there a plain text editor thing that's not Label?
@strange hedge what do you mean by "input" and "just a display"?
I was thinking just something like:
label: value for how it's displayed
I wanted to make the label bold or something maybe
then the value notbold, guess a textinput that's disabled is the best way?
Why not just two Text components...
there was a method to prepend labels to other fields so when you click in the label the field gets selected
i forgot the name of it tho 😅
oh we're talking about editor my bad
@strange hedge but what do you want exactly? you can also make an horizontal group with 2 labels and style them both to whatever you want
if you don't need to have any manual input
Yea just whatever is easiest xD
label: value
no editability, it's just to show data for values i import from files
Labelfield looks perfect!
make a horizontal group with two labels like this EditorGUILayout.LabelField(string label, GUIStyle style)
Thanks @twin dawn
optionally, if you just want to style the second label you can also do this
LabelField(GUIContent label, GUIContent label2, GUIStyle style);
the style will get applied to the second label only
oh weird
what if I want to style the first one? XD
im almost there, anyone know a way around this little bugger error?
though they do make nice dividers tbh~ lol
then
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.LabelField(string label, GUIStyle style)
EditorGUILayout.LabelField(string label, GUIStyle style)
}
I'll probs do this then x3
dont forget labelWidth
hmm?
The width of the prefix label
Oh lol, i think i'm good there, just need to figure out how to nest foldable areas~
I mean the editor is telling you that you can't
I've never done it, but you can probably do foldout-like behaviour manually with EditorGUILayout.Foldout or something
yea the EditorGUILayout.Foldout example makes like no sense to me though, I don't get how the vector field is inside of the foldout
looking for better examples~
oh wait i get it, it just uses if showposition XD
Foldout just returns a bool state
if it's true, show your stuff, it it's false, don't show anything
i also like to use this for nested stuff like that
using (new EditorGUI.IndentLevelScope())
{
//Stuff
}```
yea, i'll try that.. though also @onyx harness how do you use that width variable? I was trying this:
GUIStyle style = new GUIStyle(EditorStyles.boldLabel) {
fixedWidth = 500
};```
^
I sadly have been looking at that page for a while but don't understand how to use it
most GUILayout controls also accept an array of GUILayoutOption parameters to define widths, heights, expansion settings, etc
I don't get how the two relate, it's been a huge issue for me trying to build GUI x3
which two?
How do i get a EditorGUIUtility.labelWidth value into GUILayoutOption?
they are two different things
see the different method overloads for GUILayout controls
do you mean GUILayoutControls?
Im just legit at square zero here, I don't know if you're using names of things or unity terms sorry
GUILayout doesn't seem to have any construction docs I can find.
// This label has a default width
EditorGUILayout.LabelField("Some label");
// This label has a width of 100
EditorGUIUtility.labelWidth = 100;
EditorGUILayout.LabelField("Some label");
EditorGUIUtility.labelWidth = 0; // Setting it to zero resets to the default value
// This label has a default width
EditorGUILayout.LabelField("Some label");
// This label has a width of 200
EditorGUILayout.LabelField("Some label", GUILayout.Width(200));
Oh! Cool yea thanks, I've legit never seen it explained and I've been looking for months!
the docs for GUILayoutOption have this at the end
See Also: GUILayout.Width, GUILayout.Height, GUILayout.MinWidth, GUILayout.MaxWidth, GUILayout.MinHeight ....
those links have code examples
How do I find GUILayoutOption though? XD
i pasted the link above in one of my messages
Well yea, exactly and thank you :3
I'm just explaining why the docs didn't lead me there in my personal time looking, as you seem to be saying the examples should've
yeah the docs are kinda buried, they have good info but you have to dig for it
I'll share some links that helped me learn about IMGUI stuff
https://github.com/Bunny83/Unity-Articles/blob/master/IMGUI crash course.md
https://docs.unity3d.com/Manual/GUIScriptingGuide.html
https://docs.unity3d.com/Manual/gui-Basics.html
https://docs.unity3d.com/Manual/gui-Controls.html
https://docs.unity3d.com/Manual/gui-Customization.html
https://docs.unity3d.com/Manual/gui-Layout.html
https://docs.unity3d.com/Manual/gui-Extending.html
https://blogs.unity3d.com/2015/12/22/going-deep-with-imgui-and-editor-customization/
here ya go 🙃 read all that and you're good to go (for the most part)
all of this is on the Creating user interfaces (UI) of the Unity manual
lol bunny83
you know that person?
that article helped me a lot
even tho it has some inaccurate info
Not exactly, but we helped a lot in Unity Ask, he might be still active
god bless peeps like you guys 🙏
Nice 😄 Thanks so much i'll take a look!
@strange hedge editor extensions stuff takes a while to sink in. Don't worry if some of the stuff doesn't make sense instantly
if I told you how long it took me to "completely" understand how all the GUI flow, events and all that worked... 🙃
and don't even start me on SerializedObjects and SerializedProperties 😅 that was like trying to understand ancient Greek or something hahah
you just have to google a lot of examples, blogs, etc
stuff like this is not easy to grasp just with the Unity documentation
(specially if you don't come from a programming background)
@visual stag hey, since this topic comes up fairly often. Maybe you can pin these links so we can refer new people to those IMGUI learning resources?
Maybe just these 3 to not bloat the pinned messages
https://docs.unity3d.com/Manual/GUIScriptingGuide.html
https://github.com/Bunny83/Unity-Articles/blob/master/IMGUI crash course.md
https://blogs.unity3d.com/2015/12/22/going-deep-with-imgui-and-editor-customization/
I remember having a hard time when I didn't know anything about this topic, and it took me a while to stumble upon those resources
Is there an easy way to make a MonoBehaviour method as "I want a button for this in the inspector" ?
I've been messing around with creating something of a PropertyDrawer for a Delegate type to try and do this, but sadly Unity is not liking it
It would save a lot of time over making a custom inspector for every monobehaviour that I want to have some test buttons on
You are looking for something like that?
https://unitylist.com/p/jyb/Unity-Method-Button-Attribute
@sleek berry
That looks glorious, thanks! trying it out
This worked perfectly, thanks!
Is there a way to display a sprite field in inspector, bigger? In inspector?
Without custom editor? Maybe theres a attribute for this like TextField TextArea for string?
Nothing that I know of that can modify how a field is rendered
Ate there good resources for learning the UI elements?
I'm struggling to make anything beyond the basics
have you tried searching online for "UI Toolkit tutorials"?
as far as I know they officially renamed UIElements to UI Toolkit
Does anyone experience, in an EditorWindow", that position.size.heightis actually more than shown?
The mouse position is taken with "Event.current.mousePosition", btw
Ok, nevermind... apparently the problem was I was capturing the mouse position in a bad place. Apparently I have to do it in the root
😓
Is UI Toolkit used to create custom inspectors?
or should I be looking in a different direction? I wrote a cool custom inspector and I want to share it but I used Odin Inspector for it and that doesn't work for distributing it. So I'm trying to rewrite the gui using unity's built in features so I can distribute it.
Yes it is! Using IMGUI is going to be more like Odin I think though (That is things like GUILayout).
I personally find UI Toolkit easier than IMGUI to use in a lot of cases but it also has to do with how familiar you are with each system.
Well, if it's easier to do UI Toolkit to do what I want to do, then I'd like to use that.
I'm not married to making it "like" Odin
I just want to replicate the interface more or less.
It's a table with two text fields stacked and a button
and then text fields and buttons
By table, do you mean with rows and columns? In this case is just two columns
[text fields, button]?
Fairly easy in Odin, but I'm trying to do it now without odin.
I guess it would be 4 columns since it's labels, fields, button, delete.
I have a problem that i can not use 2d Axis Composite. I am using the new input system in 2D game. Earlier I could add 2D Axis Composits and now i can not. Did someone had a problem similar to mine?
Hi, I am trying to implement a custom control csharp static void TogglePrivate( String title, ref bool value, bool disclosureStyle = false, bool forceHorizontal = true, float width = 0, params GUILayoutOption[] options ) { options.AddItem(width == 0 ? AutoWidth() : UI.Width(width)); if (!disclosureStyle) { if (GL.Button("" + (value ? onMark : offMark) + " " + title, options)) { value = !value; } } else { if (forceHorizontal) { UI.BeginHorizontal(UI.AutoWidth()); } UI.Label(title, width == 0 ? AutoWidth() : Width(width)); GL.Space(10); if (GL.Button(value ? disclosureArrowOn : disclosureArrowOff, AutoWidth())) { value = !value; } if (forceHorizontal) { UI.EndHorizontal(); } } }
and right now it looks fine with autosizing
but when I specify width I get this
Is there an easy way for me to measure the sizes of the Label and Button I am using?
I guess as a stopgap if I can just make the title label right align that would help
Related to that I would like to get rid of this force horizontal stuff and make nested horizontal layout work
Not really sure what we are supposed to be seeing tbh. What is wrong with it? Also, what is UI andGL from I don't recognize them?
I used your idea and made the ShaderGraphToPNG tool. it's kinda clunky, but if ya want it, just DM me.
UI is my own class, GL is a Using GL = GUILayout. The thing I am trying to do is make the disclosure mark ▲ be next to the text "18 Spells". I am now looking into building a custom control for this ala http://leahayes.co.uk/2015/08/25/custom-editor-controls-in-unity-part-2.html
I think that a great place to start with custom control development is to re-create the GUI.Button and GUILayout.Button controls since these are straightforward to create and helps to establish some of the fundamentals of custom control development. Our custom button implementation will be used in the exact same way as the regular button controls:
I made progress using the approach of building a custom control. Now the only question is how do I tell the layout system how much space I need?
my draw code is doing this csharp case EventType.Repaint: Rect labelRect = rect; labelRect.size = style.CalcSize(label); var arrowStyle = GUI.skin.button; style.Draw(labelRect, label, controlID); var arrow = value ? OnContent : OffContent; Rect arrowRect = labelRect; arrowRect.x = labelRect.xMax + 10; arrowRect.size = arrowStyle.CalcSize(arrow); GUI.skin.button.Draw(arrowRect, arrow, controlID); break;
but now the arrow is drawing over adjacent stuff
on things like UIkit for iOS you have layout methods to override to say I need this much size. The custom control is that 3 classes with a triangle button that follows
can I just set the rect I got from GUILayoutUtility.GetRect()?
hi there. I have a question. I wrapped up my prototype and trying to create a series of toolchains out of it
however, my question is this
should I put ALL of the scripts I've created thus far
in the editor folder
or as long as I have the original scripts inside my asset folder
it'll be fine?
Someone knows how to show in a custom inspector an input for a Sprite (or any other type that aren't text/int/float/ecc... and boolean?
Ask your actual question, what are you trying to achieve, what have you tried
I've this class that extends the Editor class to make a custom inspector for my scriptable object. I want to add a field where the user can drag and drop a Sprite without using the base.onInspectorGUI().
thanks
Ok, i've tried to use this pattern even for an enum but i got an error trying to convert systemlanguage to unityengine.object. Code: settings.supportedLanguages[i] = EditorGUILayout.ObjectField(settings.supportedLanguages[i], typeof(SystemLanguage));
and yep i've try an explicit casting but it dosen't worked
What's SystemLanguage
it's an enum used by Unity for the user's language
Then use EnumField?
Of course
I have been breaking my head the whole, trying to friggin nag arithmetics about "zooming and panning"
This is f**king hell
There are several opensource editor graphs and you can look at the source Unity's graphs (I think the UIToolkit GraphView is on github as well)
UITookit is made for both. Actually it only worked for the editor until like 2020.2(I think it was?).
Could you give me an URL?
Im trying to build a workspace with pan and zoom, kinda like the Shader Graph has
But it is driving me nuts
Well here is a getting started.
https://learn.unity.com/tutorial/uielements-first-steps#5cd19dd8edbc2a11565247b0
Thats still in preview, no?
Nope, not in preview anymore.
Cool. But I know CSS well... I dont think it has anything for pannign and zooming, no?
Correct, if you want to have panning and zooming you need to still do that your self. OR, you can use the GraphView API, which is what both ShaderGraph and VFX Graph use. However it is technically 'experimental' and undocumented. But I wouldn't let that scare you away, I have yet to run in to any braking changes and as I said, they are already using it quite a bit.
Yep, that's the one. Cool, looks like they added some docs for it!
even though this is not too encouraging
😅
But if this is what the shadergraph and the VFX graph is using... it might be a good idea to look into it.
That is just their to cover themselves, as I said, Shadergraph and VFX graph both use it, so if they really did remove it or change it a lot, it would be a big pain for themselves too.
I just cannot take it anymore. Of doing arithmatics for pannings and zoomings.. im going crazy in here
"Panning when the mouse is in the top right corner... the pivot has to be the cursor, but the panning has to be relative to the grid..."
Headshot
So, yeah, I guess Ill take your advice, and look into it
THanks
Oh, wow. It even has a class "nodes"... It might actually be really helpful
Yeah, it is really nice! And you can always look at the ShaderGraph source to see how it is used if you need to!
Well, im not sure if im ready to understand the shadergraph source code 😄
But I guess if I dig enough, I might find what I need
This might actually be helpful:
https://www.youtube.com/watch?v=7KHGH0fPL84
In this tutorial we are going to create a SUPER SIMPLE node based dialogue system with the ability to branch story lines. We gonna create the main setup and make our graph entirely functional in this episode.
In the next episode, we gonna add save&load system for nodes and game play implementation.
This tutorial will help you to build your bran...
I am already in love
@gloomy chasm You have gotten all the karma you are gonna need this week
Well glad I could help you! If you have any questions about it feel free to ask @west drum!
Is it possible to add sub-assets to any asset in my project?
I tried using this but it fails https://docs.unity3d.com/ScriptReference/AssetDatabase.AddObjectToAsset.html
Gives me an error telling me it failed to load the asset because it's either corrupted or it was serialized with a different version of Unity
(I believe this error is inaccurate)
The docs say this
Please note that you should only add sub assets to '.asset' assets, imported models or texture assets for example will lose their data.
Any way to work around this?
In my particular case I'd like to add a TextAsset (.txt file) as a sub-asset for another asset
It means that you should only add sub assets to .asset, not that only .assets should be sub-assets.
What is the asset type that you are trying to set as the main asset? Also, you can create a new instance of that asset and try adding a sub-asset to it to see if the error is accurate or not.
yeah that's the issue, my main asset is a custom asset type (a text file with a custom extension)
I've seen people saying the AddObjectToAsset method should only be used for prefabs as the main asset type
but also seen other people using it for other main asset types
but it's hard to find info online
Ah, I see. I think it should work. Are you creating the asset and trying to set the sub-asset at the same time? Maybe the main one has not fully be serialized and everything yet by Unity?
That is nonsense I know.
both the main asset and the asset to add as a sub-asset exist in the project prior to me trying to "combine them"
And you have tried making sure they are both new?
what do yo mean by that? that they are not actually corrupted or have some serialization issues?
I as just saying to make sure to create new ones for both and try it on the off change that they are corrupted or something. However I think text files count as imported assets so wouldn't work.
A work around would be to create a ScriptableObject as a 'wrapper asset' and make it be the main asset instead, and add both as sub-assets to it.
hmmmm
i just saw someone in the forums saying to create a new asset for the one that is to be added as a sub
brb
nah no luck either
going with the ScriptableObject is not really a desirable option 😅
It may be that this is just not supported by Unity? I mean that only the assets that can have subassets by default work for this like (animations, models, etc)
How can one merge 2 existing assets into one?
Yeah, I think it is the only one since TextAssets are imported as well, so I don't think it would save anyway.
I mean I'm not trying to actually merge assets
I'm just trying to make some existing assets as sub assets of others
By existing I meant written to disk
yeah both exist in disk and in my Unity project
so for example, two text assets, or a text asset and a texture
Hum... cant help never did that, I know you can toy with .asset easily
found this online https://github.com/mob-sakai/SubAssetEditor
gonna see in their code to see what they do
right so I tried using the code from that repository, and everything has the same error
UnityEditor.AssetDatabase:AddObjectToAsset (UnityEngine.Object,UnityEngine.Object)```
But using a ScriptableObject as the main asset works
so I guess when the docs say Please note that you should only add assets to '.asset' assets they truly mean it 😅
Why were you thinking differently? O_o
should
that gave me some hope
if it said you can only then I'd have given up way earlier
What were you trying to achieve ?
it's not for a particular thing, just for learning purposes
I was testing if some sort of a "dependency" between assets could be possible with sub-assets
I found also this https://docs.unity3d.com/2020.1/Documentation/ScriptReference/Experimental.AssetImporters.CollectImportedDependenciesAttribute.html
but it's experimental
when I make changes to one, the other re-imports or updates itself to reflect said changes
but since sub-assets are not possible for other types that aren't .asset, not possible
oh, it's actually in AssetDatabase https://docs.unity3d.com/ScriptReference/AssetDatabase.RegisterCustomDependency.html
i thought it was only an experimental API
the neat thing about the sub-assets would be to have a lot more tidier project hierarchy
but I guess I can achieve this with asset dependencies and just hiding the assets and display them in a custom editor in a collection
What my nesting experience tells me, "if it can be serialized into an asset, it can be nested"
heh, well I guess I'll keep digging for the next couple days on this topic
I really want to learn how to customize my projects in the sense of simplifying what is shown in the project view
Good good
maybe creating some sort of "view modes" to hide unnecessary information/assets when only working in a certain way
HideFlags
because there's times when for example I'd like to just ignore every script and just deal with "content" assets like textures, materials, models, etc
ye ye, I recently learned how they work
is that the only way to "hide" stuff?
ok
well I could also implement a custom project view and selectively draw the items i want
but that would probably rely on hideflags too
otherwise it would be a pain to manage independently from hideflags
well, no
or maybe not. I can't really tell, I'm too much of a noob on this topic
In your custom code, you do whatever you want
wouldn't it be a good idea to keep my custom code in accordance to hideflags? at least by default
it'd be weird to see hidden assets in my custom project views and then not seeing them if I switch back to the built-in project view
I would suggest you to stay away from HideFlags
in general or in this particular approach?
Leave the Project/Hierarchy to show what should be shown
And in you EditorWindow or Editor, you display based on the selected custom view
In general
hmmm i see
I'm usually not a big fan of that, yeah
In computing, WYSIWYG ( WIZ-ee-wig), an acronym for What You See Is What You Get, is a system in which editing software allows content to be edited in a form that resembles its appearance when printed or displayed as a finished product, such as a printed document, web page, or slide presentation.
i try to follow this principle as much as i can
gut gut
Anyone know why this doesn't work to underline? GUILayout.Label("<u>Enumerable Types</u>", new GUIStyle(EditorStyles.largeLabel) { richText = true });
Because underline is not supported https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/StyledText.html
Only bold, italics, size, and color are supported.
you can probably import an underlined version of the font you are using and add that to the GUIStyle when needed
@visual stag ^
So I've got this custom layer property editor script (probably from unity forum):
using UnityEngine;
using UnityEditor;
namespace Feed {
[CustomPropertyDrawer(typeof(Layer))]
class LayerDrawer : PropertyDrawer {
public override void OnGUI(
Rect position,
SerializedProperty property,
GUIContent label
) {
property.Next(true);
property.intValue = EditorGUI.LayerField(position, label, property.intValue);
}
}
}
But when i multi-select it screws everything up.
Like everything gets reassigned to the same value
Could someone advise how to make this compatible with multi-select?
nvm, solution is:
property.Next(true);
var nextValue = EditorGUI.LayerField(position, label, property.intValue);
if (nextValue != property.intValue) {
property.intValue = nextValue;
}
hey, i was trying to create a new file in the ScriptTemplates directory from inside the Editor, but it says that access is denied, is there any workaround?
the full directory where I'm trying to create the file is
C:\Program Files\Unity\Hub\Editor\MY UNITY VERSION\Editor\Data\Resources\ScriptTemplates
it's definitely not a problem with my code since I'm used to do IO operations in C# and never got any problems so far, also it works as intended if I choose another directory, it seems like UnityHub denies access to its directories while it's running, which is understandable, but maybe there is any workaround
I also can't create a new file manually inside that folder while Hub is running, only when it's closed, but moving an already existing file inside there works
Sadly, File.Move doesn't (tried to create the file at a temp path and then moving it to the desired path, same exception, access denied)
Question about GraphView API. Do nodes have some sort of GUID or some means to identify them?
Nope, sadly there is no API for the data side of things, you have to do that your self.
so I will have to set up some sort of dictionary in the node, to give some sort of guids to the ports?
It sounds like you may be mixing the data side and the view side of things. As far as the ports go, the index may be enough, or if they represent a field, then the fields name
I am not mixing them. I have an "EdgeData" class, just to keep the data stored and serialized
But once I want to load that data in the graph, I need a way to reference the Ports of the node, right?
I thought of using the index of the port, but that is too flaky
What happens if tomorrow I decide to change the order of the ports?
I need some sort of "id" for the ports, so that they can be unequivocally referenced, not matter the layout changes
@west drum Sorry it took me a minute, I had to go look to see what I did. Basically I have the data side mirror the view side. With, SlotData(port), EdgeData, NodeData, and GraphData class. I have the SlotData, and NodeData both have Unique Ids (I used System.GUID for them), and have the GraphData keep serializable dictionaries for the nodes and edges. Each node of course containing a list of all of it's slots.
Can you show me attributes in SlotData?
What do you mean?
Oh, sure! Uh, there is a class that it inherits from and stuff, and hastebin for some reason is not wanting me to upload. Are you fine if I just DM you the file?
hastebin has not been working for months
You have to use this now:
https://paste.mod.gg/
Oh really? I had no idea, thanks!
Here is the slot: https://paste.mod.gg/asakuhivan.cs
There is some stuff about 'parent slot' and 'sub slot', but you can just ignore it. Kinda in the middle of reworking it so that it works like the VFX Graph so things like Vector3s can be expanded and be connected to directly.
I see. I guess I will try indeed to manage myself the references to the ports.
Here is the base class if you are interested, mostly it just handles serialization. Idk if I would do it again like this though https://paste.mod.gg/tabisetubu.cs
I see. I guess it indeed means that GraphView is a barebones framework to manage visuals and not much more
And just because, here is the Edge if you want to take a look https://paste.mod.gg/imoyitawit.cs
Which is cool, but a lot of data management needs to be done, of course
Yeah, I was telling you about the GraphFoundation package which I think is meant to help with the data side. The GraphView is only the View side of things, it handles it well, but would be nice if there was a data side as well.
GraphFoundation? Is that a Unity thing? Or is it more general purpose?
Oh cool!
Disclaimer: I know next to nothing about it, or looked at it much. So I have no idea what it does really or what state it is in.
I might take a look and play around with it. But for my needs, I will probably be more productive if I handle it myself
after all, it is still in preview
Yeah.
I think just setting an "id" for each port should suffice for me
One thing: About this "separation of data and view"
I get the gist of it, having a "Runtime" and "Editor" workspace, and making Runtime independent from the Editor
But
You cannot really have 100% separation, no? After all, you have to save stuff like the position of the nodes inside the graph, no?
Yeah, the position and expanded state of the node needs to be saved on the data side (I, and ShaderGraph decided to make a class inside of the NodeData class that is just the DrawerData, just to keep things clean).
But I think that is all that is really needed.
Yeah, I guess I would use another class if it got big. But since it is just the position, I am not going so overkill
But good, i wasnt sure if I was doing it wrong, or indeed it was the right thing to do, to save visual information
Nodes have a little arrow in their header that let you hide all of the unconnected ports, so you would want to save the expanded state of that as well.
I mean, when you create a node from the Node class, that is just part of it 😛
Ah, got it.
Is there a way to enter "renaming" mode for an asset through code?
Like when you press F2 on a selected asset, or when you right click it and select the "Rename" menu item
Uh, would this do it for you? https://answers.unity.com/questions/644608/sending-a-rename-commandevent-to-the-hiearchy-almo.html
Unity is the ultimate game development platform. Use Unity to build high-quality 3D and 2D games, deploy them across mobile, desktop, VR/AR, consoles or the Web, and connect with loyal and enthusiastic players and customers.
Never mind this is what you want I think UnityEditor.ProjectWindowUtil.StartNameEditingIfProjectWindowExists
yeah I found about ProjectWindowUtil.StartNameEditingIfProjectWindowExists but seems more hassle than just invoking a renaming event
(I was looking for it but couldn't remember what namespace it was in and what the class was called exactly)
gonna try the event approach and see how it works
quick question, is there a way to find and select a certain file so the inspector shows (a scriptable settings object)
find the asset and then Selection.activeObject = yourAsset
ah i see
thought maybe something to do with selection
would that be as an asset object, or file path?
object
a UnityEngine.Object iirc
or instanceid
ok well i have that already lets give it a raz
filepath is only used when dealing with drag & drop
by golly it works
well that was easy
onwards and upwards
im making a graph json encoder/compressor so they can be shared as text
down to about 4-9% smaller
4-9% of json size i mean
yes indeed, but i want to make it small enough to paste easily
So like, pretty = false 😛
(jk, jk)
haha what does that actually do, format it, tabs/newlines?
Yeah, it formats it, otherwise it is all on one line.
im actually using it with UVS mainly, but I think it could be used for many things, since most of Unity is serialised
not just sharing
i can copy and paste from project to project
thats where it started mainly, i cant stand files everywhere
Use JsonUtility no?
well my current version, has a dictionary of about 8000 to encode, then use lzma compression, then convert to base64
@gloomy chasm oh btw thanks for the link before. This seems to work perfectly
[MenuItem("Assets/Create/Example Files/Example", false, 83)]
public static void CreateExampleFile()
{
string path = GetSelectedFolderPath() + @"\" + "New Example File.example";
string uniquePath = AssetDatabase.GenerateUniqueAssetPath(path);
using (FileStream fs = File.Create(uniquePath)) {}
AssetDatabase.ImportAsset(uniquePath);
Selection.activeObject = AssetDatabase.LoadAssetAtPath(uniquePath, typeof(Example));
EditorApplication.update += TriggerRename;
}
private static void TriggerRename()
{
if (_updateFrameElapsed)
{
Event e = new Event { keyCode = KeyCode.F2, type = EventType.KeyDown }; // or Event.KeyboardEvent("f2");
EditorWindow.focusedWindow.SendEvent(e);
EditorApplication.update -= TriggerRename;
_updateFrameElapsed = false;
}
_updateFrameElapsed = true;
}
less boiler-platy than the other approach
what is a uniqueassetpath?
It is an asset path that is unique to that asset like.
So?
GenerateUniqueAssetPath does the same as duplicating assets in your project view.
It just adds an space and the next available number to the asset path
ah i see
well it doesn't actually do anything to the assets, just returns a string
like Assets/MyAsset.asset, if you tried to create another one it would be changed to Assets/MyAsset1.asset so it would be unique.
i made a tool similar so i could disable scripts
means i dont have to delete them
also backup, and save versions
there's a caveat which I don't like. You can't tell it to not add a space, so the next assets will appear before on the project, instead of after.
I just ended up making my own method to generate unique names without the space
for me, sometimes i want to try a different version of code. rather than comment and comment etc. easier to make a new file while saving the old
for example. work in progress though. i want it to detect as a group so if i enable one it disables the other. rather than 2 enable/disable
yeah, except for the option to tell it to do Prefab1 😓
last option
ooooh
i'm so stupid
🙃
and for some reason my brain had assumed that was only for Hierarchy objects, but it also affects the Project assets
Funny thing, it is present in the settings, but it does not work 🙂
(the space option does)
It does work for the Hierarchy though
not for Project
oh right, the top 2 options are just for Hierarchy, the space is just for assets
seems to be working fine for me in 2020.2.4f1
Unity does and explaning stuff...
[MenuItem("Assets/Script -> Add Text Backup")]
static void ScriptBackup()
{
Object selectedAsset = Selection.activeObject;
if (selectedAsset is MonoScript)
{
string
assetFilePath = AssetDatabase.GetAssetPath(Selection.activeObject),
projectPath = Application.dataPath.Replace("Assets", ""),
newAssetPath = assetFilePath.Replace(".cs", ".a0.txt"),
charVersion = "abcdefghijklmnopqrstuvwxyz",
intVersion = "0123456789";
(int a, int b)
lastVersion,
version = (0, 0);
while (File.Exists(projectPath + newAssetPath) || File.Exists(projectPath + newAssetPath.Replace(".txt",".cs")))
{
lastVersion = version;
version = (version.b == 9) ? (version.a + 1, 0) : (version.a, version.b + 1);
newAssetPath = newAssetPath.Replace("." + charVersion[lastVersion.a] + intVersion[lastVersion.b] + ".txt", "." + charVersion[version.a] + intVersion[version.b] + ".txt");
if (version == (25, 9)) break;
}
if (version != (25,9))
{
File.Copy(projectPath + assetFilePath, projectPath + newAssetPath);
AssetDatabase.Refresh();
}
}
}
im sure you could use that for renumbering in some way
this is just for converting a script to a text backup with versions/branches
Ok. I need some help with the new UIElements toolkit. I'm trying to create a new UXML element to show a table that connects to a list of objects, where you can prescribe a template for an individual object, and it will repeat for each object in the list as rows, and the template gives you the columns. But reading the documentation, I'm very confused where the VisualElement subclass you create actually does drawing. So I'm having a hard time figuring it out how it connects together. Are there any tutorials that someone can point me to that connects all this together?
Unlike with IMGUI, UIToolkit doesn't have a method that it draws from. Instead you add visual elements as children of other visual elements. For editor windows you add them to the rootVisualElement, and unity handles drawing that.
What they look like (Size, background color, border width roundness and color, etc) are decided by the style. You can set it with a StyleSheet (UXML) or 'hard code' it by setting them in the 'style' property like myElement.style.width = 5. Hope that clears some stuff up.
Here is the "Getting started" tutorial from unity https://learn.unity.com/tutorial/uielements-first-steps
But I'm trying to create a custom control?
Like I can create an element but then how does that element tell UIToolkit how to draw it?
It is the exact same thing, you put all the logic and create all the sub-elements inside the constructor.
public class ButtonLabelElement: VisualElement
{
public ButtonLabelElement()
{
AddChild(new Label());
AddChild(new Button());
style.flexDirection = FlexDirection.Row;
}
}
When it goes to draw it, it looks at all of the style sheets in the styleSheets property and the style that has been set in the style property and applies them.
huh. so creating a table element is going to be messy....
Actually, not too bad. But it depends on how dynamic/complex you want it.
Is anyone aware of the times editor windows are forced to reload their data? AssemblyReloadEvents.afterAssemblyReload covers one case but I'm not sure what the others are
Would EditorApplication.delayUpdate (I think that is what it is called) work?
I'm trying to mostly recreate Odin's TableList. Not everything in it, but a lot of things.
Well if each row will be the same height, you can use the ListView class and it should work perfectly if each row is it's own class.
I created a custom editor as a facade for a class in a visual novel engine, but I did so with Odin, and I've discovered that I'm not the only one who would want something like what I created so I'm trying to remake it, or mostly remake it, without Odin, so that I can distribute it and maybe even have it merged into that engine.
Doesn't look like it, the tldr is I'm keeping a path to some asset file I'm editing, occasionally (like after compiling, entering playmode, seemingly at random?) the editor will unload the asset, so I'd like to reload the asset via it's path
I successfully got it working with the domain reload callback, but it's not covering all cases
Why not just treat it like a singleton and do a null check, if it is null then load it in again?
because it's valid to be null
it will ultimately end up looking something like this:
ah, I was actually able to solve this with a dumb hack;
rootVisualElement.schedule.Execute(
() => serializedGraphSelector.SetValueWithoutNotify(gc)).StartingIn(100);
after the domain reload
lol.
unity do be like that sometimes I guess 😿
If you actually want to control the raw drawing there is a way but I wouldn't say its eats or simple or even well supported
Ive been mostly unsuccessful in using the features.
However making a table control shluld be fairly easy if you take control of populating and positioning the children
That said it looks to me like all you really need is the list control and to setup the make item call with a method that creates a visual element with 3 element children which each have a flex basis assigned where the two outer items are set to flex shrink and the middle item to flex grow
And that will basically get you there other than wiring up the x button to delete elements
Is there a way to force a field to be revaluated? Rn, I have to change the field's name. But preferably, when it reloads the script it'd revaluate the field.
Right click > reset?
Any ReorderableList experts?
I'm trying to color the background of the elements using this code:
{
Color c;
if (isActive)
c = EditorGUIUtility.isProSkin ? activeColorDark : activeColor;
else if (isFocused)
c = EditorGUIUtility.isProSkin ? focusColorDark : focusColor;
else if (index % 2 != 0)
c = EditorGUIUtility.isProSkin ? oddColorDark : oddColor;
else
c = EditorGUIUtility.isProSkin ? bgColorDark : bgColor;
Texture2D t = new Texture2D(1, 1);
t.wrapMode = TextureWrapMode.Repeat;
t.SetPixel(0, 0, c);
t.Apply();
GUI.DrawTexture(rect, t as Texture, ScaleMode.StretchToFill);
//EditorGUI.DrawRect(rect, c);
Debug.Log("color is " + c);
}```
But everything is white..
My colors are static readonly private fields
As you can see I tried with the Texture method and the DrawRect method.. both gives me white bg no matter the state (active, focused etc)
but when passing a color on the fly like EditorGUI.DrawRect(rect, Color.red); it works. 😐
Oh and the debug line prints the correct color even though i see different color...
So, EditorGUI.DrawRect doesn't work?
Try initializing c with something like Color.red to see if the problem is actually with the drawing or with your bgColor/focusColor/etc initialization (which I suspect is the case)
Also, I don't know if this would help you. But if you set the alpha for your color's low, you can basically just tint the background and that way it will still play nice with the element style with selection/focus/lost focus stuff.
I did try this.. Color.red or Color.cyan works but new Color(23,23,23) for instance, doesn't work..
alpha do work tho
and I tried EditorGUI.DrawRect and GUI.DrawTexture
same results..
there's a DrawTexture in EditorGUI let me try to use that..
Well there is your problem, it is a 0-1 range, not 0-256
And that's why my first question/statement ever to people coming in here "where's the rest of the code?"
lol you willing to dive into 500 lines of code?
He means directly relevant code. So does setting the color using a 0-1 range instead of 0-256 range work for ya?
oh all the components are 0-1 based? not byte based?
well fml..
let me try lol
oh right because of HDR 🤦
yea that's the issue thanks for the help!
next time don't just copy colors
🤣🤣
There's Color32 if you want to use 0-255 colors
and it implicitly converts to Color
Are there any good resources on how to properly use EditorGUI when creating property drawers?
An issue I constantly find myself running into is actually calculating the space needed by each step of the drawing process (For example, drawing an array). But the spacing just always seems...random?
You can use EditorGUI.GetPropertyHeight() to get the height that is required for a given property. There is also EditorGUIUtility.singleLineHeight, which is the standard height for a single line control (like text, int, or float fields).
And there is also EditorGUIUtility.standardVerticalSpacing which is the vertical space that is between fields in the inspector.
I have made a method that handles the rects for me. I also have one that is just the first line, so I can easily move to the next rect position.
Rect NextPropertyLineRect(Rect rect, SerializedProperty nextProperty)
{
rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing;
rect.height = EditorGUI.GetPropertyHeight(nextProperty)
return rect;
}
Does anyone know how to use the GraphView.Pill class?
I cant seem to find any good example
Hi , how to draw a custom class from onGUI inspector method
PropertyField?
can u show me an example ? i have a class that has a string name i want to make it visible from onInspectatorGUI
also the class is not derevid for mono behaviour i am using [System.Serializable]
can you be more specific? are you making a custom inspector or do you just want to publicly expose a field of your class's type?
oh ok you are making a custom editor
well for starters read this https://docs.unity3d.com/ScriptReference/EditorGUILayout.PropertyField.html
you need to pass a SerializedProperty as a parameter for the PropertyField
can you show the code in your ShopItems class?
oof
I think you have to go over the basics of Custom Editors
and probably read the manuals or check tutorials for ScriptableObjects
ok
just so you have an idea of what you're doing wrong. You are treating your ShopItems as a regular class and instantiating it with new ShopItems() in the custom editor for itself.
You are also trying to do a property field for a variable that doesn't exist in ShopItems
your scriptable object needs to be an asset in your project
and then you can implement the custom editor for it and find it's fields with the FindProperty() method
also, it's a good practice to name your custom editors after their target types. In this case you have ShopItems, and you should call the custom editor ShopItemsEditor instead of ItemEditor
i don't know what you want to achieve, but I get the feeling you are trying to do something you don't need to with this whole approach
@void shoal what exactly are you trying to do?
the more info you give us, the better advice we can share with you
if all you want to do is use the ScriptableObject (ShopItems) to contain your different items (Character, Map, PowerUp, etc. Each in their own class) and have a list of them with their different data...
you may not need to implement a custom editor at all
@patent pebble i am just learning about building custom editors not for an actual project i am just trying to learn the possibilities thanks for all the docs you have provided me i was currently watching the junior programmer pathway on unitylearn and i have almost reached the end of the pathway can u guide me what should i learn next for mastering unity engine?
oh I see i see
@void shoal well look at it this way, custom editors are the cherry on top. You use them mostly to customize the appearance (but also to customize the behavior) of the inspectors for your classes
hey can you help me with some networking stuff?
I put my question in #archived-networking but noone awnsered me and you seem smart
@void shoal in this case if you want to make a custom editor for a ScriptableObject, first get the structure of your classes and the scriptable object working like you normally would.
Then do something like the example in the Unity docs to create the Custom Editor for your ScriptableObject
@patent pebble ok thanks a lot for ur time.
can u tell me about what should i learn after junior pathway?
no idea what those tutorials are teaching you 🤷♂️
kinda hard to answer
it all depends on what you want/need/interests you
I never learned any code for editor customization at all in my first 4 years of using Unity
if you are still a beginner with Unity overall, there's probably more "important" things to learn. But learning the basics on extending the Unity editor is fine
Even though we might seem smart, we likely don't hang out in #archived-networking because we don't know much about it