#↕️┃editor-extensions
1 messages · Page 102 of 1
UnityEditorInternal.ReorderableList
Im trying to install the Dependencies Provider for the Quick Search Tool. I cant find the samples talked in the 2nd paragraph.
Update search providers is grayed out?
What version of both Unity and QuickSearch are you on?
It is greyed out because it is just there as a 'header' to let you know all the items below it are search providers.
Quick Search 3.0.0 preview.22 and Unity 2020.3.5f1
I think they removed it? There is this now anyway https://forum.unity.com/threads/experimental-dependency-viewer.1158899/
Ok they totaly removed the quick search package from the editor?
No, the Dependency Viewer is an extension for QuickSearch.
I'm experiencing glitches with the Selection class, sometimes when doing drag and drop with a single asset while having multiple previous selections
after the drag and drop is performed, the selection reverts back to the previous selection
how can I get a callback when I start dragging an asset?
I want to manually update the selection to that asset as soon as I start dragging it
(i wanted to attach a gif to help visualize the glitch, but it's almost impossible to replicate, it just happens at random sometimes, and it breaks a bunch of custom tools I have)
guys i am trying to follow this tutorial to change the background image of the vs code editor but I cant find the extension it says in the tutorial.Any help?
https://www.youtube.com/watch?v=q5akzMW7W-Q
Trying to do some custom inspector stuff. How do I 'lock' the current selection so I can't select another object?
I can't remember how
top right lock
Not what I was asking.
I'm asking how to do it programmatically.
I want to not be able to select another object while isConnecting is true. I know it has something to do with AddDefaultControl but I've completely forgotten how to properly use it
if (isConnecting)
{
int controlID = GUIUtility.GetControlID(GetHashCode(),FocusType.Passive);
HandleUtility.AddDefaultControl(controlID);
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
hasHit = Physics.Raycast(ray, out hit);
if(hasHit)
Handles.DrawLine(script.transform.position, hit.point);
if (Event.current.button==0 && Event.current.isMouse)
{
if (hasHit)
{
GameObject hitObject = hit.transform.gameObject;
if (hitObject.GetComponent<Teleport>())
{
script.connectedTo = hitObject;
hitObject.GetComponent<Teleport>().connectedTo = script.gameObject;
}
isConnecting = false;
}
}
}
@digital spoke iirc there was an internal field or property to set it
but I've never used it
ah it's public now
ActiveEditorTracker.sharedTracker.isLocked = true
does unity collaborate count as an extension?
probably not
Probably does but this is not for help with extensions
Hi all
In my editor script, DirectorySeparatorChar returns , while the path returned by GetAssetPath uses /
Why is it so? What am i supposed to use for environment based separator? Is this only the case in editor?
All of the asset databases paths are in that format regardless of the platform
Right ok
Is there an equivalent of Transform.GetSiblingIndex for asset folder?
I'm trying to make lastSelectedObject like the last script in this thread basically, but that's for scene selection i guess
https://forum.unity.com/threads/last-object-selected-in-editor.239900/
I want for the editor purpose
LastSelectedObject apparently is not so simple in unity..
You can utilize
The selection class's selectionChanged event to come up with something.
https://docs.unity3d.com/ScriptReference/Selection-selectionChanged.html`
if (EditorGUILayout.DropdownButton(GUIContent.none, FocusType.Passive)){
GenericMenu menu = new GenericMenu();
foreach (ContextTVoid contextMethod in Entity.contextMethods_Void)
{
AddMenuItem(menu, contextMethod.Method.Name);
}
menu.ShowAsContext();
}
//------------------------
private void AddMenuItem(GenericMenu menu, string menuPath){
string s = menuPath;
menu.AddItem(new GUIContent(menuPath), false, OnMethodSelect, s);
}
private void OnMethodSelect(object s){
GUIContent.none.text = s.ToString();
}```
What am I doing wrong when it comes to the last line? Following the GenericMenu example in the UnityDocs and trying to translate it to a dropdown menu (select item from dropdown, set dropdown tp selected item name).
``GUIContent.none.text`` doesn't work, but neither does making a new instance of ``GUIContent`` and assigning that to the dropdown...clearly I'm missing something important.
Here's what I get with the code above:
Obviously I only want "Context_None" set on the dropdown I'm working on, not.....whatever the heck is happening here
I am not sure what the result is you are going for, but the reason that OnMethodSelect is not working is because GUIContent.none is a single instance of GUIContent that everything shares.
You should never edit it in any way.
Also, it looks like a Popup field would do what you want? https://docs.unity3d.com/ScriptReference/EditorGUILayout.Popup.html
Aww hell
That's what I was looking for initially I guess
Was wondering why it wanted me to use GenericMenu. Just didn't look right
One sec, I'll see if I can rewrite this
Thank you for correcting my stupid (again) 🙂
No problem, glad you got it working!
So @gloomy chasm, I just saw something and it made me think of this channel. It was a video about stack overflow and how toxic it is to new people but he said something that really struck me: "These people ARE doing the research. They're doing it by asking you the question. They're incorporating human interaction into their research to learn about whatever programming topic they're learning about." (not an exact quote). And it made me realize that, I often tell people when I talk about my programming background that I'm self taught, but it made me realize that that's not entirely true. I didn't answer all those questions myself, I had people like you and others in here to help me, and in other forums and subreddits and discord channels and servers, and IRC channels and servers. So... I just wanted to say thanks for all the times you've helped me in the past. I'm not just self taught, I'm community taught.
Oh, well you're welcome! Lots of people have done (and still do) the same for me, so I just like to do it for others. Passing it along so to speak. Also, I like editor scripting and tooling, so it is fun for me a lot of the time.
(Self taught just means you didn't have any formal instruction or training, not literally having taught your self 🙂 )
@timid coyote this is the correct channel for inspector questions. Your extra toggle is the Toggle you have declared in your if statement
your if statement should just be if (isInteractableProperty.boolValue)
Ty so much
Cant get this to work, does someone know why?
I'm just trying to compare if the selected editor window is the SceneView
activeWindow = UnityEditor.EditorWindow.focusedWindow ? EditorWindow.focusedWindow.ToString() : "Nothing...";
if (activeWindow == "UnityEditor.SceneView") {
//DO SOMETHING;
Debug.Log("Is doing something")
}
I tried everything, with/without (), Scene, SceneView and so on.. but nothing seems to work.
When i replace "UnityEditor.SceneView" with "Nothing..." it instantly works just as intended.
Am I missing some names of the Editor window? (in this case SceneView)
if (EditorWindow.focusedWindow is SceneView) would be how I would do it
omg thanks 🤯
Is it possible to have a piece of code run when the editor updates without adding a gameobject with [AlwaysExecute] To the scene?
void OnEnable() { EditorApplication.update += Update; }
void OnDisable() { EditorApplication.update -= Update; }
im currently using something like this
this only runs when i have the scriptable object highlighted (of course)
but i want it to always execute (sort of adding code to the update loop of the main window?)
This only runs once, im looking for something that loops like Update()
still haven't manged to get this to work :(
The attribute that Navi linked is what you want.
would you mind explaining how i should implement it further?
Because im not really sure how this attribute works
should i start an infinite loop when the method is called?
Hi there
does anyone know a way to have the inspector show the properties of a scriptable object asset?
SerializedProperty m_myProperty;
void OnEnable()
{
// Fetch the objects from the MyScript script to display in the inspector
m_myProperty = serializedObject.FindProperty("PropertyName");
}
public override void OnInspectorGUI()
{
EditorGUILayout.PropertyField(m_myScript);
}
or is that not what you mean?
ive solved this by adding a EditorWindow opening it when unity loads (if its not already open ofc) then giving it a size of -10, -10 and moving it to x = 10000 and y = 10000. Then just using the update function of that window
Use it and EditorApplication.update and then you don't need to do anything ridiculous
EditorApplication.Update stops when i stop editing the object
i want it to loop no matter what im doing in unity
What object
the scriptable object that the custom editor is for
the script is not attached to any object in the scene
That callback is completely disconnected from objects, it decorates a static method, hence why three people are recommending it
when using UIToolkit for my editor extensions what is the best route to go about applying serializedObject.ApplyModifiedProperties? Just include Update or InspectorGUI still and just put those things in there still?
[InitializeOnLoad]
static class MyClass
{
static MyClass()
{
EditorApplication.update += MyUpdateMethod;
}
}
is bindings suppose to do the same thing?
What do you mean?
Once an element is bound to a SerializedObject and property it will automatically stay up to date.
awesome thanks! Haven't done any editor stuff really yet with UIToolkit, just runtime, so wasn't sure
No problem. Fun fact, the way it keeps it up to date internally is by running a check in every frame to see if the object has changed 😛
tbh, I'm still confused on the entire serialized thing. Like, does set dirty work on things that aren't serialized? I was trying to go a different route just in case serialized attributes werent somewhere, but seemed to be having a hard time with persistent editor objects without serialized
LOL, yeah, you will have a hard time with persistent (aka serialized) objects without serializing them 😛
I haven't really delved into saving data yet. Whenever I want to make changes that last between editor reloads, for example, I use System.IO and actually write to the file
without serialized that is
Yeah.... that is most likely not the best way to go about it. What data/objects are you saving?
That is serializing it.
nothing much atm. I try to use things like scriptable objects and stuff everywhere I can, more of just a side thing where I try to make custom drawers and things for regardless of if a field is serialized or not, and just haven't figured out how to in general make it so if I add to a list, for example, outside of a serializedField attribute, it actually persist through an editor reload
Oh, if you edit an object not using a SerializedProperty then you just need to set it dirty, I think if it is a GameObject you also need to set the scene dirty, but I don't remember. However I highly recommend only using SerializedProperty, especially when working with GameObjects.
Also, if you have stuff like project settings, or something then you should use this to handle persisting the data. https://docs.unity3d.com/2020.1/Documentation/ScriptReference/ScriptableSingleton_1.html
hey ! i have a question C:. I want to run a code directly in the editor (it don't work at this time but it will improve performance on my desktop :))
using UnityEngine;
public class TerrainVisibility : MonoBehaviour
{
[SerializeField]
Transform viewer;
[SerializeField]
float renderDistance = 500;
// Update is called once per frame
void Update()
{
if (Physics.CheckSphere(viewer.position, renderDistance))
{
gameObject.SetActive(true);
}
else
{
gameObject.SetActive(false);
}
}
}
This code works, but is there a better way to add "padding" to GUILayout elements? Id rather not specify a new Rect every time since id have to provide a position specific for every element which I think makes the whole GUILayout class useless since it handles positions automatically, but itd be nice to also just shift some elements over by a few pixels, I donno if "forcing" it to do that this way adds a significant performance dump in a loop of x prefabs in the project
GUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Width(150));
GUILayout.BeginHorizontal();
GUILayout.BeginVertical(GUILayout.MinWidth(50)); //add "padding" of 50 pixels to the left
GUILayout.EndVertical();
if (GUILayout.Button(AssetPreview.GetAssetPreview(prefabs[i]), GUILayout.Width(150), GUILayout.Height(150))) { EditorGUIUtility.PingObject(prefabs[i]); }
GUILayout.EndHorizontal();
//<some other irrelevant GUI stuff below this Button...
GUILayout.EndVertical();
Basically, this code "creates a vertical help box styled container, that has a horizontal container split into 2 parts with a vertical split - the left side of that split is the 'padding' while the right side is the button, all within the same horizontal container... Then that horizontal container is within the first vertical help box container" - it works but it seems dumb to me, maybe theres a more efficient way I could look into? I tried also just creating a horiztontal container with a width and min width, expand width both on and off and nothing seemed to make any difference at all, until I nested another container (vertical) inside the horizontal one, which to me, seems like a overkill solution
GUILayout.Space(50), GUILayout.Flexspace()
Or editing the GUIStyle.padding
Oh, I knew it might have been something simple like that, ill give this a try - thanks
@shadow violet to be honest, when you are getting into this sort of depth with IMGUI, it's always way easier to deal with manual GUI
creating and caching a bunch of Rects and having constants in your class is always gonna be more readable and easier to maintain
GUILayout is fine for small things and quick prototypes
but it becomes a nightmare to read pretty quickly
Using the scope version of the Begin/End methods help with this quite a bit.
oh yeah, i ALWAYS use the scoped versions of everything that has it with IMGUI
Oh, yeah im still pretty new to editor scripting, im working on a lot of tools to help my workflow a bit, and while they work, I know they are probably far from efficient, the main benefit I like with GUILayout is that it auto-formats those rects for me, so aligning things and grouping things is relatively simple with a Begin and End, but it does get messy quick lol
@shadow violet if they are tools for your personal use, don't really bother with performance and efficiency unless it becomes a problem
if your GUILayout code gets messy, you can use horizontal, vertical, scrollview, area, disabled, fadegroup, togglegroup, indentlevel, property, iconsize scopes to make it more readable
personally, as a general rule, if I have more than 2 or 3 nested scopes or begin/end stuff, I refactor to use manual GUI
it's also easier to debug, you can use this https://docs.unity3d.com/ScriptReference/EditorGUI.DrawRect.html
and even with manual GUI, you can still use GUILayout when testing something new
you just need to register the GUI rects into the layout system
i forget the name of the method to do that
something like GUILayout.GetRect or something like that
(I think it is GUILayoutUtility.GetRect())
sounds about right
@shadow violet scroll down on that and you can see the overloads that take in width/height
Oh interesting, I planned on going back and cleaning up some of my code after I finished the main functions of what I needed all my tools to do, so that will be helpful info to learn from, thanks for all this :)
IMGUI stuff can become quite the time sink, so unless you are going to add more functionality to a tool, it may not be worth to spend time refactoring from GUILayout to GUI
i have a bunch of small tools that I'm never planning on adding features to them
GUILayout its fine for those, even if the code is a little bit messy
Ah I see - well right now my plan is to build a bunch of tools (a lot of them do more than one thing, they are I guess like mini "kits" than a "tool", for example, something that lets me reorder a selection of objects, force a naming convention on that selection, space all of that selection by a set value, etc), and I plan to re-use a lot of these tools to prototype game ideas and be the kind of "building blocks" or "foundation" for projects I fully commit to
They have been a huge time sink so far, and now I have a lot of them done (and learned a bit more about editor scripting from it), but your probably right that once they are all built, I probably wont go back to the code very often, if at all for new features
yeah
oh i forgot to mention the scope classes are kinda find to hard on the docs
https://docs.unity3d.com/ScriptReference/GUILayout.HorizontalScope.html they look like this
you gotta search for them, they are kinda spread around in the documentation
Where is "LocalFileIdentifier" stored in prefab? I have text serialization of asset and there is no info about it in the prefab or meta files
Hwo can I disable gameobjects in scene from an static method during build?
@winged epoch what do you need the Local File ID for?
you can use AssetDatabase.TryGetGUIDAndLocalFileIdentifier to get file IDs
but they are used to be kept as references
if you set the inspector to debug mode you can see (some) local file IDs
i wanted to replace prefab with variant, created editor tool to change prefab to prefab variant of another prefab base but references was broken even when i used PrefabUtility.SaveAsPrefabAsset. But i found out how is Local File ID stored in prefab variant. Its xor of prefab instance id and File ID of base prefab
i don't have any experience in making editor tools for prefabs, so I can't help there
maybe someone else on this channel can offer their advice
yea, but i found out already so its fine ;D
useful tool when you forget to create prefab as variant
1 vote and 0 comments so far on Reddit
is there any limit in size for a string on EditorPrefs?
i know PlayerPrefs have limits, but can't find any info on EditorPrefs
I'm making a tool that stores paths in a single EditorPrefs entry by separating them with commas (path1, path2, path3, ...)
Should be fine for a while at least
We serialize a lot more to *prefs
Like list of objects serialized as json
@waxen sandal i see, thx!
Maybe its about time I "straightened" my editor view
im still puzzled as to how this could have happened in the first place
its also persistent
between editor restarts
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.
Idk how you managed that tho
Also the wrong channel
I thought about what channel would suit this best and I figured it would be this one. Which one do you reckon is better?
The description of that channel said "non-programming" related but I suppose this fits that description
alright then
Well since i'm here..
Is DOTS editor GUI worth investing time in? Its something I've thought about (since i ran into some performance issues when drawing large amounts of property drawers and such) but havent really looked into yet.
Let me look it up..
No wait the first one
data-driven editor gui
Or I misinterpreted some news or blog post and its actually the second thing you mentioned
ill look it up
I have no idea, I've never heard of the first one 😛
Hmmm... It appears I misinterpreted some Unity blog post about "DOTS editor" and thought it was about writing editor GUI with DOTS, not editor GUI for DOTS.
too bad
weird
i was so sure of it lol
hey guys, I'm currently working on a personal project trying to make a 3D Grid System work in Editor runtime. I'm having some troubles trying to make snap to grid for tiles. I created a topic in #915328696401952779 could check out the topic and see what was my problem no to rewrite everything here again :S
@whole steppe Freya Holmer has a great introductory video series for making Editor extensions
she makes a grid system as one of the examples
at the end of the 1st video and the beginning of the 2nd
thx, I'll marathon now 😄
most of the stuff she teaches in those videos is great in general, doesn't matter what your level of editor tooling is
it's all great learning content
@whole steppe i just checked the thread you made. The videos I linked most likely won't apply to your particular use case
but it can be a good example on how to approach grid tools
T.T
thx anyway
I'll check out those videos
certainly I'll learn something new
you will, 100%
Hi, how would I be able to set this new empty gameobject as the child of the Hierarchy's current Default Parent?
[MenuItem("GameObject/MyTools/CreateEnemySpawn", false, -1)]
public static void CreateEnemySpawn()
{
GameObject empty = new GameObject("Enemy Spawner");
empty.AddComponent<EnemySpawner>();
empty.transform.position = SceneView.lastActiveSceneView.camera.transform.position
+ SceneView.lastActiveSceneView.camera.transform.forward * 5f;
Selection.objects = new Object[] { empty };
}
You sadly need to use reflection. https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Commands/GOCreationCommands.cs#L41
Hello. I'm using OnValidate() to set the size of a sprite,
for when I change some serialized fields in the inspector
But I get the Warning 'SendMessage cannot be called during...'
From what I have read, the warning might not apply to my situation.
And I could perhaps suppress it somehow, but that doesn't seem optimal.
What is a preferable approach to this?
I've used serialized bools to run methods when activated, but I want a more flexible way, if it's not too complicated.
Changing some properties calls SendMessage internally
And you can't change that or suppress it
Alright.
My goal is to make an intuitive interface for other game designers, who aren't necessarily coders.
In this case, I want the sprite size to change when the referenced float is changed, for visual purposes.
However - it does work, I just get the warning.
Could there be some error down the line?
Custom editor probably
Hmm. Can this* override the inspector UI for specific components?
nvm, I found a good read
Alright so im getting an error
NullReferenceException: Object reference not set to an instance of an object
ContourEditor.OnInspectorGUI () (at Assets/UCartographer/Scripts/Editor/ContourEditor.cs:17)
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(UCartographerManager))]
public class ContourEditor : Editor{
UCartographerManager cartographermanager;
public override void OnInspectorGUI() {
base.OnInspectorGUI();
EditorGUI.BeginChangeCheck();
if (GUILayout.Button("Spawn Contour")) {
cartographermanager.CreateContourLine();
}
if (EditorGUI.EndChangeCheck()) {
SceneView.RepaintAll();
}
}
} ```
I don't particularly understand why it doesn't recognize UCartographerManager ...
ive said its type of ... ive made a variable ... but it doesnt recognize ?
Assign the script ?
This is more of a call for opinions than a concrete question, but:
If you were developing a package that requires a node graph editor, for future distribution (so no paid dependencies), what would be the best framework to build the graph editor on? GraphView (undocumented, only examples I know of are very complex)? Visual Scripting's graph (seems like it has all the issues of GraphView and then some)? One of the half-dozen Unity node graph frameworks on Github? Or build your own?
I would most definitely use GraphView, there is more and more community created info on using it (A video is pinned in this channel) and if you want there are open source extensions that make it easier to work with the data side. I think it was called "Graph Processor" or maybe "Blue Graph"?
Don't use the Visual Scripting's graph because it is going to be replaced with GraphView. (didn't even know it was public)
Don't make your own unless you have a good reason to. As you said, there are already a number of OS ones on github, and there is GraphView. The most popular IMGUI one is XNode I think?
Yeah, I've made my own before (back in Unity 5) and it just feels like wasted work to get it to even half the level of existing frameworks. I'll take a look at the community info and extensions for GraphView, thanks!
is it possible to render GUILayout methods onto a texture and display them in game world space ?
something to get a similar looking result to OnGUI() ?
for example something like this but rather in world space ?
looking at the reference code seems like
UnityCsReference/Editor/Mono/Overlays/IMGUIOverlay.cs
points to
UnityCsReference/ModuleOverrides/com.unity.ui/Core/IMGUIContainer.cs
which invokes DrawImmediate at
UnityCsReference/ModuleOverrides/com.unity.ui/Core/Renderer/UIRStylePainter.cs
but i still can't figure it out ...
I don't think so right now? World space rendering for UI Toolkit (and by extension IMGUIContainers) is still listed as "planned" in the 2021.2 docs.
You can render it to a camera that renders to a rendertexture
That you then can show in worldspace
how ?
do i need to create some sort of context before calling the GUILayout functions ?
and how would i decide which camera it would render to ?
Not sure how to do this but I assume it'd be possible somehow
Most of Unity's UI systems do not use cameras. As far as I know UGUI (i.e. Canvas) is currently the only one that can be set up like that.
Already stopped.
Hello !
I wanna revert a property (m_fontAsset) that is overriden on a TextMeshProUGUI, in a prefab.
I have a prefab into another prefab. the parent prefab has an override over the textFont and I wanna revert this one, and then it should take the child's one
Basically, I'm using this code :
public static void RevertOverrides(IEnumerable<TextMeshProUGUI> texts, GameObject root)
{
foreach (TextMeshProUGUI text in texts)
{
SerializedObject serializedText = new UnityEditor.SerializedObject(text);
SerializedProperty textFont = serializedText.FindProperty("m_fontAsset");
SerializedProperty textFontMaterial = serializedText.FindProperty("m_fontMaterial");
PrefabUtility.RevertPropertyOverride(textFont, InteractionMode.AutomatedAction);
PrefabUtility.RevertPropertyOverride(textFontMaterial, InteractionMode.AutomatedAction);
}
}
textFont and textFontMaterial aren't null, but there's something strange ; they seem to take the "values" of the child prefab, and not the ones from the instantiated prefab.
You can see below on the screenshot that "prefabOverride" is set to "false", but Bangers SDF is the override that should be reverted
Am I doing something wrong ?
More than that, I have plenty of errors on the PrefabUtility.RevertPropertyOverride();, but not sure to know from where it comes
so i am trying to make it so that gameobject replacer shows item to be replaced,but i don't know how to do that,any ideas what to do? https://pastebin.com/qLrn0rzM
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I think those might be coming from the debugger
Rider is a lot better for editor scripting debugging, it knows the type and only shows (and tries to read) the relevant field
Yes, they're not showing when not using the debugger
Well, with VS debugger I had sometimes different value at a different moment without changing the script, rider would be that much more pertinent ?
I have no idea why while getting the SerializedProperty of my go, it would tells me that it has no override while Unity's supposed to know that
Well, I found a way
I couldn't use the Unity's method, but if I copy it from their github and execute the inside of it, no problem
There is any way to group components in the inspector editor? For example a folder with all the movement scripts?
Create a folder, put all the movement scripts in
No why would you ever do that. You won't ever have dozens of components on one gameobject
I have a script component that I am moving to an editor menu item as a dll. I am creating the dll at the moment. The script uses a probuilder method which needs a 'using UnityEngine.probuilder;
Rephrased:
I am trying to create a Unity DLL for an asset that resides in the Unity menu bar system
My asset build tubes from the Probuilder library.
I am in Unity 2020.3.4f1 and VS2019. I have the reference to the 'using UnityEngine' but the Probuilder usages will not resolve.
I can not find the Probuilder.dll for the 'using UnityEngine.Probuilder;' reference. Any ideas?
Actually yes one could. There is a level of dynamism that needs swapping components in and out of GOs. It happens when up against a performance deprecation.. I do it as I build tiered GOs but dont need the code afterwards so I drop it. Then I have GOs that are moving in the game without the dead building code. The update() can become very large with 8000 GOs. It happens. Not all Unity projects are 2d sprites on a flat screen.
Well.. because I want to have folders. If its possible I want to do it
I think you would need to make a custom gameobject inspector to do that? Not impossible, but it's a reasonable amount of work and it will make your code incompatible with any third party extensions that need to use their own custom gameobject inspectors (because you can only have one).
Been looking around for a while...
what's the name of these buttons?
https://cdn.discordapp.com/attachments/361741445352259584/916517644381855814/unknown.png
im trying to create a custom tilemap painter, and couldn't for the life of me figure out how to find these, and they appear in a lot of packages
What do you mean exactly, the style is EditorStyles.miniButtonLeft, Mid, Right. To get the toggle effect you just style a Toggle with a button style. I'd look around the source and use the IMGUI/UIToolkit debuggers to figure out what the context is if you're looking for more info.
minibutton, thank you so much
Well... Clearly you can't put variable assignment outside of classes and methods
#💻┃code-beginner would be a better channel for this question.
If you have an actual editor scripting problem then sure post it here, but if you're trying to assign a variable outside of methods and classes go to #💻┃code-beginner
how can i use this code to save compressed textures? for some reason i'm getting
Unsupported texture format - Texture2D::EncodeTo functions do not support compressed texture formats.
with
using UnityEditor;
using UnityEngine;
using System.IO;
public class TextureExporter : MonoBehaviour
{
[MenuItem("Examples/Save Texture to file")]
static void Apply()
{
Texture2D texture = Selection.activeObject as Texture2D;
if (texture == null)
{
EditorUtility.DisplayDialog(
"Select Texture",
"You Must Select a Texture first!",
"Ok");
return;
}
var path = EditorUtility.SaveFilePanel(
"Save texture as PNG",
"",
texture.name + ".png",
"png");
if (path.Length != 0)
{
var pngData = texture.EncodeToPNG();
if (pngData != null)
File.WriteAllBytes(path, pngData);
}
}
}
I think you need a copy of the texture.
So...
using UnityEditor;
using UnityEngine;
using System.IO;
public class TextureExporter : MonoBehaviour
{
[MenuItem("Examples/Save Texture to file")]
static void Apply()
{
Texture2D texture = Selection.activeObject as Texture2D;
if (texture == null)
{
EditorUtility.DisplayDialog(
"Select Texture",
"You Must Select a Texture first!",
"Ok");
return;
}
var path = EditorUtility.SaveFilePanel(
"Save texture as PNG",
"",
texture.name + ".png",
"png");
if (path.Length != 0)
{
var texCopy = new Texture2D(texture.width, texture.height);
texCopy.SetPixels(texture.GetPixels(0), 0);
texCopy.Apply();
var pngData = texCopy.EncodeToPNG();
if (pngData != null)
File.WriteAllBytes(path, pngData);
}
}
}
I think that works.
Let me know if that works.
@whole steppe
Thanks, @ivory fulcrum! 🙂
It worked?
Oh, I should also recommend logging to the console or to a dialog if (pngData is null), or rather...
_ = pngData ?? throw new NullReferenceException("Could not encode texture to PNG");
Finally got around to getting menu customization working, thought it is a bit janky right now at least it works.
Instead of doing it 'properly' using the 'API', I am just registering a callback to the VisualElement of the project browser and preventing the event from going to IMGUI, instead opening my own menu.
It is a lot more stable this way and won't break hard coded stuff that executes menu items.
@ivory fulcrum Dunno bro. Too tired right now to test it, I was thanking you for helping me & continuing to help me. I will test it when I wake up 🙂
@ivory fulcrum yes, it did work! much thanks! How can I automatically enable read/write on the texture? also, for some reason my texture is invisible on windows but shows up in Unity. How can I make it visible on windows? I think it's called a "hidden" texture or something.
here it is, see how it's invisible? i don't want it to be invisible.
it will import into Unity just fine
as you can see
I am in the middle of this action right now.
I have a script on an empty GO that generates children in play. The generation specs keep because of the inspector values that I type in. But I only have GOs in play. I want the GOs in the editor too.
So I migrate the component to an editor menu. But now I have to find a way to save off those variables for each iteration of parameter entries for its specific GO model.
.
I am wondering if the 'registering a callback to the VisualElement of the project browser and preventing the event from going to IMGUI' will cause unforeseen problems in the future? Because I too would like something like this. Otherwise there is scripting involved that the dev has to do to reproduce the 'display' of the modifiable variables.
I use Visio 2010 for the pix.
I'm sorry I don't understand what you are trying to do. Or I guess, what you are trying to solve.
From your description I don't see why you would need to do what I am doing. What would be your goal with blocking an event to IMGUI?
someone can help? question above.
What do you mean "invisible"? Do you mean you can't see the file, or that it appears to be full alpha?
@gloomy chasm So I can see the texture just fine in the editor, but when I try to view it in any other program, it won't show up. I tried re-exporting it with an export script, but it was still fully transparent.
Hmmm, does it have the proper color channels?
It looks to me like you are displaying a component panel without having to reproduce the variables in an OnGui type method.
What? No not at all. On the left is a editor window with a list containing all of the menu items that are show in the menu when you right click in the project browser.
But, if you are wanting to show a component you can simply create an editor for one and call the OnInspectorGUI method for it.
This is the basic, of doing it. You would want to destroy the instance of editor before setting it, but otherwise that is it really.
private Editor editor;
public void ShowEditorFor(Object obj)
{
editor = Editor.CreateEditor(obj);
}
void OnGUI()
{
editor.OnInspectorGUI();
}
Wow. Thanks. You just save me major design headaches. I dont have to reproduce anything now.
yes it has the right color channels
@gloomy chasm
Not sure, sorry.
😦
So the file shows up, but the contents are just all transparent pixels?
Sent this in advanced code but realizing this might be a better place:
hey yall, I'm trying to write a custom importer to auto-generate TMP files when otf or tff files are imported, but I'm getting this error that I can find nothing about, and I'm not sure where I went wrong code-wise: "The asset is loaded, but not tracked. source hash='e297be892e5f61012d3aee81b5ef64a9'"
this is my first time working with the import pipeline so I don't super know what I'm doing but I don't think I'm too off-base code wise
http://pastie.org/p/0pjIbsed7B29269LkL9C5F this is what I have currently
That won't load
https://gdl.space/hufunezezu.cs does this work?
What's the line it throws the error on?
the code compiles, the error is thrown from UnityEngine.GUIUtility:ProcessEvent
It usually still says the line in the stack trace
I wonder if you're not allowed to create assets there 🤔
Try removing smoe bits and see what triggers it
Weird, I'd expect another error then
Hi all,
I'd like to know if there's a way to trigger some code when I drag and drop an asset on another one in my project view.
I have a "Collection" scriptable object that has a collection of "Item".
Right now, the way I populate this is by selecting the Collection asset, locking the inspector, then selecting the items I want to add do that collection and dropping them on the inspector.
I'd like to speed things up a bit by simply dragging and dropping an Item asset directly on top of the Collection asset. Is there a way to do this?
Maybe with https://docs.unity3d.com/ScriptReference/EditorApplication-projectWindowItemOnGUI.html and Event.current
Hi! Can i use the new 2021 graph view of unity (the "visual scripting") to create my own visual scripting window from scratch?
(aka this: https://docs.unity3d.com/2021.1/Documentation/Manual/com.unity.visualscripting.html)
i can't seem to find tutorials of where i can begin this
(Navi i'm back
)
You don't want to even if you can. The front end is going to be replaced with the GraphView, the same thing that ShaderGraph and VX Graph use.
There is a link in one of the pinned messages in this channel for getting started with it.
https://docs.unity3d.com/ScriptReference/Experimental.GraphView.GraphView.html
Yup, but note that it is only the visuals, you will need to handle the data and setting up the graph on your own.
yup! okok
i thought bolt was like a package to make your own windows, graphs, etc; which i missunderstood heavily
Oh, haha yes very much so not that.
They are working on package called Graph Tools Foundation which will be that, all Unity graph based tools will use it. However it has not been publicly update in some time.
hmm...
well, what if... Lets say i want to create a tool that will last through time, like... a lot. Should i use the graph view?
'Yes'
ooh, a rather timid yes 👀
You may need to make updates to it, but I don't foresee it being removed.
No problem. Just so you know, there is this community made package that is built on top of the GraphView API that handles the data side of things as well as already setting up a lot of the front end stuff. I have not used it myself, and don't personally like some of the styling choices they made, but it is something that exists if you want it.
https://github.com/alelievr/NodeGraphProcessor
i'll check this out, thanks!
@ivory fulcrum Yes, the file shows up but the contents are just all transparent pixels, the texture shows up fine in the Unity Editor but nowhere else.
Oh, and also: will the ui toolkit be deprecated, at some point?
No plans currently
i can't seem to find any tutorials on how to create my own graph view, sadly
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...
damn-
It's right there in the pins
😭
Is it possible to control the layering of handles? I have a dot handle drawn in the middle of a circle handle but the circle intercepts all input. I'm drawing the circle before the dot in the hopes that draw order has an effect, but it does not appear to
Here's the two handles with the circle blocking the dot
And without the circle handles you can click and drag the dot handle ofc)
(sorry, mouse is hidden in recording because sharex positions it incorrectly with my different monitor resolutions)
There is no easy way. I would look to see how they do it with the position handle. https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/EditorHandles/PositionHandle.cs#L275
(No idea if that is the right place to look, but with a quick look it seemed so to me)
thanks @gloomy chasm this looks promising. worst case scenario i bet i could try and offset its position more towards the camera. would make the math tricky but might work
or i guess i could try and make my own circle handle that requires you to actually click on the circle, not the inside, but ive always struggled with custom handles
Yeah, hope you can get it to work without too much work. You could also implement the controls your self maybe using the HandleUtility class. Let me know what you end up coming up with if you would.
will do 👍
Hey guys, let's say I have a gameobject field in a script in the scene that's filled with a file in the project folder... How would I access this project file through that field?
the texture Idle1 for example, how do i access that through editor script?
in the assets folder:
it seems a little silly to do it through name comparison, there's also instanceid but idk how that works
somehow i need to fetch the dataPath to the object that's in the Frames array on element 1
anyone know how?
I'm not sure exactly what you're trying to do, but generally you use the AssetDatabase class to work with asset files in the editor. So in this case perhaps https://docs.unity3d.com/ScriptReference/AssetDatabase.GetAssetPath.html
hells yeah, put me in the right direction, thx a lot @icy merlin 🙂
hells yeah it works
Hi all, Im looking to automate the process of adding Human template files to avatars in a editor script.
Does anyone know the process to apply a template to an avatar?
Hi!, could anyone advice me, how to setup vscode for unity C# plz
especious: my vscode add some crazy "import" paths on top when trying to write Deub.Log
Wrong channel
Hey everyone, Ive worked with Unity in small projects but at the moment im working on a game I want to upload on steam etc.
My problem is: How do I make my project multiplatform properly without messing up with the settings. Ideally I want it to be on pc steam, ios and Android mobile. These are my current settings:
You create your own builder that sets your preferred settings for each platform before calling build
Okay, the issue appeared when i wanted to test my game using Unity remote 5.
It only allows me to add adroid device.
Unity Remote is (afaik) outdated and if not, not a good representation of your app running on the device
Oh so how should I test my games on iphones? :/
Any suggestions?
#📱┃mobile ? But your question is answered. To test a game for iOS properly, you use an iOS device.
Alright I will write there, I do understand that i should use an Iphone. I already do. My problem is how to do it
I tried to reload a year old project where I used probuild and I'm getting some error related to a common issue, does anybody know how can I fix that?
Wrong channel
The class you're inhereting from isn't marked as abstract, or the function you're overriding isn't marked as abstract
unless you have access to the code of that class you're going to need read the documentation
I know that's the problem, I can read the console.
I just asked if somebody knew how to fix that since I touched nothing about ProBuilder and now its giving issues
probably some code changed
so read the updated documentation
Maybe you need to pass .DoAction() a function instead.
instead of overriding
Hi all, Im looking to automate the process of adding Human template files to avatars in a editor script.
Does anyone know the process to apply a template to an avatar?
Can you be more specific in what you want to know?
sure! i have a automation script that sets up all the players with their scripts that is needed. one of my tasks include removing the jaw bone in the avatar before it goes out, i made a .ht file that excludes that bone, and i can load it one by one on a avatar, i am looking to make this process automatic.
So you are not wanting to apply it to the imported model asset, correct?
im unsure i understand. im talking about this if that helps
To tell the truth I have never worked with it the human template files or avatars really. I just know the unity code base fairly well and know where to look for stuff. With that said, where is this window and where is it in the editor/inspector that you use a human template file?
if you click on a Avatar then configure
So that is just a Avatar file/object?
have ya tried using one of these?
https://docs.unity3d.com/ScriptReference/AvatarBuilder.BuildHumanAvatar.html
https://docs.unity3d.com/ScriptReference/Avatar.html
I did try something like that once or twice but i didnt get anywhere, perhaps i can try again.
so i can load the .ht into a human description class?
i could change the approach, if we can find out how to make the HT file apply on import
I have an editor that gens a GO. Is it possible to store the current editor state as a component object to the fresh GameObject?
I'm not sure what you mean by "store the current editor state", but you can add a monobehaviour containing whatever data you want by calling GameObject.AddComponent()?
would the settings survive a project reload ?
At the moment no, but that is trivial to do. Also, where you the one that wanted me to ping you if I got it working? Someone asked but I couldn't remember for the life of me or find it in discord history.
yes
i'd like to try it ( the context menu in my project is larger then 1080p so it becomes scroll-able - absolutely barbaric )
It is just in a prototype state atm, I plan on working on it more this weekend. I should be able to get it to a much more usable state, I can send it to you then if you want 🙂
Mine is in the same state of needing to 'scroll'
yea and fresh new urp project creation menu already takes 90% of the screen height
I have a lot of ideas like having multiple presets, and an option for a searchable menu instead of the normal generic menu. These are the the things I plan to add along with making it more stable of course.
woah that's alot
Yeah, but a lot of it is just really basic stuff.
i'd personally use something like " favorites " so instead of the normal create submenu it would show Favorites -> fav items ... , Default -> All Items ... *
this avoids the need to always re-open the menu window if one of the items is missing
You could just add like a "Assets/Create Favorite/" and leave the normal "Assets/Create/" unchanged.
true
i think i did try something similar before , but i dont know where are my scripts anymore lol , will wait for your one
^ hmmm i think this is it
What is the full workflow to instantiate x SO, save them in separate files, then have another scriptable object store these SOs in a list.
At the moment I am creating instances of SOs, assigning them in the container SO's list. After that I use CreateAsset to save them to a file. Then I use SaveAssets to save all the SOs and the container.
Problem is, upon serialization, the container SOs looses reference to a random number of SOs. For example, I'll launch the game, and the container serialized only 50% if the references.
To give more context, I create hex maps from editor code. A map is a SO that also contains a list of hex SOs. Everything is created on the click of a button. So I create an instance of Map, create instances of Hex, fill the Map list, save these to database.
Does this ring any bell to you guys? I'm loosing my mind here that my map only serializes a random number of hexes.
have you used the FBX presets before?
Are you making sure to set the object with the list dirt? If you are, you may need to save them and then set them in the list.
You mean just normal old presets?
Also, did those really not work?
I am. What do you mean by "save then set" ?
I mean save them as assets and then add them to the list.
Oooooh. That very well might be it. Gonna have to change the workflow a bit but I'll give it a try
we were able to remove the bone that we wanted out, but it messed up alot of other bones
i have a avatar made correctly
and if i an just tell it to use that one when models are imported it should be easy
but its not applying when i actually import models
or at least the models are still using their own
It might also not be it. But there are too many small moving parts that could be just slightly incorrect for me to be able to think of and suggest without any code. So if that doesn't work I would try recreating the problem with only the bare minimum so it is easier to debug.
Thanks. If it doesn't work, I'll strip it down to a simple example. It's the randomness of it that makes me go crazy. If the list was empty of references sure, but why in hell would it successfully save and load a random percentage of the hexes is baffling.
My current guess would be that when saved, the reference id needs to be changed... idk if that even makes sense the more I think about it but that is the best I got atm.
Yeah, well what you said made sense, say the ID needs to be changed BEFORE the Map is saved, then it would lose reference to that hex.
That's why I should save the hex before assigning it to the map.
Seems like it should be working...
Yeah that was my thinking, but again I could be wrong.
I know right! Lol
I’ll keep messing with it just glad I’m not going crazy
#🔀┃art-asset-workflow Would be a better and correct place for this question now.
Also, you can always ask on the forums!
ill move that way, thanks
Wow, it does it even on a simple example.
{
public int randomNumber;
}```
public class Map : ScriptableObject, ISerializationCallbackReceiver
{
public List<Hex> hexes = new();
public void BuildMap()
{
for (int i = 0; i < 10; i++)
{
var hex = CreateInstance<Hex>();
hex.randomNumber = UnityEngine.Random.Range(1, 1000);
var path = AssetDatabase.GetAssetPath(this);
path = path.Substring(0, path.LastIndexOf('/') + 1) + $"{hex}.asset";
path = AssetDatabase.GenerateUniqueAssetPath(path);
AssetDatabase.CreateAsset(hex, path);
EditorUtility.SetDirty(hex);
AssetDatabase.SaveAssetIfDirty(hex);
hexes.Add(hex);
}
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssetIfDirty(this);
}
public void OnAfterDeserialize()
{
Debug.Log($"{hexes.Count(h => h.randomNumber != 0)} serialized hexes out of 10");
}
public void OnBeforeSerialize()
{
}
}```
public class TestMapEditor : DataEditor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Create Hexes"))
{
(target as Map).BuildMap();
}
}
}```
The interesting thing is, if I change the list through the editor, it saves correctly. So I'm pretty sure it's the way I do it from code...
See anything wrong here? 🙂
What I'm guessing is that, since I don't set the list through serializedProperties, the Editor doesn't see the change on the list?
Why are you doing the count like that? hexes.Count(h => h.randomNumber != 0)
It's just a way for to check if the randomNumber was saved
Wait... so the list is saving...
The list is saving with the good amount of elements, but a random amount of elements are "defaulted"
It is the hex that is not saving
Sorry if I didn't explain right
Well, thing is, it IS saving correctly. If I open the asset file, the random number is there...
That is a 'completely' different problem. I thought the references were null in the list.
It is the wrong reference then in the list
Try loading the asset and adding the loaded asset to the list instead. Another thing to do is on deserialze check if each item is persistent.
Or I guess is an asset.
So this is what I get on play.
Index 2 and 9 didn't serialize properly. I'll try to check if they're persistent
BUT
Map.asset is referring the good ID of Index 9
@hushed oar I think I figured it out
👀
The problem seems to be that the references are not all resolved when deserialization runs.
It works fine if you check it manually
How can that happen?
threads
😱
"Care needs to be taken whilst within these callbacks, as Unity's serializer runs on a different thread to most of the Unity API. It is advisable to only process fields directly owned by the object, keeping the processing burden as low as possible."
So the references would be fixed AFTER the call? So the only problem is my debug line?
As long as you don't need to edit the values of the scriptableobjects in the list at deserialization for some reason
So just to make sure I understand, it is possible that my fields aren't ready to be read/edited during OnDeserializedCallback?
That kindof... explains a LOT
When looking at different objects
Than "this"
Yes and no, the fields are but not the references. Basically don't read or edit the data of other scriptableObjects inside of OnDeserializedCallback
That's actually great, I also do this in my original Map/Hex setup. Fantastic. Thank you!!!!
You're welcome! Glad we got it figured out.
I didn't know this is how it worked exactly either, so I learned something new too!
Yeah that's really good to know haha
I got a good one for you then. Say my map actually wants to store the hexes in a 2D Array [,]. Obviously Unity can't serialize that. So I serialize a list of hexes instead and upon deserialization, I create my 2D array. Considering what we've just learned, I cannot create my 2D array on deserialization because some values of hexes will be null. Any ideas how I can go around that?
No, I think that should work fine since you are just passing references and not read/writing data of them
But the hexes store their own coordinates. So I need them to assign the hex at the right indexes in the array: [x,y]
What? No, you just flatten the list of hexes and then unflatten it. All you need to do is have the map store the width and height of the 2d array.
Right, I'm actually using a different coordinate system, so it's not easily flattened but that's most likely the right answer still
The two have nothing todo with each other. I am simply talking about converting an elements index in a 2d array to an index in a 1d array. Nothing more.
Hey all, my team and I have been using Collab for a while to work on our app, but frankly Collab sucks and we're thinking of changing over to PlasticSCM. I was wondering if you brilliant folks had any thoughts before we make the switch and if there are any things we should look out for in the conversion process
Never used it my self but I just saw a thread on twitter about someone using it, maybe something in there will be interesting for you.
I doubt you will get much input in this channel as it for talking about creating extensions to the editor rather than talking about existing ones.
https://twitter.com/docky/status/1468251363763183617
Ahhh my bad, misunderstood the channel - thanks @gloomy chasm
No problem, it is pretty common thing!
I have built a menu editor. This is the bees knees. I generate GOs in edit rather than play.
Some of the input fields are m_GameObject1 = EditorGUILayout.ObjectField("Label", m_GameObject1, typeof(GameObject), false) as GameObject;
I notices that only prefabs can be dragged here. Doco on ObjectField is sparse.
Any way to get a hierarchy GO in that field?
I also noticed the Monobehaviour type object is not valid in an editor menu. I need to connect a script to a editor menu gend object.
Any ideas?
I think you want your last param allowSceneObjects to be true instead of false, if its false only project objects like prefabs and assets will be valid, if its true, that should extend to hierarchy/scene objects as well
You should be able to access UnityEngine.Object from even a editor script, I dont think thats exclusive to MonoBehaviours, but you can also use a cheeky workaround, and use UnityEngine.GameObject.FindObjctOfType<T>() directly from a editor script to basically get access to any scene object, of course using Find... methods isnt super efficient (moreso if you have a large or complex/deep-nested scene), its just an option
Thanks. I will check these next session tomorrow.
Looks like there is no longer any need for me to do it now haha. I am curious how they went about it...
Yeah, material variants, woo!
Out of curiosity I took a look at how they implemented it, I should have guessed, it is just baked in to it. Looks like the overriding and inheritance of values is handled C++ side
So [InitializeOnLoad] allows you to have a static class constructor run whenever the editor starts OR whenever the scripts are compiled.
... ... ... because it can happen during the editor runtime (if you recompile scripts) what do we do if we need to clean up? Is there an event / etc. that we can hook onto?
If scripts are being recompiled most things will be thrown away, so there's a good chance there won't be anything to clean up.
In theory there's https://docs.unity3d.com/ScriptReference/AssemblyReloadEvents.html to get notified before and after assemblies are reloaded (e.g. from recompilation or play mode), but I haven't used them so I can't swear to their reliability.
The object that I'm keeping alive (a RESTful web server) needs to persist in and out of play mode.
So AssemblyReloadEvents won't work (unless I figure out how to ignore switches in and out of play mode). That said, this (assemblyCompilationStarted) looks promising https://docs.unity3d.com/ScriptReference/Compilation.CompilationPipeline.html
Why won't it work?
Because it would be called before play mode and shut down the server while I'm still using it.
Correct... but trying to infer state from two separate sources is brittle.
Wait, what are you wanting?
What if Unity swaps the order?
Current use case is to have a web server remote control Unity Recorder.
(I sorry, I misread at first, thus the playmode suggestion)
I mean, what are you asking for. Do you want a callback when scripts recompile or not?
Mostly high-level whether there's a canonical pairing to [InitializeOnLoad] static constructor to destruct... callback when scripts recompile would be a useful fix but slightly brittle. Looks like CompilationPipeline::assemblyCompilationStarted might be a good option.
If there were a canonical pairing to InitializeOnLoad it would be called before you enter playmode, because entering play mode will call InitializeOnLoad again.
It sounds like "every InitializeOnLoad" isn't actually the lifetime you want for this service?
Ah... weird... I tested that but it looks like that's the case. Hmm.
(Unless you have domain reload on play mode turned off in your options, which is possible but not the default.)
That is exactly what the assembly reload event is... When you enter playmode the domain is reloaded and when scripts recompile. There is no getting around a domain reload on play unless you turn domain reloading off.
Buttttttt then how does editor scripts persist across reloads?
They don't. Which ones are you talking about?
So if I want to start something when the editor launches and leave it running until the editor closes, there's no way?
Generally anything that persists information across reloads does so by serializing its state to a saved object.
There is no way because the domain reloads, clearing it.
Serialization is the only way to persist data.
So there's no distinction between runtime and editor domains?
Not in the way you are wanting.
If the "something" is an outside application and you don't need to keep a reference to it (which sounds like it might be the case here?) you could start it in InitializeOnLoad if it's not running, and end it in EditorApplication.quitting?
It's a .NET standard 2.1 DLL.
Ah, so it's still part of the Unity application? Then yes, I would expect it to be killed automatically when Unity reloads the domain, nothing you can do to change that.
So now I'm confused about how typical Unity tools work (C# ones of course... C++ are obvious)
Like Unity Recorder pushes the editor in and out of play mode.
It just serializes the fields.
EditorWindows are serialized to disk on domain reload so all of their serialized fields are as well
Yep, though it's a little more evil than that; on domain reload Unity will automatically serialize everything serializable in all loaded scripts - even private fields which aren't marked for serialization. So everything comes back almost but not quite exactly the way it was before.
(Can you tell I've had to debug far too many issues caused by this.)
Yeah.
So I should just use an external process for a web server then.
That... complicates a lot.
If you absolutely need it to persist in and out of play mode then yes, I think that's probably best? You could disable domain reloads on entering play mode, but my intuition is that that will just move your problems somewhere else.
Yeah we could disable domain reloads, but I'm trying to keep things as simple as possible.
How do Presets work by code? I feel like im misunderstanding something about the docs for it - I have this bit of code, after I click a button to call a AssetDatabase.ImportAsset(Selection.activeObject), it re-imports whatever fbx I had selected, and console prints its name then if the Apply worked, it always prints false so the model import settings dont get applied (same happens if I manually re-import from the context menu or drag a new fbx into the project), maybe im doing this incorrectly?
public class AssetProcessor : AssetPostprocessor
{
void OnPostprocessModel(GameObject g)
{
string presetPath = "Assets/Presets/FBXTest.preset";
var preset = AssetDatabase.LoadAssetAtPath<Preset>(presetPath);
Debug.Log("Preset on " + g + ":" + preset.ApplyTo(g));
}
}
Im still trying to learn how Presets work in general, and so far I havnt found much code for it, just the manuals, what id like to basically do is automate importing, so when I import any .fbx file, itll auto-apply whatever settings are in the Preset - I also tried using var importer (ModelImporter)assetImporter; which prints null, but ApplyTo still takes it with no problem, id assume it would at least print a warning or error or something o.o
I haven't used them, but I would certainly assume that an FBX import preset would need to be applied to the ModelImporter in OnPreprocessModel? Once it's a GameObject it's too late to change any of the import settings.
I tried casting it as a Object as well, but im not sure if my brain is too tired or I misunderstood - do you mean var importer (ModelImporter)assetImporter; when you say applying the FBX preset to ModelImporter? I also tried this and it seems to print null, and I cant specify any params in a new ModelImporter, is there another way to set it?
As I said, I'm mostly guessing. But I would hypothesise that the reason assetImporter is null is because you're accessing it in OnPostprocessModel, after the import process is finished and it has already been used. Any changes to its settings would need to be done in OnPreprocessModel.
I'm trying to auto-generate textmeshpro assets from script when a font is imported into Unity, and the assets are created and have the reference to the font, but it seems like they don't actually generate the atlas texture or anything like that, so there are no characters and it shows this for the textures:
Ah wow, I think you were right, I must have been calling it wrong cause I thought I tried with OnPreProcess and got not model name from the importer, so I thought it the object maybe had to been passed instead - looks like its working now, thanks for the help
missing class " prefabs stage utility " :UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage()
.. The type or namespace name 'PrefabStageUtility' does not exist in the namespace 'UnityEditor.SceneManagement ..
anyone knows what it was upgraded to ?
I don't think PrefabStageUtility has ever been outside the Experimental namespace?
thanks
in which file the project editor version is stored ?
What?
Porject Version - that defines what editor version would get launched from the Unity Hub
ProjectSettings/ProjectVersion.txt ?
If you want it in code there is https://docs.unity3d.com/ScriptReference/Application-unityVersion.html
yes that , but is there anywhere else ?
trying to restore a project version , edited this file but the Hub still shows the new version i tried upgrade the project to 🤔
Try removing it from the hub then re adding it?
did that
Hey, can where help me to implement the XBL in unity
How To open a custom EditorWindow when doubleclick on custom ScriptableObject asset in project window?
OnOpenAsset callback
I apologize if this is the wrong place to ask this question, but have any of you had trouble generating lighting (via the button in the Lighting window) since switching from Collab to Plastic SCM? When I click the Generate Lighting button, I get hundreds of errors that Unity is not able to access files it needs to compute the lighting, and the build lighting background process just hangs.
bizarre. Your SCM shouldn't be interferring with light generation
Thanks for the response. I was afraid that it might be locking files. When I try to modify a prefab in the Project pane, Plastic forces me to check the file out before I can change anything.
Ok, I'm sorry. Nevermind. I restarted Unity, and magically it works now.
OH okay yeah then that sounds like it is Plastic SCM. Unfortunately I don't know enough to help you troubleshoot but it's worthy post for general coding- focus on the fact that PlasticSCM seems to be locking your files and now you can't operate so well
If I had a nickel for every time that happened, I'd be able to afford my utility bills
Yeah, I know. Me too. 😉
I've extended GraphView.
I lost my created nodes in the grid.
How can i found them back?
There is a way to constraint the view to keep view at least one element?
or... idk should I add arrows to point out of view elements?
Pressing F should do the trick
(I mean pressing F should center the view on all nodes)
It works perfectly
until the nodes aren't too far from each
but it's fine
how to asks user data to fill the node data with context menu add option?
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
Vector2 mousePosition = (evt.mousePosition -
new Vector2(base.viewTransform.position.x, base.viewTransform.position.y)
) / base.viewTransform.scale.x;
evt.menu.AppendAction("Aggiungi Nodo", action => CreateNode(mousePosition));
}
fk I renamed the fine where i was working with UI Builder and now it's all broken
fixed.. in the there was an error in .uxml
I'm using the A* pathfinding package, and for some reason my seeker does not attempt to path to it's set target. I have no clue why. It's settings are all default, and setting the seeker manually works for some gamobjects, but not this one. Why is this?
It seems to only happen with certain gameobjects, if i set others to be the targets then the enemy paths towards them fine
it might not be able to find a path then
The target i've set is an empty gameobject within a very clear path to the enemy with nothing blocking it
its also not inside any other gameobjects
also, If i change from a 'valid' target to one that doesnt work, it still keeps on going to that 'valid' target instead of stopping
i have this code
and when it runs i get this error
NullReferenceException: Object reference not set to an instance of an object
GameNetworkGUI.PickTeam (System.String _teamcolor) (at Assets/Scripts/Server/GameNetworkGUI.cs:35)
UnityEngine.Events.InvokableCall1[T1].Invoke (T1 args0) (at <e7c72e4b0bcb4085b636d7e8921f7453>:0)
UnityEngine.Events.CachedInvokableCall1[T].Invoke (System.Object[] args) (at <e7c72e4b0bcb4085b636d7e8921f7453>:0)
so i have no idea whats wrong
the print statements give me the correct information
GameNetworkGUI is the script that this code is in
so im not sure what the problem is
{
print(_teamcolor);
print(connID);
gameManager.PickTeam(connID, _teamcolor);
}```
im using mirror
for networking
how do i get the words such as 'CharacterController' and 'MonoBehaviour' to be highlighted?
the pure white makes it kinda harder to read
current:
#854851968446365696 look how to set up your IDE
ah okay ty
Hey people. Anyone know of a quick way to tell an Editor to be drawn with UI Elements without having to manually construct it yourself?
You can create a default editor for all MonoBehaviours that is drawn with it. Or create a base editor that uses UITK and then just inherit from it. But there is no built in toggle. You could try overriding the UITK method and keep the base implementation and see if that works. I don't remember if it does or not.
Thanks! Last time I tried keeping the base didn't work, so I'll go with one of the other options.
how do i make these do something because for me its not working when im trying to follow a tutorial
thats the whole script but it doesnt load the game scene when i click the button
you have to subscribe StartButtonpressed() to the clicked event of course
Greetings everyone I have a problem that may sound very common but I had no luck fixing it. I'm creating a custom editor and it doesn't save the values. I have tried EditorUtility.SetDirty(target); but no luck
Doesn't save the values when?
when I close Unity and reopen it
For components you may also need to do EditorSceneManager.MarkSceneDIrty(..)
Really it is best to use SerializedObject and SerializedProperty when making custom editors though
I've never figured out all the rules, but I wouldn't be surprised if SetDirty isn't reliable if you call it while other code has the object serialised (e.g. inside an Editor's OnInspectorGUI?).
I'm using a scriptable object so making the scene dirty wouldn't help much
but i'll check the SerializedObject && SerializedProperty
Is it possible to use AssetDatabase.ImportPackage(path, true); in a loop that can somehow "wait" (like a coroutine, for example) until you decide to do something with that dialogue? Basically I want to make a editor that lets me select a bunch of .unitypackage files, and import them all at once but still let me decide which files from those packages I want to import, just using the for loop as-is, will only show the dialogue for the last index of the loop (since Unity doesnt make multiple import windows it just updates the current opened one), is there possibly a not-janky way to go about this?
I tried the UnityEditorCoroutine class for some reason even though it says its imported correctly and shows up as a package, the namespace just doesnt want to exist in Unity namespace or UnityEditor which the docs say it should exist, even with a full project re-import, so im wondering if theres maybe a native/practical way to approach this or a way to get the namespace to be recognized by the Editor assembly? (assuming its an assembly issue), right now im thinking I could maybe use the "importComplete" callback and basically just import element 0, when callback fires, remove element 0 and repeat recursively, (which so far seems to work) but I feel thats janky
I don't think that's how it will get solved, I I'm trying to get my head around serializedObject and SetDirty,
What are you having trouble with?
There isn't a way to queue multiple like you want. The best you could do is just start importing the next as soon as one finishes. Also, if you are using assemblies then you will need to reference the editor coroutine assembly.
Ah alright, ill go with the "janky" approach then, it seems like the best way - I am just assuming its under a different assembly, since I know anything in the Editor folder gets put under a different assembly than the MonoBehaviour scripts, and I would have thought EditorCoroutines would be automatically added to that same Editor assembly, but if its not showing up, my guess is that its probably installed in my project somewhere, just not in the Editor assembly? How could I find this out? Currently im not really sure where EditorCoroutines exists in the project, but PackageManager says its installed
Sorry, I should have said assembly definition reference. If you have one, then you will need to reference the EditorCoRoutine assembly def ref.
Ah ok, ill look into that further, thank you btw
how can i get the ui scaling from preferences?
i found out that an old asset store plugin uses hardcoded values for a few things so it doesn't work if your ui scaling isn't at 100%
i just need to know what namespace/class/variable that ui scaling can be retrieved from
What are you needing it for?
trying to make an old asset store plugin work for 2020.3
i found this in the code: // I can hard code this b/c the transform inspector is always drawn in the same spot lmao var dragRect = new Rect (16, 105, EditorGUIUtility.labelWidth - 10, 10);
the dragRect doesn't work and i'm pretty certain it's bc i need to account for the ui scaling
Did you change the UI scaling?
i have mine at 125% since i use a large monitor
It is EditorPrefs.GetInt("CustomEditorUIScale") to get the UI scale
Or so it seems.
You're welcome, hope it helps!
hey guys
im wondering if anyone can help me succesfully import this third party plugin
i keep getting this error on a fresh project, and am lost on what to do
Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform. (C:/Users/37067/Desktop/New Unity Project/Library/PackageCache/com.unity.nuget.newtonsoft-json@2.0.0/Runtime/Newtonsoft.Json.dll)
It is because multiple packages/assets/plugins are shipping with the same dll without renaming it. Look for file called Newtonsoft.Json.dll in the pcakage and renaming, iirc that should fix it.
@gloomy chasm i need to use the imported version of the psckage, so then should i rename the version that ships with unity?
No... you either remove or rename the one that is in the imported package...
okay, will try renaming that dll
@gloomy chasm i then get this issue
C:\Users\HP\Code\Unity\web3-test\unity-solana-wallet\Runtime\codebase\utility\ObjectToByte.cs(101,38): error CS0433: The type 'JToken' exists in both 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' and 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null'
after renaming the dll and meta
Renaming a DLL does not change its content
It fixed the first error though 👌
( 😛 )
The only solution is to delete the dll that is shipped with the package right?
what if that dll has been modified such that the package requires it
dll resolution blows, and it's kinda astounding Unity didn't think this problem wouldn't occur very often.
To solve it on my projects I have a fake com.unity.nuget.newtonsoft-json that doesn't contain anything, so I could resolve Newtonsoft.Json with a DLL of my choosing.
If they modified Newtonsoft's json serializer and then repackaged it as a dll and didn't change the namespace or dll name... -_-
Yeah, idk how they didn't think "Oh maybe multiple assets/packages will use the same dll"
when i delete it, i get this error lol
C:\Users\HP\Code\Unity\web3-test\unity-solana-wallet\Runtime\codebase\utility\ObjectToByte.cs(104,13): error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'
thank you. I believe its either this or pointing the packages newtonsoft to the unity version
and then seeing if this is the case
both things i've no idea how to do 😂
https://github.com/vertxxyz/UPM-Newtonsoft-JSON-Empty
this was the package I created to resolve the error for me. Then in the package manifest I have "com.unity.nuget.newtonsoft-json": "https://github.com/vertxxyz/UPM-Newtonsoft-JSON-Empty.git",
and that overrides that package entirely
@visual stag I would change that in the package-lock.json?
that should update automatically I think
under packages
you may have to remove the lock for com.unity.nuget.newtonsoft-json if there is one in there
Just updating manifest.json to replace the old com.unity.nuget.newtonsoft-json should do
👍 it's a dependency only
so i added it and removed the depenancy from the lockfile
this is the resulting error
I would restart Unity and then check how things are.
Is there a way to change what the "Apply" and "Revert" actions are for a custom property drawer? I have a tree-ish data structure that I have a property drawer for and when a item is reverted/applied I also need to change another serialized property. Is there a way to do this by chance?
Is there a way to draw a texture from an atlas with IMGUI, for example with GUILayout.Box(texture, -> texture coords <-) ?
I have a bunch of icons in an atlas, but unfortunately if I pass the atlas texture, it expectedly just draws the entire atlas.
I would probably look into getting a Texture2D from the position on the sprite atlas, and then use that in GUILayout.Box(). But I don't know if that's how it works.
Yeah I'm not sure if I can get a Texture2D from the atlas + the position, but I'll look into that.
How can I truncate overflow to stop Unity doing this?
I would like to just cut off the word before the labels start overlapping
Change the https://docs.unity3d.com/ScriptReference/GUIStyle-clipping.html field ofthe foldout style
Let's see ...
@waxen sandal
GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout);
foldoutStyle.clipping = TextClipping.Clip;
serializedProperty.isExpanded = EditorGUI.Foldout(idRect, serializedProperty.isExpanded, label, toggleOnLabelClick: true, foldoutStyle);
No dice. I'm probably doing this wrong.
Looks okay but foldout might use the normal label style for drawnig the label, not sure. You shoud check the reference source
To be fair, GUIStyles aren't really designed to draw multiple things
No way to change the label GUIStyle either
So it's fitting a square peg into a round hole
Unless I'm missing something
I suppose I could just stop showing too many things on a single line and accept the limitations 🧙♂️
The eternal struggle
You can try changing editorstyles.label
with UI Builder and UnityEditor.Experimental.GraphView how to change color of edges with a gradient from output port to input port?
want to achieve this result:
Say I create a prefab with a custom script "MyCustomScript". Is there some kind of event that I can hook onto to register this new instance of MyCustomScript to my CustomScriptManager that is also in the scene? The way I have it solved now is that I press a button on the Manager to get all instances of MyCustomScript in the scene, but fetching them automatically would be more elegant.
I thought of creating a "RegisterMyCustomScript"-class that executes in editor mode and has an OnEnable()-function that registers MyCustomScript but that seems to be... not very nice.
OnValidate() seems to do the trick.
OnValidate is executed a lot more than once, be sure to check whether ti's not already added
Apparently OnValidate does not get called when you drag a prefab in the scene, so it is not what I was looking for. :/
I'd use executeineditmode probably
With OnEnable
Or make a custom editor for the component that has an OnEnable as well, think that might also always work when you add it to the scene
Alright, thanks.
This is what I ended up doing:
public override void OnInspectorGUI()
{
DrawDefaultInspector();
[...]
if(!isRegistered)
{
RegisterCustomScriptInManager();
isRegistered = true;
}
}```
That doesn't persist if you deselect it by the way
I'm not sure what you mean. When I create my prefab by dragging it to the scene it gets selected and my function gets called once. Am I missing something?
If you select it again then RegisterCustomScriptInManager will be called again
I see. Yes, that is not very nice. In my case it should not cause any problems but I'll keep that in the back of my mind. Thank you again.
I solved my problem.
public class NodeView : Node
{
[...]
public readonly Port inputPort;
public readonly Port outputPort;
public NodeView(StateData stateData)
{
[...]
if (stateData.key != StateMachineMapSO.FIRST_STATE_KEY)
{
inputPort = base.InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Multi, typeof(bool));
inputPort.portName = "precedente";
inputPort.portColor = Color.red;
inputContainer.Add(inputPort);
}
outputPort = base.InstantiatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Multi, typeof(bool));
outputPort.portName = "prossimo";
outputPort.portColor = Color.green;
outputContainer.Add(outputPort);
}
}
I'm having an issue:
- I have a custom button in inspector
- When I press my button, it grabs RectTransform info and stuffs it into a custom class (for transform, scale, ect)
- I can see the info in my inspector, the button does it's job
- When I press play, that info wipes
I read up a bit about serialization and thought that serializing my class would help but it still wipes on pressing play. Any ideas what I may want to look into next?
you should create a scriptableobject with that infos
check AssetDatabase methods
and than attach the SO to your monobehaviour to use it in playmode
@silent stratus
Hi all
I'm using an asset, which has an SO that has a custom inspector
I'm now subclassing that SO but the custom inspector is still what's drawn for that base SO
If i do DrawDefaultInspector, i guess every custom thing from the base SO will be drawn again in default
Is it possible to only do DrawDefaultInspector for the subclass properties, and not the base SO?
Ah found this..
https://forum.unity.com/threads/is-it-possible-to-mixed-inherited-custom-inspector-and-default-inspector-for-not-inherited-members.516813/
Thank you for the reply. The component that I am trying to do this on may be placed on potentially dozens of GOs in my app and they may all act a bit differently. Is this still the best way?
I think
Ok, thank you, I'll look into it. 🙂
public override void OnInspectorGUI()
{
StateMachineMapSO obj = target as StateMachineMapSO;
Tree.BeginDraw(false);
if (obj != null && obj.transitions.Count > 0)
{
InspectorProperty someProp1 = Tree.GetPropertyAtPath("transitions");
foreach (InspectorProperty child in someProp1.Children)
{
string propertyPath = child.Path.Split('"')[1];
if (propertyPath == selectedKey)
{
foreach (InspectorProperty grandChild in child.Children)
{
if (!grandChild.Path.EndsWith("#key"))
{
grandChild.Draw();
}
}
}
}
}
Tree.EndDraw();
}
this code shows only one specific value of a dictionary.
How to modify the result? for example I want to change the name Value
I would ask in the odin discord server.
what would be the best way to slap a button right here? i figured this out before, but can't find my old code for the life of me 😅
This is what I did https://paste.mod.gg/przakxxmmudl/0
A tool for sharing your source code with the world!
ooh thanks! for the ViewUtility and AccessUtility are those custom reflection utilities?
found it AccessUtility on your core repo haha 🕵️ 🔎 (looks slick btw)
Oh well thank you. The ViewUtility is just used for getting the editor assembly typeof(Editor).Assembly
I'm going to ask again on the off chance that some one who knows will see it. Is there any sort of callback or way to tell when a serialized property has had "Revert" or "Apply" invoked. Or I guess a way to change what that does? I need to modify(but not revert or apply) the value of another serialized property when one changes.
Well I found this which I find very interesting, but not helpful for me. https://docs.unity3d.com/2021.2/Documentation/ScriptReference/IApplyRevertPropertyContextMenuItemProvider.html
This issue was raised so many times in so many years, I dont think we will see anything on the C# side
Hi, I want to do custom editor of class without monobehaviour, and without using PropertyDrawer, but I can't convert target.
I want to hide value when checkbox is false
[System.Serializable]
public class ExampleClass
{
[SerializeField] public bool checkbox;
[HideInInspector] public int value;
}
[CustomEditor(typeof(ExampleClass))]
public class ExampleClassEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
ExampleClass script = (ExampleClass)target; // ← Cannot convert type 'UnityEngine.Object' to 'ExampleClass'
if (script.checkbox == true)
{
int value = script.value;
script.value = EditorGUILayout.IntField("Value: ", value);
}
}
}
Hello, do you know if its possible to get nonserializeObject ?
Editor requires the target to derive from an Object, no?
Depends on the context, usually no, but in some case yes (like the above)
like the exemple of Marieldrill ?
Yes
Because she has access to the Object directly (and not its Serialized version), from the Object you can access whatever you want
so, if in ExempleClass, she have "private bool myBool", she can access it ?
Yes
SerializedObject allows provide you access to serialized data
From an Object, it's pure C# doing 🙂
and, if my calss inherit from monobehaviour, i can't do that so ? i need that my class inherit from nothing ?
2 cases:
Either you inherit from MB (MonoBehaviour), then you will have anything under that is serializable.
Or your class must be serializable and live under a MB
I have to admit that i don't really understand rn... :/
anyone familiar with how shader graph generates the code ? i want to use shader graph asset files to generate matching c# code
was thinking to build my own GraphView but kinda hoping to get away with just using the asset files since it already does exactly what i need
Hi, can I somehow get the dimensions of an image file on the hard drive (that is not imported as a Unity asset) from a Unity in-editor (not runtime) C# script? (please ping on reply ❤️ )
Currently leaning towards calling some powershell stuff from terminal and writing that to a temporary file on the hard drive (since powershell has .net access, including access to System.Drawing) - that the C# script later on reads from, but Im thinking maybe there is an easier way?
What file format of the image?
Png & jpg, but I would like to support as many file formats as possible
^ png is perhaps most important
I'm using Visusal Studio Code, and it normally works, but today i got this error:
Extension 'ms-dotnettools.csharp' CANNOT use API proposal: quickPickSeparators. Its package.json#enabledApiProposals-property declares: [] but NOT quickPickSeparators. The missing proposal MUST be added and you must start in extension development mode or use the following command line switch: --enable-proposed-api ms-dotnettools.csharp
Does anybody use Mob Sakai's Soft Masks For UGUI?? It seems like all of a sudden my mask actually hides all of its child sprite and doesn't work as intended. Has that happened to anybody?
I want to know how to use assetDatabase.IsValidFolder, so lets say i want to make sure from editor script do i have a spesific folder before using something in that folder, and i believe it take string to a path so if my folder structure like "Assets/Graphics/Balls/FolderiLookFor" do i pass like tjis for path??, because when i tried even i did a 1 wrong character its still return true?
hey, does anyone know how to replicate [CreateAssetMenu] attribute behaviour, without actually using that attribute
I'm struggling with item selection in a ReorderableList.
How can I get the selected items? All it has exposed is ReorderableList.index which only gives you the active item
i've tried the internal m_Selection, but I can't seem to make it work 😓
Use IsSelected(index)
or .selectedIndices
These were very easy to find using intellisense
@visual stag those don't exist in my version of Unity (2020.3)
is that a recent addition?
ah and I was checking the wrong source code version, of course m_Selection doesn't work, it doesn't exist in 2020.3
😓 whoops
Maybe, but I swear I have used IsSelected before
yeah I was under the impression multi-selection was supported based on the tests i've done with ReorderableLists in the past (which may have been in the latest engine versions)
i don't think it's supported at all in the current LTS
it has the usual bools for drawing the elements (selected, focused, active...)
maybe you're thinking of those?
public delegate void ElementCallbackDelegate(Rect rect, int index, bool isActive, bool isFocused);
public void DrawElement(Rect rect, SerializedProperty element, object listItem, bool selected, bool focused, bool draggable);
at first glance it seems like any sort of multi-selection related things appeared on Unity 2021
Maybe, but you can use that and onSelectCallback I suppose
yeah, seems like I just need to handle my own multi-selection, I can do with some crude implementation for now
i want my tools to support older versions of the engine, otherwise I'd just upgrade to 2021+
There's little reason to use reorderable list post 2020 as lists are reorderable by default
It's very nice, saves so much of my time
yep, but ReorderableList is still needed for editor tools
either that or TreeView
(for custom data types I mean)
Only if you're not using property drawers for whatever reason
when I use ReorderableLists it's usually because I want more customization over how they look and behave
when I want to mimic Unity's default appearance I just go for property drawers
You would useObject.CreateInstance<T>(), AssetDatabase.GenerateUniquidPath(..) andAssetDatabase.CreateAsset(..)
what should i install to vscode to get code completion?
Is there a way to get the selected index on an array that's drawn using a PropertyDrawer?
I'm writing some utility scripts for collections and I've been stuck on this for a while 😕
Nope, not at all*
(You could use reflection on the utility class that stores the instances of the ReorderableLists and find the one for your property)
what class is that?
Don't remember sorry
Just open up dnSpy and find all usage of ReorderableListWrapper and you should see it right away
Are you drawing it with EditorGUI.Begin/EndProperty or EitorGUILayout.PropertyField?
@gloomy chasm thanks for the pointer! 🙏 I'll go do some digging
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
using (new EditorGUI.PropertyScope(position, label, property))
{
DrawProperties(property);
}
}
private void DrawProperties(SerializedProperty property)
{
EditorGUI.PropertyField(...);
EditorGUI.PropertyField(...);
}
it's easy to get the selected index on mouse events by testing mouse position against rects, but I need to get the actual selection index that Unity has internally
because it survives the enable/disable of the inspector
Ah ok, I thought you could maybe loop through the property and store the index as you draw it with property.GetArrayElementAtIndex, but if PropertyField itself is already drawing the whole array at once, that might not help you
Though they might be using [SerializeField] on that internal index reference, or a really cheecky way to get around it might be to use EditorPrefs but I feel thats a very "it works but not the best approach" solution
Yeah i'm trying to use an elegant solution
I could do that and store the index on the class instance itself. But that's a bad solution, I don't want to pollute runtime classes with editor data.
I could also use a wrapper class for editor-only purposes, or store the index data in editor prefs or a file, but that's also not great
Unity is storing the data somewhere, I just need to know where to look
using a ReorderableList for this is very convenient because it has it exposed through the public API. But with PropertyDrawers is trickier 😓
Ah, gotta love the Editor API lol
it's so inconsistent, some APIs are great, others are super basic or nonexistent 🙃
for example you have the TreeView API, with everything you can possibly dream of, then you get PropertyDrawer... that only gives you a measly FieldInfo
Very true, some of the API just doesnt make sense to me (but that could be cause im still pretty new with Editor scripting), most of the time im running janky solutions and Reflection with Linq to try and solve some issues and it just feels "all over the place"
Any clues?
@gloomy chasm hey thanks a lot for the help earlier. I figured out how to get instances of ReorderableLists that are inspected through the internal class PropertyHandler
public static class PropertyDrawerUtility
{
public static int GetSelectedIndex(string propertyName)
{
object reorderableWrappersObject = PropertyHandlerProxy.s_reorderableLists;
IDictionary dictionary = (IDictionary)reorderableWrappersObject;
foreach (object key in dictionary.Keys)
{
string keyToCheck = key.ToString().Substring(0, propertyName.Length);
if (!keyToCheck.ToString().Contains(propertyName))
{
continue;
}
ReorderableListWrapperWrapper wrapper = new ReorderableListWrapperWrapper(dictionary[key]);
ReorderableList reorderableList = wrapper.m_ReorderableList as ReorderableList;
if (reorderableList.serializedProperty.name == propertyName)
{
return reorderableList.index;
}
}
return -1;
}
}
[CustomPropertyDrawer(typeof(SomeClass))]
public class SomeClassDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Debug.Log($"{fieldInfo.Name} selected index: {PropertyDrawerUtility.GetSelectedIndex(fieldInfo.Name)}");
...
}
}```
it's a little bit hacky, but seems to not break anything
haven't tested it much tho
PropertyHandler has a dictionary of ReorderableListWrappers and I was able to get it from there
I have an editor extension that wont retain GameObject selections, toggles that wont set/unset and variables that wont clear or retain the script value.
were can i place my style sheet file so they can be found in the EditorGUIUtility.Load method ?
the docs recommend placing them in Resources folder , but a tutorial im watching recommends putting it into Editor Default Resources , any ideas ?
so i ended up with something like this :
public static class NoiseGraphEx
{
public static void Add( this VisualElementStyleSheetSet self, string path )
{
self.Add( ( StyleSheet ) Resources.Load( "NoiseGraph" + path ) );
// self.Add( ( StyleSheet ) EditorGUIUtility.Load( "MCBurstNoiseGraph/NoiseGraph" + path + ".uss" ) );
}
}
so for example i load the NoiseGraphStyle.uss file which is loaded in the Editor / Resources folder like so :
public class NoiseGraphWindow : EditorWindow
{
private void OnEnable()
{
rootVisualElement.styleSheets.Add("Style");
}
}
After building a handful of editor windows for my projects, im thinking of making a wrapper to centralize all the editor API scattered across the different classes, im wondering if something like this already exists? Maybe im just still not used to the Editor API, I just really dont like the "guess work" involved with a lot of simple things - for example, if I wanted to create a label GUILayout.Label cool, if I wanted to create a label with a icon... GUILayout.Label(new GUIContent(EditorGUIUtility.IconContent("...").image, "optional tooltip"), GUILayout.Height(GUI.labelHeight)) to me that just seems like theres no reason it couldnt be simplified, it feels like half the time I need to go through like 6 different internals and utility classes to do what I figured is relatively simple things - thats one example though, im wondering if something like this exists or if its worth spending time creating my own? I found one wrapper on github, but it seems more like coding in CSS which im not sure if thatll help or not
I haven't seen any really my self. You could always use UIToolkit instead 😉 (I will continue to shill UITK to people haha)
In the example you gave that isn't really a good way to do it anyway because it would create a new instead of GUIContent each frame which is additional garbage and also because using EditorGUIUtility.IconContent("...") causes it to find the icon content each frame as well. Creating a GUIContent field and setting it once is the way to go about it. I normally have a static class inside of my Editor/EditorWindow called Styles which handles styles and GUIContent for me.
public class MyWindow : EditorWindow
{
private void OnGUI()
{
GUILayout.Label(Styles.OptionsContent);
}
private static class Styles
{
public static readonly GUIContent OptionsContent;
static Styles()
{
OptionsContent = EditorGUIUtility.IconContent("...");
}
}
}
I see - so you would have I guess another Contents class with every GUIContent("...", "optional tooltip") as well and pass everything around as needed? Im still trying to figure out the best way to learn editor scripting, it feels way more messy than regular C# scripting in Unity but then again coding gameplay is different than coding a editor window - I heard of UIToolkit, it seems like its essentially coding like a website with YAML/XML/HTML formatting and additional "stylesheet"-like files?
No, I just have the GUIStyle and GUIContent fields all in the Styles class because there is normally only a few of each. And the Styles class is local to each editor window class as you can see, I just use the same name each time for consistency. This is how Unity does a lot of their Editor and EditorWindows as well.
Yeah UITK uses UXML(aka. XML) files for structure and USS(aka. CSS, aka. stylesheet) files for styling. Though you don't need to use either, you can do it all in C# if you really wanted.
public class MyWindow : EditorWindow
{
private void CreateGUI()
{
var label = new Label("Some Label Tex");
rootVisualElement.Add(label);
}
}
Super simple example of adding a label to the editor window.
Interesting, ill have to study that a bit further and try this out with my next editor, maybe itll be a bit better to try and get used to this style - thanks :)
Anyone knows how to get Handles to work together with PreviewRenderUtility?
I can get them to draw just fine but they aren't registering any mouse inputs
does anybody know how to disable a guilayout button of an editor window if the selection.gameobjects.length != 1?
If you're scripting the OnInspectorGUI yourself you can use https://docs.unity3d.com/ScriptReference/EditorGUI.BeginDisabledGroup.html (see the example on the page for how to use it).
alright
is there a way to duplicate a gameobject or prefab upon pressing a gui button? do i use instantiate for it?
correct
instantiate does create a copy
you can have a button call your script
does instantiate work the same way as ctrl + d though?
iirc it is a deep copy. So yes it does, though it doesn't handle things like creating files if you are making an instance of an asset.
alright thankss
hmmm what's the difference between EditorGUI.DisabledScope and EditorGUI.BeginDisabledGroup/EditorGUI.EndDisabledGroup
Functionally they are the same. Just convenience/code readability
imo EditorGUI.DisabledScope is nicer because it clearly indents and marks the code that it affects.
But you can use either. EditorGUILayout.Begin/EndVertical/Horizontal also have scope equivalents.
alright so i have this code right here, the problem now is that every time i press the button, an error keeps appearing without instantiating the prefab at all
if (GUILayout.Button("Special Duplicate"))
{
GameObject selectedObject = Selection.gameObjects[0];
Debug.Log(selectedObject);
for (int i = 0; i < _instances; i++)
{
float x = (i + 1) * _rotation.x;
float y = (i + 1) * _rotation.y;
float z = (i + 1) * _rotation.z;
//GameObject instantiatedObject = Instantiate(selectedObject, parent.transform);
GameObject instantiatedObject = (GameObject) PrefabUtility.InstantiatePrefab(selectedObject, parent.transform);
Debug.Log(instantiatedObject);
instantiatedObject.transform.localRotation = Quaternion.Euler(new Vector3(x, y, z));
}
}
SpecialDuplicate.OnGUI () (at Assets/Editor/SpecialDuplicate.cs:51)```
and the Debug.Log(instantiatedObject); returns a Null in the Console for some reason
line 51 is instantiatedObject.transform.localRotation = Quaternion.Euler(new Vector3(x, y, z));
oh and adding on, the selected object is indeed a prefab
Is there a way to make Unity not freak out with the Windows long path limits?
My windows machine has long paths enabled but Unity doesn't let me work with paths longer than 254 characters
I've seen Unity staff saying that enabling long paths on Windows should make Unity work with them
my editor tools work fine but when they need to interact with Unity's asset system they break 😓
any help?
That is the problem. That is not in fact a prefab. That is a prefab instance.
oh shoot
how do i duplicate that prefab instance/any other selected prefab instance though while still retaining the prefab itself (if you get what i mean)
Like duplicate does?
yep
i tried it but the instantiated object doesn't have that blue icon thingy beside its name
That is because it is unsupported 😛
Looks like this is what Unity uses internally https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/CutCopyPasteUtility.cs#L81
hmmm that DuplicateGO function is literally ctrl + d?
Yup
Looks like they use the same method from Unsupported
So no real need for reflection it seems. You can just use what is on the forum post
yep alright
(The method from the Unsupported class is external so that is where the rabbit trail ends)
oooo
Hello.
Would anyone know how to set the icon for a custom file extension asset?
E.g:
The file itself contains json data serialized for an editor extension, I'd like to set it to a custom icon.
Hey folks, I'm writing a custom editor window with draggable windows inside. I'm trying to use GUILayout and EditorGUILayout inside of these windows, but from what I see I have to do everything manually with Rects which slows me down. How can I get around this to use Layout?
Is there a way to do any of the following?
- Create a
GUI.Windowthat is sized automatically via contents (like mostGUILayout/EditorGUILayoutstuff) - Simulate drawing GUI but don't actually draw it - just calculate the size it would need to then draw appropriately
Looks like there's literally just a GUILayout.Window lol
hmmm is there a way to access the transform of the duplicated gameobjects when using Unsupported.DuplicateGameObjectsUsingPasteboard();, any idea?
It is the Selection.activeGameObject
Seems that GUILayout.Window doesn't pass back the correct size... anyone know a workaround?
That window is most definitely not 0x0
Changed are you're checking in the wrong UI pass
the rect im passing in is, but that's not what I expect it to return
not sure that i follow
IMGUI works in passes, layout, draw, and a bunch of others
In some passes; not all data is available
should i be safe if i just add a check if size is 0?
Might work yeah
Hello. This could be a crazy question, but let me ask.
How do I use the code completion for the Unity on the portable mode Visual Studio Code?
Trying to follow along with this video.
https://www.youtube.com/watch?v=7LHiye0OsBw
All my changes in the ProBuilder UV editor window keep resetting. What could I be doing wrong?
Learn how to create a simple, low poly building asset in Unity using Probuilder and Polybrush and use the FBX Exporter to export the mesh to Maya/3ds Max.
Speakers:
Stephen Studyvin 3D Artist & Educator
Sandeep Kulkarni Product Operations Manager - Education
Did you find this video useful? Room for improvement? Let us know: https://on.unity.co...
with the newish generic support im trying to hack together serializable interfaces.
i'm doing this by wrapping a UnityEngine.Object in a generic property that enforces assigning the correct type to the Object
i'm also enforcing the generic type in the gui via a simple property drawer
Ref.cs: https://www.toptal.com/developers/hastebin/ezamukucaz.csharp
RefDrawer.cs: https://www.toptal.com/developers/hastebin/upudogahep.cpp
end result is you can declare a field like this
public Ref<IColorSource> colorSource;
and it works as you'd hope.
you can reference assets and components
handles prefab overrides, editing multiple objects, invalidated references, and drag and drop (for the most part)
There's only one weird edge case I've ran into so far I'd love to get thoughts on...
When dragging another gameobject with an implementation of the interface onto the field it does not work. however, if you open another inspector for the other gameobject and drag the component it does. The following gif demonstrates this odd behavior
I thiiiink this is because of EditorGUI.ObjectFieldinternal call to another EditorGUI.ObjectField overload that takes in an EditorGUI.ObjectFieldValidator delegate. I think that private delegate is not able to find the right component when dragging a whole gameobject or something. not sure tho cuz the internal gui code is so hard to grok.
i'm curious if there's a good way to make this work without writing my own EditorGUI.ObjectField lol
Yeah, it calls EditorGUI.ValidateObjectFieldAssignment which magically turns the GameObject into the correct type for the field. If you could pass your own validator function you could make it work, but I think all the methods that would allow that are internal or private, so it's either nasty reflection hacks or writing your own object field.
I'm unsure whether this would work but you may also be able to change the type used to draw the object field based on the object that is currently being dragged. Seeing as the drag should initiate a repaint, I imagine you should be able to alter the field
thanks for confirming my suspicions @icy merlin
would be nice to make my own validator, but both rewriting the function and reflecting a call to the function will require a bunch of extra scary reflection since the validator and function both use other private members.
@visual stag i ended up trying the drag idea and it seems to work!? not sure if this implementation will have problems I can't forsee, but i actually kinda like that the type changes on drag to show what object is about to be assigned.
code is a lil gross but it def works. only weird thing is if another type is already assigned it says "type mismatch." i figure there's a way to change the type only when the current event is of the right type, but i'm still not super fluent with all the different imgui passes
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var type = fieldInfo.FieldType.GenericTypeArguments[0];
var dragging = DragAndDrop.objectReferences;
if (dragging.Length > 0)
{
if (dragging[0] is GameObject obj && obj.TryGetComponent(type, out var comp))
{
type = comp.GetType();
}
}
EditorGUI.ObjectField
(
position,
property.FindPropertyRelative("Reference"),
type,
label
);
edit: this seems to work! if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
Anyone know why / have seen where if you even have a custom editor with an OnSceneGUI function, the typical position handles and etc stop working in the scene view?
should work if its empty
Yeah, no idea why even an empty one would mess it up 😐
The handle is still there, but it's a tiny red dot in the upper left lol, and this is just with a completely empty OnSceneGUI method, so ... fun.
well, hmm, upgraded to 2021.2.7 and it's all working now, so .. weird ok bye 😛
Does anyone who uses Odin Inspector know how I grab a static variable from a different class? to use for something like show if
Found it! For anyone also wondering
looking at Modules/GraphViewEditor/Manipulators/ContentDragger.cs its setting the view zoom and position like so :
Vector3 p = graphView.contentViewContainer.transform.position;
Vector3 s = graphView.contentViewContainer.transform.scale;
graphView.UpdateViewTransform(p, s);
but when i attempt to call this method on enable i get the following artifact ( node is a white box ) - moving the graph won't make it go away , how ever zooming in with the scrollbar will redraw the node and it will display as usual
at : window on enable -> graphView.UpdateViewTransform
also tried the following after calling graphView.UpdateViewTransform :
/// < this = graphView >
contentViewContainer.MarkDirtyRepaint();
contentContainer.MarkDirtyRepaint();
placematContainer.MarkDirtyRepaint();
MarkDirtyRepaint();
funny thing is that i still can drag the node around and even collapse / expand it and it would still be a white rectangle ( it does change in size but stays white )
even when im creating new nodes they are still rendered wrong , very strange
I'll try and keep this a comprehensible as possible:
Entity. Holds an int[,].
EntityEditor. Editor script for Entity, does some stuff to open a custom EditorWindow.
CustomEW. Pulls the int[,] from the Entity, I can apply modifications to the values here.
What's the best way to "send back" the modified int[,]? I've tried to just set the array directly to the Entity via Clone(), but when I hit Play or recompile the changes vanish. I guess it needs to be sent back to the EntityEditor and serialized? I'll give this a go: https://forum.unity.com/threads/how-i-serialize-multidimensional-arrays.988704/ , but I'm wondering if there's a better way that I'm missing?
is there a way to add exceptions of customPropertyDrawer ? like i want to add a drawer for every scriptable object, except 2 types of em
?
You can check the field type on the drawer and only draw the custom logic for the ones you want
I don't have enough knowledge on how Drawers and the ScriptableObject type interact, so I don't know if this is a good approach or not
Because there is hundreds of classes in Unity that derive from ScriptableObject
[CustomPropertyDrawer(typeof(ScriptableObject), true)]
public class TypeDependantScriptableObjectDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (property.GetFieldInfo().FieldType == typeof(SomeScriptableObjectForTypeDependantDrawer))
{
EditorGUI.LabelField(position, label.text, "Custom drawer logic");
}
else
{
//base.OnGUI(position, property, label); // This seems to cause issues with ScriptableObjects (it shows "No GUI Implemented" in the inspector
EditorGUI.PropertyField(position, property, label);
}
}
}
I'd rather aim to use the drawer for the types you need, to avoid colliding with Unity types that derive from SO
If someone else can share their input on this it would be nice, because as I said I have no clue how safe it is to do this with ScriptableObjects
hmm, i believe this would solve my problem. Although i also think this is not the best approach to the solution, and normally i try to use drawer only for the types i wanted, for a long time now, my only problem was this, and i though maybe i should update my drawer script accordingly
@patent pebble thank you
if anyone else has any information for the long term effects, i would like the learn
The reason that the changes are not saved as you said is because Unity cannot serialize any other type of collection beyond LIst<T> and T[].
As far as 'sending back' the data. Just give the editor window a reference to the Entity, and apply it there.
Hey, I'm not sure if this is the right channel to ask this kind of question, but here's what's happening... I exported a mesh using FBX Exported and applied some edits in Blender then exported it using Better FBX (also used for the import), and put it back in Unity, now the mesh reacts quite differently to light than the original one, and yes I'm using the same material as well as the shader... Here's how it looks like (see image below), do you know what could be the issue? Thanks
Hi, is there a way from the inspector to limit the Object Picker when assigning a TextAsset to just pickup Json files? As it is, it picks up everything..txt, cs scripts, json, etc...
or at the very least specify a specific folder to pick an asset from ?
if you're using an ObjectField you can tell it the type of object that can be assigned
using a TextAsset
as it is... it lists every cs script, txt file, anything text based
producing a list of hundreds of files everytime
@prisma olive do you have a custom editor or are you just using Unity's default inspector?
default... basically just a public TextAsset jsonFile;
I'd also be fine if the asset selector just limits itself to a specific folder or something (or both)
@prisma olive in order to specify how a field looks like and how it behaves you need to implement a custom editor for your inspector
or use a PropertyDrawer for TextAsset fields
then inside of those you would use EditorGUILayout.ObjectField or EditorGUI.ObjectField to specify what type of asset it takes
would ObjectField allow you to just select files with the .json extension ?
I don't think you can search by extension, no
you'd have to search online for a custom solution for that
mehhh...ok.. .thanks so much for your help Mad. Appreciate it
i don't think it's even possible to search by extension using Unity's default asset search bar in the project window
you can with QuickSearch, but iirc it's still half baked
and I don't think it can be integrated as of now with inspectors, editorwindows, etc
yeah... it's so annoying that basic stuff like this is even possible after hundreds of versions of an AAA engine lol
yeah. The only thing that can be done about this is using a ScriptableObject, then you can search by type in the object picker
or to implement a custom asset type, but that's more difficult
but then your asset is no longer a TextAsset, you would need to handle how to get the data from the ScriptableObject
ah no that's not an option for me since i basically need this to be used with Ink (the dialogue system)
it compiles into json assets
essentially to avoid this :
lol look at that scrollbar hahaha
Then I guess the only option would be to implement your custom asset type so the AssetDatabase recognizes .json files as it's own asset type
hmmm
I've done this as a learning exercise
i have text files with the extensions .example and .xmpl
they are recognized by Unity as a custom asset type Example
then you would have to find your own way how to convert it to a textasset or is this just a filtering thing ?
yes you would need a way to do that, but I think that part would be easy
the harder part is to implement your custom asset type
I'd rather explore if you are able to do that with ScriptableObjects
i recon it would be the easiest solution
they can also be searched with the type filter t:YourScriptableObject
i can't modify the Ink compiler though
and you can just have it contain a TextAsset reference
yeah I have no experience with that, so idk
no worries .. you've been very helpful...at least you pointed me in the right direction 🙂
thank you very much
@prisma olive another solution that I forgot to mention, is to implement your own Object Picker
it's fairly doable
i've done mine to slightly modify some of the default functionality, but I haven't tried to implement extension filtering
because you would probably need to not only make your custom Object Picker, but also make your custom Search Bar, or whatever it's called
wouldn't even know where to begin in doing something like that but i guess i'll look that up too
I can share the code if you want, it's not really finished, or optimized, or extensively tested and the code is kinda messy
if you feel ok with that, i wouldn't mind to be honest. Don't wanna impose 🙂
it works with attributes though, it doesn't override normal object pickers
[CustomObjectPicker(doAssets: true, doScene: false)]
[SerializeField] public GameObject _sceneGameObject;
so it not may fit your exact needs
oh i thought you meant that t: Example code
coz that looks more like what i'm looking for, at least i can drill down by extension
ah yeah I can share the ScriptedImporter example
