Add WeaponFeedback component and AddressableManagerWindow meta file

- Implemented WeaponFeedback class for handling weapon-related feedbacks such as hit effects and attack sounds.
- Added meta file for AddressableManagerWindow to manage addressable assets.
- Included a new jump.data file for profiler data.
This commit is contained in:
2026-05-22 22:03:32 +08:00
parent 3e1f234ddc
commit b7baf7ad6a
44 changed files with 1783 additions and 1927 deletions

View File

@@ -142,8 +142,8 @@ namespace BaseGames.Combat
bool isRivalHitBoxLayer = (_rivalHitBoxMask.value & (1 << otherLayer)) != 0;
if (isRivalHitBoxLayer && CanClash)
{
var rivalHitBox = other.GetComponent<HitBox>();
if (rivalHitBox != null && rivalHitBox.IsActive && rivalHitBox.CanClash)
if (other.TryGetComponent<HitBox>(out var rivalHitBox) &&
rivalHitBox.IsActive && rivalHitBox.CanClash)
{
_clashService?.ResolveClash(this, rivalHitBox);
return; // 拼刀,中止伤害流水线
@@ -151,8 +151,7 @@ namespace BaseGames.Combat
}
// ② 命中 HurtBox
var hurtBox = other.GetComponent<HurtBox>();
if (hurtBox != null)
if (other.TryGetComponent<HurtBox>(out var hurtBox))
{
// 用 HitBox 自身碰撞盒中心在 HurtBox 表面上的最近点作为受击位置。
// 对大体积/长条形受击体(如地刺),此点远比 HurtBox 节点中心更准确。
@@ -163,7 +162,8 @@ namespace BaseGames.Combat
}
// ③ 命中 IBreakable机关/障碍物)
other.GetComponent<IBreakable>()?.TryInteract(info);
if (other.TryGetComponent<IBreakable>(out var breakable))
breakable.TryInteract(info);
}
// ── 当前激活期已命中目标集合(防止复合子 Collider 导致同帧多次命中)────────────

View File

@@ -18,6 +18,8 @@ namespace BaseGames.Combat
protected Rigidbody2D _rb;
protected HitBox _hitBox;
protected float _aliveTimer;
// Lifetime 在 Initialize 时缓存,避免 Update 每帧访问 SO 成员并做 null check
private float _lifetime = float.MaxValue;
private PooledObject _pooledObject;
@@ -32,6 +34,7 @@ namespace BaseGames.Combat
public virtual void Initialize(ProjectileConfigSO config, DamageInfo damageInfo, Vector2 direction, int ownerLayer = 0)
{
_config = config;
_lifetime = config.Lifetime;
DamageInfo = damageInfo;
Direction = direction.normalized;
_aliveTimer = 0f;
@@ -75,7 +78,7 @@ namespace BaseGames.Combat
protected virtual void Update()
{
_aliveTimer += Time.deltaTime;
if (_config != null && _aliveTimer >= _config.Lifetime)
if (_aliveTimer >= _lifetime)
ReturnToPool();
}
@@ -91,6 +94,7 @@ namespace BaseGames.Combat
protected virtual void OnDisable()
{
_aliveTimer = 0f;
_lifetime = float.MaxValue; // 归还对象池后重置,防止未初始化时自毁
}
}
}

View File

@@ -19,6 +19,11 @@ namespace BaseGames.Combat
public event System.Action<DamageInfo> OnHitConfirmed;
private Coroutine _returnCoroutine;
// 按 duration 缓存 WaitForSeconds同一技能复用无 GC 分配
private WaitForSeconds _cachedWait;
private float _cachedWaitDuration = float.NaN;
private void Awake()
{
foreach (var hb in _hitBoxes)
@@ -35,7 +40,31 @@ namespace BaseGames.Combat
hb?.Activate(source, attacker);
}
/// <summary>duration 秒后自动销毁此 GameObject。</summary>
/// <summary>
/// duration 秒后归还对象池SetActive false
/// 由 SkillManager 对象池调用;替代旧版 Destroy 流程。
/// </summary>
public void AutoReturnAfter(float duration)
{
if (!Mathf.Approximately(_cachedWaitDuration, duration))
{
_cachedWaitDuration = duration;
_cachedWait = new WaitForSeconds(duration);
}
if (_returnCoroutine != null) StopCoroutine(_returnCoroutine);
_returnCoroutine = StartCoroutine(ReturnCoroutine());
}
private System.Collections.IEnumerator ReturnCoroutine()
{
yield return _cachedWait;
foreach (var hb in _hitBoxes)
hb?.Deactivate();
_returnCoroutine = null;
gameObject.SetActive(false); // 触发对象池回收
}
/// <summary>duration 秒后销毁(非池化路径,保留向后兼容)。</summary>
public void AutoDestroyAfter(float duration)
=> Destroy(gameObject, Mathf.Max(0f, duration));

View File

@@ -11,8 +11,9 @@ namespace BaseGames.Combat.StatusEffects
public override StatusEffectType EffectType => StatusEffectType.Fire;
public override int MaxStacks => 1;
private static readonly StatusEffectType[] s_MutualExclusions = { StatusEffectType.Freeze };
/// <summary>施加燃烧时移除冻结(火冰互斥)。</summary>
public override StatusEffectType[] MutualExclusions => new[] { StatusEffectType.Freeze };
public override StatusEffectType[] MutualExclusions => s_MutualExclusions;
public FireEffect()
{

View File

@@ -27,6 +27,8 @@ namespace BaseGames.Combat.StatusEffects
// ── Shader 渲染MaterialPropertyBlock不修改共享材质─────────
private SpriteRenderer _renderer;
private MaterialPropertyBlock _propBlock;
// 缓存 Shader 属性 ID避免每次调用 SetShaderParam 都做字符串哈希查找
private readonly Dictionary<string, int> _shaderPropIds = new();
// ── DoT 伤害代理(由 StatusEffect.OnTick 通过 Owner 调用)──────────
private IDamageable _damageable;
@@ -135,8 +137,13 @@ namespace BaseGames.Combat.StatusEffects
public void SetShaderParam(string param, float value)
{
if (_renderer == null) return;
if (!_shaderPropIds.TryGetValue(param, out int propId))
{
propId = Shader.PropertyToID(param);
_shaderPropIds[param] = propId;
}
_renderer.GetPropertyBlock(_propBlock);
_propBlock.SetFloat(param, value);
_propBlock.SetFloat(propId, value);
_renderer.SetPropertyBlock(_propBlock);
}