diff --git a/Assets/_Game/Scripts/Enemies/Abilities/AnimatedCeilingDropAbility.cs b/Assets/_Game/Scripts/Enemies/Abilities/AnimatedCeilingDropAbility.cs index 947f3307..cf1a2355 100644 --- a/Assets/_Game/Scripts/Enemies/Abilities/AnimatedCeilingDropAbility.cs +++ b/Assets/_Game/Scripts/Enemies/Abilities/AnimatedCeilingDropAbility.cs @@ -13,48 +13,39 @@ namespace BaseGames.Enemies.Abilities [RequireComponent(typeof(Rigidbody2D))] public class AnimatedCeilingDropAbility : EnemyAbilityBase { - [Header("动画")] - [Tooltip("下落循环动画(旋转下落姿态,循环播放直到落地)")] - [SerializeField] private ClipTransition _fallLoopClip; - - [Header("物理下落")] - [Tooltip("切换 Dynamic 后使用的重力倍率")] - [SerializeField] private float _fallGravityScale = 3.5f; - [Tooltip("下落超时保护(秒),超时后强制继续执行")] - [SerializeField] private float _maxFallTime = 3f; - [SerializeField] private LayerMask _groundMask; - [Header("落地后")] - [Tooltip("落地后恢复帧延迟(秒),之后切换为 Patrol 阶段")] - [SerializeField] private float _recoveryTime = 0.1f; [SerializeField] private BodyContactDamage _contactDamage; + private AnimatedCeilingDropAbilitySO _cfg; private Rigidbody2D _rb; protected override void Awake() { base.Awake(); + _cfg = ResolveConfig(); _rb = GetComponentInParent(); } protected override IEnumerator ExecuteCoroutine() { + if (_cfg == null) yield break; + Phase = AbilityRunState.Active; // 播放下落动画(能力脚本负责动画所有权) - if (_fallLoopClip.Clip != null) - _animancer.Play(_fallLoopClip); + if (_cfg.fallLoopClip.Clip != null) + _animancer.Play(_cfg.fallLoopClip); // 切换物理:Kinematic → Dynamic + 重力 var origBodyType = _rb.bodyType; var origGravScale = _rb.gravityScale; _rb.bodyType = RigidbodyType2D.Dynamic; - _rb.gravityScale = _fallGravityScale; + _rb.gravityScale = _cfg.fallGravityScale; _rb.velocity = Vector2.zero; // 等待落地(超时保护) float elapsed = 0f; - while (elapsed < _maxFallTime) + while (elapsed < _cfg.maxFallTime) { elapsed += Time.fixedDeltaTime; yield return new WaitForFixedUpdate(); @@ -66,7 +57,7 @@ namespace BaseGames.Enemies.Abilities if (_contactDamage != null) _contactDamage.enabled = true; - yield return EnemyAbilityWaits.Get(_recoveryTime); + yield return EnemyAbilityWaits.Get(_cfg.recoveryTime); // PlayLocomotionClip(Patrol) 播放 AnimConfig.Walk(地面移动动画) _enemy.PlayLocomotionClip(LocomotionMode.Patrol); @@ -74,7 +65,7 @@ namespace BaseGames.Enemies.Abilities private bool IsGrounded() { - var hit = Physics2D.Raycast(_rb.position, Vector2.down, 0.6f, _groundMask); + var hit = Physics2D.Raycast(_rb.position, Vector2.down, 0.6f, _cfg.groundMask); return hit.collider != null; } diff --git a/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs b/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs new file mode 100644 index 00000000..22df34ad --- /dev/null +++ b/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs @@ -0,0 +1,25 @@ +using Animancer; +using UnityEngine; + +namespace BaseGames.Enemies.Abilities +{ + /// AnimatedCeilingDropAbility 的配置:下落动画 + 物理下落/落地参数。 + [CreateAssetMenu(menuName = "BaseGames/Enemies/Abilities/Animated Ceiling Drop Ability", fileName = "ABL_")] + public class AnimatedCeilingDropAbilitySO : EnemyAbilitySO + { + [Header("动画")] + [Tooltip("下落循环动画(旋转下落姿态,循环播放直到落地)")] + public ClipTransition fallLoopClip; + + [Header("物理下落")] + [Tooltip("切换 Dynamic 后使用的重力倍率")] + public float fallGravityScale = 3.5f; + [Tooltip("下落超时保护(秒),超时后强制继续执行")] + public float maxFallTime = 3f; + public LayerMask groundMask; + + [Header("落地后")] + [Tooltip("落地后恢复帧延迟(秒),之后切换为 Patrol 阶段")] + public float recoveryTime = 0.1f; + } +} diff --git a/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs.meta b/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs.meta new file mode 100644 index 00000000..be17bfd1 --- /dev/null +++ b/Assets/_Game/Scripts/Enemies/Abilities/Configs/AnimatedCeilingDropAbilitySO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b339b460d92741e44832fe66863741e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: