#region Includes using UnityEngine; using UnityEngine.Events; using System.Collections.Generic; #endregion #if UNITY_EDITOR using UnityEditor; #endif /// /// This class manages a collection of page dots used for navigation in a paginated view. /// It provides methods to add, clear, and change the active dot. /// public class PageDotsIndicator : MonoBehaviour { #region Variables [Header("References")] /// /// Prefab reference for the PageDot component representing a single dot indicator. /// [Tooltip("Prefab reference for the PageDot component representing a single dot indicator")] [SerializeField] private PageDot _prefab; [Header("Children")] /// /// List containing references to all currently displayed PageDot instances. /// [Tooltip("List containing references to all currently displayed PageDot instances")] [SerializeField] private List _dots; [Header("Events")] /// /// UnityEvent that is invoked when a page dot is pressed, passing the index of the pressed dot. /// [Tooltip("Invoked when a page dot is pressed, passing the index of the pressed dot")] public UnityEvent OnDotPressed; /// /// Gets or sets the visibility of the PageDotsIndicator game object. /// public bool IsVisible { get { return gameObject.activeInHierarchy; } set { gameObject.SetActive(value); } } #endregion private void Awake() { if (_dots.Count == 0) return; for (int i = 0; i < _dots.Count; i++) { _dots[i].ChangeActiveState(i == 0); } } /// /// Adds a new page dot indicator to the collection. /// public void Add() { PageDot dot = null; #if UNITY_EDITOR if (!Application.isPlaying) { // In editor mode, use PrefabUtility for non-destructive instantiation. dot = (PageDot)PrefabUtility.InstantiatePrefab(_prefab, transform); } #endif // If no dot was instantiated in editor mode, use regular Instantiate in play mode. if (dot == null) { dot = Instantiate(_prefab, transform); } dot.Index = _dots.Count; dot.ChangeActiveState(_dots.Count == 0); // Activate the first dot. _dots.Add(dot); #if UNITY_EDITOR if (Application.isPlaying) { return; } // In editor mode, mark the scene as dirty to save changes. EditorUtility.SetDirty(this); #endif } /// /// Clears all the page dot indicators from the collection and destroys their game objects. /// public void Clear() { for (int i = 0; i < _dots.Count; i++) { if (_dots[i] == null) { continue; } #if UNITY_EDITOR // In editor mode, use DestroyImmediate for immediate object removal. DestroyImmediate(_dots[i].gameObject); #else // In play mode, use Destroy for object removal during gameplay. Destroy(_dots[i].gameObject); #endif } _dots.Clear(); #if UNITY_EDITOR // In editor mode, mark the scene as dirty to save changes. EditorUtility.SetDirty(this); #endif } /// /// Changes the active state of the page dots. /// It deactivates the dot at the 'fromIndex' and activates the dot at the 'toIndex'. /// /// The index of the dot to deactivate. /// The index of the dot to activate. public void ChangeActiveDot(int fromIndex, int toIndex) { _dots[fromIndex].ChangeActiveState(false); _dots[toIndex].ChangeActiveState(true); } #if UNITY_EDITOR [CustomEditor(typeof(PageDotsIndicator))] public class PageDotsIndicatorEditor : Editor { #region Variables private PageDotsIndicator _target; #endregion private void OnEnable() { _target = (PageDotsIndicator)target; } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Editor"); if (GUILayout.Button("Clear")) { _target.Clear(); } } } #endif }