Files
zeling_v2/Assets/_Game/Scripts/Player/WeaponManager.cs

126 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using UnityEngine;
namespace BaseGames.Player
{
/// <summary>
/// 武器管理器。
/// 监听 FormController.OnFormChanged依据当前形态切换 ActiveWeapon。
/// 支持护符 Override护符调用 SetOverride() 临时替换特定形态的武器。
/// 架构 05_PlayerModule §7。
/// </summary>
public class WeaponManager : MonoBehaviour
{
[SerializeField] private FormController _formController;
[SerializeField] private WeaponSO _startingWeapon; // 无 FormController 时的回退武器
[Header("HitBox 挂载点")]
[Tooltip("武器 HitBox Prefab 实例化的父节点,应为 Player 层级下的 [WeaponSocket] ")]
[SerializeField] private Transform _weaponSocket;
public WeaponSO ActiveWeapon { get; private set; }
public WeaponHitBoxInstance ActiveHitBoxInstance { get; private set; }
public event Action<WeaponSO> OnWeaponChanged;
// 护符注入的武器覆盖Key = FormSO.formIdValue = 替换武器(架构 05 §7
private readonly Dictionary<string, WeaponSO> _overrides = new();
private void Awake()
{
if (_formController != null && _formController.CurrentForm != null)
ApplyWeapon(_formController.CurrentForm);
else if (_startingWeapon != null)
SetDirectWeapon(_startingWeapon);
}
private void OnEnable()
{
if (_formController != null)
_formController.OnFormChanged += HandleFormChanged;
}
private void OnDisable()
{
if (_formController != null)
_formController.OnFormChanged -= HandleFormChanged;
}
private void Start()
{
// 若 FormController 在 Awake 时 CurrentForm 尚未初始化,在 Start 重试
if (ActiveWeapon == null && _formController != null && _formController.CurrentForm != null)
ApplyWeapon(_formController.CurrentForm);
else if (ActiveWeapon == null && _startingWeapon != null)
SetDirectWeapon(_startingWeapon);
}
// ── 内部切换 ───────────────────────────────────────────────────────────
private void HandleFormChanged() => ApplyWeapon(_formController.CurrentForm);
private void ApplyWeapon(FormSO form)
{
if (form == null) return;
WeaponSO next = _overrides.TryGetValue(form.formId, out var ov) ? ov : form.defaultWeapon;
if (next == ActiveWeapon) return;
SetDirectWeapon(next);
}
private void SetDirectWeapon(WeaponSO weapon)
{
var oldInstance = ActiveHitBoxInstance;
ActiveWeapon = weapon;
ActiveHitBoxInstance = null;
if (weapon?.hitBoxPrefab != null && _weaponSocket != null)
{
var go = Instantiate(weapon.hitBoxPrefab, _weaponSocket);
ActiveHitBoxInstance = go.GetComponent<WeaponHitBoxInstance>();
}
// 先通知订阅者(使其有机会取消对旧实例的事件订阅),再销毁旧实例
OnWeaponChanged?.Invoke(weapon);
if (oldInstance != null)
Destroy(oldInstance.gameObject);
}
// ── 护符 Override API由 WeaponOverrideEffect 调用,架构 05 §7──────
/// <summary>为指定形态设置武器覆盖。formId 为空 = 覆盖所有形态。</summary>
public void SetOverride(string formId, WeaponSO weapon)
{
if (string.IsNullOrEmpty(formId))
{
if (_formController != null)
foreach (var f in _formController.AllForms)
_overrides[f.formId] = weapon;
}
else
{
_overrides[formId] = weapon;
}
if (_formController?.CurrentForm != null)
ApplyWeapon(_formController.CurrentForm);
}
/// <summary>移除覆盖恢复默认武器。formId 为空 = 移除所有形态覆盖。</summary>
public void ClearOverride(string formId)
{
if (string.IsNullOrEmpty(formId))
{
_overrides.Clear();
}
else
{
_overrides.Remove(formId);
}
if (_formController?.CurrentForm != null)
ApplyWeapon(_formController.CurrentForm);
}
}
}