12

Is it possible to extend the new unity ui components like for example the transform component? Because nothing happens when i try to extend the button, instead of the transform component

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Transform))]
public class CustomTransform : Editor
{
    public override void OnInspectorGUI()
    {            
    }
}
Greg Lukosek
  • 1,774
  • 20
  • 40
Eknoes
  • 349
  • 4
  • 6
  • 17
  • That's not extending, it's just an editor for a specific Component that derives from `MonoBehaviour` – Tseng Mar 14 '15 at 18:52
  • So it is only possible to extend components that derive from MonoBehavior? – Eknoes Mar 14 '15 at 19:00
  • Extending in C# means, create a new class which derives from another class, aka inheritance. The above code snippet isn't related to inheritance, it is and editor extension. `public class Player : MonoBehavior { }` is extending MonoBehavior and adds new functionality. And UI components can be extended, you just need to inherit from them, not from `Editor`. The Editor is for a simplified UI within the Unity Inspector – Tseng Mar 14 '15 at 19:04
  • 2
    If you need to recompile your own version of the Unity UI (i.e. cause inheritance may not work in a certain case), you can download the Unity UI Source from https://bitbucket.org/Unity-Technologies/ui and compile it yourself. Check the read me on that page on how to replace the Unity standard UI assemblies with your newly compiled ones – Tseng Mar 14 '15 at 19:06
  • Sorry i used extending again. I said extend, because i just want to add a few GUI controls to the editor and then use DrawDefaultInspector() So i'm not talking about inheritance. Edit: Didn't read your last comment. Should have refreshed before posting – Eknoes Mar 14 '15 at 19:15

2 Answers2

26

Yes you can extend UI components and write them their own custom inspector. You just need to remember to use right namespaces and also inherit from the right Inspector class.

You can of course override too!.

Example here is a UISegmentedControlButton

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class UISegmentedControlButton : Button {

public Sprite offSprite;
public Sprite onSprite;
public Color offTextColor = Color.white;
public Color onTextColor = Color.white;

private bool isSelected;
public bool IsSelected {
    get {
        return isSelected;
    }
    set {
        isSelected = value;

        Text text = this.transform.GetComponentInChildren<Text>();

        if (value) {
            this.GetComponent<Image>().sprite = onSprite;
            text.color = onTextColor;
        } else {
            this.GetComponent<Image>().sprite = offSprite;
            text.color = offTextColor;
        }
    }
}




public override void OnPointerClick(PointerEventData eventData) {

    this.transform.parent.GetComponent<UISegmentedControl>().SelectSegment(this);
    base.OnPointerClick(eventData);
}

}

And Editor class for it:

P.S. ButtonEditor is different from UnityEditor.UI.ButtonEditor as the first one is from UnityEngine.ButtonEditor. To access .UI from UnityEditor, you need to put your Editor script under Editor folder

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.Collections;

[CustomEditor(typeof(UISegmentedControlButton))]
public class UISegmentedControlButtonEditor : UnityEditor.UI.ButtonEditor {


public override void OnInspectorGUI() {

    UISegmentedControlButton component = (UISegmentedControlButton)target;

    base.OnInspectorGUI();

    component.onSprite = (Sprite)EditorGUILayout.ObjectField("On Sprite", component.onSprite, typeof(Sprite), true);
    component.onTextColor = EditorGUILayout.ColorField("On text colour", component.onTextColor);
    component.offSprite = (Sprite)EditorGUILayout.ObjectField("Off Sprite", component.offSprite, typeof(Sprite), true);
    component.offTextColor = EditorGUILayout.ColorField("Off text colour", component.offTextColor);

}
}

Also here is a useful link directly to the source of Unity UI

https://github.com/Unity-Technologies/uGUI

And a little proof that it works:

enter image description here

Greg Lukosek
  • 1,774
  • 20
  • 40
  • I can't extend from UnityEditor.UI.ButtonEditor in the Editor class. The type does not exist. But i looked at the source on bitbucket and the class does exist and is public. I can only extend from GraphicEditor and TextEditor – Eknoes Jul 21 '15 at 12:59
  • Make sure you are using above namespaces. Works 100%. Im using this in the live project now – Greg Lukosek Jul 21 '15 at 13:17
  • 3
    Thanks. Now it works. Simply forgot to move the script into the editor folder ;) But is there no way to extend the component directly like it's possible with the transform component so that i can use the default button? – Eknoes Jul 21 '15 at 14:33
  • Awesome, please tick this as answered – Greg Lukosek Jul 21 '15 at 17:03
  • 1
    I will, but i still would like to know whether it is actually possible to directly extend an ui component. – Eknoes Jul 21 '15 at 17:07
  • Another aspect to consider is that you cannot modify properties (ie, getters/setters) but only fields, (ie, `public bool myValue;`). That is because properties (ie Methods) are not serializable. – mayo Aug 22 '17 at 20:56
  • FYI, to access .UI from UnityEditor, you either need to put your editorscript under the right namespace, or just it under Editor folder. – libra Aug 23 '18 at 09:06
  • @GregLukosek Do you know if you should be able to get this into the Create menu using `[AddComponentMenu("UI/My Component Name")]`? – netpoetica Apr 18 '19 at 12:49
  • The link of that answer leads to a 404 – Petschko May 08 '23 at 21:08
  • 1
    @Petschko thanks for flagging this up. Looks like they moved to https://github.com/Unity-Technologies/uGUI I will update the answer – Greg Lukosek May 10 '23 at 10:02
1

Tried the example above but EditorGUILayout.ObjectField gets empty when I exit the prefab I placed my object in.

However, this method works without zeroing the field.

using Game.Ui.Views.DialoguePanel;
using UnityEditor;
using UnityEditor.UI;

namespace Editor
{
    [CustomEditor(typeof(MyButtonExtension))]
    public class MyButtonExtensionDrawer : ButtonEditor
    {
        SerializedProperty m_testObject;
        
        protected override void OnEnable()
        {
            base.OnEnable();
            m_testObject = serializedObject.FindProperty("testObject");
        }
        
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            EditorGUILayout.Space();
            
            serializedObject.Update();
            EditorGUILayout.PropertyField(m_testObject);
            serializedObject.ApplyModifiedProperties();
        }
    }
}

In fact, this is just a slightly modified content of the ButtonEditor class.

Сергей
  • 111
  • 4
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 13 '22 at 08:47