多轮审查评估
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using BaseGames.Core;
|
||||
using BaseGames.Core.Events;
|
||||
using BaseGames.Enemies;
|
||||
@@ -25,7 +28,10 @@ namespace BaseGames.Challenge
|
||||
private int _remainingEnemies;
|
||||
private float _elapsedTime;
|
||||
private bool _isRunning;
|
||||
private bool _noHitViolated; // 架构 §12:requireNoHit 挑战是否被破坏
|
||||
private bool _noHitViolated;
|
||||
|
||||
// 预加载句柄(挑战开始前预热全部敌人资源,结束时释放)
|
||||
private readonly List<AsyncOperationHandle<GameObject>> _preloadHandles = new();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
@@ -35,6 +41,7 @@ namespace BaseGames.Challenge
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_player != null) _player.OnDamaged -= OnPlayerDamaged;
|
||||
ReleasePreloadedAssets();
|
||||
}
|
||||
|
||||
private void OnPlayerDamaged() => _noHitViolated = true;
|
||||
@@ -58,7 +65,51 @@ namespace BaseGames.Challenge
|
||||
_currentEncounterIndex = 0;
|
||||
_elapsedTime = 0f;
|
||||
_noHitViolated = false;
|
||||
SpawnWave(0);
|
||||
|
||||
// 预加载所有敌人资源,全部缓存就绪后再开始生成第一波
|
||||
PreloadEnemyAssets(() => SpawnWave(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预加载本次挑战所有敌人的 Addressable 资源。
|
||||
/// 确保所有资源均已内存驻留后才调用 <paramref name="onComplete"/>.
|
||||
/// 无敌人配置时直接回调。
|
||||
/// </summary>
|
||||
private void PreloadEnemyAssets(Action onComplete)
|
||||
{
|
||||
var keys = new HashSet<string>();
|
||||
if (_challengeData.encounters != null)
|
||||
foreach (var enc in _challengeData.encounters)
|
||||
if (enc.enemies != null)
|
||||
foreach (var entry in enc.enemies)
|
||||
if (!string.IsNullOrEmpty(entry.enemyAddressKey))
|
||||
keys.Add(entry.enemyAddressKey);
|
||||
|
||||
if (keys.Count == 0)
|
||||
{
|
||||
onComplete?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
int remaining = keys.Count;
|
||||
foreach (var key in keys)
|
||||
{
|
||||
var handle = Addressables.LoadAssetAsync<GameObject>(key);
|
||||
_preloadHandles.Add(handle);
|
||||
handle.Completed += _ =>
|
||||
{
|
||||
if (--remaining == 0)
|
||||
onComplete?.Invoke();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>释放预加载的所有资源句柄。</summary>
|
||||
private void ReleasePreloadedAssets()
|
||||
{
|
||||
foreach (var h in _preloadHandles)
|
||||
if (h.IsValid()) Addressables.Release(h);
|
||||
_preloadHandles.Clear();
|
||||
}
|
||||
|
||||
private void SpawnWave(int index)
|
||||
@@ -77,7 +128,16 @@ namespace BaseGames.Challenge
|
||||
for (int i = 0; i < entry.count; i++)
|
||||
{
|
||||
_remainingEnemies++;
|
||||
Vector3 pos = entry.spawnPoint != null ? entry.spawnPoint.position : Vector3.zero;
|
||||
Vector3 pos;
|
||||
if (entry.spawnPoint != null)
|
||||
{
|
||||
pos = entry.spawnPoint.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[ChallengeRoomManager] encounter[{index}] 中的 enemyAddressKey='{entry.enemyAddressKey}' 未配置 spawnPoint,将在 Vector3.zero 生成。请在 ChallengeRoomSO 中补全配置。", this);
|
||||
pos = Vector3.zero;
|
||||
}
|
||||
Addressables.InstantiateAsync(entry.enemyAddressKey, pos, Quaternion.identity)
|
||||
.Completed += handle =>
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace BaseGames.Quest
|
||||
[Header("标识")]
|
||||
public string objectiveId;
|
||||
[TextArea(1, 4)]
|
||||
public string displayText; // 任务日志中显示的文本
|
||||
public string displayTextKey; // 本地化 key(通过 LocalizationManager.Get(displayTextKey, "Quest") 显示)
|
||||
public bool IsOptional; // 可选目标(完成加奖励但不阻塞任务)
|
||||
|
||||
/// <summary>根据当前进度判断目标是否完成。</summary>
|
||||
|
||||
Reference in New Issue
Block a user