feat(ai): EnemyBrainContext——EnemyBase子系统适配为BrainGraph能力接口
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dbaeb7890d1b7140b255b738fdc3ce0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
using UnityEngine;
|
||||
using BaseGames.AI;
|
||||
|
||||
namespace BaseGames.Enemies
|
||||
{
|
||||
/// <summary>
|
||||
/// 把 EnemyBase 的子系统包装成 BrainGraph 的能力接口(每敌人一实例)。
|
||||
/// 状态逻辑只依赖这些接口,不直接引用具体子系统。
|
||||
/// </summary>
|
||||
public sealed class EnemyBrainContext : IAiContext, ISensor, IMover, ICombatant, IActorVitals
|
||||
{
|
||||
readonly EnemyBase _enemy;
|
||||
readonly Blackboard _blackboard = new Blackboard();
|
||||
Vector2 _lastKnown;
|
||||
float _lostTimer;
|
||||
|
||||
public EnemyBrainContext(EnemyBase enemy) { _enemy = enemy; }
|
||||
|
||||
// ---- IAiContext ----
|
||||
public ISensor Sensor => this;
|
||||
public IMover Mover => this;
|
||||
public ICombatant Combat => this;
|
||||
public IActorVitals Vitals => this;
|
||||
public Blackboard Blackboard => _blackboard;
|
||||
|
||||
/// <summary>每帧由 EnemyAiBrain 在 Tick 之前调用,维护最后已知位置与丢失计时。</summary>
|
||||
public void Refresh(float dt)
|
||||
{
|
||||
if (_enemy.IsPlayerVisible() && _enemy.PlayerTransform != null)
|
||||
{
|
||||
_lastKnown = _enemy.PlayerTransform.position;
|
||||
_lostTimer = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lostTimer += dt;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>对象池复用时清空临时态。</summary>
|
||||
public void ResetScratch()
|
||||
{
|
||||
_blackboard.Clear();
|
||||
_lastKnown = _enemy.transform.position;
|
||||
_lostTimer = 0f;
|
||||
}
|
||||
|
||||
// ---- ISensor ----
|
||||
public bool SeesPlayer() => _enemy.IsPlayerVisible();
|
||||
public bool InRange(float range) => _enemy.IsPlayerInRange(range);
|
||||
public bool LostFor(float seconds) => !_enemy.IsPlayerVisible() && _lostTimer >= seconds;
|
||||
public Vector2 LastKnown => _lastKnown;
|
||||
|
||||
// ---- IMover ----
|
||||
public void MoveTo(Vector2 target) => _enemy.MoveTo(target);
|
||||
public void FacePlayer() => _enemy.FacePlayer();
|
||||
public void Stop() => _enemy.StopMovement();
|
||||
public void WalkRandom()
|
||||
{
|
||||
var nav = _enemy.Nav;
|
||||
if (nav != null && !nav.IsMoving) nav.WalkToRandom();
|
||||
}
|
||||
public void LookAround() => _enemy.BeginLookAround();
|
||||
|
||||
// ---- ICombatant ----
|
||||
public bool UseAbility(string abilityId)
|
||||
{
|
||||
var a = _enemy.Abilities?.Get(abilityId);
|
||||
return a != null && a.Execute();
|
||||
}
|
||||
public bool IsAbilityRunning(string abilityId = null)
|
||||
{
|
||||
var reg = _enemy.Abilities;
|
||||
if (reg == null) return false;
|
||||
if (abilityId != null)
|
||||
{
|
||||
var a = reg.Get(abilityId);
|
||||
return a != null && a.IsRunning;
|
||||
}
|
||||
var all = reg.All;
|
||||
for (int i = 0; i < all.Count; i++)
|
||||
if (all[i].IsRunning) return true;
|
||||
return false;
|
||||
}
|
||||
public bool NoAbilityRunning => !IsAbilityRunning();
|
||||
public bool CanUseAbility(string abilityId)
|
||||
{
|
||||
var a = _enemy.Abilities?.Get(abilityId);
|
||||
return a != null && a.CanUse;
|
||||
}
|
||||
|
||||
// ---- IActorVitals ----
|
||||
public bool IsAlive => _enemy.IsAlive;
|
||||
public bool IsControllable => _enemy.CurrentState == EnemyStateType.Controlled;
|
||||
public float HpPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
var stats = _enemy.Stats;
|
||||
return stats != null && stats.MaxHP > 0 ? (float)stats.CurrentHP / stats.MaxHP : 0f;
|
||||
}
|
||||
}
|
||||
public bool HpBelow(float ratio) => HpPercent < ratio;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9459e1a1d93189547ab3354d181bf4ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -3,6 +3,7 @@
|
||||
"rootNamespace": "BaseGames.Enemies",
|
||||
"references": [
|
||||
"BaseGames.Core",
|
||||
"BaseGames.AI",
|
||||
"BaseGames.Core.Events",
|
||||
"BaseGames.Combat",
|
||||
"BaseGames.Feedback",
|
||||
|
||||
Reference in New Issue
Block a user