问题描述:有时我们想要制作靠边停靠的菜单,当点击菜单时按钮时弹出菜单,而又不想使用第三方插件和Mecanim动画系统来制作,那么我们就可以用纯代码来实现这类菜单的动画效果。
一、首先定义一个枚举类,用于确定菜单停靠在窗口的哪边。
/// <summary>
/// 菜单停靠边的枚举类
/// </summary>
public enum DockPosition
{
Left,
Right,
Up,
Bottom
}
二、然后定义MenuAnim类用于控制菜单的弹出效果,具体代码如下:
public class MenuAnim : MonoBehaviour
{
private Vector2 initialPosition, targetPosition, terminalPosition; //用于存储菜单动画相关的位置
public float SmoothRate = 1.0f; //控制动画快慢的参数
public DockPosition menuPositon; //菜单停靠边的参数
private float halfWidth, halfHeight; //用于计算动画移动目的地的参数
private bool isAnimStart = false; //控制是否开始动画
private bool isOpen = false; //控制打开还是关闭菜单
// Use this for initialization
void Start()
{
initialPosition = transform.position; //获取菜单的初始位置
halfWidth = GetComponent<RectTransform>().rect.width; //计算菜单的长宽
halfHeight = GetComponent<RectTransform>().rect.height;
switch (menuPositon) //根据菜单的停靠位置确定菜单的弹出位置
{
case DockPosition.Left:
terminalPosition = initialPosition + new Vector2(halfWidth, 0);
break;
case DockPosition.Right:
terminalPosition = initialPosition + new Vector2(-halfWidth, 0);
break;
case DockPosition.Up:
terminalPosition = initialPosition + new Vector2(0, -halfHeight);
break;
case DockPosition.Bottom:
terminalPosition = initialPosition + new Vector2(0, halfHeight);
break;
}
}
// Update is called once per frame
void Update()
{
if (isAnimStart) //菜单动画开始执行
{
transform.position = Vector2.Lerp(transform.position, targetPosition, SmoothRate * 10 * Time.deltaTime);
if (Vector2.SqrMagnitude(new Vector2(transform.position.x, transform.position.y) - targetPosition) < 0.1)
{
transform.position = targetPosition;
isAnimStart = false;
}
}
}
/// <summary>
/// 控制菜单弹出还是收回
/// </summary>
public void ShowOrHide()
{
isOpen = !isOpen;
if (isOpen)
{
targetPosition = terminalPosition; //菜单弹出
}
else
{
targetPosition = initialPosition; //菜单收回
}
isAnimStart = true;
}
}
三、将脚本挂到自己的菜单上,并将菜单调整到需要停靠的边外面同时设置好参数,这里挂在一个叫Right的Panel上,如下图:
四、找到控制菜单弹出或关闭的按钮,并将点击事件绑定到ShowOrHide()方法,如下图:
五、运行查看运行效果。
备注:详细的工程可以查看我的github:Unity3D-UGUI-MenuAnimation