Files
bansonic_beta_main/Assets/scripts/eula_and_warnings.cs
T

541 lines
15 KiB
C#

using System.Collections.Generic;
using Bansonic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class eula_and_warnings : MonoBehaviour
{
private const string MainSceneName = "Main_main";
private const string RankingConsentPrefKey = "before_everything_agree_ranking";
private const float LightWarningMinimumSeconds = 5f;
private const float FadeDuration = 0.3f;
private const float RequiredScrollReadThreshold = 0.1f;
[Header("objs")]
[SerializeField] GameObject lightWarningObj;
[SerializeField] GameObject uInfoEulaObj;
[Header("canvas groups")]
[SerializeField] CanvasGroup lightWarningCG;
[SerializeField] CanvasGroup uInfoEulaCG;
[Header("intro")]
[SerializeField] float lightWarningFadeInDelay = 0f;
[Header("light warnings")]
[SerializeField] Toggle lw_uhaveRead;
[SerializeField] Button lw_next;
[SerializeField] Button lw_quit;
[Header("user infomation eula")]
[SerializeField] Toggle uie_uhaveRead;
[SerializeField] Toggle uie_agreeRanking;
[SerializeField] Button uie_next;
[SerializeField] Button uie_quit;
[SerializeField] ScrollRect uie_scrollRect;
private float _lightWarningShownAtRealtime;
private AsyncOperation _mainScenePreloadOperation;
private Tween _lightWarningTween;
private Tween _userInfoTween;
private bool _isTransitioning;
private bool _mainScenePreloadRequested;
private bool _mainScenePreloadReady;
private readonly List<GameObject> _hiddenMainSceneRoots = new List<GameObject>();
private void Awake()
{
AutoAssignReferences();
ForceInitialState();
BindEvents();
}
private void Start()
{
PlayLightWarningIntro();
}
private void OnDestroy()
{
if (lw_next != null) lw_next.onClick.RemoveListener(HandleLightWarningNextClicked);
if (lw_quit != null) lw_quit.onClick.RemoveListener(HandleLightWarningQuitClicked);
if (uie_next != null) uie_next.onClick.RemoveListener(HandleUserInfoNextClicked);
if (uie_quit != null) uie_quit.onClick.RemoveListener(HandleUserInfoQuitClicked);
_lightWarningTween?.Kill();
_userInfoTween?.Kill();
}
private void ForceInitialState()
{
if (lightWarningObj != null) lightWarningObj.SetActive(true);
if (uInfoEulaObj != null) uInfoEulaObj.SetActive(false);
SetupCanvasGroup(lightWarningCG, false);
SetupCanvasGroup(uInfoEulaCG, false);
if (lw_uhaveRead != null) lw_uhaveRead.SetIsOnWithoutNotify(false);
if (uie_uhaveRead != null) uie_uhaveRead.SetIsOnWithoutNotify(false);
if (uie_agreeRanking != null)
{
bool agreeRanking = PlayerPrefs.GetInt(RankingConsentPrefKey, 0) == 1;
uie_agreeRanking.SetIsOnWithoutNotify(agreeRanking);
}
if (uie_scrollRect != null)
{
Canvas.ForceUpdateCanvases();
uie_scrollRect.verticalNormalizedPosition = 1f;
}
_lightWarningShownAtRealtime = Time.realtimeSinceStartup;
_isTransitioning = false;
}
private void PlayLightWarningIntro()
{
if (lightWarningObj == null || lightWarningCG == null)
{
return;
}
lightWarningObj.SetActive(true);
lightWarningCG.alpha = 0f;
lightWarningCG.interactable = false;
lightWarningCG.blocksRaycasts = false;
_lightWarningTween?.Kill();
_lightWarningTween = lightWarningCG
.DOFade(1f, FadeDuration)
.SetDelay(Mathf.Max(0f, lightWarningFadeInDelay))
.SetUpdate(true)
.OnStart(() => _lightWarningShownAtRealtime = Time.realtimeSinceStartup)
.OnComplete(() => SetupCanvasGroup(lightWarningCG, true));
}
private void BindEvents()
{
if (lw_next != null)
{
lw_next.onClick.RemoveListener(HandleLightWarningNextClicked);
lw_next.onClick.AddListener(HandleLightWarningNextClicked);
}
if (lw_quit != null)
{
lw_quit.onClick.RemoveListener(HandleLightWarningQuitClicked);
lw_quit.onClick.AddListener(HandleLightWarningQuitClicked);
}
if (uie_next != null)
{
uie_next.onClick.RemoveListener(HandleUserInfoNextClicked);
uie_next.onClick.AddListener(HandleUserInfoNextClicked);
}
if (uie_quit != null)
{
uie_quit.onClick.RemoveListener(HandleUserInfoQuitClicked);
uie_quit.onClick.AddListener(HandleUserInfoQuitClicked);
}
}
private void BeginPreloadMainScene()
{
if (!Application.isPlaying || _mainScenePreloadRequested)
{
return;
}
_mainScenePreloadRequested = true;
StartCoroutine(PreloadMainSceneRoutine());
}
private System.Collections.IEnumerator PreloadMainSceneRoutine()
{
_mainScenePreloadOperation = SceneManager.LoadSceneAsync(MainSceneName, LoadSceneMode.Additive);
if (_mainScenePreloadOperation == null)
{
yield break;
}
_mainScenePreloadOperation.allowSceneActivation = false;
while (_mainScenePreloadOperation.progress < 0.9f)
{
yield return null;
}
HidePreloadedMainSceneRoots();
_mainScenePreloadReady = true;
}
private void HandleLightWarningNextClicked()
{
if (_isTransitioning)
{
return;
}
float staySeconds = Time.realtimeSinceStartup - _lightWarningShownAtRealtime;
float remainSeconds = Mathf.Max(0f, LightWarningMinimumSeconds - staySeconds);
bool hasRead = lw_uhaveRead != null && lw_uhaveRead.isOn;
if (!hasRead || remainSeconds > 0f)
{
if (!hasRead && remainSeconds > 0f)
{
gNotice.error.display($"您必须知悉相关风险,还需停留{Mathf.CeilToInt(remainSeconds)}秒后才可进入");
}
else if (!hasRead)
{
gNotice.error.display("您必须知悉相关风险");
}
else
{
gNotice.error.display($"还需停留{Mathf.CeilToInt(remainSeconds)}秒后才可进入");
}
return;
}
TransitionCanvasGroup(lightWarningObj, lightWarningCG, false, () =>
{
BeginPreloadMainScene();
TransitionCanvasGroup(uInfoEulaObj, uInfoEulaCG, true, null);
});
}
private void HandleLightWarningQuitClicked()
{
MarkPolicyRejectedAndQuit();
}
private void HandleUserInfoNextClicked()
{
if (_isTransitioning)
{
return;
}
if (!HasScrolledToBottom())
{
gNotice.error.display("必须完整阅读");
return;
}
if (uie_uhaveRead == null || !uie_uhaveRead.isOn)
{
gNotice.error.display("请勾选“我已知晓”");
return;
}
bool agreeRanking = uie_agreeRanking != null && uie_agreeRanking.isOn;
PlayerPrefs.SetInt(RankingConsentPrefKey, agreeRanking ? 1 : 0);
PlayerPrefs.Save();
TransitionCanvasGroup(uInfoEulaObj, uInfoEulaCG, false, ActivateMainScene);
}
private void HandleUserInfoQuitClicked()
{
MarkPolicyRejectedAndQuit();
}
private static void MarkPolicyRejectedAndQuit()
{
PlayerPrefs.SetInt(RankingConsentPrefKey, 0);
PlayerPrefs.Save();
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
private void ActivateMainScene()
{
if (_mainScenePreloadReady)
{
StartCoroutine(ActivatePreloadedMainSceneRoutine());
return;
}
SceneManager.LoadScene(MainSceneName, LoadSceneMode.Single);
}
private System.Collections.IEnumerator ActivatePreloadedMainSceneRoutine()
{
Scene sourceScene = gameObject.scene;
if (_mainScenePreloadOperation == null)
{
SceneManager.LoadScene(MainSceneName, LoadSceneMode.Single);
yield break;
}
_mainScenePreloadOperation.allowSceneActivation = true;
while (!_mainScenePreloadOperation.isDone)
{
yield return null;
}
RestorePreloadedMainSceneRoots();
Scene mainScene = SceneManager.GetSceneByName(MainSceneName);
if (mainScene.isLoaded)
{
SceneManager.SetActiveScene(mainScene);
}
if (sourceScene.IsValid() && sourceScene.isLoaded && sourceScene.name == "beforeEverything")
{
yield return SceneManager.UnloadSceneAsync(sourceScene);
}
_mainScenePreloadOperation = null;
_mainScenePreloadReady = false;
}
private void HidePreloadedMainSceneRoots()
{
_hiddenMainSceneRoots.Clear();
Scene mainScene = SceneManager.GetSceneByName(MainSceneName);
if (!mainScene.IsValid() || !mainScene.isLoaded)
{
return;
}
List<GameObject> roots = new List<GameObject>();
mainScene.GetRootGameObjects(roots);
for (int i = 0; i < roots.Count; i++)
{
GameObject root = roots[i];
if (root == null || !root.activeSelf)
{
continue;
}
_hiddenMainSceneRoots.Add(root);
root.SetActive(false);
}
}
private void RestorePreloadedMainSceneRoots()
{
for (int i = 0; i < _hiddenMainSceneRoots.Count; i++)
{
GameObject root = _hiddenMainSceneRoots[i];
if (root != null)
{
root.SetActive(true);
}
}
_hiddenMainSceneRoots.Clear();
}
private bool HasScrolledToBottom()
{
if (uie_scrollRect == null)
{
return true;
}
if (!uie_scrollRect.vertical)
{
return true;
}
return uie_scrollRect.verticalNormalizedPosition <= RequiredScrollReadThreshold;
}
private void TransitionCanvasGroup(GameObject targetObj, CanvasGroup targetGroup, bool show, TweenCallback onComplete)
{
if (targetObj == null || targetGroup == null)
{
onComplete?.Invoke();
return;
}
_isTransitioning = true;
if (show)
{
targetObj.SetActive(true);
targetGroup.alpha = 0f;
targetGroup.interactable = false;
targetGroup.blocksRaycasts = false;
}
Tween tween = targetGroup
.DOFade(show ? 1f : 0f, FadeDuration)
.SetUpdate(true)
.OnComplete(() =>
{
SetupCanvasGroup(targetGroup, show);
if (!show)
{
targetObj.SetActive(false);
}
_isTransitioning = false;
onComplete?.Invoke();
});
if (ReferenceEquals(targetGroup, lightWarningCG))
{
_lightWarningTween?.Kill();
_lightWarningTween = tween;
}
else if (ReferenceEquals(targetGroup, uInfoEulaCG))
{
_userInfoTween?.Kill();
_userInfoTween = tween;
}
}
private static void SetupCanvasGroup(CanvasGroup group, bool visible)
{
if (group == null)
{
return;
}
group.alpha = visible ? 1f : 0f;
group.interactable = visible;
group.blocksRaycasts = visible;
}
private void AutoAssignReferences()
{
if (lightWarningObj == null && lightWarningCG != null)
{
lightWarningObj = lightWarningCG.gameObject;
}
if (uInfoEulaObj == null && uInfoEulaCG != null)
{
uInfoEulaObj = uInfoEulaCG.gameObject;
}
if (lightWarningObj == null)
{
lightWarningObj = FindSceneObject("illnessWarnings");
}
if (uInfoEulaObj == null)
{
uInfoEulaObj = FindSceneObject("userDataProcessing");
}
if (lightWarningCG == null && lightWarningObj != null)
{
lightWarningCG = lightWarningObj.GetComponent<CanvasGroup>();
}
if (uInfoEulaCG == null && uInfoEulaObj != null)
{
uInfoEulaCG = uInfoEulaObj.GetComponent<CanvasGroup>();
}
if (lw_uhaveRead == null && lightWarningObj != null)
{
lw_uhaveRead = FindComponentInChildrenByName<Toggle>(lightWarningObj.transform, "uread");
}
if (lw_next == null && lightWarningObj != null)
{
lw_next = FindComponentInChildrenByName<Button>(lightWarningObj.transform, "enter");
}
if (lw_quit == null && lightWarningObj != null)
{
lw_quit = FindComponentInChildrenByName<Button>(lightWarningObj.transform, "quit");
}
if (uie_uhaveRead == null && uInfoEulaObj != null)
{
uie_uhaveRead = FindComponentInChildrenByName<Toggle>(uInfoEulaObj.transform, "uread");
}
if (uie_agreeRanking == null && uInfoEulaObj != null)
{
uie_agreeRanking = FindComponentInChildrenByName<Toggle>(uInfoEulaObj.transform, "joinRankingList");
}
if (uie_next == null && uInfoEulaObj != null)
{
uie_next = FindComponentInChildrenByName<Button>(uInfoEulaObj.transform, "enter");
}
if (uie_quit == null && uInfoEulaObj != null)
{
uie_quit = FindComponentInChildrenByName<Button>(uInfoEulaObj.transform, "quit");
}
if (uie_scrollRect == null && uInfoEulaObj != null)
{
uie_scrollRect = FindComponentInChildrenByName<ScrollRect>(uInfoEulaObj.transform, "sv");
if (uie_scrollRect == null)
{
uie_scrollRect = uInfoEulaObj.GetComponentInChildren<ScrollRect>(true);
}
}
}
private static GameObject FindSceneObject(string objectName)
{
if (string.IsNullOrWhiteSpace(objectName))
{
return null;
}
GameObject[] allObjects = Resources.FindObjectsOfTypeAll<GameObject>();
for (int i = 0; i < allObjects.Length; i++)
{
GameObject go = allObjects[i];
if (go == null)
{
continue;
}
if (!go.scene.IsValid() || !go.scene.isLoaded)
{
continue;
}
if (go.name == objectName)
{
return go;
}
}
return null;
}
private static T FindComponentInChildrenByName<T>(Transform root, string objectName) where T : Component
{
if (root == null || string.IsNullOrWhiteSpace(objectName))
{
return null;
}
T[] components = root.GetComponentsInChildren<T>(true);
for (int i = 0; i < components.Length; i++)
{
T component = components[i];
if (component != null && component.gameObject.name == objectName)
{
return component;
}
}
return null;
}
}