Unity3d中Tab控件的实现
1.按如下结构建立一个Tabs
2.Tabs上添加Toggle Group组件
3.Tab上添加Toggle、ToggleHighlightStaysActiveAfterLosingFocus
4.Page上添加Canvas Group
5.在Menu上添加TabMenu,系统会自动识别,无需手动赋值(识别错误的话见下文)。这样就完成了Tab控件的制作
6.如果Page下有Toggle,TabMenu会识别错误,需要手动赋值。
解决方法:注释TabMenu.cs以下代码,再手动赋值
7.设定初始选中项,将对应的Tab下的Toggle的isOn勾上,其余Tab的取消勾选就可以了。
附:
TabMenu.cs代码
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;namespace ChristinaCreatesGames.UI
{public class TabMenu : MonoBehaviour{[Header("Current Index")][SerializeField] private int pageIndex = 0;[Header("Components")][SerializeField] private ToggleGroup toggleGroup;[SerializeField] private List<Toggle> tabs = new List<Toggle>();[SerializeField] private List<CanvasGroup> pages = new List<CanvasGroup>();[Header("Event to call")]public UnityEvent<int> OnPageIndexChanged;private void Initialize(){toggleGroup = GetComponentInChildren<ToggleGroup>();tabs.Clear();pages.Clear();tabs.AddRange(GetComponentsInChildren<Toggle>());pages.AddRange(GetComponentsInChildren<CanvasGroup>());}private void Reset(){Initialize();}private void OnValidate(){Initialize();OpenPage(pageIndex);tabs[pageIndex].SetIsOnWithoutNotify(true);}private void Awake(){foreach (var toggle in tabs){toggle.onValueChanged.AddListener(CheckForTab);toggle.group = toggleGroup;}}private void OnDestroy(){foreach (var toggle in tabs){toggle.onValueChanged.RemoveListener(CheckForTab);}}private void CheckForTab(bool value){for (int i = 0; i < tabs.Count; i++){if (!tabs[i].isOn) continue;pageIndex = i;}OpenPage(pageIndex);}private void OpenPage(int index){EnsureIndexIsInRange(index);for (int i = 0; i < pages.Count; i++){bool isActivePage = (i == pageIndex);pages[i].alpha = isActivePage ? 1.0f : 0.0f;pages[i].interactable = isActivePage;pages[i].blocksRaycasts = isActivePage;}if (Application.isPlaying)OnPageIndexChanged?.Invoke(pageIndex);}private void EnsureIndexIsInRange(int index){if (tabs.Count == 0 || pages.Count == 0){Debug.Log("Forgot to setup Tabs or Pages");return;}pageIndex = Mathf.Clamp(index, 0, pages.Count - 1);}public void JumpToPage(int page){EnsureIndexIsInRange(page);tabs[pageIndex].isOn = true;}}
}
ToggleHighlightStaysActiveAfterLosingFocus.cs代码
using UnityEngine;
using UnityEngine.UI;namespace ChristinaCreatesGames.UI
{public class ToggleHighlightStaysActiveAfterLosingFocus : MonoBehaviour{[SerializeField] private Toggle toggle;[SerializeField] private Image imageToKeepFocusActive;private void Reset(){toggle = GetComponent<Toggle>();}private void Awake(){toggle.onValueChanged.AddListener(OnToggleValueChanged);OnToggleValueChanged(toggle.isOn);}private void OnDestroy(){toggle.onValueChanged.RemoveListener(OnToggleValueChanged);}private void OnToggleValueChanged(bool isOn){if (imageToKeepFocusActive == null) return;imageToKeepFocusActive.color = toggle.isOn ? toggle.colors.highlightedColor : Color.clear;}}
}
参考视频