Friday, April 5, 2013

Object and Actor References in UnrealScript

  
Some beginners confuse an object with the variable that references the object. This lack of understanding can cause some errors when writing new UnrealScript codes.

Analyze the code below and think about the values ​​that will be written on the screen.
class TestObjReference extends UTGame;

var int xValue;
var int yValue;
var vector vectorStruct;
var Pawn pawnObj;
     
event PostBeginPlay()
{
  SetTimer(3);    
}

function Timer()
{        
  xValue = 10;
  yValue = 10;
  vectorStruct.X = 10;

          //Get a reference to the Player Pawn
  pawnObj = GetALocalPlayerController().Pawn;     
  pawnObj.health = 10;    
    
  ChangeValues( xValue, yValue, vectorStruct, pawnObj);
    
  Broadcast(self, "xValue =" @ xValue);
  Broadcast(self, "yValue =" @ yValue);
  Broadcast(self, "vectorStruct.X =" @ vectorStruct.X );
  Broadcast(self, "pawnObj.health =" @ pawnObj.health);    
}

function ChangeValues(int x, out int y, vector xVector, Pawn xPawn )
{
  x = 50;
  y = 50;
  xVector.X = 50;
  xPawn.health = 50;    
}

If you want to test this code in UDK just set the Game Type to "TestObjReference". (UDK Menu: View -> WorldProperties -> Game Type)

The primitive variables like "int" and "float" and the structs such as "Vector" and "Rotator" contains the values ​​that are assigned to them. But Objects and Actors variables are just references, so they do not contain the values ​​of objects. The image below represents the use of variables of this code in memory.


When you declare a variable of some class it starts with the value "None". This means that it does not reference any object. You can get a reference to an object or create one using the "New" operator. If the variable references an Actor (or a subclass) you must use the "Spawn" function to create a new object.

In the image above we can see that although the variables "pawnObj" and "xPawn" are different they refer to the same object Player Pawn, whereas the variables "vectorStruct" and "xVector" do not have any kind of relationship.

The variables "xValue" and "x" are independent whereas the variables "yValue" and "y" are related because the variable "y" was declared as "out" in the function ChangeValues().

The image below shows the values ​​that will be written on the screen.


When you declare a variable of a specific class, this variable can also refer the subclasses. However, to access the variables and functions that belong to the subclasses is necessary to "cast" this variable into the desired subclass.

The code below shows a simple example of an Actor variable that references an object of the Pawn class. The cast is necessary to access the "Health" variable that belongs to the Pawn class.
function Timer()
{
  local Actor actorObj;

  actorObj = GetALocalPlayerController().Pawn;     

  Pawn(actorObj).health = 10;    
}