/// /// Credit - ryanslikesocool /// Sourced from - https://github.com/ryanslikesocool/Unity-Card-UI /// using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace UnityEngine.UI.Extensions { [ExecuteInEditMode] public class CardExpanding3D : MonoBehaviour { [SerializeField] private float lerpSpeed = 12; [SerializeField] private float cornerSize = 64; [Header("Parts")] public RectTransform[] cardCorners; public RectTransform[] cardEdges; public RectTransform cardCenter; [Header("Card Info")] [Tooltip("Positions and sizes card to its current transform.")] public bool cardAutoSize = true; public Vector2 cardSize; public Vector2 cardPosition; [Range(1, 96)] public int cardSuperness = 4; [Header("Page Info")] [Tooltip("Positions and sizes the page to the top third of the screen.")] public bool pageAutoSize = true; public Vector2 pageSize; public Vector2 pagePosition; [Range(1, 96)] public int pageSuperness = 96; ///Just like with the 2D version of this script, I don't recommend touching this. private int animationActive = 0; private Vector2[] nextCornerPos = new Vector2[4]; private Vector2[] nextEdgePos = new Vector2[4]; private Vector2[] nextEdgeScale = new Vector2[4]; private Vector2 nextCenterScale; private Vector2 nextPos; private int nextSuperness; private RectTransform rect; private Vector2 nextMin; private Vector2 nextMax; void Start() { if (cardAutoSize) { cardSize = new Vector2(cardCorners[0].localScale.x * 2 + cardEdges[0].localScale.x, cardCorners[0].localScale.y * 2 + cardEdges[0].localScale.y); cardPosition = cardCenter.localPosition; } if (pageAutoSize) { pageSize = new Vector2(Screen.width, Screen.height / 3); pagePosition = new Vector2(0, Screen.height / 2 - pageSize.y / 2); } rect = GetComponent(); } void Update() { if (animationActive == 1 || animationActive == -1) { ///Lerps the corners to new positions and supernesses. for (int i = 0; i < cardCorners.Length; i++) { cardCorners[i].localPosition = Vector3.Lerp(cardCorners[i].localPosition, nextCornerPos[i], Time.deltaTime * lerpSpeed); cardCorners[i].GetComponent().superness = Mathf.Lerp(cardCorners[i].GetComponent().superness, nextSuperness, Time.deltaTime * lerpSpeed); ///Forces everything to either the card layout or the page layout once the superness is similar enough. if (Mathf.Abs(cardCorners[i].GetComponent().superness - nextSuperness) <= 1) { cardCorners[i].localPosition = nextCornerPos[i]; cardEdges[i].localPosition = nextEdgePos[i]; cardEdges[i].localScale = new Vector3(nextEdgeScale[i].x, nextEdgeScale[i].y, 1); transform.localPosition = nextPos; cardCenter.localScale = new Vector3(nextCenterScale.x, nextCenterScale.y, 1); cardCorners[i].GetComponent().superness = nextSuperness; rect.offsetMin = nextMin; rect.offsetMax = nextMax; } } ///Lerps the edges to new positions and sizes. for (int i = 0; i < cardEdges.Length; i++) { cardEdges[i].localPosition = Vector3.Lerp(cardEdges[i].localPosition, nextEdgePos[i], Time.deltaTime * lerpSpeed); cardEdges[i].localScale = Vector3.Lerp(cardEdges[i].localScale, new Vector3(nextEdgeScale[i].x, nextEdgeScale[i].y, 1), Time.deltaTime * lerpSpeed); } ///Lerps the center to new position and size. transform.localPosition = Vector3.Lerp(transform.localPosition, nextPos, Time.deltaTime * lerpSpeed); cardCenter.localScale = Vector3.Lerp(cardCenter.localScale, new Vector3(nextCenterScale.x, nextCenterScale.y, 1), Time.deltaTime * lerpSpeed); ///Lerps the RectTransform. rect.offsetMin = Vector3.Lerp(rect.offsetMin, nextMin, Time.deltaTime * lerpSpeed); rect.offsetMax = Vector3.Lerp(rect.offsetMax, nextMax, Time.deltaTime * lerpSpeed); } } public void ToggleCard() { if (animationActive != 1 || animationActive == 0) { animationActive = 1; ///Gets new corner positions. for (int i = 0; i < cardCorners.Length; i++) { float posX = pageSize.x / 2 * Mathf.Sign(cardCorners[i].localScale.x) - cardCorners[i].localScale.x; float posY = pageSize.y / 2 * Mathf.Sign(cardCorners[i].localScale.y) - cardCorners[i].localScale.y; nextCornerPos[i] = new Vector2(posX, posY); } ///Same concept as the last loop. for (int i = 0; i < cardEdges.Length; i++) { float posX = 0; float posY = 0; float scaleX = 0; float scaleY = 0; if (cardEdges[i].localPosition.x != 0) { posX = Mathf.Sign(cardEdges[i].localPosition.x) * ((pageSize.x / 2) - (cardEdges[i].localScale.x / 2)); posY = 0; scaleX = cornerSize; scaleY = pageSize.y - cornerSize * 2; } else if (cardEdges[i].localPosition.y != 0) { posX = 0; posY = Mathf.Sign(cardEdges[i].localPosition.y) * ((pageSize.y / 2) - (cardEdges[i].localScale.y / 2)); scaleX = pageSize.x - cornerSize * 2; scaleY = cornerSize; } nextEdgePos[i] = new Vector2(posX, posY); nextEdgeScale[i] = new Vector2(scaleX, scaleY); } nextCenterScale = pageSize - new Vector2(cornerSize * 2, cornerSize * 2); nextPos = pagePosition; nextSuperness = pageSuperness; nextMin = new Vector2(-pageSize.x / 2, -pageSize.y / 2) + nextPos; nextMax = new Vector2(pageSize.x / 2, pageSize.y / 2) + nextPos; } else if (animationActive != -1) { animationActive = -1; ///Gets new corner positions. for (int i = 0; i < cardCorners.Length; i++) { float posX = Mathf.Sign(cardCorners[i].localScale.x) * (cardSize.x / 2) - cardCorners[i].localScale.x; float posY = Mathf.Sign(cardCorners[i].localScale.y) * (cardSize.y / 2) - cardCorners[i].localScale.y; nextCornerPos[i] = new Vector2(posX, posY); } ///Same concept as the last loop. for (int i = 0; i < cardEdges.Length; i++) { float posX = 0; float posY = 0; float scaleX = 0; float scaleY = 0; if (cardEdges[i].localPosition.x != 0) { posX = Mathf.Sign(cardEdges[i].localPosition.x) * (cardSize.x / 2) - Mathf.Sign(cardEdges[i].localPosition.x) * (cardEdges[i].localScale.x / 2); posY = 0; scaleX = cornerSize; scaleY = cardSize.y - cornerSize * 2; } else if (cardEdges[i].localPosition.y != 0) { posX = 0; posY = Mathf.Sign(cardEdges[i].localPosition.y) * (cardSize.y / 2) - Mathf.Sign(cardEdges[i].localPosition.y) * (cardEdges[i].localScale.y / 2); scaleX = cardSize.x - cornerSize * 2; scaleY = cornerSize; } nextEdgePos[i] = new Vector2(posX, posY); nextEdgeScale[i] = new Vector2(scaleX, scaleY); } nextCenterScale = cardSize - new Vector2(cornerSize * 2, cornerSize * 2); nextPos = cardPosition; nextSuperness = cardSuperness; nextMin = new Vector2(-cardSize.x / 2, -cardSize.y / 2) + nextPos; nextMax = new Vector2(cardSize.x / 2, cardSize.y / 2) + nextPos; } } } }