diff --git a/Assets/UIManager/Scripts/Editor.meta b/Assets/UIManager/Scripts/Editor.meta new file mode 100644 index 0000000..507c789 --- /dev/null +++ b/Assets/UIManager/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0249c3578f508264a919a07eb6092406 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs b/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs new file mode 100644 index 0000000..1ca59dd --- /dev/null +++ b/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs @@ -0,0 +1,45 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +namespace Rellac.UI.Editor +{ + [CustomEditor(typeof(UIManager))] + [CanEditMultipleObjects] + public class UIManagerEditor : UnityEditor.Editor + { + SerializedProperty containsLoopGroup; + SerializedProperty initialPanel; + SerializedProperty loopTransitionSpeed; + SerializedProperty prevTransition; + SerializedProperty nextTransition; + SerializedProperty loopGroup; + + void OnEnable() + { + containsLoopGroup = serializedObject.FindProperty("containsLoopGroup"); + initialPanel = serializedObject.FindProperty("initialPanel"); + loopTransitionSpeed = serializedObject.FindProperty("loopTransitionSpeed"); + prevTransition = serializedObject.FindProperty("prevTransition"); + nextTransition = serializedObject.FindProperty("nextTransition"); + loopGroup = serializedObject.FindProperty("loopGroup"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(containsLoopGroup); + if (containsLoopGroup.boolValue) + { + EditorGUILayout.PropertyField(loopTransitionSpeed); + EditorGUILayout.PropertyField(prevTransition); + EditorGUILayout.PropertyField(nextTransition); + EditorGUILayout.PropertyField(loopGroup); + } else + { + EditorGUILayout.PropertyField(initialPanel); + } + serializedObject.ApplyModifiedProperties(); + } + } +} \ No newline at end of file diff --git a/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs.meta b/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs.meta new file mode 100644 index 0000000..273a40e --- /dev/null +++ b/Assets/UIManager/Scripts/Editor/UIManagerEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb630395c46da7843a875b324c02b6e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UIManager/Scripts/UIManager.cs b/Assets/UIManager/Scripts/UIManager.cs index 69faab7..7779f77 100644 --- a/Assets/UIManager/Scripts/UIManager.cs +++ b/Assets/UIManager/Scripts/UIManager.cs @@ -5,11 +5,36 @@ namespace Rellac.UI [CreateAssetMenu(fileName = "New UI Manager", menuName = "UI/Manager", order = 1)] public class UIManager : ScriptableObject { + /// + /// Manager loops between a selection of UIPanels + /// + [Tooltip("")] + [SerializeField] private bool containsLoopGroup = false; /// /// Panel to start when manager is initialised - no transition will be made /// [Tooltip("Panel to start when manager is initialised - no transition will be made")] [SerializeField] private UIPanel initialPanel = null; + /// + /// Speed to play transitions across a loop group + /// + [Tooltip("Speed to play transitions across a loop group")] + [SerializeField] private float loopTransitionSpeed = 1; + /// + /// Animation to play when transitioning to the previous panel in a loop group + /// + [Tooltip("Animation to play when transitioning to the previous panel in a loop group")] + [SerializeField] private UITransition prevTransition = null; + /// + /// Animation to play when transitioning to the next panel in a loop group + /// + [Tooltip("Animation to play when transitioning to the next panel in a loop group")] + [SerializeField] private UITransition nextTransition = null; + /// + /// Group of UIPanels to transition between is manager contains a loop group + /// + [Tooltip("Group of UIPanels to transition between is manager contains a loop group")] + [SerializeField] private UIPanel[] loopGroup = null; RectTransform root_; /// @@ -45,6 +70,27 @@ public Animator animator private bool transitioning = false; private UIPanel currentPanel; + private int loopIdx_; + private int loopIdx + { + get + { + return loopIdx_; + } + set + { + loopIdx_ = value; + if (loopIdx_ >= loopGroup.Length) + { + loopIdx_ = 0; + } + if (loopIdx < 0) + { + loopIdx = loopGroup.Length - 1; + } + } + } + /// /// Initialise manager in scene /// @@ -63,11 +109,18 @@ public void Initialise(RectTransform parent) fitter.Fit(); } - RectTransform panelRoot = (RectTransform)Instantiate(initialPanel.panelPrefab, inParent).transform; + UIPanel panel = initialPanel; + if (containsLoopGroup) + { + panel = loopGroup[0]; + loopIdx = 0; + } + + RectTransform panelRoot = (RectTransform)Instantiate(panel.panelPrefab, inParent).transform; animator.Play("Instant"); - initialPanel.Initialise(panelRoot); - root.GetComponent().StartCoroutine(initialPanel.WaitForTransitionIn(panelRoot)); - currentPanel = initialPanel; + panel.Initialise(panelRoot); + root.GetComponent().StartCoroutine(panel.WaitForTransitionIn(panelRoot, panel.animationSpeed)); + currentPanel = panel; transitioning = false; } @@ -76,11 +129,61 @@ public void Initialise(RectTransform parent) /// /// UIPanel to transition to public void SetPanel(UIPanel input) + { + if (TryPreparePanel(input)) + { + input.PlayTransition(this, input.transition, containsLoopGroup ? loopTransitionSpeed : input.animationSpeed); + transitioning = true; + } + } + + public void NextPanel() + { + if (CheckIsValidLoopGroup()) + { + loopIdx++; + if (TryPreparePanel(loopGroup[loopIdx])) + { + loopGroup[loopIdx].PlayTransition(this, nextTransition, containsLoopGroup ? loopTransitionSpeed : loopGroup[loopIdx].animationSpeed); + transitioning = true; + } + } + } + + public void PreviousPanel() + { + if (CheckIsValidLoopGroup()) + { + loopIdx--; + if (TryPreparePanel(loopGroup[loopIdx])) + { + loopGroup[loopIdx].PlayTransition(this, prevTransition, containsLoopGroup ? loopTransitionSpeed : loopGroup[loopIdx].animationSpeed); + transitioning = true; + } + } + } + + private bool CheckIsValidLoopGroup() + { + if (!containsLoopGroup) + { + Debug.LogError("Trying to Call NextPanel() on a UIManager that doesn't contain a loop group"); + return false; + } + if (loopGroup.Length == 0) + { + Debug.LogError("No panels listed in loop group of " + name); + return false; + } + return true; + } + + private bool TryPreparePanel(UIPanel input) { if (transitioning) { Debug.LogError("Wait for transition to end before setting new panel"); - return; + return false; } if (currentPanel != null) { @@ -102,8 +205,7 @@ public void SetPanel(UIPanel input) } root.GetComponent().StartCoroutine(WaitForAnimationEnd(input)); input.Initialise((RectTransform)Instantiate(input.panelPrefab, inParent).transform); - input.PlayTransition(this); - transitioning = true; + return true; } private IEnumerator WaitForAnimationEnd(UIPanel panel) diff --git a/Assets/UIManager/Scripts/UIPanel.cs b/Assets/UIManager/Scripts/UIPanel.cs index 83965c0..ee0cfbc 100644 --- a/Assets/UIManager/Scripts/UIPanel.cs +++ b/Assets/UIManager/Scripts/UIPanel.cs @@ -66,16 +66,16 @@ public void Initialise(RectTransform input) /// Play set animation transition for this panel /// /// UIManager handling Animation - public void PlayTransition(UIManager manager) + public void PlayTransition(UIManager manager, UITransition transition_, float speed) { - manager.animator.speed = 1f / animationSpeed; - manager.animator.Play(transition.inAnimation.name); - manager.root.GetComponent().StartCoroutine(WaitForTransitionIn(instantiation)); + manager.animator.speed = 1f / speed; + manager.animator.Play(transition_.inAnimation.name); + manager.root.GetComponent().StartCoroutine(WaitForTransitionIn(instantiation, speed)); } - public IEnumerator WaitForTransitionIn(RectTransform parent) + public IEnumerator WaitForTransitionIn(RectTransform parent, float speed) { - yield return new WaitForSeconds(transition.inAnimation.length * animationSpeed); + yield return new WaitForSeconds(transition.inAnimation.length * speed); onPanelTransitionedIn.Invoke(parent); } diff --git a/README.md b/README.md index cafeb0f..0bcfb8e 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,10 @@ An initialised Manager can swap between panels via SetPanel(UIPanel) ![](SetPanel-example.png) +UI Managers can be set to have "loop groups" - if so, you will specify here a previous/next transition to override what is specified in the UIPanels listed on the UIManager. Panels will logically transition by calling NextPanel() and PreviousPanel() in the UIManager, the index will reset automatically. A Manager with a loop group will override the speed of the animation transition. That value is set here. + +![](UIManagers-example.png) + # UI Panel ---------- **Create > UI > Panel** diff --git a/UIManagers-example.png b/UIManagers-example.png new file mode 100644 index 0000000..e42204c Binary files /dev/null and b/UIManagers-example.png differ