Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Make it easier to inherit from Button with custom properties for the editor

Abierto
#15 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
csharp, unity
Área
game-dev, tooling

Línea de trabajo

Comienza con Editor/UGUI/UI/SelectableEditor.cs, especialmente ChildClassPropertiesGUI e IsDerivedSelectableEditor, y reproduce el caso de herencia con el ejemplo MyButton. Rastrea cómo se descubren OnClick de Button y las propiedades serializadas de la clase derivada; el trabajo estará terminado cuando aparezcan tanto las propiedades heredadas de Button como las propiedades de MyButton y sigan siendo editables sin un editor separado para cada subclase.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

I wanted to have a button that would behave like a sprite button for the background: one sprite by default, a different sprite when it's highlighted, and another for when it's pressed, but also have the ability to set the text dynamically.

To get this behavior I need to set text position dynamically for when button is in different states. Since there are no public events for when button is highlighted, selected, returns to default state, I need to either inherit from the Button class or copy paste the code and make my own class. I decided to inherit from the Button class:

    [AddComponentMenu("UI/My Button", 30)]
    public class MyButton : Button {
        HorizontalLayoutGroup HorizontalLayoutGroup;

        int NormalTextTopPadding;
        int NormalTextBottomPadding;
        [SerializeField] int HighlightedTextBottomPadding;
        [SerializeField] int PressedTextBottomPadding;

        void Awake() {
            HorizontalLayoutGroup = GetComponent<HorizontalLayoutGroup>();
            NormalTextTopPadding = HorizontalLayoutGroup.padding.top;
            NormalTextBottomPadding = HorizontalLayoutGroup.padding.bottom;
        }

        protected override void DoStateTransition(SelectionState state, bool instant) {
            base.DoStateTransition(state, instant);

            if(state == SelectionState.Normal || state == SelectionState.Selected) {
                HorizontalLayoutGroup.padding.top = NormalTextTopPadding;
                HorizontalLayoutGroup.padding.bottom = NormalTextBottomPadding;
            }
            if(state == SelectionState.Highlighted) {
                HorizontalLayoutGroup.padding.top = NormalTextTopPadding + HighlightedTextBottomPadding;
                HorizontalLayoutGroup.padding.bottom = NormalTextBottomPadding - HighlightedTextBottomPadding;
            }
            if(state == SelectionState.Pressed) {
                HorizontalLayoutGroup.padding.top = NormalTextTopPadding + HighlightedTextBottomPadding + PressedTextBottomPadding;
                HorizontalLayoutGroup.padding.bottom = NormalTextBottomPadding - HighlightedTextBottomPadding - PressedTextBottomPadding;
            }
        }
    }

This is the class. The first problem that I get is that the editor doesn't draw the properties HighlightedTextBottomPadding and PressedTextBottomPadding . I don't understand why, since in the SelectableEditor class it should draw all the child properties:

        private void ChildClassPropertiesGUI()
        {
            if (IsDerivedSelectableEditor())
                return;

            DrawPropertiesExcluding(serializedObject, m_PropertyPathToExcludeForChildClasses);
        }

So what do I do? I write my own editor to draw my properties:

    [CustomEditor(typeof(MyButton), true)]
    public class MyButtonEditor : SelectableEditor {
        SerializedProperty HighlightedTextBottomPadding;
        SerializedProperty PressedTextBottomPadding;

        protected virtual void OnEnable() {
            base.OnEnable();
            HighlightedTextBottomPadding = serializedObject.FindProperty("HighlightedTextBottomPadding");
            PressedTextBottomPadding = serializedObject.FindProperty("PressedTextBottomPadding");
        }

        public override void OnInspectorGUI() {
            base.OnInspectorGUI();

            EditorGUILayout.PropertyField(HighlightedTextBottomPadding);
            EditorGUILayout.PropertyField(PressedTextBottomPadding);

            serializedObject.ApplyModifiedProperties();
        }
    }

This starts to draw the MyButton properties but it stops drawing the original button OnClick property. That's because I now have a custom editor and IsDerivedSelectableEditor() returns false and ChildClassPropertiesGUI() doesn't draw child class properties. A naive thing to try is to add SerializedProperty OnClick; field to the editor and then find it on Enable: OnClick = serializedObject.FindProperty("m_onClick"); and then draw it: EditorGUILayout.PropertyField(OnClick);. Again, for some reason it doesn't work(FindProperty returns null), even considering the MyButton object does have m_onClick property: it inherits it from Button class.

So, how do I fix that problem? I have to write my own ButtonEditor class for Button and then inherit from that instead in my own MyButtonEditor:

    [CustomEditor(typeof(Button), true)]
    public class ButtonEditor : SelectableEditor {
        SerializedProperty OnClick;

        protected virtual void OnEnable() {
            base.OnEnable();
            OnClick = serializedObject.FindProperty("m_OnClick");
        }

        public override void OnInspectorGUI() {
            base.OnInspectorGUI();

            EditorGUILayout.PropertyField(OnClick);

            serializedObject.ApplyModifiedProperties();
        }
    }

Now with all those changes I(finally) have my own button with the behavior I want. But it's too much code for something simple like that. It would be nice to just write MyButton class and be done with that. Not sure why SelectableEditor only iterates over Button properties but not properties of my child class.

Lenguaje dominante
C#
Estrellas
1.6k
Forks
324
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Unity-Technologies/uGUI

Todos los issues de Unity-Technologies/uGUI

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.