Summary
Various extension methods for
Animancer.FSM.IState
and Animancer.FSM.IOwnedState`1
.- Assembly
- Animancer
.dll - Namespace
- Animancer
.FSM - Base Types
-
- Object
graph BT
Type-->Base0["Object"]
Type["StateExtensions"]
class Type type-node
Syntax
[HelpURL(APIDocumentationURL + nameof(StateExtensions))]
public static class StateExtensions
Examples
public class Character : MonoBehaviour
{
public StateMachine<CharacterState> StateMachine { get; private set; }
}
public class CharacterState : StateBehaviour, IOwnedState<CharacterState>
{
[SerializeField]
private Character _Character;
public Character Character => _Character;
public StateMachine<CharacterState> OwnerStateMachine => _Character.StateMachine;
}
public class CharacterBrain : MonoBehaviour
{
[SerializeField] private Character _Character;
[SerializeField] private CharacterState _Jump;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
// Normally you would need to refer to both the state machine and the state:
_Character.StateMachine.TrySetState(_Jump);
// But since CharacterState implements IOwnedState you can use these extension methods:
_Jump.TryEnterState();
}
}
}
Inherited Types
Unfortunately, if the field type is not the same as theT
in the IOwnedState<T>
implementation then attempting to use these extension methods without specifying the generic argument will
give the following error:
The type 'StateType' cannot be used as type parameter 'TState' in the generic type or method
'StateExtensions.TryEnterState<TState>(TState)'. There is no implicit reference conversion from
'StateType' to 'Animancer.FSM.IOwnedState<StateType>'.
For example, you might want to access members of a derived state class like this SetTarget
method:
public class AttackState : CharacterState
{
public void SetTarget(Transform target) { }
}
public class CharacterBrain : MonoBehaviour
{
[SerializeField] private AttackState _Attack;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
_Attack.SetTarget(...)
// Can't do _Attack.TryEnterState();
_Attack.TryEnterState<CharacterState>();
}
}
}
Unlike the _Jump
example, the _Attack
field is an AttackState
rather than the base
CharacterState
so we can call _Attack.SetTarget(...)
but that causes problems with these extension
methods.
Calling the method without specifying its generic argument automatically uses the variable's type as the
argument so both of the following calls do the same thing:
_Attack.TryEnterState();
_Attack.TryEnterState<AttackState>();
The problem is that AttackState
inherits the implementation of IOwnedState
from the base
CharacterState
class. But since that implementation is IOwnedState<CharacterState>
, rather
than IOwnedState<AttackState>
that means TryEnterState<AttackState>
does not satisfy
that method's generic constraints: where TState : class, IOwnedState<TState>
That is why you simply need to specify the base class which implements IOwnedState
as the generic
argument to prevent it from inferring the wrong type:
_Attack.TryEnterState<CharacterState>();
Remarks
Documentation:
Finite State Machines
Attributes
Type | Description |
---|---|
HelpURLAttribute |
Fields
Name | Constant Value | Summary |
---|---|---|
APIDocumentationURL | https://kybernetik.com.au/animancer/api/Animancer.FSM/ |
The URL of the API documentation for the
Animancer.FSM system.static
|
Methods
Name | Value | Summary |
---|---|---|
ForceEnterState |
void |
[Animancer Extension]
Calls
Animancer.FSM.IState.OnExitState on the Animancer.FSM.StateMachine`1.CurrentState then
changes to the specified `state` and calls Animancer.FSM.IState.OnEnterState on it.
This method does not check Animancer.FSM.IState.CanExitState or
Animancer.FSM.IState.CanEnterState . To do that, you should use TrySetState instead.
static
|
GetNextState |
TState |
[Animancer Extension] Returns the
Animancer.FSM.StateChange`1.NextState .static
|
GetPreviousState |
TState |
[Animancer Extension] Returns the
Animancer.FSM.StateChange`1.PreviousState .static
|
IsCurrentState |
bool |
[Animancer Extension]
Checks if the specified `state` is the
Animancer.FSM.StateMachine`1.CurrentState in its
Animancer.FSM.IOwnedState`1.OwnerStateMachine .
static
|
TryEnterState |
bool |
[Animancer Extension]
Attempts to enter the specified `state` and returns true if successful.
This method returns true immediately if the specified `state` is already the
Animancer.FSM.StateMachine`1.CurrentState . To allow directly re-entering the same state, use
Animancer.FSM.StateExtensions.TryReEnterState``1(``0) instead.
static
|
TryReEnterState |
bool |
[Animancer Extension]
Attempts to enter the specified `state` and returns true if successful.
This method does not check if the `state` is already the
Animancer.FSM.StateMachine`1.CurrentState .
To do so, use Animancer.FSM.StateExtensions.TryEnterState``1(``0) instead.
static
|