Class AICombatPersonality
Data-driven combat personality asset that makes two NPCs with the same ability set behave differently in combat. Assign to Personality.
The personality provides per-AbilityCategory score multipliers that PickBestAbility(float) applies on top of the default scoring. Two warriors sharing the same ability list but with different personalities will favour different abilities and positioning.
Range thresholds control how abilities are classified. Abilities whose Range falls below MeleeRangeThreshold are considered melee; those above are ranged. Abilities with HitCount greater than 1 or grounded spawn targets are classified as AOE. Self-targeted abilities are classified as Support.
[CreateAssetMenu(fileName = "New Combat Personality", menuName = "FishMMO/Character/NPC/AI/Combat Personality", order = 10)]
public class AICombatPersonality : ScriptableObject
- Inheritance
-
ObjectScriptableObjectAICombatPersonality
- 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
Fields
AOEHitCountThreshold
[Tooltip("Abilities with HitCount > this value are considered AOE (multi-target).")]
public int AOEHitCountThreshold
Field Value
AOEWeight
[Tooltip("Score multiplier for AOE-classified abilities.")]
[Range(0, 5)]
public float AOEWeight
Field Value
BuffWeight
[Tooltip("Score multiplier for abilities that strengthen a friend.")]
[Range(0, 5)]
public float BuffWeight
Field Value
ControlWeight
[Tooltip("Score multiplier for abilities that stun, root, freeze, interrupt or knock back.")]
[Range(0, 5)]
public float ControlWeight
Field Value
DamageWeight
[Header("Ability Intent Weights")]
[Tooltip("Score multiplier for abilities that deal damage.")]
[Range(0, 5)]
public float DamageWeight
Field Value
DebuffWeight
[Tooltip("Score multiplier for abilities that weaken a target.")]
[Range(0, 5)]
public float DebuffWeight
Field Value
HealWeight
[Tooltip("Score multiplier for abilities that restore health.")]
[Range(0, 5)]
public float HealWeight
Field Value
HealthyAggressionBonus
[Tooltip("Bonus score added to abilities when health is above retreat threshold. Encourages aggressive play while healthy.")]
public float HealthyAggressionBonus
Field Value
LowHealthSupportBonus
[Tooltip("Bonus score added to support/self-buff abilities when health is below retreat threshold. Encourages defensive play when hurt.")]
public float LowHealthSupportBonus
Field Value
MeleeRangeThreshold
[Header("Classification Thresholds")]
[Tooltip("Abilities with range <= this value are considered melee. Above this = ranged.")]
public float MeleeRangeThreshold
Field Value
MeleeWeight
[Header("Ability Category Weights")]
[Tooltip("Score multiplier for melee-classified abilities. >1 = prefer, <1 = avoid.")]
[Range(0, 5)]
public float MeleeWeight
Field Value
PATHETIC_DEFAULT_RETREAT_THRESHOLD
Fallback retreat threshold applied to a Pathetic personality whose RetreatHealthThreshold was left at zero.
public const float PATHETIC_DEFAULT_RETREAT_THRESHOLD = 0.5
Field Value
Remarks
A "pathetic" archetype that silently never flees because a serialized field defaulted to 0 is the exact failure this guards against: the style is the designer's stated intent, so it wins over an unset number rather than being quietly ignored.
RampageRetargetChance
[Tooltip("Chance (0-1) a Rampaging NPC switches to a new random enemy on each re-evaluation.")]
[Range(0, 1)]
public float RampageRetargetChance
Field Value
RangedWeight
[Tooltip("Score multiplier for ranged-classified abilities.")]
[Range(0, 5)]
public float RangedWeight
Field Value
RetreatHealthThreshold
[Header("Combat Behavior")]
[Tooltip("Health percentage (0-1) at which this NPC considers retreating. Berserker, Determined and Rampaging styles ignore this. 0 = never retreat.")]
[Range(0, 1)]
public float RetreatHealthThreshold
Field Value
Style
[Header("Style")]
[Tooltip("The broad combat archetype. Affects retreat threshold behaviour.")]
public NPCCombatStyle Style
Field Value
SupportWeight
[Tooltip("Score multiplier for support/self-buff abilities.")]
[Range(0, 5)]
public float SupportWeight
Field Value
Targeting
[Header("Targeting")]
[Tooltip("How this NPC chooses between available enemies. Rampaging style forces Random.")]
public AITargetingMode Targeting
Field Value
ThreatWeight
[Tooltip("Score multiplier for taunts and other threat manipulation.")]
[Range(0, 5)]
public float ThreatWeight
Field Value
Properties
EffectiveRetargetChance
Chance this NPC abandons its current target for a fresh random one on each mid-combat re-evaluation. Non-zero only for Rampaging.
public float EffectiveRetargetChance { get; }
Property Value
EffectiveRetreatHealthThreshold
The retreat threshold actually used at runtime, after style overrides. Returns 0 for fearless styles, and the Pathetic fallback for a Pathetic personality left unconfigured.
public float EffectiveRetreatHealthThreshold { get; }
Property Value
IsFearless
True when this style is constitutionally incapable of fleeing, whatever RetreatHealthThreshold says.
public bool IsFearless { get; }
Property Value
TargetingMode
The targeting mode actually used at runtime, after style overrides. Rampaging always targets randomly — that unfocused re-targeting is what the style means.
public AITargetingMode TargetingMode { get; }
Property Value
Methods
ClassifyAbility(Ability)
Classifies an ability into a AbilityCategory based on its template data. Uses range, spawn target, hit count, and ability type to infer the category.
public AbilityCategory ClassifyAbility(Ability ability)
Parameters
abilityAbilityThe ability instance to classify.
Returns
- AbilityCategory
The inferred category for personality scoring.
GetBonusScore(Ability, float)
Computes a personality-aware bonus score for the given ability, factoring in the NPC's current health and combat style.
public float GetBonusScore(Ability ability, float healthPercent)
Parameters
abilityAbilityThe ability being scored.
healthPercentfloatCurrent health as a fraction (0-1). Pass 1 if unknown.
Returns
- float
An additive bonus to the ability's base score.
GetCategoryWeight(Ability)
Returns the multiplier for how an ability is delivered — melee, ranged, area, or self.
public float GetCategoryWeight(Ability ability)
Parameters
abilityAbilityThe ability being scored.
Returns
- float
The category multiplier.
GetIntentWeight(Ability)
Returns the multiplier for what an ability does, derived from its ECA actions.
public float GetIntentWeight(Ability ability)
Parameters
abilityAbilityThe ability being scored.
Returns
- float
The intent multiplier, or 1 for an ability with no recognised intent.
Remarks
The strongest matching weight, not the product of all of them. Abilities routinely carry several intents — a nuke that also applies a burn is Damage and Debuff — and multiplying would let a merely-compound ability out-score a genuinely specialised one purely for having more flags set.
GetWeight(Ability)
Returns a score multiplier for the given ability, combining how it is delivered with what it does.
public float GetWeight(Ability ability)
Parameters
abilityAbilityThe ability being scored.
Returns
- float
A multiplier (typically 0.1–5.0) to apply to the ability's base score.
Remarks
Called by PickScoredAbility(float, Func<Ability, bool>, float) to bias ability selection. The delivery weight and the intent weight multiply: an archer personality that favours ranged delivery and a caster personality that favours control can share an ability list and still reach for different things in it.
ShouldRetreat(float)
Returns true if this personality's style allows retreating, and the NPC's health has dropped to or below its EffectiveRetreatHealthThreshold.
public bool ShouldRetreat(float healthPercent)
Parameters
healthPercentfloatCurrent health as a fraction (0-1).
Returns
- bool
True if the NPC should break off and flee.