Class DefenderAttackingState
Defender / tank archetype. Fights in melee, keeps its taunts on cooldown to hold threat, and physically interposes itself between the enemy and whoever it is protecting.
[CreateAssetMenu(fileName = "New AI Defender Attacking State", menuName = "FishMMO/Character/NPC/AI/Defender Attacking State", order = 5)]
public class DefenderAttackingState : BaseAttackingState, ICachedObject
- Inheritance
-
ObjectScriptableObjectDefenderAttackingState
- Implements
- Inherited Members
-
ScriptableObject.SetDirty()ScriptableObject.CreateInstance<T>()Object.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.ToString()Object.nameObject.hideFlags
Remarks
This needs code rather than tuning for two reasons: taunts have to be prioritised over raw damage regardless of what the scoring picker thinks, and body-blocking means walking to a position derived from a third character rather than from the target.
As a pet this is the "defender" stance made concrete — the pet plants itself between its owner and whatever is trying to reach them.
Fields
BlockRepositionTolerance
The defender only bothers repositioning when it is further than this from its ideal blocking spot. Prevents jitter.
[Tooltip("Only reposition when further than this from the ideal blocking spot.")]
public float BlockRepositionTolerance
Field Value
BlockStandoffDistance
How far in front of the protected character the defender plants itself, in world units.
[Tooltip("Distance in front of the protected character to hold the line.")]
public float BlockStandoffDistance
Field Value
BodyBlock
When true the defender positions itself on the line between the enemy and the character it is protecting, rather than simply closing on the enemy.
[Tooltip("Stand between the enemy and the protected character.")]
public bool BodyBlock
Field Value
TauntAbilityTemplateIDs
Optional escape hatch: template IDs to treat as taunts in addition to whatever AIAbilityClassifier identifies.
[Header("Defender Behavior")]
[Tooltip("Optional. Extra AbilityTemplate IDs to force-treat as taunts. Normally empty — taunts are detected from the ability's ECA actions.")]
public List<int> TauntAbilityTemplateIDs
Field Value
Remarks
Normally empty. A taunt is recognised by the threat-manipulating action in its own ECA graph — ApplyTauntAction or ApplyThreatAction — so a defender asset works for any creature whose spellbook contains one, and picks up a taunt added later without being edited.
Methods
Enter(AIController)
Called when entering the attacking state. Sets agent speed to run.
public override void Enter(AIController controller)
Parameters
controllerAIControllerThe AI controller.
ExecutePlan(AIController, IAbilityController, ICharacter, AICombatPlan, in AICombatContext, Ability)
Holds the line in front of the protected character instead of simply walking at the enemy, when body-blocking is enabled and there is somebody to protect.
protected override void ExecutePlan(AIController controller, IAbilityController abilityController, ICharacter targetCharacter, AICombatPlan plan, in AICombatContext context, Ability chosenAbility)
Parameters
controllerAIControllerThe AI controller.
abilityControllerIAbilityControllerThe NPC's ability controller.
targetCharacterICharacterThe target character.
planAICombatPlanThe decision to execute.
contextAICombatContextThe context the decision was made from.
chosenAbilityAbilityThe ability the picker returned, or null.
PickAbility(AIController)
Prefers an available taunt over anything else, then falls back to the normal picker.
protected override Ability PickAbility(AIController controller)
Parameters
controllerAIControllerThe AI controller.
Returns
- Ability
The chosen ability, or null.
ResolveProtectedTransform(AIController)
Resolves who this defender is protecting: a pet protects its owner, a grouped NPC protects the group's most wounded member.
protected virtual Transform ResolveProtectedTransform(AIController controller)
Parameters
controllerAIControllerThe AI controller.
Returns
- Transform
The protected character's transform, or null when there is nobody to protect.