Advertisement
JimTheJam

Activity Wheel (Carousel Menu) C#

Aug 1st, 2023
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.99 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using TMPro;
  5. using UnityEngine;
  6. using UnityEngine.Events;
  7. using UnityEngine.UI;
  8.  
  9. namespace ParentHouse.UI
  10. {
  11.     public class ActivityWheel : MonoBehaviour
  12.     {
  13.         [Header("Demo Settings")] public List<string> demoMessages = new();
  14.         public Color foregroundColor;
  15.         public Color backgroundColor;
  16.         public float bgColorCellSizeRequirement;
  17.         public TextMeshProUGUI textOutput;
  18.         public GameObject demoPrefabObject;
  19.  
  20.         [Header("Settings")] public float radius = 280;
  21.         public float vertialSquish = 0.35f;
  22.         public float spinSpeed = 7;
  23.         public bool targetCellOnTop = true;
  24.         public Vector2 minimumCellSize = new Vector2(50, 50);
  25.         public Vector2 cellSize = new Vector2(150, 150);
  26.  
  27.         [Header("Debugging")] [SerializeField] private int selectIndex;
  28.         [SerializeField] private float targetAngle;
  29.         [SerializeField] private float angleOffset;
  30.         [SerializeField] private float facingAngle;
  31.         [SerializeField] private bool needsToBeNormalized;
  32.         [SerializeField] private float scrollInput;
  33.         [SerializeField] private readonly List<ActivityWheelAction> wheelActions = new();
  34.         [SerializeField] private List<GameObject> wheelDisplayObjectPool = new();
  35.  
  36.         private void OnEnable()
  37.         {
  38.             for (int i = 0; i < 20; i++)
  39.             {
  40.                 wheelDisplayObjectPool.Add(Instantiate(demoPrefabObject, this.transform));
  41.                 wheelDisplayObjectPool[i].gameObject.name = $"Object {i}";
  42.                 wheelDisplayObjectPool[i].gameObject.SetActive(false);
  43.             }
  44.  
  45.             Show();
  46.         }
  47.  
  48.         private void Show()
  49.         {
  50.             ClearWheel();
  51.             GenerateActivityWheelDisplays();
  52.             if (wheelActions.Count == 0) return;
  53.             wheelActions.Reverse();
  54.             if (wheelActions.Count > 1)
  55.                 angleOffset = wheelActions[^2].storedAngle;
  56.             else
  57.             {
  58.                 targetAngle = 0;
  59.             }
  60.  
  61.             CheckScrollInput(1);
  62.             facingAngle = targetAngle;
  63.         }
  64.  
  65.         private void ClearWheel()
  66.         {
  67.             facingAngle = 0;
  68.             targetAngle = 0;
  69.             selectIndex = 0;
  70.             wheelActions.Clear();
  71.         }
  72.  
  73.         private void InvokeSelectedActivityAction()
  74.         {
  75.             if (wheelActions.Count == 0) return;
  76.             int offsetIndex = selectIndex + 1;
  77.             offsetIndex = offsetIndex >= wheelActions.Count ? 0 :
  78.                 offsetIndex < 0 ? wheelActions.Count - 1 : offsetIndex;
  79.             wheelActions[offsetIndex].WheelUnityAction.Invoke();
  80.         }
  81.  
  82.         private void Update()
  83.         {
  84.             scrollInput = Input.mouseScrollDelta.y;
  85.             if (Input.GetKeyDown(KeyCode.Space))
  86.                 InvokeSelectedActivityAction();
  87.             CheckScrollInput(scrollInput);
  88.         }
  89.  
  90.         private void FixedUpdate()
  91.         {
  92.             AnimateWheelDisplays();
  93.         }
  94.  
  95.         private void CheckScrollInput(float input)
  96.         {
  97.             if (input == 0 || wheelActions.Count <= 1) return;
  98.             if (needsToBeNormalized)
  99.             {
  100.                 facingAngle = targetAngle = wheelActions[selectIndex].storedAngle;
  101.                 needsToBeNormalized = false;
  102.             }
  103.  
  104.             input = Mathf.Clamp(input, -1, 1);
  105.             selectIndex += (int) input;
  106.  
  107.             if (selectIndex >= wheelActions.Count)
  108.             {
  109.                 targetAngle = -angleOffset;
  110.                 needsToBeNormalized = true;
  111.             }
  112.             else if (selectIndex < 0)
  113.             {
  114.                 targetAngle = wheelActions[0].storedAngle + angleOffset;
  115.                 needsToBeNormalized = true;
  116.             }
  117.             else targetAngle = wheelActions[selectIndex].storedAngle;
  118.  
  119.             selectIndex = selectIndex >= wheelActions.Count ? 0 :
  120.                 selectIndex < 0 ? wheelActions.Count - 1 : selectIndex;
  121.             int offsetIndex = selectIndex + 1;
  122.             offsetIndex = offsetIndex >= wheelActions.Count ? 0 :
  123.                 offsetIndex < 0 ? wheelActions.Count - 1 : offsetIndex;
  124.         }
  125.  
  126.         private void AnimateWheelDisplays()
  127.         {
  128.             for (int i = 0; i < wheelActions.Count; i++)
  129.             {
  130.                 var rect = wheelActions[i].Obj.GetComponent<RectTransform>();
  131.  
  132.                 float angle = (i * Mathf.PI * 2f / wheelActions.Count) + facingAngle;
  133.                 if (!wheelActions[i].hasAngle)
  134.                 {
  135.                     wheelActions[i].hasAngle = true;
  136.                     wheelActions[i].storedAngle = angle;
  137.                 }
  138.  
  139.                 float y = (Mathf.Cos(angle) * radius) * vertialSquish;
  140.                 float x = Mathf.Sin(angle) * radius;
  141.                 rect.anchoredPosition = new Vector2(x, y);
  142.  
  143.                 int verticalFlip = targetCellOnTop ? 1 : -1;
  144.                 float unscaledSize = Mathf.InverseLerp(-cellSize.x * verticalFlip, cellSize.y * verticalFlip, y);
  145.                 float scaledSize = Mathf.Clamp(cellSize.x * unscaledSize, minimumCellSize.x, cellSize.x);
  146.                 var size = new Vector2(scaledSize, scaledSize);
  147.                 rect.sizeDelta = size;
  148.  
  149.                 var c = rect.GetComponent<Canvas>();
  150.                 c.overrideSorting = true;
  151.                 c.sortingOrder = (int) size.y;
  152.  
  153.                 // For demonstrating depth
  154.                 wheelActions[i].DemoImage.color =
  155.                     scaledSize < bgColorCellSizeRequirement ? backgroundColor : foregroundColor;
  156.             }
  157.  
  158.             if (wheelActions.Count <= 1) return;
  159.             facingAngle = Mathf.Lerp(facingAngle, targetAngle, spinSpeed * Time.deltaTime);
  160.         }
  161.  
  162.         private void GenerateActivityWheelDisplays()
  163.         {
  164.             for (var i = 0; i < demoMessages.Count; i++)
  165.             {
  166.                 SetupWheelListObject(wheelDisplayObjectPool[i], demoMessages[i]);
  167.             }
  168.  
  169.             selectIndex = selectIndex >= wheelActions.Count ? wheelActions.Count - 1 :
  170.                 selectIndex < 0 ? 0 : selectIndex;
  171.             AnimateWheelDisplays();
  172.         }
  173.  
  174.         private void SetupWheelListObject(GameObject displayObject, string message)
  175.         {
  176.             displayObject.SetActive(true);
  177.             var WheelObject = new ActivityWheelAction
  178.             {
  179.                 WheelUnityAction = delegate
  180.                 {
  181.                     print(message);
  182.                     textOutput.text = message;
  183.                 },
  184.                 Obj = displayObject,
  185.                 DemoImage = displayObject.GetComponent<Image>()
  186.             };
  187.             wheelActions.Add(WheelObject);
  188.         }
  189.     }
  190.  
  191.     public class ActivityWheelAction
  192.     {
  193.         public UnityAction WheelUnityAction;
  194.         public GameObject Obj;
  195.         public Image DemoImage;
  196.         public float storedAngle;
  197.         public bool hasAngle = false;
  198.     }
  199. }
Tags: C# Unity utility
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement