117 lines
3.6 KiB
C#
117 lines
3.6 KiB
C#
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
public class BottomBarButtonHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerMoveHandler
|
|
{
|
|
public float hoverScale = 1.06f;
|
|
public float pressScale = 0.92f;
|
|
public float hoverWidthScale = 1.08f;
|
|
public float scaleLerp = 12f;
|
|
public float gyroAngle = 6f;
|
|
public float gyroLerp = 12f;
|
|
|
|
private RectTransform rect;
|
|
private LayoutElement layout;
|
|
private float basePreferredWidth;
|
|
private Vector3 baseScale;
|
|
private bool hovering;
|
|
private bool pressed;
|
|
private Vector3 targetScale;
|
|
private Quaternion targetRotation = Quaternion.identity;
|
|
private Camera eventCamera;
|
|
private RectTransform layoutRoot;
|
|
|
|
private void Awake()
|
|
{
|
|
rect = GetComponent<RectTransform>();
|
|
baseScale = transform.localScale;
|
|
targetScale = baseScale;
|
|
|
|
layout = GetComponent<LayoutElement>();
|
|
if (layout == null)
|
|
layout = gameObject.AddComponent<LayoutElement>();
|
|
|
|
basePreferredWidth = layout.preferredWidth;
|
|
if (basePreferredWidth <= 0f && rect != null)
|
|
basePreferredWidth = rect.rect.width;
|
|
|
|
if (basePreferredWidth <= 0f)
|
|
basePreferredWidth = 100f;
|
|
|
|
layout.preferredWidth = basePreferredWidth;
|
|
|
|
var group = GetComponentInParent<LayoutGroup>();
|
|
if (group != null)
|
|
layoutRoot = group.GetComponent<RectTransform>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
float dt = Time.unscaledDeltaTime;
|
|
transform.localScale = Vector3.Lerp(transform.localScale, targetScale, 1f - Mathf.Exp(-scaleLerp * dt));
|
|
|
|
if (hovering)
|
|
{
|
|
Vector2 localPoint;
|
|
if (rect != null && RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, Input.mousePosition, eventCamera, out localPoint))
|
|
{
|
|
Vector2 size = rect.rect.size;
|
|
float nx = size.x > 0f ? localPoint.x / size.x : 0f;
|
|
float ny = size.y > 0f ? localPoint.y / size.y : 0f;
|
|
float rotX = -ny * gyroAngle * 2f;
|
|
float rotY = nx * gyroAngle * 2f;
|
|
targetRotation = Quaternion.Euler(rotX, rotY, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
targetRotation = Quaternion.identity;
|
|
}
|
|
|
|
transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, 1f - Mathf.Exp(-gyroLerp * dt));
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
hovering = true;
|
|
eventCamera = eventData.pressEventCamera;
|
|
layout.preferredWidth = basePreferredWidth * hoverWidthScale;
|
|
RebuildLayout();
|
|
if (!pressed)
|
|
targetScale = baseScale * hoverScale;
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
hovering = false;
|
|
layout.preferredWidth = basePreferredWidth;
|
|
RebuildLayout();
|
|
if (!pressed)
|
|
targetScale = baseScale;
|
|
}
|
|
|
|
public void OnPointerDown(PointerEventData eventData)
|
|
{
|
|
pressed = true;
|
|
targetScale = baseScale * pressScale;
|
|
}
|
|
|
|
public void OnPointerUp(PointerEventData eventData)
|
|
{
|
|
pressed = false;
|
|
targetScale = baseScale * (hovering ? hoverScale : 1f);
|
|
}
|
|
|
|
public void OnPointerMove(PointerEventData eventData)
|
|
{
|
|
eventCamera = eventData.pressEventCamera;
|
|
}
|
|
|
|
private void RebuildLayout()
|
|
{
|
|
if (layoutRoot != null)
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(layoutRoot);
|
|
}
|
|
}
|