feat(Cycle):实现循环提前检测,修复交互提示消失,按键绑定的事件在重启的时候没能正确,触发循环的提前检测有错误

This commit is contained in:
2025-10-27 10:31:01 +08:00
parent e8b9f47067
commit 9646483fa6
36 changed files with 6743 additions and 5221 deletions

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using Core;
using UnityEngine;
using UnityEngine.Events;
namespace Script.Gameplay.Global
{
public struct StackOverflowBUGLog
{
public Transform TargetTransform;
public int BeTriggerCycle; // 触发时的游戏循环次数
public StackOverflowBUGLog(Transform targetTransform, int beTriggerCycle)
{
TargetTransform = targetTransform;
BeTriggerCycle = beTriggerCycle;
}
}
public class BUGManager : MonoSingleton<BUGManager>
{
[SerializeField] private GameObject bugCubePrefab;
[Header("天核区域检测设置")] [SerializeField] private Vector3 AreaCenter = Vector3.zero;
[SerializeField] private Vector3 AreaSize = new Vector3(50, 50, 50);
public UnityEvent OnBUGHappenedInArea;
private List<StackOverflowBUGLog> stackOverflowBugLogs = new List<StackOverflowBUGLog>();
private List<GameObject> bugCubes = new List<GameObject>();
private void Start()
{
OnBUGHappenedInArea.AddListener(() =>
{
Debug.LogWarning("天核区域内检测到BUG立方体");
});
GameManager.Instance.OnGameStart += GenerateBUGCubes;
}
public void LogStackOverflowBUG(Transform targetTransform)
{
int beTriggerCycle = GameDataManager.Instance.TotalLoopCount;
stackOverflowBugLogs.Add(new StackOverflowBUGLog(targetTransform, beTriggerCycle));
GameManager.Instance.ReStartGame();
}
public void GenerateBUGCubes()
{
bugCubes.Clear();
int currentCycle = GameDataManager.Instance.TotalLoopCount;
// 记录的BUG位置生成BUG立方体
foreach (var log in stackOverflowBugLogs)
{
if (bugCubePrefab != null)
{
// 仅在下一次循环生成BUG立方体
if (log.BeTriggerCycle + 1 != currentCycle) continue;
GameObject go = Instantiate(bugCubePrefab, log.TargetTransform.position, Quaternion.identity);
bugCubes.Add(go);
}
}
// 检测天核区域内是否有BUG立方体
Collider[] colliders = Physics.OverlapBox(AreaCenter, AreaSize * 0.5f);
foreach (var collider in colliders)
{
if (bugCubes.Contains(collider.gameObject))
{
OnBUGHappenedInArea?.Invoke();
break;
}
}
}
// 可视化天核区域
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(1, 0, 0, 0.3f);
Gizmos.DrawCube(AreaCenter, AreaSize);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7600480a20114f90a3cf7fea47d0b897
timeCreated: 1761492538

View File

@@ -9,13 +9,18 @@ namespace Script.Gameplay.Global
private const string LoopCountKey = "TotalLoopCount";
public int TotalLoopCount { get; private set; }
private void Start()
protected override void Awake()
{
GameManager.Instance.OnGameStart += AddLoop;
base.Awake();
// 读取已保存的循环次数
TotalLoopCount = PlayerPrefs.GetInt(LoopCountKey, 0);
Debug.Log("目前循环次数:" + TotalLoopCount);
}
private void Start()
{
GameManager.Instance.OnGameStart += AddLoop;
}
public void AddLoop()
{

View File

@@ -41,7 +41,7 @@ namespace Script.Gameplay.Global
{
StartCoroutine(ScreenGlitchManager.Instance.TriggerGlitchEffect());
yield return new WaitForSeconds(1.0f);
GameManager.Instance.StartGameplay();
GameManager.Instance.ReStartGame();
}
}
}

View File

@@ -6,6 +6,7 @@ namespace Script.Gameplay.Global
public class GameManager : MonoSingleton<GameManager>
{
public event Action OnGameStart;
private string currentStartGameMode = "Level1";
private void Start()
{
ScenesManager.Instance.LoadMainMenu();
@@ -14,12 +15,20 @@ namespace Script.Gameplay.Global
public void StartGameplay()
{
ScenesManager.Instance.LoadGameplay("Level1");
currentStartGameMode = "Level1";
OnGameStart?.Invoke();
}
public void StartTest()
{
ScenesManager.Instance.LoadGameplay("Test");
currentStartGameMode = "Test";
OnGameStart?.Invoke();
}
public void ReStartGame()
{
ScenesManager.Instance.LoadGameplay(currentStartGameMode);
OnGameStart?.Invoke();
}
}

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
using System.Collections.Generic;
using Core;
using Script.Gameplay.Input;
namespace Script.Gameplay.Global
{
public class ScenesManager : MonoSingleton<ScenesManager>
{
private string currentGameplayScene;
private bool isLoadGameplayUI = false;
// 修正:直接根据当前激活场景判断
public bool IsInMainMenu =>
currentGameplayScene == "StartMenu";
// 修正:只有当已有记录的 gameplay 场景且激活场景与之匹配时才返回 true
public bool IsInGameplay =>
currentGameplayScene == "Level1" || currentGameplayScene == "Test";
public bool IsActiveScene(string sceneName)
{
return SceneManager.GetActiveScene().name == sceneName;
}
public bool IsSceneLoaded(string sceneName)
{
return SceneManager.GetSceneByName(sceneName).isLoaded;
}
public void LoadMainMenu()
{
if (isLoadGameplayUI)
{
StartCoroutine(UnloadScene("UIScene"));
isLoadGameplayUI = false;
}
StartCoroutine(SwitchGameplay("StartMenu"));
}
public void LoadGameplay(string sceneName)
{
StartCoroutine(SwitchGameplay(sceneName));
ReLoadUIScene();
}
public void ReLoadUIScene()
{
if (isLoadGameplayUI)
{
StartCoroutine(UnloadScene("UIScene"));
}
StartCoroutine(LoadSceneAdditive("UIScene"));
isLoadGameplayUI = true;
}
private IEnumerator SwitchGameplay(string newScene)
{
if (!string.IsNullOrEmpty(currentGameplayScene))
{
yield return UnloadScene(currentGameplayScene);
}
yield return LoadSceneAdditive(newScene);
currentGameplayScene = newScene;
// 可选:将新场景设置为激活场景
SceneManager.SetActiveScene(SceneManager.GetSceneByName(newScene));
}
private IEnumerator LoadSceneAdditive(string sceneName)
{
var async = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
while (!async.isDone)
{
yield return null;
}
}
private IEnumerator UnloadScene(string sceneName)
{
var async = SceneManager.UnloadSceneAsync(sceneName);
while (!async.isDone)
{
yield return null;
}
}
public IEnumerator UnloadScenesInOrder(List<string> sceneNames)
{
foreach (var sceneName in sceneNames)
{
if (IsSceneLoaded(sceneName))
{
var async = SceneManager.UnloadSceneAsync(sceneName);
while (!async.isDone)
{
yield return null;
}
}
}
}
public void QuitGame()
{
var scenesToUnload = new List<string> { "UIScene", currentGameplayScene };
StartCoroutine(QuitAndUnload(scenesToUnload));
}
private IEnumerator QuitAndUnload(List<string> scenes)
{
yield return UnloadScenesInOrder(scenes);
// 清理 InputManager
if (InputManager.Instance != null)
{
Destroy(InputManager.Instance.gameObject);
}
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9f0b4ab0cd384d91bfb99fd97c34ac5d
timeCreated: 1760401308