摄像机区域的架构改动

This commit is contained in:
2026-05-15 14:47:24 +08:00
parent 1b37297585
commit f264329751
3591 changed files with 1687228 additions and 446503 deletions

View File

@@ -0,0 +1,21 @@
{
"excludePlatforms": [],
"allowUnsafeCode": false,
"precompiledReferences": [],
"name": "BaseGames.Spells",
"defineConstraints": [],
"noEngineReferences": false,
"versionDefines": [],
"rootNamespace": "BaseGames.Spells",
"references": [
"BaseGames.Core.Events",
"BaseGames.Input",
"BaseGames.Player",
"BaseGames.Combat",
"BaseGames.Skills",
"Kybernetik.Animancer"
],
"autoReferenced": true,
"overrideReferences": false,
"includePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2bd9f31896eb6c5489e2e4fd357f2132
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
using UnityEngine;
using BaseGames.Player;
using BaseGames.Input;
namespace BaseGames.Spells
{
/// <summary>
/// 法术管理器(架构 BaseGames.Spells
/// 挂在 Player 上,管理已装备法术的施放、冷却与资源消耗。
/// 装备/卸下法术通过 EquipSpell / UnequipSpell 公共 API 完成(如护符系统调用)。
///
/// 输入事件:订阅 InputReaderSO.SpellCastEvent对应 InputActionAsset 中的 "Spell" Action
/// </summary>
public class SpellManager : MonoBehaviour
{
[Header("依赖引用")]
[SerializeField] private PlayerStats _stats;
[SerializeField] private InputReaderSO _input;
[Header("法术挂载点")]
[Tooltip("法术 HitBox / 投射物的生成位置")]
[SerializeField] private Transform _spellSocket;
// 当前装备的法术(单槽;如需多槽可扩展为数组)
private SpellSO _equippedSpell;
private float _cooldownRemaining;
// ── 生命周期 ──────────────────────────────────────────────────────────
private void OnEnable()
{
if (_input != null)
_input.SpellCastEvent += TryCastSpell;
}
private void OnDisable()
{
if (_input != null)
_input.SpellCastEvent -= TryCastSpell;
}
private void Update()
{
if (_cooldownRemaining > 0f)
_cooldownRemaining -= Time.deltaTime;
}
// ── 公共 API ─────────────────────────────────────────────────────────
/// <summary>装备一个法术(替换当前已装备的)。</summary>
public void EquipSpell(SpellSO spell)
{
_equippedSpell = spell;
_cooldownRemaining = 0f;
}
/// <summary>卸下当前装备的法术。</summary>
public void UnequipSpell()
{
_equippedSpell = null;
_cooldownRemaining = 0f;
}
/// <summary>返回当前冷却进度0 = 就绪1 = 刚施放)。供 UI 血条使用。</summary>
public float CooldownFraction
=> _equippedSpell != null && _equippedSpell.cooldown > 0f
? Mathf.Clamp01(_cooldownRemaining / _equippedSpell.cooldown)
: 0f;
public SpellSO EquippedSpell => _equippedSpell;
public bool IsReady => _equippedSpell != null && _cooldownRemaining <= 0f;
// ── 内部施放逻辑 ──────────────────────────────────────────────────────
private void TryCastSpell()
{
if (_equippedSpell == null || _cooldownRemaining > 0f) return;
if (_stats == null) return;
// 消耗资源(扣除护符提供的灵力减免后计算实际消耗)
int cost = Mathf.Max(0, _equippedSpell.baseCost - _stats.SoulCostReduction);
bool consumed = _equippedSpell.resourceType == SpellResourceType.SoulPower
? _stats.ConsumeSoulPower(cost)
: _stats.ConsumeSpiritPower(cost);
if (!consumed) return;
_cooldownRemaining = _equippedSpell.cooldown;
ExecuteSpellEffect(_equippedSpell);
}
private void ExecuteSpellEffect(SpellSO spell)
{
// 生成 HitBox Prefab近战/爆炸类法术)
if (spell.spellHitBoxPrefab != null)
{
var socket = _spellSocket != null ? _spellSocket : transform;
Instantiate(spell.spellHitBoxPrefab, socket.position, socket.rotation, socket);
}
// TODO: 根据 spell.effectType 扩展施放逻辑
// SpellEffectType.Projectile → ProjectileManager 发射
// SpellEffectType.AreaOfEffect → AreaOfEffectSpawner 生成
// SpellEffectType.SelfBuff → PlayerStats/StatusEffectManager 施加增益
// SpellEffectType.SummonShade → 召唤投影 Prefab
// SpellEffectType.TeleportBlink → 瞬移至光标/方向
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05418e468b23b8f43a5619b7066bad6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using UnityEngine;
using Animancer;
using BaseGames.Combat;
using BaseGames.Skills; // FeedbackPresetSO
namespace BaseGames.Spells
{
/// <summary>
/// 法术消耗的资源类型。
/// </summary>
public enum SpellResourceType { SoulPower, SpiritPower }
/// <summary>
/// 法术效果分类(决定施放时的逻辑分支)。
/// </summary>
public enum SpellEffectType
{
Projectile, // 投射物法术
AreaOfEffect, // 范围爆炸
SelfBuff, // 自身增益(护盾/加速/再生)
SummonShade, // 召唤投影
TeleportBlink, // 瞬移
}
/// <summary>
/// 法术数据 SO架构 BaseGames.Spells
/// 创建路径Assets/Data/Spells/SPL_{spellId}.asset
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/Spells/Spell")]
public class SpellSO : ScriptableObject
{
[Header("Identity")]
[Tooltip("全局唯一 ID建议使用 GameIds 域中的常量")]
public string spellId;
[Tooltip("本地化 Key从 LocalizationManager.Get(displayNameKey, \"Spells\") 获取)")]
public string displayNameKey;
[TextArea(1, 3)]
public string descriptionKey;
public Sprite icon;
[Header("Resource")]
public SpellResourceType resourceType;
[Min(1)]
public int baseCost;
[Min(0f)]
public float cooldown;
[Header("Effect")]
public SpellEffectType effectType;
public DamageSourceSO damageSource;
[Header("Projectile")]
public ProjectileConfigSO projectileConfig;
[Tooltip("是否追踪最近敌人")]
public bool isHoming;
[Header("AoE")]
[Min(0f)] public float explosionRadius;
[Min(0f)] public float explosionDelay;
[Header("Buff")]
[Min(0f)] public float buffDuration;
[Min(0f)] public float buffValue; // 含义由 effectType 决定(如护盾量、速度倍率)
[Header("Animation")]
public ClipTransition castAnimation;
[Min(0f)]
public float castLockDuration; // 施放锁定时长(秒)
[Header("HitBox Prefab")]
[Tooltip("近战/爆炸类法术的命中盒 Prefab投射物法术留空")]
public GameObject spellHitBoxPrefab;
[Header("Feedback")]
public FeedbackPresetSO castFeedback;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8a13925466199144adf5c61bb717e25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: