I am trying to wrap my head around this concept. So I was wondering, if I make a button like so Code (CSharp): VisualElement root = rootVisualElement; StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Scripts/Editor/UIElements/ShaderSelector.uss"); VisualElement but = new Button(); but.styleSheets.Add(styleSheet); but.name = "fred"; root.Add(but); Is there anyway to add Text to the Button via code? ie Do I have to use .UXML to put in text on the button? Please clarify.
Solution Code (CSharp): Button b = new Button(); b.text = "hello"; VisualElement but = b; but.styleSheets.Add(styleSheet); but.name = "fred"; root.Add(but);
How to disable(enable) button in new UIElements? For example: when "MyInteger" field have value 0 => disable "MyButton" button
Hi, I want to add a button to a custom UIElements inpector, I couldn't find it in the docs or the examples repository.
@xCyborg There are multiple ways to do it, via uxml or by code. Here is a quick snippet: Code (CSharp): [CustomEditor(typeof(NewBehaviourScript))] public class NewBehaviourScriptEditor : Editor { public override VisualElement CreateInspectorGUI() { var root = new VisualElement(); var b = new Button( () => Debug.Log("Clicked!")) { text = "Click Me!"}; root.Add(b); return root; } }
@UnityMat Thank you so much, this is way better than previous imgui workflow. On a side note, didn't you mean to return the root visual element at the end? Code (CSharp): return root; Also, would you be so kind as to show me how to display the underlying script properties in the inspector as usual? I tried calling some base functions and adding targets property to the root but it didn't work. Also I would like to know how to access those propertied from the custom inspector. Thanks in advance so much.
@xCyborg Sorry about the late answer, I just returned from vacation You're right, I meant returning root in my code snippet, fixed it in my original post. An Editor has a serializedObject property that let's you list serialized properties. Here is how you could populate your inspector: Code (CSharp): SerializedProperty property = serializedObject.GetIterator(); property.NextVisible(true); // Expand the first child. do { var field = new PropertyField(property); root.Add(field); } while (property.NextVisible(false)); You can also create your own fields and set their binding path to the names of the edited object's fields: Code (CSharp): var field = new IntegerField(); field.bindingPath = "IntValue"; root.Add(field); Once returned, the created VisualElement tree will be bound to the serialized object. Hope that helps!
@UnityMat Thanks Mat and welcome back. I used your snippet but I find using serializedObject way convoluted for the simple task I aim to. I've gathered some feedback ans I hope you take a look into it. -First it requires iteration and dynamic querying, -Displaying some attributes like [Space] behave weirdly or don't function. -Also I'd still need to query individual properties if I need to reference them again. -Lastly, assigning or modifying serialized properties from UIElements callback doesn't seem to work. Code (CSharp): var d = serializedObject.FindProperty("deutch"); // default value = "Empty" // ADD MY STUFF var b = new Button(() => { Debug.Log(d.stringValue); d.stringValue = "Deutch!"; // <=== Value doesn't change in inspector nor in debug mode. }) { text = "Click Me Deutch!" }; Could there be a way to automatically draw the public properties of the custom editor's backing class? or at least wrap it in a single function call like : DrawDefaultInspector()... And more importantly be able to reference all the fields and properties of the inspected class in each object directly. Is that possible? whether sooner or later, it would be a huge boost for editor scripting. Thanks.
EDIT: I was able to enforce the property change by using : Code (csharp): serializedObject.ApplyModifiedProperties() But still, most of the things I mentioned stand. It would be far better if we could access the underlying inspected object directly without the`serializedObject` mess, can't even call GetComponent from Editor scripts. And also to easily OR automatically draw the public variables of the inspected script. Thanks again.
EDIT #2: I remembered target property, it works wonderfully, now I got rid of all serialized stuff complication. So the reference issue is no longer an issue now. That leaves us with only the need for a DrawDefaultInspector() counterpart in UIElements. Maybe you could add an overloaded method in Editor that takes a VisualElement and does something like what you posted above. Code (CSharp): private void DrawDefaultInspector(VisualElement root) { SerializedProperty property = serializedObject.GetIterator(); property.NextVisible(true); // Expand the first child. do { var field = new PropertyField(property); root.Add(field); } while (property.NextVisible(false)); }
Awesome! glad to hear it, thanks again for the tip and I hope we get some documentation on UIElements, it's a brilliant system.
Is there any way to do this without a method? It should not be a method, it should be a property - as a method, it's impossible to use C# standard constructor syntax, e.g. this code is impossible: Code (CSharp): element.Add( new Button(()=>{onclick();}) { text = "Button", isEnabled = /* not possible :( */ } );
OK, for now I'm using a workaround - a static class that adds a method to UIToolkit: public static void AddButton_WorkaroundUIToolkitMissingAPI( this VisualElement e, onclickHandler, string text, bool isDisabled = false ) {..} ...unless anyone has better ideas? It works and it allows us to keep instantiating buttons in a single line of code, but ... it's not ideal because it disables access to C#'s constructor-initialization system - I'll have to add a lot of extra duplicate methods to accomodate all the different parameters you could add to a Button, e.g. every style change etc - but at least I can delete it if/when UIToolkit adds the appropriate property.