-
Notifications
You must be signed in to change notification settings - Fork 369
Ped states development guide
Ped behaviour is controlled by states. States respond to various game events, control the ped, and switch to other states when they find it appropriate.
All ped states should inherit BaseScriptState class, and should be attached to ped's game object.
-
GetState<T>()
- Gets state of type T -
GetStateOrLogError<T>()
- Gets state of type T, and logs error if there is no such state -
SwitchState<T>()
- Switches current state to state of type T
For switching state, use Ped.SwitchState()
. If target state needs parameters before switching to it, you can pass them like this:
ped.GetState<TargetState>().EnterState(param1, param2);
Of course, target state needs to have EnterState()
method. If your state needs to meet some conditions before switching to, create a method CanEnterState(param)
. Then, call it before switching to state:
if (ped.GetState<TargetState>().CanEnterState(param))
ped.GetState<TargetState>().EnterState(param);
else
// switch to other state
ped.SwitchState<OtherState>();
Note that any script can forcefully change the state, so your states need to be prepared for that.
BaseScriptState contains many methods that you can override. Let's take a look at those that are most important.
- OnBecameActive()
Called immediately after switching state. Use this method to initialize the state, or, for example, to play animation related to this state.
Don't do complex game logic here, because this method call is nested in other game logic code. Although you can switch to another state from here, it is not recommended. It's better to do it from one of Update() methods.
- OnBecameInactive()
Called immediately after your state becomes inactive. Use this method to cleanup after yourself. Don't try to switch state from here, or to do anything that will result in switching state, because state machine will reject it.
- Update methods
As the name says, these methods are called from corresponding Update methods in Ped class. Use it to update your state. For example, you can read current input and based on it, perform some actions or switch to another state.
Always make sure to call overriden method from base class, and to check if your state is still active:
public override void UpdateState()
{
base.UpdateState ();
if (!this.IsActiveState) // state was changed in the meantime
return;
// do your stuff here
}
- Button events
There are various button events that you can detect. For these callbacks, you mostly don't need to call base method:
public override void OnJumpPressed()
{
// jump was pressed, switch to other state
m_ped.SwitchState<SpidermanState>();
}
- Animation updating
Use UpdateAnims()
for animation updating. Here's how you can do it for simple states that only need to play single animation, and then switch to other state when animation is finished:
AnimationState m_animState;
public override void OnBecameActive()
{
base.OnBecameActive();
m_animState = m_model.PlayAnim(myAnim); // play anim
m_animState.wrapMode = WrapMode.Once; // stop anim when it reaches end
}
protected override void UpdateAnims()
{
if(!m_animState.enabled) // animation finished playing
m_ped.SwitchState<OtherState>(); // switch to other state
}
- Unity messages
Because state classes inherit MonoBehaviour, you can also use Unity messages. But make sure that you call overriden methods from base class, like this:
protected override void Awake()
{
base.Awake ();
// do your initialization here
}