using System; using UnityEngine; using Animancer; using BaseGames.Combat; using BaseGames.Feedback; namespace BaseGames.Player { /// /// 武器数据 SO(纯数据,不含 Prefab 引用)。 /// 每个攻击方向对应一个 DamageSourceSO 和 ClipTransition。 /// HitBox 直接挂载在 Player Prefab 上(架构 05_PlayerModule §7)。 /// [CreateAssetMenu(menuName = "BaseGames/Player/Weapon")] public class WeaponSO : ScriptableObject { [Header("基础信息")] public string weaponId; // 全局唯一 ID,如 "Weapon_SkyBlade" public string displayName; // 显示名,如 "天裂刃" public Sprite icon; public WeaponType weaponType; [Header("地面连击序列(任意段数)")] [Tooltip("每个元素对应一段连击,支持任意段数,无需修改代码。")] public ComboStepConfig[] groundComboSteps = { new ComboStepConfig { hitBoxEnter = 0.3f, hitBoxExit = 0.6f, comboInputOpen = 0.3f, cancelWindowOpen = 0.5f, recoveryTime = 0.05f, comboTimeout = 0.25f, } }; [Header("空中攻击序列")] [Tooltip("空中攻击连击序列,通常只需 1 段。")] public ComboStepConfig[] airComboSteps = { new ComboStepConfig { hitBoxEnter = 0.1f, hitBoxExit = 0.8f, recoveryTime = 0.05f } }; [Header("上劈(固定单段)")] public ComboStepConfig upStep = new ComboStepConfig { hitBoxEnter = 0.2f, hitBoxExit = 0.7f, recoveryTime = 0.05f }; [Header("下劈(固定单段)")] public ComboStepConfig downStep = new ComboStepConfig { hitBoxEnter = 0.1f, hitBoxExit = 0.9f, recoveryTime = 0.05f }; [Header("HitBox Prefab")] [Tooltip("武器专属 HitBox Prefab,内含 WeaponHitBoxInstance。\nWeaponManager 在切换武器时实例化于 [WeaponSocket] 下,武器卸下时销毁。\n命名规范:Assets/Prefabs/Weapons/WPN_{weaponId}_HitBox.prefab")] public GameObject hitBoxPrefab; [Header("武器特效")] public WeaponVFXConfig vfxConfig; [Header("战斗参数")] [Tooltip("命中确认时增加的灵力值(覆盖 PlayerCombat 默认值 10)")] [Min(0)] public int soulPowerGain = 10; // ── 查询 API ────────────────────────────────────────────────────────── /// 取指定方向、指定段的完整配置,越界自动取最后一个。 public ComboStepConfig GetDirStep(AttackDirection dir, int index = 0) { if (dir == AttackDirection.Up) return upStep; if (dir == AttackDirection.Down) return downStep; var arr = dir switch { AttackDirection.Ground => groundComboSteps, AttackDirection.Air => airComboSteps, _ => groundComboSteps, }; if (arr == null || arr.Length == 0) return new ComboStepConfig { hitBoxEnter = 0.3f, hitBoxExit = 0.6f, recoveryTime = 0.05f, comboTimeout = 0.25f }; int idx = index < arr.Length ? index : arr.Length - 1; return arr[idx]; } /// 取指定方向第 0 段的 DamageSource(供 EnableWeaponHitBox 使用)。 public DamageSourceSO GetSourceByDir(AttackDirection dir) => GetDirStep(dir, 0).damageSource; // ── 地面连击便捷方法 ────────────────────────────────────────────────── public ComboStepConfig GetGroundStep(int index) => GetDirStep(AttackDirection.Ground, index); public ClipTransition GetClipByCombo(int index) => GetGroundStep(index).clip; /// 地面连击最大段数。 public int GroundComboCount => groundComboSteps?.Length ?? 0; } /// 单段攻击的完整配置:动画、伤害、HitBox 时间、连击窗口、攻速缩放参数。 [System.Serializable] public struct ComboStepConfig { [Header("动画 & 伤害")] public ClipTransition clip; public DamageSourceSO damageSource; [Header("HitBox 激活窗口(归一化 0-1)")] [Tooltip("HitBox 开启时间点")] [UnityEngine.Range(0f, 1f)] public float hitBoxEnter; [Tooltip("HitBox 关闭时间点")] [UnityEngine.Range(0f, 1f)] public float hitBoxExit; [Header("连击输入窗口(归一化 0-1,0 = 从动画开始就可输入)")] [Tooltip("从此时间点起接受下一段连击输入(0 = 动画开始即可)")] [UnityEngine.Range(0f, 1f)] public float comboInputOpen; [Tooltip("从此时间点起停止接受连击输入(0 = 持续到动画结束)")] [UnityEngine.Range(0f, 1f)] public float comboInputClose; [Header("取消窗口(归一化 0-1,0 = 仅在动画结束后恢复期内开放)")] [Tooltip("从此时间点起允许跳跃/冲刺打断")] [UnityEngine.Range(0f, 1f)] public float cancelWindowOpen; [Header("时间(秒,受攻速倍率缩放)")] [Tooltip("动画结束后的硬直时间,期间跳跃/冲刺无法打断")] [UnityEngine.Min(0f)] public float recoveryTime; [Tooltip("硬直结束后等待连击输入的时间,超时返回 Idle(0 = 立即返回)")] [UnityEngine.Min(0f)] public float comboTimeout; [Header("HitBox 绑定(留空 = 使用该方向的默认 HitBox)")] [Tooltip("对应 Prefab 中 HitBox 组件的 Id 字段。\n留空 = 使用方向默认 HitBox;\n非空 = 精确激活该 Id 的 HitBox,可视化编辑其 Collider2D 即为本段的判定形状。")] public string hitBoxId; } // ── 武器类型枚举(架构 05 §7)────────────────────────────────────────────── public enum WeaponType { TianHun, // 天魂:裂空刃(高频轻击) DiHun, // 地魂:地震锤(低频重击,范围大) MingHun, // 命魂:命镰(穿透,直线斩) Custom, // 护符替换或未来扩展武器 } // ── 武器特效配置([Serializable] 内嵌,架构 05 §7)──────────────────────── [Serializable] public class WeaponVFXConfig { [Tooltip("切换到此武器时播放的特效预设 ID(对应 IFeedbackPlayer.TriggerPreset)")] public string onEquipPresetId; [Tooltip("武器挥斩拖尾 Prefab(null = 不显示拖尾)")] public GameObject weaponTrailPrefab; public Color trailColor = Color.white; } }