- Add Menu scene with Rive-driven login and navigation UI (RiveLoginController, RiveNavigationController) for entering a username and starting/navigating the client via Rive triggers - Add SceneTransitionController to fade out and load the Landscape gameplay scene when Play is selected - Add procedural low-poly triangle field background and animated wave panel (LowPolyTriangleField, TriangleWavePanel) with matching editor menus and materials - Add MenuLightAnimator for animated menu lighting and UI fade helpers (MenuFadeIn, DebugFadeToggle/Bridge) - Rename SampleScene to Landscape and wire ChatNetworkManager to hide the new Rive login canvas once gameplay starts - Bump Input System action codegen version and add Rive package references/project settings updates to support the new UI
133 lines
4.1 KiB
C#
133 lines
4.1 KiB
C#
using ProceduralEditor;
|
|
using Rive;
|
|
using Rive.Components;
|
|
using System.Reflection.Metadata;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
/// Sends keyboard navigation commands to the Rive menu and
|
|
/// activates the Play option when Enter is pressed
|
|
public class RiveNavigationController : MonoBehaviour
|
|
{
|
|
[Header("Rive")]
|
|
[Tooltip("RiveWidget that hosts the menu artboard.")]
|
|
[SerializeField] private RiveWidget riveWidget;
|
|
|
|
[Header("Scene Transition")]
|
|
[Tooltip("Object containing the SceneTransitionController component.")]
|
|
[SerializeField] private SceneTransitionController sceneTransitionController;
|
|
|
|
[Header("Menu Selection")]
|
|
[Tooltip("Total number of selectable Rive menu buttons.")]
|
|
[Min(1)]
|
|
[SerializeField] private int menuItemCount = 1;
|
|
|
|
|
|
private const string NextTriggerName = "nextButtonClicked";
|
|
private const string PreviousTriggerName = "previousButtonClicked";
|
|
private const int PlayIndex = 0;
|
|
|
|
private ViewModelInstanceTriggerProperty nextTrigger;
|
|
private ViewModelInstanceTriggerProperty previousTrigger;
|
|
|
|
private int selectedIndex;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (riveWidget == null)
|
|
{
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: riveWidget is not assigned.");
|
|
return;
|
|
}
|
|
|
|
if (sceneTransitionController == null)
|
|
{
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: SceneTransitionController is not assigned.");
|
|
}
|
|
|
|
riveWidget.OnWidgetStatusChanged += HandleWidgetStatusChanged;
|
|
// In case the widget already finished loading before we subscribed.
|
|
HandleWidgetStatusChanged();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (riveWidget != null)
|
|
riveWidget.OnWidgetStatusChanged -= HandleWidgetStatusChanged;
|
|
}
|
|
|
|
private void HandleWidgetStatusChanged()
|
|
{
|
|
if (riveWidget.Status != WidgetStatus.Loaded)
|
|
return;
|
|
|
|
ViewModelInstance viewModelInstance = riveWidget.StateMachine?.ViewModelInstance;
|
|
if (viewModelInstance == null)
|
|
{
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: ViewModelInstance is null. " +
|
|
"Set Data Binding Mode to Auto Bind Default on the Rive Widget.");
|
|
return;
|
|
}
|
|
|
|
// Cache both triggers once the artboard is ready so Update() doesn't do
|
|
// string lookups every frame.
|
|
nextTrigger = viewModelInstance.GetTriggerProperty(NextTriggerName);
|
|
previousTrigger = viewModelInstance.GetTriggerProperty(PreviousTriggerName);
|
|
|
|
if (nextTrigger == null)
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: Trigger '{NextTriggerName}' not found on view model.");
|
|
if (previousTrigger == null)
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: Trigger '{PreviousTriggerName}' not found on view model.");
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
Keyboard keyboard = Keyboard.current;
|
|
|
|
if (keyboard == null)
|
|
return;
|
|
|
|
if (keyboard.rightArrowKey.wasPressedThisFrame)
|
|
{
|
|
MoveSelection(+1);
|
|
nextTrigger?.Trigger();
|
|
}
|
|
|
|
if (keyboard.leftArrowKey.wasPressedThisFrame)
|
|
{
|
|
MoveSelection(-1);
|
|
previousTrigger?.Trigger();
|
|
}
|
|
|
|
bool enterPressed = keyboard.enterKey.wasPressedThisFrame || keyboard.numpadEnterKey.wasPressedThisFrame;
|
|
|
|
if (enterPressed && selectedIndex == PlayIndex)
|
|
{
|
|
if (sceneTransitionController == null)
|
|
{
|
|
Debug.LogError($"{nameof(RiveNavigationController)}: SceneTransitionController is not assigned.");
|
|
|
|
return;
|
|
}
|
|
|
|
sceneTransitionController.LoadGameplayScene();
|
|
}
|
|
}
|
|
|
|
private void MoveSelection(int direction)
|
|
{
|
|
if (menuItemCount <= 0)
|
|
return;
|
|
|
|
selectedIndex += direction;
|
|
|
|
if (selectedIndex >= menuItemCount)
|
|
selectedIndex = 0;
|
|
|
|
if (selectedIndex < 0)
|
|
selectedIndex = menuItemCount - 1;
|
|
|
|
Debug.Log($"Rive menu selection index: {selectedIndex}");
|
|
}
|
|
}
|