Files
Kizza00232Jera 17532b524f [unity] avatars
2025-06-11 14:45:45 +02:00

398 lines
13 KiB
C#

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#nullable enable
using System.Collections;
using Oculus.Avatar2;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class UIWindowController : MonoBehaviour
{
private const string logScope = "UIWindowController";
[System.Serializable]
public enum UISectionType
{
Overview,
Scenes,
Settings,
Controls,
Logs,
[HideInInspector] Invalid,
}
[System.Serializable]
public struct UISection
{
public UISectionType sectionType;
public GameObject sectionPanel;
public GameObject tabButton;
public ScrollRect scrollArea;
}
[SerializeField] private UISection[]? sections;
[SerializeField] private Text? sceneNameText;
[SerializeField] private GameObject? uiInstructionTextGameObject;
[SerializeField] private GameObject? uiSectionTabsParentGameObject;
private int _currentActiveSectionIndex = 0;
private bool _initialized;
private void Awake()
{
if (sections == null || sections.Length < 1)
{
OvrAvatarLog.LogError("UIWindowController::Awake : Empty 'Sections'. This could be due to an empty field from the inspector.", logScope);
return;
}
if (uiInstructionTextGameObject == null)
{
OvrAvatarLog.LogError("UIWindowController::Awake : Null uiInstructionTextGameObject. This could be due to an empty field from the inspector.", logScope);
return;
}
if (uiSectionTabsParentGameObject == null)
{
OvrAvatarLog.LogError("UIWindowController::Awake : Null uiSectionTabsParentGameObject. This could be due to an empty field from the inspector.", logScope);
return;
}
uiInstructionTextGameObject.SetActive(true);
uiSectionTabsParentGameObject.SetActive(true);
foreach (var section in sections)
{
var textComponent = section.tabButton.GetComponentInChildren<Text>();
if (textComponent)
{
textComponent.text = section.sectionType.ToString();
}
section.sectionPanel.SetActive(false);
}
if (sceneNameText != null)
{
sceneNameText.gameObject.SetActive(true);
sceneNameText.text = SceneManager.GetActiveScene().name;
}
}
private void UpdateTabHighlight(int index)
{
if (sections == null || sections.Length < 1)
{
OvrAvatarLog.LogError("UIWindowController::UpdateTabHighlight : Empty 'Sections'. This could be due to an empty 'Sections' field from the inspector.", logScope);
return;
}
if (index >= sections.Length || index < 0)
{
OvrAvatarLog.LogError($"UIWindowController::UpdateTabHighlights : index '{index}' out of bounds.", logScope);
return;
}
var button = sections[index].tabButton.GetComponentInChildren<Button>();
if (button == null)
{
OvrAvatarLog.LogError($"UIWindowController::UpdateTabHighlights : Could not find a Button component under game object {sections[index].tabButton.name}", logScope);
return;
}
EventSystem.current.SetSelectedGameObject(null);
button.Select();
}
public void UpdateSceneNameText(Scene scene, LoadSceneMode loadSceneMode)
{
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSceneNameText : Failed to retrieve UIManager instance.", logScope);
return;
}
var sceneSwitcher = UIManager.Instance.GetUISceneSwitcher();
if (sceneSwitcher == null)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSceneNameText : Failed to retrieve SceneSwitcher from UIManager.", logScope);
return;
}
if (sceneNameText != null)
{
sceneNameText.text = sceneSwitcher.GetCurrentSceneName();
}
}
private void Start()
{
ActivateSection(0);
_initialized = true;
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::Start : Failed to retrieve UIManager instance.", logScope);
return;
}
UIManager.Instance.AddOnPauseEvent(ResetTabs);
}
private void ResetTabs()
{
ActivateSection(0);
}
public void ActivateSection(int index)
{
// Don't activate a section when clicked on by mouse.
// As clicking on a menu button directly calls this method, this check is
// needed to prevent unwanted behavior.
if (UIManager.Instance != null && UIManager.Instance.Initialized)
{
var uiInputController = UIManager.Instance.GetUIInputController();
if (uiInputController != null && !uiInputController.IsMenuNavigationEnabled())
{
return;
}
}
if (_initialized && index == _currentActiveSectionIndex)
{
UpdateTabHighlight(index);
return;
}
if (sections == null)
{
OvrAvatarLog.LogError("UIWindowController::ActivateSection : Empty 'Sections'. This could be due to an empty 'Sections' field from the inspector.", logScope);
return;
}
sections[_currentActiveSectionIndex].sectionPanel.SetActive(false);
sections[index].sectionPanel.SetActive(true);
UpdateSectionFromType(sections[_currentActiveSectionIndex].sectionType, false);
_currentActiveSectionIndex = index;
UpdateSectionFromType(sections[_currentActiveSectionIndex].sectionType, true);
UpdateTabHighlight(index);
}
private void UpdateSectionFromType(UISectionType sectionType, bool isActive)
{
switch (sectionType)
{
case UISectionType.Scenes:
UpdateSceneSection(isActive);
break;
case UISectionType.Overview:
UpdateOverviewSection();
break;
case UISectionType.Logs:
UpdateLogSection(isActive);
break;
case UISectionType.Settings:
UpdateSettingsSection(isActive);
break;
default:
break;
}
// reset scrolls to top
var activeScrollArea = GetActiveScrollArea();
if (activeScrollArea != null)
{
activeScrollArea.verticalNormalizedPosition = 1;
}
}
private void UpdateSettingsSection(bool isActive)
{
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSettingsSection : Failed to retrieve UIManager instance.", logScope);
return;
}
var settingsManager = UIManager.Instance.GetUISettingsManager();
if (settingsManager == null)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSettingsSection : Failed to retrieve SettingsManager from UI Manager.", logScope);
return;
}
// search for avatars only if the Settings section is activated
if (isActive)
{
settingsManager.SearchForAvatarsInScene();
settingsManager.ResetIndex();
}
else
{
settingsManager.MoveOutOfSettings();
}
}
private void UpdateLogSection(bool isActive)
{
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::UpdateLogSection : Failed to retrieve UIManager instance.", logScope);
return;
}
var uiLogger = UIManager.Instance.GetUILogger();
if (uiLogger == null)
{
OvrAvatarLog.LogError("UIWindowController::UpdateLogSection : Failed to retrieve UILogger from UIManager.", logScope);
return;
}
if (isActive)
{
uiLogger.ActivateUILogger();
}
else
{
uiLogger.DeactivateUILogger();
}
}
private void UpdateOverviewSection()
{
if (sections == null || sections.Length < 1)
{
OvrAvatarLog.LogError("UIWindowController::UpdateOverviewSection : Null or empty sections.", logScope);
return;
}
var section = sections[_currentActiveSectionIndex];
var textComponent = section.sectionPanel.GetComponentInChildren<Text>();
if (textComponent)
{
SetOverviewText(textComponent);
}
}
private void SetOverviewText(Text text)
{
StartCoroutine(SetOverviewTextWithDelay(text));
}
private IEnumerator SetOverviewTextWithDelay(Text text)
{
yield return null;
text.text = GetCurrentSceneInfo();
}
private string GetCurrentSceneInfo()
{
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::GetCurrentSceneInfo : Failed to retrieve UIManager instance.", logScope);
return "Could not retrieve information for this scene.";
}
var sceneSwitcher = UIManager.Instance.GetUISceneSwitcher();
if (sceneSwitcher == null)
{
OvrAvatarLog.LogError("UIWindowController::GetCurrentSceneInfo : Failed to retrieve SceneSwitcher from UIManager.", logScope);
return "Could not retrieve information for this scene.";
}
return sceneSwitcher.GetCurrentSceneDescription();
}
private void UpdateSceneSection(bool isActive)
{
if (UIManager.Instance == null || !UIManager.Instance.Initialized)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSceneSection : Failed to retrieve UIManager instance.", logScope);
return;
}
var sceneSwitcher = UIManager.Instance.GetUISceneSwitcher();
if (sceneSwitcher == null)
{
OvrAvatarLog.LogError("UIWindowController::UpdateSceneSection : Failed to retrieve UISceneSwitcher from UIManager.", logScope);
return;
}
if (isActive)
{
sceneSwitcher.OnSectionEnable();
}
else
{
sceneSwitcher.OnSectionDisable();
}
}
public void MoveSectionIndex(int index)
{
if (sections == null)
{
OvrAvatarLog.LogError("UIWindowController::MoveSectionIndex : Empty 'Sections'. This could be due to an empty 'Sections' field from the inspector.", logScope);
return;
}
int newIndex = WrapIndex(_currentActiveSectionIndex + index, sections.Length);
ActivateSection(newIndex);
}
private int WrapIndex(int index, int arraySize)
{
return ((index % arraySize) + arraySize) % arraySize;
}
public void ResetIndex()
{
if (sections == null)
{
OvrAvatarLog.LogError("UIWindowController::ResetIndex : Empty 'Sections'. This could be due to an empty 'Sections' field from the inspector.", logScope);
return;
}
ActivateSection(0);
}
public UISectionType GetActiveSectionType()
{
if (sections == null)
{
OvrAvatarLog.LogError("UIWindowController::GetActiveSectionType : Empty 'Sections'. This could be due to an empty 'Sections' field from the inspector.", logScope);
return UISectionType.Invalid;
}
return sections[_currentActiveSectionIndex].sectionType;
}
public ScrollRect? GetActiveScrollArea()
{
return sections?[_currentActiveSectionIndex].scrollArea != null ? sections[_currentActiveSectionIndex].scrollArea : null;
}
}