Add main menu scene with Rive UI, procedural background, and scene transitions
- 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
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
using Mirror;
|
||||
using Rive;
|
||||
using Rive.Components;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
public class RiveLoginController : MonoBehaviour
|
||||
{
|
||||
[Header("Rive")]
|
||||
[SerializeField] private RiveWidget riveWidget;
|
||||
[SerializeField] private string startTriggerName = "startClicked";
|
||||
|
||||
[Header("Login")]
|
||||
[Tooltip("Still needed username until Rive has a bound string property.")]
|
||||
[SerializeField] private TMP_InputField usernameInput;
|
||||
|
||||
[SerializeField] private LoginUI loginUI;
|
||||
|
||||
private ViewModelInstanceTriggerProperty startTrigger;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (riveWidget == null)
|
||||
riveWidget = GetComponent<RiveWidget>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (riveWidget == null) return;
|
||||
|
||||
riveWidget.OnWidgetStatusChanged += HandleWidgetStatusChanged;
|
||||
HandleWidgetStatusChanged();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (riveWidget != null)
|
||||
riveWidget.OnWidgetStatusChanged -= HandleWidgetStatusChanged;
|
||||
|
||||
if (startTrigger != null)
|
||||
startTrigger.OnTriggered -= OnStartClicked;
|
||||
}
|
||||
|
||||
private void HandleWidgetStatusChanged()
|
||||
{
|
||||
if (riveWidget.Status != WidgetStatus.Loaded)
|
||||
return;
|
||||
|
||||
ViewModelInstance vm = riveWidget.StateMachine?.ViewModelInstance;
|
||||
if (vm == null)
|
||||
{
|
||||
Debug.LogError("RiveLoginController: ViewModelInstance is null. Set Data Binding Mode to Auto Bind Default.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (startTrigger != null)
|
||||
startTrigger.OnTriggered -= OnStartClicked;
|
||||
|
||||
startTrigger = vm.GetTriggerProperty(startTriggerName);
|
||||
if (startTrigger == null)
|
||||
{
|
||||
Debug.LogError($"RiveLoginController: Trigger '{startTriggerName}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
startTrigger.OnTriggered += OnStartClicked;
|
||||
}
|
||||
|
||||
private void OnStartClicked()
|
||||
{
|
||||
StartMultiplayerSession();
|
||||
}
|
||||
|
||||
public void StartMultiplayerSession()
|
||||
{
|
||||
string username = usernameInput != null
|
||||
? usernameInput.text.Trim()
|
||||
: string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
{
|
||||
if (loginUI != null && loginUI.errorText != null)
|
||||
{
|
||||
loginUI.errorText.text = "Enter a username";
|
||||
loginUI.errorText.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("RiveLoginController: Username is empty");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ChatAuthenticator auth = NetworkManager.singleton.GetComponent<ChatAuthenticator>();
|
||||
if (auth != null)
|
||||
auth.SetPlayerName(username);
|
||||
else
|
||||
Debug.LogWarning("RiveLoginController: ChatAuthenticator not found on NetworkManager");
|
||||
|
||||
NetworkManager.singleton.StartClient();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user