v10 全量评审:修复 TD-06 至 TD-12(InputReader 移除资产扫描回退 / EmergencySave 解除 LocalFileStorage 直接依赖 / AccessibilityManager 注册 IAccessibilityService / HUDController HP/SpringIcon SetActive 复用 / MovingPlatform 缓存 WaitForSeconds / RewardSO IRewardTarget 解耦 Quest←Player 依赖 / CrashReporter 频率限制崩溃日志)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using BaseGames.Core.Events;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.World
|
||||
@@ -14,17 +15,25 @@ namespace BaseGames.World
|
||||
[SerializeField, Min(1)] private int _maxCrumbs = 20;
|
||||
[SerializeField, Min(0.1f)] private float _minMoveDistance = 1f;
|
||||
|
||||
private readonly Queue<Vector2> _crumbs = new();
|
||||
private Vector2 _lastPos;
|
||||
private float _timer;
|
||||
[Header("事件频道")]
|
||||
[SerializeField] private TransformEventChannelSO _onPlayerSpawned;
|
||||
|
||||
private readonly Queue<Vector2> _crumbs = new();
|
||||
private readonly CompositeDisposable _subs = new();
|
||||
private Vector2 _lastPos;
|
||||
private float _timer;
|
||||
|
||||
private Transform _playerTransform;
|
||||
|
||||
// ── Unity 生命周期 ────────────────────────────────────────────────
|
||||
private void Awake()
|
||||
private void OnEnable()
|
||||
{
|
||||
var go = GameObject.FindWithTag("Player");
|
||||
if (go != null) _playerTransform = go.transform;
|
||||
_onPlayerSpawned?.Subscribe(t => _playerTransform = t).AddTo(_subs);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_subs.Clear();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
||||
@@ -71,7 +71,12 @@ namespace BaseGames.World
|
||||
|
||||
private void Despawn()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
// 若由对象池创建(PooledObject 存在),归还到池;否则直接停用(场景内静态放置的 Collectible)
|
||||
var po = GetComponent<Core.Pool.PooledObject>();
|
||||
if (po != null)
|
||||
po.ReturnToPool();
|
||||
else
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// ── 运行时配置(由 CollectibleSpawner 在实例化后调用)────────────────
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
using UnityEngine;
|
||||
using BaseGames.Core;
|
||||
using BaseGames.Core.Assets;
|
||||
|
||||
namespace BaseGames.World
|
||||
{
|
||||
/// <summary>
|
||||
/// 可收集物生成器(静态工具类)。
|
||||
/// 封装 Geo / 道具 Collectible 的实例化逻辑,供 LootResolver 等调用。
|
||||
/// Prefab 引用通过 CollectibleSpawnerConfig SO 注入,避免 Resources.Load。
|
||||
/// 封装 Geo / 道具 Collectible 的 Spawn 逻辑,供 LootResolver 等调用。
|
||||
/// 优先通过 IObjectPoolService 从对象池取用(需预热 COL_Geo / COL_Item);
|
||||
/// 池服务不可用时退回 Object.Instantiate(仅限编辑器 / 单元测试场景)。
|
||||
/// Prefab 引用通过 CollectibleSpawnerConfig 注入,避免 Resources.Load。
|
||||
/// </summary>
|
||||
public static class CollectibleSpawner
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局配置引用(由 CollectibleSpawnerConfig.Initialize() 在游戏启动时设置)。
|
||||
/// 全局配置引用(由 CollectibleSpawnerConfig.Awake() 注册)。
|
||||
/// </summary>
|
||||
private static CollectibleSpawnerConfig _config;
|
||||
|
||||
@@ -19,40 +23,42 @@ namespace BaseGames.World
|
||||
|
||||
/// <summary>
|
||||
/// 在世界坐标生成 Geo 拾取物。
|
||||
/// 若配置未注册则仅输出日志(编辑器 / 测试场景兜底)。
|
||||
/// 优先从 GlobalObjectPool 取用(key = AddressKeys.PrefabCollectibleGeo),
|
||||
/// 池服务不可用时退回 Object.Instantiate。
|
||||
/// </summary>
|
||||
public static void SpawnGeo(Vector2 position, int amount)
|
||||
{
|
||||
if (_config == null || _config.GeoPrefab == null)
|
||||
{
|
||||
Debug.LogWarning($"[CollectibleSpawner] GeoPrefab 未配置,Geo x{amount} 无法生成 at {position}");
|
||||
return;
|
||||
}
|
||||
|
||||
var go = Object.Instantiate(_config.GeoPrefab, position, Quaternion.identity);
|
||||
if (go.TryGetComponent<Collectible>(out var c))
|
||||
{
|
||||
var go = SpawnFromPool(AddressKeys.PrefabCollectibleGeo, position)
|
||||
?? InstantiateFallback(_config?.GeoPrefab, position,
|
||||
$"[CollectibleSpawner] GeoPrefab 未配置,Geo x{amount} 无法生成 at {position}");
|
||||
if (go != null && go.TryGetComponent<Collectible>(out var c))
|
||||
c.SetGeo(amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在世界坐标生成道具拾取物(通过 itemId 广播 EVT_CollectiblePickup)。
|
||||
/// 若配置未注册则仅输出日志。
|
||||
/// 优先从 GlobalObjectPool 取用(key = AddressKeys.PrefabCollectibleItem),
|
||||
/// 池服务不可用时退回 Object.Instantiate。
|
||||
/// </summary>
|
||||
public static void SpawnItem(Vector2 position, string itemId)
|
||||
{
|
||||
if (_config == null || _config.ItemPrefab == null)
|
||||
{
|
||||
Debug.LogWarning($"[CollectibleSpawner] ItemPrefab 未配置,物品 {itemId} 无法生成 at {position}");
|
||||
return;
|
||||
}
|
||||
|
||||
var go = Object.Instantiate(_config.ItemPrefab, position, Quaternion.identity);
|
||||
if (go.TryGetComponent<Collectible>(out var c))
|
||||
{
|
||||
var go = SpawnFromPool(AddressKeys.PrefabCollectibleItem, position)
|
||||
?? InstantiateFallback(_config?.ItemPrefab, position,
|
||||
$"[CollectibleSpawner] ItemPrefab 未配置,物品 {itemId} 无法生成 at {position}");
|
||||
if (go != null && go.TryGetComponent<Collectible>(out var c))
|
||||
c.SetItem(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 内部工具 ──────────────────────────────────────────────────────
|
||||
|
||||
private static GameObject SpawnFromPool(string key, Vector2 position)
|
||||
=> ServiceLocator.GetOrDefault<IObjectPoolService>()
|
||||
?.Spawn(key, position, Quaternion.identity);
|
||||
|
||||
private static GameObject InstantiateFallback(GameObject prefab, Vector2 position, string warnMsg)
|
||||
{
|
||||
if (prefab == null) { Debug.LogWarning(warnMsg); return null; }
|
||||
return Object.Instantiate(prefab, position, Quaternion.identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace BaseGames.World
|
||||
private bool _movingForward = true;
|
||||
private bool _triggered;
|
||||
private bool _waiting;
|
||||
private WaitForSeconds _waitForEndpoint;
|
||||
private readonly CompositeDisposable _subs = new();
|
||||
|
||||
private void Awake()
|
||||
@@ -39,6 +40,7 @@ namespace BaseGames.World
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
_rb.bodyType = RigidbodyType2D.Kinematic;
|
||||
_rb.interpolation = RigidbodyInterpolation2D.Interpolate;
|
||||
_waitForEndpoint = new WaitForSeconds(_waitAtEndpoint);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
@@ -73,7 +75,7 @@ namespace BaseGames.World
|
||||
private IEnumerator WaitAndAdvance()
|
||||
{
|
||||
_waiting = true;
|
||||
yield return new WaitForSeconds(_waitAtEndpoint);
|
||||
yield return _waitForEndpoint;
|
||||
AdvanceWaypoint();
|
||||
_waiting = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user