Possessor
MonoBehaviour component placed on entities that can possess others (players, AI controllers). Manages a list of currently possessed Possessable entities, executes configurable PossessAction hooks, and fires events on possession/release.
Definition
Namespace: Paragon.Townskeep.PossessionSystem
Assembly: Townskeep.dll
public class Possessor : ParagonBehaviourInheritance: SerializedMonoBehaviour → ParagonBehaviour → Possessor
Remarks
Possessor is the "controlling" side of the possession pattern. It maintains a list of all entities currently possessed by this possessor, enabling one possessor to control multiple possessables simultaneously (e.g., a player possessing both a character and a mount).
Possession flow
IPossessor interface
The sibling IPossessor component (e.g., Player) provides the higher-level identity. Possessor.Owner returns the IPossessor, enabling typed queries like possessor.IsPossessing<Character>() which checks the possessable's IPossessable owner type.
Automatic cleanup
On OnDestroy, ReleaseAll() is called to release all current possessions. This prevents dangling references when the possessor GameObject is destroyed.
Quick Lookup
Possess an entity
possessor.Possess(possessable)
Release an entity
possessor.Release(possessable)
Release all possessions
possessor.ReleaseAll()
Check if possessing a specific entity
possessor.IsPossessing(possessable)
Check if possessing a type
possessor.IsPossessing<Character>()
Get a possessed entity by type
possessor.TryGetPossession<Character>(out var c)
Get all possessions
possessor.GetPossessions()
Listen for possession
possessor.Possessed += OnPossessed
Listen for release
possessor.Released += OnReleased
Properties
Owner (internal)
The IPossessor component on the same GameObject. Used internally for typed queries.
Fields
possessAction
Optional PossessAction executed on the possessor's side when possessing. Configured in the Inspector.
releaseAction
Optional PossessAction executed on the possessor's side when releasing. Configured in the Inspector.
Events
Possessed
Fires when this possessor possesses a new entity.
Released
Fires when this possessor releases a possessed entity.
Methods
Awake
Caches the IPossessor component and creates the possessions list.
Possess
Possesses a target entity. Adds it to the possessions list, executes the possessAction, notifies the possessable, and fires the Possessed event.
possessable
Possessable
The entity to possess
Release
Releases a possessed entity. Removes it from the possessions list, executes the releaseAction, notifies the possessable, and fires the Released event.
possessable
Possessable
The entity to release
TryGetPossession<TPossessable>
Finds a possessed entity whose IPossessable owner matches the given type.
Returns: true if a matching possession was found.
IsPossessing (instance)
Returns true if the given Possessable is in the possessions list.
IsPossessing<TPossessable>
Returns true if any possession's IPossessable owner matches the given type.
GetPossessions
Returns all currently possessed entities.
ReleaseAll
Releases all current possessions. Iterates a copy of the list to avoid modification during enumeration.
OnDestroy
Calls ReleaseAll() to clean up all possessions when the possessor is destroyed.
Common Pitfalls
No double-possession guard
Possess() does not check if the possessable is already in the list. Calling Possess() twice with the same possessable will add duplicate entries, causing Release() to only remove one and leaving a stale entry.
IPossessor required on same GameObject
Awake() calls GetComponent<IPossessor>(). If no component implementing IPossessor exists, Owner will be null and typed queries will fail.
Action execution order
Possess() executes the possessAction before calling possessable.OnPossessed(this). This means the possessable is not yet in the "possessed" state when the action runs. Similarly, Release() executes releaseAction before possessable.OnReleased(this).
ReleaseAll iterates a copy
ReleaseAll() calls possessions.ToArray() before iterating to avoid InvalidOperationException from modifying the list during enumeration. This is intentional — each Release() call removes from the original list.
See Also
Possessable — the other half of the possession pattern (the possessed side)
Player — a concrete
IPossessorthat uses this componentPlayerNetwork — networks possession events via RPCs
Last updated