I have seen many samples,and they used AssetDatabase.LoadAssetAtPath.
But this kind of reference is too much fragile for renaming or moving asset.
Using GUID seems to be robust,but too much complicated.Is there any good way?
Hello, if you mean a way to refer to UXML and USS files from MonoBehaviour or ScriptableObject types, you can use VisualTreeAsset and StyleSheet, respectively.
If thatâs not your question, can you clarify what exactly youâre trying to do?
Iâm just trying to create UI with UI Toolkit.
How we could assign SerializeField of Editor or EditorWindow?
Not sure I understand what you mean.
VisualTreeAsset and StyleSheet are types you can use for serialization on both MonoBehaviour and ScriptableObject types.
Yeah,we could assign any UnityEngine.Object to SerializeField of MonoBehaviour,or ScriptableObject from Inspector.
But where could we assign object to SerializeField of UnityEditor.Editor or UnityEditor.EditorWindow?
And hereâs built-in UIToolikit EditorWindow Templete,what unity officialy proposed.
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
public class UIToolkitEditorWindow : EditorWindow
{
[MenuItem("Window/Project/UIToolkitEditorWindow")]
public static void ShowExample()
{
UIToolkitEditorWindow wnd = GetWindow<UIToolkitEditorWindow>();
wnd.titleContent = new GUIContent("UIToolkitEditorWindow");
}
public void OnEnable()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;
// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Main/UIToolkitEditorWindow.uxml");
VisualElement labelFromUXML = visualTree.Instantiate();
root.Add(labelFromUXML);
// A stylesheet can be added to a VisualElement.
// The style will be applied to the VisualElement and all of its children.
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Main/UIToolkitEditorWindow.uss");
VisualElement labelWithStyle = new Label("Hello World! With Style");
labelWithStyle.styleSheets.Add(styleSheet);
root.Add(labelWithStyle);
}
}
This code is too much fragile for renaming or moving asset.
Thatâs how assets have been referenced even before UI Toolkit, through Resources.Load as well, they all depend on hard coded paths. Even if you make references through serialized properties on MonoBehaviour or ScriptableObject, unless theyâre preloaded in the scene youâd have to load those assets probably by path anyway. Thatâs why Iâm not sure what the issue is
If you declare [SerializedField] on members of an EditorWindow subclass, you can also use the âDefault Referencesâ when selecting the Script of the window itself.
Our package samples use this:
As for the default generated code from the âCreateâ menu, itâs true that using path strings makes it harder to move files around but it makes this example self-contained and very clear (while Default References rely on the .meta file).
Thanks! It works very well! I hope this solution documented.
But does it work for precompiled assembly?
Default generated code is very clear example,but I think it is not a good âdefaultâ.
Default âNewBehaviourScriptâ or âNewPlayableAssetâ doesnât behaves like it.
I donât think this will work with precompiled assemblies because this information is usually saved in meta file by Unity.
Using a Resources folder like @JuliaP_Unity mentioned should allow a more resilient link between code and assets (only the dependency on the name remains).
I will pass along the feedback of ânot a good defaultâ to the team.
I am facing with a issue with your solution.
Default Reference could not work in PlayMode.
It throws NullReferenceException if I opened a inspector in PlayMode.
Hey RamType0,
I wrote myself a little helper method. This is a little more robust and you can work around the issue when moving assets around ( solution ). (This only works in Edit mode of course. If you need runtime support you need to handle the asset loading differently)
In Edit mode you then just have to call:
LoadFirstAssetByFilter<VisualTreeAsset>("AwesomeTemplate")
or
LoadFirstAssetByFilter<StyleSheet>("AwesomeStyle")
with this solution you still have issues when changing the name ÂŻ_(ă)_/ÂŻ but at least for me itâs a good compromise
Best Daniel
I have tried going into play mode with both a custom window and a custom editor using default references and it worked in both cases.
Which Unity version are you using? Can you tell us more about your code?
Note: I have observed that Default References will not work during playmode unless the script (e.g. the CS file holding the custom window or custom editor) is inside an Editor folder or an Asmdef marked âEditorâ only.
This is expected and consistent with the fact that Unity will not ârememberâ default references in a player build.
Hope this helps.
That was the reason. Thanks!
This saved me, thanks