feat: Implement Room Streaming System
- Add RoomStreamingManager to manage room loading and unloading based on player proximity. - Create StreamingBudgetConfigSO for memory and performance budgeting of the streaming system. - Introduce TransitionDirector to handle seamless and atmospheric fade transitions between rooms. - Develop WorldGraph to represent room connectivity and facilitate neighbor queries and distance calculations. - Implement RoomNode and RoomEdge classes to structure room data and connections.
This commit is contained in:
98
Assets/_Game/Scripts/Enemies/Abilities/LeapAttackAbility.cs
Normal file
98
Assets/_Game/Scripts/Enemies/Abilities/LeapAttackAbility.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using BaseGames.Combat;
|
||||
|
||||
namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 跳跃俯冲能力:起跳后以抛物线轨迹扑向目标,落地触发 AoE。
|
||||
/// 流程:起跳预备 → 抛物线移动到目标 → 落地 AoE。
|
||||
/// 使用 Rigidbody2D 直接物理推动;NavAgent 在执行期间被禁用以避免冲突。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public sealed class LeapAttackAbility : EnemyAbilityBase
|
||||
{
|
||||
[Header("跳跃参数")]
|
||||
[SerializeField] private float _jumpHeight = 4f;
|
||||
[SerializeField] private float _maxRange = 8f;
|
||||
[SerializeField] private float _windupTime = 0.35f;
|
||||
[SerializeField] private float _recoveryTime = 0.4f;
|
||||
[SerializeField] private LayerMask _groundMask;
|
||||
|
||||
[Header("落地 AoE")]
|
||||
[SerializeField] private HitBox _landingHitBox;
|
||||
[SerializeField] private float _hitBoxActiveTime = 0.15f;
|
||||
|
||||
private Rigidbody2D _rb;
|
||||
private float _origGravity;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_rb = GetComponentInParent<Rigidbody2D>();
|
||||
if (_rb != null) _origGravity = _rb.gravityScale;
|
||||
}
|
||||
|
||||
protected override IEnumerator ExecuteCoroutine()
|
||||
{
|
||||
if (_rb == null || _enemy == null || _enemy.PlayerTransform == null) yield break;
|
||||
var atk = _config.attackSequence != null && _config.attackSequence.Length > 0
|
||||
? _config.attackSequence[0] : null;
|
||||
|
||||
FaceTarget(_enemy.PlayerTransform);
|
||||
|
||||
// Windup(可选动画)
|
||||
if (atk != null && atk.clip != null && _animancer != null)
|
||||
_animancer.Play(atk.clip);
|
||||
yield return EnemyAbilityWaits.Get(_windupTime);
|
||||
|
||||
// 计算抛物线初速度
|
||||
Vector2 from = _rb.position;
|
||||
Vector2 to = _enemy.PlayerTransform.position;
|
||||
float dx = Mathf.Clamp(to.x - from.x, -_maxRange, _maxRange);
|
||||
float g = Mathf.Abs(Physics2D.gravity.y) * _origGravity;
|
||||
float vy = Mathf.Sqrt(2f * g * Mathf.Max(0.1f, _jumpHeight));
|
||||
float tUp = vy / g;
|
||||
float dyDown = (from.y + _jumpHeight) - to.y;
|
||||
float tDown = Mathf.Sqrt(2f * Mathf.Max(0.01f, dyDown) / g);
|
||||
float total = tUp + tDown;
|
||||
float vx = dx / Mathf.Max(0.1f, total);
|
||||
|
||||
Phase = AbilityRunState.Active;
|
||||
_rb.velocity = new Vector2(vx, vy);
|
||||
|
||||
// 空中飞行直到接触地面
|
||||
yield return null;
|
||||
float airTimer = 0f;
|
||||
while (airTimer < total + 0.5f)
|
||||
{
|
||||
airTimer += Time.fixedDeltaTime;
|
||||
yield return new WaitForFixedUpdate();
|
||||
if (airTimer > 0.1f && IsGrounded()) break;
|
||||
}
|
||||
_rb.velocity = new Vector2(0f, _rb.velocity.y);
|
||||
|
||||
// 落地 AoE
|
||||
if (_landingHitBox != null)
|
||||
{
|
||||
var src = atk != null ? atk.damageSource : null;
|
||||
_landingHitBox.Activate(src, _transform);
|
||||
yield return EnemyAbilityWaits.Get(_hitBoxActiveTime);
|
||||
_landingHitBox.Deactivate();
|
||||
}
|
||||
|
||||
yield return EnemyAbilityWaits.Get(_recoveryTime);
|
||||
}
|
||||
|
||||
private bool IsGrounded()
|
||||
{
|
||||
var hit = Physics2D.Raycast(_rb.position, Vector2.down, 0.6f, _groundMask);
|
||||
return hit.collider != null;
|
||||
}
|
||||
|
||||
protected override void OnInterrupted(InterruptReason reason)
|
||||
{
|
||||
if (_landingHitBox != null && _landingHitBox.IsActive) _landingHitBox.Deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user