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:
pelpanagiotis
2026-09-17 17:18:45 +03:00
parent aa248cda7e
commit d04ff998cb
101 changed files with 297098 additions and 8223 deletions
+102
View File
@@ -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();
}
}