EVERYTHING
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BlockSpace.Worlds
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class WorldLoadingScreenController : MonoBehaviour
|
||||
{
|
||||
private struct CameraState
|
||||
{
|
||||
public CameraClearFlags clearFlags;
|
||||
|
||||
public Color backgroundColor;
|
||||
}
|
||||
|
||||
private struct RigidbodyState
|
||||
{
|
||||
public Vector3 linearVelocity;
|
||||
|
||||
public Vector3 angularVelocity;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private GameObject loadingScreenObject;
|
||||
|
||||
[SerializeField]
|
||||
private Slider progressSlider;
|
||||
|
||||
[SerializeField]
|
||||
private bool hideSceneWhileLoading = true;
|
||||
|
||||
[SerializeField]
|
||||
private int requiredTeleportsToComplete = 2;
|
||||
|
||||
private readonly Dictionary<Renderer, bool> rendererStates = new Dictionary<Renderer, bool>();
|
||||
|
||||
private readonly Dictionary<Canvas, bool> canvasStates = new Dictionary<Canvas, bool>();
|
||||
|
||||
private readonly Dictionary<Graphic, bool> graphicStates = new Dictionary<Graphic, bool>();
|
||||
|
||||
private readonly Dictionary<Camera, CameraState> cameraStates = new Dictionary<Camera, CameraState>();
|
||||
|
||||
private readonly Dictionary<Behaviour, bool> movementBehaviourStates = new Dictionary<Behaviour, bool>();
|
||||
|
||||
private readonly Dictionary<Rigidbody, RigidbodyState> rigidbodyStates = new Dictionary<Rigidbody, RigidbodyState>();
|
||||
|
||||
private bool loading;
|
||||
|
||||
private int completedTeleports;
|
||||
|
||||
public static WorldLoadingScreenController Instance { get; private set; }
|
||||
|
||||
public bool IsLoading => loading;
|
||||
|
||||
public static event Action LoadingFinished;
|
||||
|
||||
public void Configure(GameObject screenObject, Slider slider)
|
||||
{
|
||||
if (screenObject != null)
|
||||
{
|
||||
loadingScreenObject = screenObject;
|
||||
}
|
||||
if (slider != null)
|
||||
{
|
||||
progressSlider = slider;
|
||||
}
|
||||
if (!loading)
|
||||
{
|
||||
SetScreenVisible(visible: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Debug.LogWarning("Multiple WorldLoadingScreenController instances found. Using the latest active instance.", this);
|
||||
}
|
||||
Instance = this;
|
||||
SetScreenVisible(visible: false);
|
||||
SetProgress(0f);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SetLoading(isLoading: false);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginLoading(float initialProgress = 0f)
|
||||
{
|
||||
completedTeleports = 0;
|
||||
SetLoading(isLoading: true);
|
||||
SetProgress(initialProgress);
|
||||
}
|
||||
|
||||
public void SetLoading(bool isLoading)
|
||||
{
|
||||
if (loading == isLoading)
|
||||
{
|
||||
SetScreenVisible(isLoading);
|
||||
return;
|
||||
}
|
||||
loading = isLoading;
|
||||
SetScreenVisible(isLoading);
|
||||
if (hideSceneWhileLoading)
|
||||
{
|
||||
if (isLoading)
|
||||
{
|
||||
HideScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreScene();
|
||||
}
|
||||
}
|
||||
if (isLoading)
|
||||
{
|
||||
DisableMovement();
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreMovement();
|
||||
}
|
||||
if (!isLoading)
|
||||
{
|
||||
completedTeleports = 0;
|
||||
SetProgress(0f);
|
||||
WorldLoadingScreenController.LoadingFinished?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCheckpoint(float progress)
|
||||
{
|
||||
if (loading && (!(progressSlider != null) || !(progress < progressSlider.value)))
|
||||
{
|
||||
SetProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyLocalPlayerTeleported(bool forceComplete = false)
|
||||
{
|
||||
if (loading)
|
||||
{
|
||||
completedTeleports++;
|
||||
if (!forceComplete && completedTeleports < Mathf.Max(1, requiredTeleportsToComplete))
|
||||
{
|
||||
SetCheckpoint(0.97f);
|
||||
}
|
||||
else
|
||||
{
|
||||
CompleteLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CompleteLoading()
|
||||
{
|
||||
if (loading)
|
||||
{
|
||||
SetProgress(1f);
|
||||
SetLoading(isLoading: false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetProgress(float progress)
|
||||
{
|
||||
if (loading && hideSceneWhileLoading)
|
||||
{
|
||||
HideScene();
|
||||
}
|
||||
if (!(progressSlider == null))
|
||||
{
|
||||
progressSlider.minValue = 0f;
|
||||
progressSlider.maxValue = 1f;
|
||||
progressSlider.value = Mathf.Clamp01(progress);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetScreenVisible(bool visible)
|
||||
{
|
||||
if (loadingScreenObject != null)
|
||||
{
|
||||
loadingScreenObject.SetActive(visible);
|
||||
}
|
||||
}
|
||||
|
||||
private void HideScene()
|
||||
{
|
||||
Transform loadingRoot = ((loadingScreenObject != null) ? loadingScreenObject.transform : base.transform);
|
||||
Renderer[] array = UnityEngine.Object.FindObjectsByType<Renderer>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Renderer renderer in array)
|
||||
{
|
||||
if (!(renderer == null) && !rendererStates.ContainsKey(renderer) && !IsInsideLoadingScreen(renderer.transform, loadingRoot))
|
||||
{
|
||||
rendererStates[renderer] = renderer.enabled;
|
||||
renderer.enabled = false;
|
||||
}
|
||||
}
|
||||
Canvas[] array2 = UnityEngine.Object.FindObjectsByType<Canvas>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Canvas canvas in array2)
|
||||
{
|
||||
if (!(canvas == null) && !canvasStates.ContainsKey(canvas) && !IsInsideLoadingScreen(canvas.transform, loadingRoot))
|
||||
{
|
||||
canvasStates[canvas] = canvas.enabled;
|
||||
canvas.enabled = false;
|
||||
}
|
||||
}
|
||||
Graphic[] array3 = UnityEngine.Object.FindObjectsByType<Graphic>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Graphic graphic in array3)
|
||||
{
|
||||
if (!(graphic == null) && !graphicStates.ContainsKey(graphic) && !IsInsideLoadingScreen(graphic.transform, loadingRoot))
|
||||
{
|
||||
graphicStates[graphic] = graphic.enabled;
|
||||
graphic.enabled = false;
|
||||
}
|
||||
}
|
||||
Camera[] array4 = UnityEngine.Object.FindObjectsByType<Camera>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Camera camera in array4)
|
||||
{
|
||||
if (!(camera == null) && !cameraStates.ContainsKey(camera))
|
||||
{
|
||||
cameraStates[camera] = new CameraState
|
||||
{
|
||||
clearFlags = camera.clearFlags,
|
||||
backgroundColor = camera.backgroundColor
|
||||
};
|
||||
camera.clearFlags = CameraClearFlags.Color;
|
||||
camera.backgroundColor = Color.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreScene()
|
||||
{
|
||||
foreach (KeyValuePair<Renderer, bool> rendererState in rendererStates)
|
||||
{
|
||||
if (rendererState.Key != null)
|
||||
{
|
||||
rendererState.Key.enabled = rendererState.Value;
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<Canvas, bool> canvasState in canvasStates)
|
||||
{
|
||||
if (canvasState.Key != null)
|
||||
{
|
||||
canvasState.Key.enabled = canvasState.Value;
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<Graphic, bool> graphicState in graphicStates)
|
||||
{
|
||||
if (graphicState.Key != null)
|
||||
{
|
||||
graphicState.Key.enabled = graphicState.Value;
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<Camera, CameraState> cameraState in cameraStates)
|
||||
{
|
||||
if (cameraState.Key != null)
|
||||
{
|
||||
cameraState.Key.clearFlags = cameraState.Value.clearFlags;
|
||||
cameraState.Key.backgroundColor = cameraState.Value.backgroundColor;
|
||||
}
|
||||
}
|
||||
rendererStates.Clear();
|
||||
canvasStates.Clear();
|
||||
graphicStates.Clear();
|
||||
cameraStates.Clear();
|
||||
}
|
||||
|
||||
private void DisableMovement()
|
||||
{
|
||||
Behaviour[] array = UnityEngine.Object.FindObjectsByType<Behaviour>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Behaviour behaviour in array)
|
||||
{
|
||||
if (!(behaviour == null) && !movementBehaviourStates.ContainsKey(behaviour) && IsMovementBehaviour(behaviour))
|
||||
{
|
||||
movementBehaviourStates[behaviour] = behaviour.enabled;
|
||||
behaviour.enabled = false;
|
||||
}
|
||||
}
|
||||
Rigidbody[] array2 = UnityEngine.Object.FindObjectsByType<Rigidbody>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (Rigidbody rigidbody in array2)
|
||||
{
|
||||
if (!(rigidbody == null) && !rigidbodyStates.ContainsKey(rigidbody))
|
||||
{
|
||||
rigidbodyStates[rigidbody] = new RigidbodyState
|
||||
{
|
||||
linearVelocity = rigidbody.linearVelocity,
|
||||
angularVelocity = rigidbody.angularVelocity
|
||||
};
|
||||
rigidbody.linearVelocity = Vector3.zero;
|
||||
rigidbody.angularVelocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreMovement()
|
||||
{
|
||||
foreach (KeyValuePair<Behaviour, bool> movementBehaviourState in movementBehaviourStates)
|
||||
{
|
||||
if (movementBehaviourState.Key != null)
|
||||
{
|
||||
movementBehaviourState.Key.enabled = movementBehaviourState.Value;
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<Rigidbody, RigidbodyState> rigidbodyState in rigidbodyStates)
|
||||
{
|
||||
if (rigidbodyState.Key != null)
|
||||
{
|
||||
rigidbodyState.Key.linearVelocity = rigidbodyState.Value.linearVelocity;
|
||||
rigidbodyState.Key.angularVelocity = rigidbodyState.Value.angularVelocity;
|
||||
}
|
||||
}
|
||||
movementBehaviourStates.Clear();
|
||||
rigidbodyStates.Clear();
|
||||
}
|
||||
|
||||
private bool IsMovementBehaviour(Behaviour behaviour)
|
||||
{
|
||||
if (behaviour == this)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
string text = behaviour.GetType().Name;
|
||||
if (!((behaviour.GetType().FullName ?? string.Empty) == "GorillaLocomotion.Player") && !(text == "DesktopRigController") && !(text == "CreatorFlightController") && !text.Contains("LocomotionProvider") && !text.Contains("MoveProvider") && !text.Contains("TurnProvider") && !text.Contains("JumpProvider") && !text.Contains("TeleportationProvider") && !text.Contains("ClimbProvider") && !text.Contains("ContinuousMove") && !text.Contains("DynamicMove") && !text.Contains("SnapTurn"))
|
||||
{
|
||||
return text.Contains("SmoothTurn");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsInsideLoadingScreen(Transform target, Transform loadingRoot)
|
||||
{
|
||||
if (target != null && loadingRoot != null)
|
||||
{
|
||||
if (!(target == loadingRoot) && !target.IsChildOf(loadingRoot))
|
||||
{
|
||||
return loadingRoot.IsChildOf(target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user