Skip to content

UnitState 系统 ​

概述 ​

UnitState 是运行时可变的单位状态标签。与静态的 UnitFilter 分类不同,状态标签可以在运行时通过 Buff、技能效果或游戏逻辑动态设置和清除。

状态标签的两个用途:

  1. 行为控制 — 直接影响单位行为(如 SuppressMovement 阻止移动,Hidden 隐藏显示)
  2. 过滤条件 — 作为 TargetFilter.Excluded 的成员,将特定状态的单位排除在攻击目标之外(如排除无敌、已死亡的单位)

关于过滤用法,参见 目标过滤系统。

引用计数与免疫机制 ​

状态的添加和移除基于 StateCounter 的引用计数机制(SERVER):

  • 引用计数:每次 AddState 计数 +1,每次 RemoveState 计数 -1。状态在计数从 0 变为正数时激活,从正数变为 0 时清除。多个 Buff 可以独立 Add/Remove 同一状态而互不干扰。
  • 免疫压制:AddImmunity 会压制指定状态——即使引用计数 > 0,状态也不生效。RemoveImmunity 后若引用计数仍 > 0,状态恢复。免疫本身也是引用计数的。
csharp
// Buff A 添加无敌
unit.AddState(UnitState.Invulnerable);   // 计数 1 → 无敌生效
// Buff B 也添加无敌
unit.AddState(UnitState.Invulnerable);   // 计数 2 → 仍然无敌
// Buff A 到期移除
unit.RemoveState(UnitState.Invulnerable); // 计数 1 → 仍然无敌
// Buff B 到期移除
unit.RemoveState(UnitState.Invulnerable); // 计数 0 → 无敌解除

// 免疫示例
unit.AddImmunity(UnitState.SuppressMovement);  // 免疫定身
unit.AddState(UnitState.SuppressMovement);     // 添加定身但被免疫压制,HasState 返回 false
unit.RemoveImmunity(UnitState.SuppressMovement); // 移除免疫,定身生效

战斗免疫 ​

控制单位在战斗中的免疫能力。

值含义说明
Invulnerable无敌完全免疫所有伤害。常用于出生保护、过场动画等场景。默认 AI ScanFilters 排除此状态。
SpellImmunity魔免免疫法术类伤害和效果。物理攻击仍然有效。
Ethereal物免(虚无)免疫物理伤害。法术攻击仍然有效。与 SpellImmunity 互补。
Unkillable免死生命值不会降到 0 以下,无法被击杀。仍然会受到伤害。
Dead死亡系统管理,不要手动操作。 由框架在单位死亡时自动设置,编辑器中隐藏。开发者应通过 unit.Kill() 击杀单位,而不是手动 AddState(UnitState.Dead)。

控制限制 ​

限制单位接受命令、移动和转向的能力。

值含义说明
UnCommandable无法被命令单位无法被玩家或 AI 下达命令。
SuppressMovement暂时阻止移动暂时阻止行走和寻路(如眩晕、冰冻)。单位仍可接受接近命令,解除后自动恢复执行。
DisableMovement永久禁止移动永久禁止移动,不再处理接近命令。适用于固定炮台等设计。
SuppressTurning暂时阻止转向暂时阻止转向(如眩晕时锁定朝向)。解除后自动恢复。
DisableTurning永久禁止转向永久禁止转向,锁定当前朝向。

Suppress vs Disable 语义对比 ​

维度Suppress(暂时抑制)Disable(永久禁止)
持续性暂时的,通常由 Buff 设置永久的,通常在 GameData 中配置
命令处理仍然接受接近命令并排入队列不再处理接近命令
解除后行为自动恢复并执行排队的命令不适用
典型场景眩晕、冰冻、定身等控制效果固定炮台、建筑等不可移动单位

Movement 和 Turning 各有一对 Suppress/Disable 状态,遵循相同的语义模式。

可见性 ​

控制单位对其他玩家的可见性。

值含义说明
Hidden隐藏单位完全不可见,对所有玩家隐藏。
InvisibleToEnemy对敌方不可见敌方玩家无法看到此单位(隐身)。友方仍可见。
Detected被侦测压制 InvisibleToEnemy 效果,使单位对敌方重新可见(如真视宝石、侦测技能)。
SuppressActor隐藏表现隐藏单位的视觉表现(模型、特效),但逻辑实体仍然存在。
IgnoreSelector无法被搜索所有基于场景范围的搜索均忽略此单位(包括 AI 扫描、技能目标选取和脚本中的范围搜索)。只有通过直接引用(如变量持有)或 Player.Units 等非范围方式才能获取到。

InvisibleToEnemy 与 Detected 的交互 ​

InvisibleToEnemy 使单位进入隐身状态,敌方无法看到也无法选为目标。Detected 标签会压制隐身效果——当两个标签同时存在时,单位对敌方可见。移除 Detected 后隐身恢复。

移动特性 ​

控制单位的移动方式。

值含义说明
VectorMove3D3D 摇杆移动单位可以进行 3D 方向的摇杆移动(如飞行)。仅适用于 3D 模式游戏。
VectorMoveBypassOrderQueue施法中摇杆移动允许在施法期间进行摇杆移动,不打断技能释放。
SuppressAutoTurningWhenMoving禁止自动转向摇杆移动和寻路时不自动面向移动方向。适用于需要边退边攻的单位。

碰撞与地形 ​

控制单位的碰撞和地形交互。

值含义说明
SuppressDynamicCollision忽略动态碰撞不与其他单位发生碰撞(穿透)。
SuppressStaticCollision忽略静态碰撞不与地形障碍物发生碰撞(穿墙)。
IgnoreTerrainHeight忽略地形高度计算中忽略地形高度差。适用于飞行单位等不受地形影响的场景。

其他 ​

值含义说明
Summoned召唤物标记单位为召唤物。可用于过滤或特殊逻辑(如召唤物死亡不计统计)。
Illusion幻象标记单位为幻象。通常承受额外伤害或有特殊交互。
UnobstructedSight无遮挡视野视野范围为圆形,不会被障碍物阻挡(空中视野)。

可扩展性 ​

UnitState 使用 [EnumExtension(Extendable = true)] 标记,游戏项目可以定义新的状态标签:

csharp
[EnumExtension(Extends = typeof(UnitState))]
internal enum ECustomUnitState
{
    Stunned,
    Silenced,
    Rooted,
}
// 生成 → CustomUnitState.Stunned, CustomUnitState.Silenced, ...

扩展 UnitState(而非直接扩展基类 UnitFilterTag)的好处是与现有基础设施无缝集成:

  • 数据编辑器:状态相关的下拉列表自动出现扩展的选项
  • Buff 系统:通过 AddState / RemoveState 直接设置和清除自定义状态
  • 过滤 API:TargetFilter.Pass()、AI ScanFilters、技能 TargetingFilters 直接支持扩展值作为 Required 或 Excluded 条件,零额外代码

详见 EnumExtension 工具。

相关文档 ​