Skip to content

Ped states development guide

in0finite edited this page Feb 27, 2019 · 1 revision

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.

Ped state API:

  • 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

Switching states

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.

State methods

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

}