Glad it helped. The example I gave for accessing the hud from the pawn may be a little confusing, because I included all the necessary typecasting and safety checks. Conceptually all it boils down to is:
Code:
// psuedocode from Pawn
Controller.MyHUD.SomeVariable = 100;
Pawn's variable Controller is a reference to a controller object (could be a PlayerController).
PlayerController's variable MyHUD is a reference to the HUD object.
I'll briefly go over types and typecasting...
Types
Every object has a type - it's class - and references to objects must be typed accordingly: just like int, float and bool variables represent integer, floating point numbers and true/false values respectively.
Code:
var Pawn MyPawn; // MyPawn is a variable of type Pawn; a reference to a Pawn object
I explained a little about inheritance and polymorphism, and the notion that objects of a subclass can also be typed as their base class. The Siamese being a Cat in the example. This is also true of references.
Code:
// assuming the class Siamese extends from Cat, and Cat extends from Actor...
var Siamese MySiameseCat; // reference to a Siamese object
var Cat MyCat; // ... to a Cat object
var Actor MyGenericActor; // ... to an Actor object
........
MySiameseCat = Spawn(class'Siamese'); // Spawn the breed of cat and assign it
MyCat = MySiameseCat; // this also works, because Siamese is a Cat
MyGenericActor = MySiameseCat; // and so will this, since Cat derives from Actor; Siamese are Cats and Actors
However, a reference has scope. Scope is limited to the type (class). In the above, MyCat can point to a Siamese cat, but you cannot use it to access the properties and methods of Siamese because the Cat class has no idea what a siamese is. All it knows about are cats and actors. The same is true for MyGenericActor, whose scope is limited to Actors (and whatever else actor classes inherit).
Importantly, the reference still points to a Siamese object. It's just that the usefulness of the MyCat and MyGenericActor references are limited in context.
Typecasting
Is the conversion of a reference of one type to another type. For the cast to succeed the types must be related. Unrelated casts fail by producing a reference of None.
Code:
MySiamese = Siamese(MyCat); // cast the MyCat reference back to a Siamese
MySiamese = Siamese(MyGenericActor); // and again, for MyGenericActor;
// suppose we have another breed of cat...
MyPersian = Spawn(class'Persian');
MyCat = MyPersian; // yes, persians are cats
MySiamese = Siamese(MyCat);
// FAIL - siamese are cats, but MyCat is pointing to a Persian
// Persians are cats too, but Persian is an unrelated class to Siamese
Throughout UDK you'll see the same thing happening, with checks and balances for None results. These checks have two purposes. They ensure that a reference points to something, because it's always possible the reference is None to begin with. And they also ensure that the object is relevant to the context in which you want to use it.
A perfect example of this is the Controller variable in Pawn. There are two main types of controller, PlayerController and AIController. By having a reference to the more generic base class Controller the pawn solves the problem of complexity by using a single property regardless of which it is. So is it a player or an AI? Cast it and see...
Code:
if( PlayerController(Controller) != None )
{
// pawn is being controller by a player
}
One thing to note, UDK has a habit of using conflicting names. That variable Controller is of type Controller. The compiler considers this legal and it works fine - but it is really confusing at first, and to be honest it's bad practice and should be avoided.
Bookmarks