地图系统

This commit is contained in:
2026-06-05 18:41:33 +08:00
parent 613f2a4d13
commit fe4fd60083
234 changed files with 33090 additions and 4899 deletions

View File

@@ -32,6 +32,8 @@ namespace BaseGames.UI.MainMenu
[SerializeField] private CanvasGroup _mainButtonsGroup;
[SerializeField] private RectTransform _mainButtonsRect; // 用于滑入动画
[SerializeField] private GameObject _saveSlotPanel;
[Tooltip("存档槽面板控制器。打开前调用 SetMode 区分新游戏 / 继续语境。")]
[SerializeField] private BaseGames.UI.Menus.SaveSlotController _saveSlotController;
[SerializeField] private GameObject _settingsPanel;
[SerializeField] private GameObject _creditsPanel;
@@ -157,8 +159,16 @@ namespace BaseGames.UI.MainMenu
// ── 按钮回调 ─────────────────────────────────────────────────────────
private void OnNewGameClicked() => SetPanel(_saveSlotPanel, true);
private void OnContinueClicked() => SetPanel(_saveSlotPanel, true);
private void OnNewGameClicked()
{
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.NewGame);
SetPanel(_saveSlotPanel, true);
}
private void OnContinueClicked()
{
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.Continue);
SetPanel(_saveSlotPanel, true);
}
private void OnSettingsClicked() => SetPanel(_settingsPanel, true);
private void OnCreditsClicked() => SetPanel(_creditsPanel, true);
@@ -168,9 +178,16 @@ namespace BaseGames.UI.MainMenu
{
SetPanel(_saveSlotPanel, false);
// 继续游戏:存档已记录检查点场景时加载该场景并落在存档点出生位;
// 否则(新游戏 / 存档尚无检查点)加载首关。
var svc = ServiceLocator.GetOrDefault<ISaveService>();
string checkpointScene = svc?.LastCheckpointScene;
bool hasCheckpoint = !string.IsNullOrEmpty(checkpointScene);
_onSceneLoadRequest?.Raise(new SceneLoadRequest
{
SceneName = _firstGameSceneKey,
SceneName = hasCheckpoint ? checkpointScene : _firstGameSceneKey,
EntryTransitionId = hasCheckpoint ? svc.LastCheckpointSpawnId : null,
TransitionType = TransitionType.Scene,
ShowLoadingScreen = true,
});

View File

@@ -0,0 +1,107 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
using BaseGames.Core.Events;
using BaseGames.Localization;
namespace BaseGames.UI.MainMenu
{
/// <summary>
/// 新游戏模式选择面板(普通 / 钢铁之魂):开新档前选择难度模式。
///
/// 设计:
/// · 自包含、场景无关——本地 SetActive 显隐 + 回调,不走 UIManager 面板栈,
/// 与 MainMenuController 现有的子面板管理方式一致。
/// · 选定后通过 onModeChosen 回调把 DifficultyLevel 交还给调用方SaveSlotController
/// 由调用方负责 CreateSlot(slot, steelSoul) + IDifficultyService.BeginNewGame(level)。
/// · 钢铁之魂为破坏性/高难选项,默认焦点置于普通,并显示一段警示文案。
/// </summary>
public class NewGameModeController : MonoBehaviour
{
[Header("根节点(显隐用,留空则用本 GameObject")]
[SerializeField] private GameObject _root;
[Header("按钮")]
[SerializeField] private Button _btnNormal;
[SerializeField] private Button _btnSteelSoul;
[SerializeField] private Button _btnBack;
[Header("钢铁之魂说明")]
[Tooltip("选中钢铁之魂时显示的警示文案(一命模式,死亡即清档)。走本地化键 MODE_STEELSOUL_DESC。")]
[SerializeField] private TMP_Text _steelSoulDescText;
[SerializeField] private string _steelSoulDescKey = "MODE_STEELSOUL_DESC";
private Action<DifficultyLevel> _onModeChosen;
private Action _onBack;
private void Awake()
{
_btnNormal? .onClick.AddListener(() => Choose(DifficultyLevel.Normal));
_btnSteelSoul?.onClick.AddListener(() => Choose(DifficultyLevel.SteelSoul));
_btnBack? .onClick.AddListener(HandleBack);
SetVisible(false);
}
/// <summary>
/// 弹出模式选择。
/// </summary>
/// <param name="onModeChosen">玩家选定模式后回调(面板已自动关闭),携带难度档位。</param>
/// <param name="onBack">点击返回 / 取消后回调(可选)。</param>
public void Show(Action<DifficultyLevel> onModeChosen, Action onBack = null)
{
_onModeChosen = onModeChosen;
_onBack = onBack;
if (_steelSoulDescText != null && !string.IsNullOrEmpty(_steelSoulDescKey))
{
string s = LocalizationManager.Get(_steelSoulDescKey, LocalizationTable.UI);
_steelSoulDescText.text = string.IsNullOrEmpty(s) ? _steelSoulDescKey : s;
}
SetVisible(true);
// 默认焦点置于普通模式(避免误选一命模式)
EventSystem.current?.SetSelectedGameObject(_btnNormal != null
? _btnNormal.gameObject
: _btnSteelSoul?.gameObject);
}
/// <summary>外部强制关闭,不触发回调。</summary>
public void Close()
{
_onModeChosen = null;
_onBack = null;
SetVisible(false);
}
// ── 回调 ──────────────────────────────────────────────────────────────
private void Choose(DifficultyLevel level)
{
var cb = _onModeChosen;
SetVisible(false);
_onModeChosen = null;
_onBack = null;
cb?.Invoke(level);
}
private void HandleBack()
{
var cb = _onBack;
SetVisible(false);
_onModeChosen = null;
_onBack = null;
cb?.Invoke();
}
// ── 工具 ──────────────────────────────────────────────────────────────
private void SetVisible(bool visible)
{
var go = _root != null ? _root : gameObject;
go.SetActive(visible);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 84dfb5f813928934b9da0994f3c074eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: