天天看点

button组件 untiy_Unity自定义Button组件Transition

Unity自带的Button组件有三种不同的Transition(过渡)选项,分别是None, ColorTint, SpriteSwap, Animation。现在想自定义其他功能,比如在不同的状态下,按钮上的文字不同。

首先想到的是直接写一个脚本挂在Button上,实现UnityEngine.EventSystems中定义的IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler这三个接口,代码如下:

public class MyButton1 : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler

{

[SerializeField]

private Button button;

[SerializeField]

private Text text;

private void Start()

{

if(button == null)

{

button = GetComponent();

}

if(text == null)

{

text = GetComponentInChildren();

}

}

public void OnPointerEnter(PointerEventData eventData)

{

Debug.Log("Pointer enter");

text.text = "Pointer enter";

}

public void OnPointerExit(PointerEventData eventData)

{

Debug.Log("Pointer Exit");

text.text = "Pointer Exit";

}

public void OnPointerClick(PointerEventData eventData)

{

Debug.Log("Pointer click");

text.text = "Pointer click";

}

}

实际上Button自身已经实现了这几个接口,所以可以直接继承Button并重写这三个方法,将原来的Button组件换成MyButton2:

public class MyButton2 : Button

{

[SerializeField]

private Text text;

protected override void Awake()

{

base.Awake();

if(text == null)

{

text = GetComponentInChildren();

}

}

public override void OnPointerEnter(PointerEventData eventData)

{

base.OnPointerEnter(eventData);

Debug.Log("Pointer enter");

text.text = "Pointer enter";

}

public override void OnPointerExit(PointerEventData eventData)

{

base.OnPointerExit(eventData);

Debug.Log("Pointer Exit");

text.text = "Pointer Exit";

}

public override void OnPointerClick(PointerEventData eventData)

{

base.OnPointerClick(eventData);

Debug.Log("Pointer click");

text.text = "Pointer click";

}

}

这时候会发现继承自Button的MyButton2在Inspector里并不能看到text字段,这时需要对Button的编辑器显示进行扩展:

using UnityEditor;

using UnityEditor.UI;

[CustomEditor(typeof(MyButton2), true)]

[CanEditMultipleObjects]

public class MyButton2Editor : ButtonEditor

{

private SerializedProperty text;

protected override void OnEnable()

{

base.OnEnable();

text = serializedObject.FindProperty("text");

}

public override void OnInspectorGUI()

{

base.OnInspectorGUI();

EditorGUILayout.Space();

serializedObject.Update();

EditorGUILayout.PropertyField(text);

serializedObject.ApplyModifiedProperties();

}

}

(将上面这个脚本放到Assets>Editor文件夹下,这样只是在编辑器里使用,不会被打包发布)

其实也可以直接重写Button的DoStateTransition这个方法,对应的就是Button组件显示在Inspector里的Transition:

public class MyButton3 : Button

{

[SerializeField]

private Text text;

protected override void Awake()

{

base.Awake();

if(text == null)

{

text = GetComponentInChildren();

}

}

protected override void DoStateTransition(SelectionState state, bool instant)

{

switch(state)

{

case SelectionState.Normal:

Debug.Log("Normal");

text.text = "Normal";

break;

case SelectionState.Pressed:

Debug.Log("Pressed");

text.text = "Pressed";

break;

case SelectionState.Highlighted:

Debug.Log("Highlited");

text.text = "Highlited";

break;

case SelectionState.Disabled:

Debug.Log("Disabled");

text.text = "Disabled";

break;

}

}

}

按照这个思路还可以实现更多的效果。