说明
Button原生按钮点击时只有颜色变化,不能大小变化,针对原生Button进行扩展,实现大小变化,以及捆绑多个物体同时进行变化
效果如下:
演示视频
创建脚本MobeeButton, 继承原生按钮Button
在Editor目录下创建脚本MobeeButtonInspector, 继承原生按钮ButtonEditor
颜色大小变化用到了DOTweenPro动画插件,需要可自行下载安装
绑定是GameObject类型支持大小变化
绑定的组件若继承自MaskableGraphic(包含color属性),可实现颜色变化,没有继承则自动过滤掉
说明
- MobeeButton.cs
继承自Button,重写Transition.Animation类型点击效果,使用DOTween实现效果- 按钮点击颜色动画,继承自MaskableGraphic的UI组件
- 按钮点击缩放Scale动画
- loopScale动画
- MobeeBottonAnimationCurve.cs
继承自ScriptableObject, 主要存储自定义的动画曲线AnimationCurve - MobeeButtonInspector.cs
继承自ButtonEditor,主要在Inspector面板绘制各属性,便于设置 - 创建
- 创建MobeeBottonAnimationCurve.asset
选中Assets/HotAssets/Scriptable,右键Create/2D/Mobee…创建
- 添加曲线
- 创建MobeeBotton
-
方式1
-
方式2
将Transition改为Animation
-
- 创建MobeeBottonAnimationCurve.asset
MobeeBotton面板属性
- AudioId: 点击音效, 待实现
- AudioIds: 常用音效,可在MobeeButtonInspector.m_AllAudioIds添加按钮音效
- Transition: 点击效果类型,可切换其他类型
- Loop: 按钮缩放Scale动画开关
-
Target: 动画对象, 默认为自身,可以指定其他UI对象
-
Duration: 动画时间
-
Number: 动画缩放次数 <0: 无限次; =0:无次数Loop不生效;>0:次数,默认值: -1
-
Type: 重复播放类型,默认值: Yoyo
-
Ease: 动画运动曲线, 默认值 ::AnimationCure
-
EaseCurve: 自定义的动画曲线存储文件,值为Null时,
- 每次选中多会自动加载
- 默认路径: HotAssets/Scriptable/MobeeBottonAnimationCurve.asset
- 可修改MobeeButtonInspector.curveAssetPath默认路径,也可以手动指定其他MobeeBottonAnimationCurve类型的文件
- 不为空时,Inspector界面
-
五个属性
- 按钮+/- : 切换EaseCurve中动画曲线
- 数字: EaseCurve中的索引,每次开启动画时都会根据索引重新从EaseCurve中获取最新的动画曲线
- 展示曲线: 仅只展示选中的动画曲线
- 曲线数量: EaseCurve中动画曲线数组的数量
-
运行时可见
- Play/Stop: 播放/暂停
- RePlay: 修改属性后,需重新运行修改后动画
-
- ColorMultiplier: 按钮点击颜色动画混合系数,建议保持默认值
- FadeDuration: 按钮点击动画时长, 默认值: 0.1f
- Ease: 按钮点击动画运动曲线,默认值: Linear, 主要用Dotween内置曲线,暂不支持AnimationCurve, 值为: Unset时使用Linear
- Scale: 放缩Scale动画开关
- From: 从To恢复到原始Scale值
- Self: 是否使用自身值, 默认值: True , 建议保持默认值
- True: transform.scale * 该值
- False: 直接使用该值
- To: 动画播放值
- Self: 是否使用自身值, 默认值: True , 建议保持默认值
- True: transform.scale * 该值
- False: 直接使用该值
- Color: 颜色Color动画开关
- From: 从To恢复到原始Color值
- Self: 是否使用自身值(颜色混合), 默认值: True , 建议保持默认值
- True: maskableGraphic.color * 该值
- False: 直接使用该值
- To: 动画播放值
- Self: 是否使用自身值(颜色混合), 默认值: True , 建议保持默认值
- True: maskableGraphic.color * 该值
- False: 直接使用该值
- MainTarget: 按钮点击动画主对象,默认为按钮本身,可以指定其他对象
- Childs: 子对象相关控制属性
- Scale: 所有子对象是否播放放缩Scale动画,与MainTarget公用From/To值, 建议子对象在主对象节点下设置为False
- Color: 所有子对象是否播放颜色Color动画,与MainTarget公用From/To值
- Child Targets: 子对象数组
MobeeBottonAnimationCurve代码如下
using UnityEngine;
namespace MobeeScript
{
[CreateAssetMenu(fileName = "MobeeBottonAnimationCurve.asset", menuName = "2D/MobeeBottonAnimationCurve")]
public class MobeeBottonAnimationCurve : ScriptableObject
{
[SerializeField]
public AnimationCurve[] animationCurves;
}
}
MobeeButtonInspector代码如下:
using MobeeScript;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
using UnityEngine.UI;
namespace MobeeED
{
[CustomEditor(typeof(MobeeButton))]
public class MobeeButtonInspector : ButtonEditor
{
#region 创建
[MenuItem("GameObject/UI/MobeeButton")]
private static void CreateMobeeButton(MenuCommand menuCommand)
{
GameObject gameObject = new GameObject("MobeeButton");
Image image = gameObject.AddComponent<Image>();
image.raycastTarget = true;
image.rectTransform.sizeDelta = new Vector2(200, 80);
Button btn = gameObject.AddComponent<MobeeButton>();
btn.transition = Selectable.Transition.Animation;
if (menuCommand.context == null)
{
AttachToCanvas(gameObject);
}
else
{
GameObjectUtility.SetParentAndAlign(gameObject, menuCommand.context as GameObject);
}
gameObject.transform.localPosition = Vector3.zero;
Selection.activeObject = gameObject;
}
/// <summary>
/// 附加到画布
/// </summary>
/// <param name="gameObject"></param>
public static void AttachToCanvas(GameObject gameObject)
{
Canvas canvas = UnityEngine.Object.FindObjectOfType<Canvas>();
if (canvas == null)
{
GameObject obj = new GameObject();
canvas = obj.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.gameObject.AddComponent<CanvasScaler>();
canvas.gameObject.AddComponent<GraphicRaycaster>();
}
gameObject.transform.SetParent(canvas.transform);
}
#endregion 创建
#region Property
private MobeeButton mobeeButton;
private SerializedProperty m_AudioIdProperty;
private SerializedProperty m_TransitionProperty;
private SerializedProperty m_MainTargetProperty;
private SerializedProperty m_ChildTargetsProperty;
private SerializedProperty m_ColorBlockProperty;
private SerializedProperty m_EaseProperty;
private SerializedProperty m_DOMainScaleProperty;
private SerializedProperty m_DOChildScaleProperty;
private SerializedProperty m_FromScaleProperty;
private SerializedProperty m_SelfFromScaleProperty;
private SerializedProperty m_ToScaleProperty;
private SerializedProperty m_SelfToScaleProperty;
private SerializedProperty m_DOMainColorProperty;
private SerializedProperty m_DOChildColorProperty;
private SerializedProperty m_SelfFromColorProperty;
private SerializedProperty m_SelfToColorProperty;
private SerializedProperty m_OnClickProperty;
private GameObject mainTarget;
private List<GameObject> childTargets = new List<GameObject>();
private int childCount = 0;
private int m_AudioIdIndex;
private bool isinit = false;
private string[] m_AllAudioIds = new string[] {
"自定义", "音效id1", "音效id2", "音效id3" };
#region 显示内容
private GUIContent m_NoneContent = new GUIContent("");
private GUIContent m_TransitionPropertyContent = new GUIContent("Transition", "动画类型(继承自Button)");
private GUIContent m_ColorMultiplierPropertyContent = new GUIContent("ColorMultiplier", "颜色叠加系数(继承自Button)");
private GUIContent m_FadeDurationPropertyContent = new GUIContent("FadeDuration", "动画时长(继承自Button)");
private GUIContent m_DOMainScalePropertyContent = new GUIContent("Scale", "主绑定对象是否播放缩放动画");
private GUIContent m_FromScalePropertyContent = new GUIContent("From", "缩放动画值(恢复点击前状态)");
private GUIContent m_SelfFromScalePropertyContent = new GUIContent("Self", "True:对象本身Scale值*该值\nFalse:直接使用该值");
private GUIContent m_ToScalePropertyContent = new GUIContent("To", "缩放动画值(点击时状态)");
private GUIContent m_SelfToScalePropertyContent = new GUIContent("Self", "True:对象本身Scale值*该值\nFalse:直接使用该值");
private GUIContent m_SelfFromColorPropertyContent = new GUIContent("Self", "True:对象本身Color值*该值\nFalse:直接使用该值\n※ 建议勾选");
private GUIContent m_SelfToColorPropertyContent = new GUIContent("Self", "True:对象本身Color值*该值\nFalse:直接使用该值\n※ 建议勾选");
private GUIContent m_MainTargetPropertyContent = new GUIContent("MainTarget", "主绑定对象");
private GUIContent m_ChildTargetsPropertyContent = new GUIContent("Childs");
private GUIContent m_DOChildScalePropertyContent = new GUIContent("Scale", "子绑定对象是否播放缩放动画");
private GUIContent m_DOChildColorPropertyContent = new GUIContent("Color", "子绑定对象是否播放颜色动画");
private GUIContent m_DOMainColorPropertyContent = new GUIContent("Color", "主绑定对象是否播放颜色动画");
private GUIContent m_FromColorBlockPropertyContent = new GUIContent("From", "颜色动画值(恢复