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:
91
Assets/_Game/Scripts/Enemies/Abilities/CeilingDropAbility.cs
Normal file
91
Assets/_Game/Scripts/Enemies/Abilities/CeilingDropAbility.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using BaseGames.Combat;
|
||||
|
||||
namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 挂顶下落能力:怪物初始挂在天花板(kinematic,重力 0)。能力触发后:
|
||||
/// 1. 切换为 dynamic + 恢复重力
|
||||
/// 2. 自由落体到接触地面
|
||||
/// 3. 落地播放 AoE HitBox + 砸地反馈
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public sealed class CeilingDropAbility : EnemyAbilityBase
|
||||
{
|
||||
[Header("下落")]
|
||||
[SerializeField] private float _fallGravityScale = 3.5f;
|
||||
[SerializeField] private float _maxFallTime = 3f;
|
||||
[SerializeField] private LayerMask _groundMask;
|
||||
|
||||
[Header("落地")]
|
||||
[SerializeField] private HitBox _landingHitBox;
|
||||
[SerializeField] private float _hitBoxActiveTime = 0.2f;
|
||||
[SerializeField] private float _recoveryTime = 0.4f;
|
||||
|
||||
private Rigidbody2D _rb;
|
||||
private RigidbodyType2D _origBodyType;
|
||||
private float _origGravityScale;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_rb = GetComponentInParent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
protected override IEnumerator ExecuteCoroutine()
|
||||
{
|
||||
if (_rb == null) yield break;
|
||||
var atk = (_config.attackSequence != null && _config.attackSequence.Length > 0)
|
||||
? _config.attackSequence[0] : null;
|
||||
|
||||
Phase = AbilityRunState.Active;
|
||||
|
||||
// 切换到动态 + 恢复重力
|
||||
_origBodyType = _rb.bodyType;
|
||||
_origGravityScale = _rb.gravityScale;
|
||||
_rb.bodyType = RigidbodyType2D.Dynamic;
|
||||
_rb.gravityScale = _fallGravityScale;
|
||||
_rb.velocity = Vector2.zero;
|
||||
|
||||
float t = 0f;
|
||||
while (t < _maxFallTime)
|
||||
{
|
||||
t += Time.fixedDeltaTime;
|
||||
yield return new WaitForFixedUpdate();
|
||||
if (t > 0.05f && IsGrounded()) break;
|
||||
}
|
||||
|
||||
_rb.velocity = Vector2.zero;
|
||||
|
||||
if (_landingHitBox != null)
|
||||
{
|
||||
_landingHitBox.Activate(atk != null ? atk.damageSource : null, _transform);
|
||||
yield return EnemyAbilityWaits.Get(_hitBoxActiveTime);
|
||||
_landingHitBox.Deactivate();
|
||||
}
|
||||
|
||||
yield return EnemyAbilityWaits.Get(_recoveryTime);
|
||||
|
||||
// 落地后不恢复挂顶状态(一般转为地面行为),保持动态 Rigidbody
|
||||
}
|
||||
|
||||
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();
|
||||
// 中断时恢复 Rigidbody 原始状态,防止物理参数泄漏
|
||||
if (_rb != null)
|
||||
{
|
||||
_rb.velocity = Vector2.zero;
|
||||
_rb.bodyType = _origBodyType;
|
||||
_rb.gravityScale = _origGravityScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user