Friday, October 5, 2012

Cookbook: Utilizing UDK states

State mechanics in UDK is very useful and makes it easier to organize the code into more readable form and have multiple behaviors ready and running at different times (states). Let's say you want to have your custom camera, that is by default sidescroller 3rd person and can be switched to overhead camera with a key input. Additionally you have a pause mode in your game, where it only slowly rotates around player character...

It's all easy to achieve with state machine in UDK. Let's see some basic syntax:


   1:  //switches given Object into new state
   2:  function GotoState (optional name NewState, ...)
   3:   
   4:  //////////////////////////////////////////////////////////////////////////
   5:  //state basic example
   6:  state ExploreLevel
   7:  {
   8:      //these functions are not processed in this state!
   9:      ignores SeePlayer, HearNoise, Bump, ...; 
  10:      
  11:      //this function has overriden behaviour in this state
  12:      function PlayerMove( float DeltaTime )
  13:      {
  14:          if (explorationKeyPressed)
  15:          {
  16:             BallPuzzlerCamera(PlayerCamera).Explore(DeltaTime);
  17:          else 
  18:          {
  19:             //no key pressed, use the global version of method!
  20:             global.PlayerMove(DeltaTime);
  21:          }
  22:      }
  23:      
  24:      Begin: //do something immediately after switching to this state!
  25:       BallPuzzlerCamera(PlayerCamera).SetBallActor(Ball);
  26:  }

Inside state code, you can utilize these useful keywords:

  • ignores - given methods are not processed while in this state
  • global.FunctionName -  calls default version of method
  • Begin: - called immediately after switching to this state (you can init some data)

Let's get back to our example. Some simple skeleton of what we want to achieve may look like this:


   1:  class BallPuzzlerCamera extends Camera;
   2:   
   3:  ...
   4:   
   5:  //state where we act as 3rd person sidescroller camera
   6:  state SideScroller
   7:  {
   8:    function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
   9:    {
  10:      //sidescroller specific behavior
  11:    }
  12:  }
  13:   
  14:  //state where we place camera overhead
  15:  state Overhead
  16:  {
  17:    function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
  18:    {
  19:      //overhead specific behavior
  20:    }
  21:  }
  22:   
  23:  //state where camera is rotation around level
  24:  state ExploreLevel
  25:  {
  26:      function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
  27:      {
  28:          //level exploration behavior (rotate around level)
  29:      }
  30:   
  31:      Begin: //some init
  32:          ResetExploration();
  33:  }
  34:   
  35:  /////////////////////////////////////////////////////////////
  36:  //+ in controller class:
  37:  /////////////////////////////////////////////////////////////
  38:  enum E_CameraMode 
  39:  {
  40:      E_CM_Sidescroller,
  41:      E_CM_Overhead,
  42:      E_CM_Exploration
  43:  };
  44:   
  45:  var byte CurrentCameraMode;
  46:   
  47:  exec function ToggleCameraMode() //change camera mode with key binding
  48:  {
  49:     switch (CurrentCameraMode) //move to next state!
  50:     {
  51:        case E_CM_Sidescroller:
  52:           BallPuzzlerCamera(PlayerCamera).GotoState('Overhead'); break;
  53:        case E_CM_Overhead:
  54:           BallPuzzlerCamera(PlayerCamera).GotoState('ExploreLevel'); break;
  55:        case E_CM_Exploration:
  56:           BallPuzzlerCamera(PlayerCamera).GotoState('SideScroller'); break;
  57:     }
  58:   
  59:     //move variable to next state
  60:     CurrentCameraMode = 
  61:        CurrentCameraMode >= E_CM_Exploration ?
  62:        E_CM_Sidescroller : CurrentCameraMode + 1;
  63:  }

No comments:

Post a Comment