Even unrealscript enables you to utilize inheritance and class hierarchy of your custom classes. So it is a good idea to design your actors/object in a way, that as much of the shared functionality and variables are in parental classes (to avoid copying the same code over and over) and be able to access that basic functionality after typecasting to a parent class (for example useful for storing all differing actors with same parent in one array and accessing them by their parent class...
Let me show you all of this in an example:
Let's say we need a couple of types of platforms, one that turns on some lights, one that opens doors, one that gives player some points. What they have in common is a mesh and slight movement upon touch (to emulate being used). Additionally there is a class that stores a set of references to such platforms and handles global resetting, changing of states, etc.
All the common functionality goes into some PlatformBase.uc:
1: class PlatformBase extends Actor
2: placeable;
3:
4: //our mesh
5: var (StaticMesh) StaticMeshComponent StaticMesh;
6:
7: /** movement offset from base position */
8: var(Game) vector vMoveOffset;
9:
10: //========================================================================
11: function TriggerAction()
12: {
13: //move
14: SetLocation(Location + vMoveOffset);
15: }
16:
17: //========================================================================
18: simulated event Reset()
19: {
20: //reset
21: SetLocation(OrigLocation);
22: super.Reset();
23: }
In the inherited classes you only need to add additional functionality, all the functionality of parental class is intact and can be used:
PlatformPoints.uc:
1: class PlatformPoints extends PlatformBase
2: placeable;
3:
4: //========================================================================
5: function TriggerAction()
6: {
7: super.TriggerAction(); //call parent method (move platform)
8:
9: PlayerController.AddPoints(100); //add some points
10: }
PlatformLight.uc:
1: class PlatformLight extends PlatformBase
2: placeable;
3:
4: var(Light) const LightComponent Light;
5:
6: //========================================================================
7: function TriggerAction()
8: {
9: super.TriggerAction(); //call parent method (move platform)
10:
11: Light.SetEnabled(true); //enable referenced light
12: }
13:
14: //========================================================================
15: simulated event Reset()
16: {
17: super.Reset(); //call parent method
18:
19: Light.SetEnabled(false); //reset light state
20: }
PlatformDoor.uc:
1: class PlatformDoor extends PlatformBase
2: placeable;
3:
4: //========================================================================
5: function TriggerAction()
6: {
7: super.TriggerAction(); //call parent method (move platform)
8:
9: //trigger event with myself as instigator
10: TriggerEventClass(class'SeqEvent_DoorOpen', self);
11: }
12:
13: //========================================================================
14: simulated event Reset()
15: {
16: super.Reset(); //call parent method
17:
18: //trigger event with myself as instigator
19: TriggerEventClass(class'SeqEvent_DoorClose', self);
20: }
The handler class than collects references to all platforms by their parental class and can access all the basic functionality or typecast it to inherited class to use additional functionality. And remember accessing basic functionality of class referenced by its parental class actually calls the overriden method of actual class!
1: class PlatformHandler extends Actor;
2:
3: //references to all platforms
4: var array<PlatformBase> Platforms;
5:
6: //========================================================================
7: event PostBeginPlay()
8: {
9: local PlatformBase platform;
10:
11: //iterate over all actors with exact or parental class of PlatformBase
12: foreach WorldInfo.DynamicActors(class'PlatformBase', platform)
13: {
14: Platforms.AddItem(platform); //store reference
15: }
16: }
17:
18: //========================================================================
19: function ResetActors()
20: {
21: local PlatformBase platform;
22: local PlatformDoor door;
23:
24: //reset all platforms
25: foreach Platforms(platform)
26: {
27: //call the reset
28: //(this will call actual reset of real platform class type!)
29: platform.Reset();
30:
31: //you can even typecast to some inherited type
32: door = (PlatformDoor)platform;
33:
34: if (door != none) //success, this one is really platformDoor
35: {
36: //call method unique for PlatformDoor!
37: door.StringToHUD("door opening!");
38: }
39: }
40: }