You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
5.1 KiB
C#

using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
namespace FluffyGroomingTool {
public class ImportantButton {
public Rect positionRect;
public UnityAction clickAction { get; set; }
public string resource;
public string gradientResource = "important_button_gradient";
public Color fillColor = Color.black;
public bool isRippleEnabled = true;
private Material material;
private Texture2D texture;
private Texture2D gradient;
private float scrollingGradientTextureOffset;
private Vector2 easedMousePosition = Vector2.zero;
private Vector2 mousePosition = Vector2.zero;
private const float circleAlphaFadeSpeed = 3;
private const float easeMousePosSpeed = 10f;
private const float gradientScrollSpeed = 0.2f;
public bool disableCircle;
public bool disableCircleAfterClick;
public float getTextureWidth() {
return texture ? texture.width : 0f;
}
public float getTextureHeight() {
return texture ? texture.height : 0f;
}
public void draw() {
loadResources();
if (material == null || texture == null) return; //This may happen during builds.
material.SetTexture("_MainTex", texture);
material.SetTexture("_Gradient", gradient);
material.SetColor("_FillColor", fillColor);
EditorGUI.DrawPreviewTexture(positionRect, texture, material);
float mouseX = (Event.current.mousePosition.x - positionRect.x);
float mouseY = (positionRect.y + positionRect.height - Event.current.mousePosition.y);
if (!isClicked) material.SetVector("_MousePosition", new Vector2(mouseX, mouseY));
material.SetVector("_RectSize", new Vector2(positionRect.width, positionRect.height));
mousePosition = Event.current.mousePosition;
setupButton();
}
private void loadResources() {
if (ReferenceEquals(material, null) || material == null || texture == null) {
material = new Material(Shader.Find("Hidden/Important-Button"));
texture = Resources.Load<Texture2D>(resource);
gradient = Resources.Load<Texture2D>(gradientResource);
}
}
public float speedDiff;
public float easedSpeedDiff;
private bool isClicked;
public void update(float deltaTime) {
scrollingGradientTextureOffset -= gradientScrollSpeed * deltaTime;
loadResources();
material.SetFloat("_Offset", scrollingGradientTextureOffset);
if (isClicked) {
easedSpeedDiff += (targetExpand - easedSpeedDiff) * easeMousePosSpeed * deltaTime;
if (circleAlpha == 0f) invokeClick();
circleAlpha -= circleAlphaFadeSpeed * deltaTime;
}
else {
circleAlpha += circleAlphaFadeSpeed * deltaTime;
easedMousePosition += (mousePosition - easedMousePosition) * easeMousePosSpeed * deltaTime;
speedDiff = Mathf.Clamp01(Vector3.Distance(easedMousePosition, mousePosition) / 100f);
easedSpeedDiff += (speedDiff - easedSpeedDiff) * easeMousePosSpeed * deltaTime;
}
if (disableCircle) {
circleAlpha = 0;
}
else {
circleAlpha = Mathf.Clamp01(circleAlpha);
}
material.SetFloat("_circleAlpha", easeOutExpo(circleAlpha));
material.SetFloat("_SpeedDiff", easedSpeedDiff);
}
private void invokeClick() {
isClicked = false;
easedSpeedDiff = 2;
clickAction?.Invoke();
if (disableCircleAfterClick) {
disableCircle = true;
}
}
private float targetExpand;
private float circleAlpha = 1f;
float easeOutExpo(float x) {
// ReSharper disable once CompareOfFloatsByEqualityOperator
return x == 1f ? 1f : 1f - Mathf.Pow(2f, -10f * x);
}
private void setupButton() {
Color temp = GUI.color;
GUI.color = new Color(1, 1, 1, 0.0f);
if (GUI.Button(positionRect, "") && !isClicked) {
if (isRippleEnabled) {
isClicked = true;
float mouseDistanceToButtonCenter =
Vector2.Distance(mousePosition,
new Vector2(positionRect.x + positionRect.width / 2f, positionRect.y + positionRect.height / 2f));
float edgeDistanceToButtonCenter = Vector2.Distance(new Vector2(positionRect.x, positionRect.y),
new Vector2(positionRect.x + positionRect.width / 2f, positionRect.y + positionRect.height / 2f));
float distanceToCenterInPercent = mouseDistanceToButtonCenter / edgeDistanceToButtonCenter;
targetExpand = -6.3f * distanceToCenterInPercent;
}
else {
invokeClick();
}
}
GUI.color = temp;
}
}
}