Class RogueAttackingState
Rogue archetype. Melee, but refuses to trade blows face-to-face: it circles into the target's rear arc before opening, and drifts back around whenever the target turns on it.
[CreateAssetMenu(fileName = "New AI Rogue Attacking State", menuName = "FishMMO/Character/NPC/AI/Rogue Attacking State", order = 6)]
public class RogueAttackingState : BaseAttackingState, ICachedObject
- Inheritance
-
ObjectScriptableObjectRogueAttackingState
- 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 is the third archetype that needs code: "behind the target" is a function of the target's facing, which no amount of distance tuning can express.
It degrades gracefully — a rogue that cannot reach the rear arc (cornered target, bad navmesh) still attacks from wherever it is rather than standing there circling forever.
Fields
FlankArcDegrees
Half-angle (degrees) of the arc behind the target that counts as "flanked". 90 means the whole rear hemisphere qualifies.
[Header("Rogue Behavior")]
[Range(15, 180)]
[Tooltip("Half-angle of the rear arc that counts as flanked.")]
public float FlankArcDegrees
Field Value
FlankStandoffDistance
Distance behind the target the rogue aims for when repositioning.
[Tooltip("Distance behind the target to aim for when repositioning.")]
public float FlankStandoffDistance
Field Value
MaxFlankSeconds
How long (seconds) the rogue will keep manoeuvring for a flank before giving up and attacking from wherever it stands. Prevents an infinite circling stalemate.
[Tooltip("Seconds spent trying to flank before attacking from the current position.")]
public float MaxFlankSeconds
Field Value
Methods
Enter(AIController)
Called when entering the attacking state. Sets agent speed to run.
public override void Enter(AIController controller)
Parameters
controllerAIControllerThe AI controller.
IsFlanking(AIController)
True when the rogue is currently inside the target's rear arc.
public bool IsFlanking(AIController controller)
Parameters
controllerAIControllerThe AI controller.
Returns
- bool
True if flanked.
ReevaluateTarget(AIController, float)
Periodically reconsiders the current target.
protected override void ReevaluateTarget(AIController controller, float deltaTime)
Parameters
controllerAIControllerThe AI controller.
deltaTimefloatSeconds elapsed since the previous AI tick.
Remarks
Threat-based NPCs switch when a tracked aggressor exceeds the current target by AggressionSwitchThreshold; a rampaging NPC instead re-rolls onto a random nearby enemy at its personality's retarget chance, which is what makes it impossible to hold with threat.
Candidates come from a fresh detection sweep. The previous implementation scanned
controller.SweepHits directly, but that buffer is only filled by
AIController's out-of-combat sweep, which is skipped for the whole
duration of a fight — so it held stale colliders from before combat started (and
entries past the last hit count from sweeps before that), and could retarget onto
something no longer present.
TryAttack(AIController, ICharacter)
Spends its flank budget circling into the target's rear arc, then fights normally.
protected override void TryAttack(AIController controller, ICharacter targetCharacter)
Parameters
controllerAIControllerThe AI controller.
targetCharacterICharacterThe target character being attacked.