Lithtech 2.1 Cobalt
2 posts • Page 1 of 1
The KeyFramer is used to move WorldObjects along a given path.
This is done by giving the KeyFramer the names of the Object that shall be moved and setting up Keys that define the path.
We will start with the situation shown in the picture. The gridsize is 64. The big square is the floor (seal the whole thing with a big box), the red thingie is the GameStartPoint, the white one a Light.
Now on to the brush that we actually want to move. It's a simple arrow-like thing, consisting of a rectangle and a triangle (Height:64px). Both are floating 64px above the ground.
Place the cursor as shown in the picture (Grid is now 32) an create a WorldModel that we can move (just use a Door), and call it 'arrow'.
After you have done this, go to the Nodes View and drag and drop the two brushes into that WorldModel.
Now at the same position as the WorldModel 'arrow' create a KeyFramer and call it 'arrowmover'. Under it's properties tab set the following:
StartActive to 'True', so we don't have to trigger it to start.
Looping to 'True'.
ObjectName is 'arrow', the object we want to move.
BaseKeyName is 'arrowpath', the BaseName of the Keys that describe the path.
At last we create the Keys. Make your KeyFramer 'arrowmover' as active Node in the NodeTree and add the first Key (same place as KeyFramer itself) called 'arrowpath0'. The next Key is called 'arrowpath01', followed by 'arrowpath02' and 'arrowpath03'.
Right-klick the KeyFramer 'arrowpath' and choose 'Set Path', this will cause DEdit to visualize the path
Under the Keys properties set their TimeStamps (the time needed for the Object to move to this Key from the Key before): '0' for 'arrowpath0', '3' for 'arrowpath01', '1' for 'arrowpath02' and '3' for 'arrowpath03'.
Let's process the thing now and have a look at it. As you can see, that's not exactly what we wanted, as the arrow should point at the direction it moves. For this we have to set the Rotation of the Keys correct. So let's set the following rotation parameters: '90' for 'arrowpath0, '135' for 'arrowpath01', '180' for 'arrowpath02' and '180' for 'arrowpath03'. Run again.
That was better, although not perfect. But it will do it for now, because I actually did not figure out yet how to get a really smooth curve. I thought the Bezier thingies should do it, but I didn't got them to work...
Next thing we want to try is to have the arrow point at some Object while traveling down it's path. I first thought the KeyFramer's or WorldObjects Rotation would set the forward facing vector of the Object, but it seems 'forward' in this case is always '+z', means 'up' in Top View. Correct me if I'm wrong.
So put an object somewhere (a brush bound to a Door), call it 'pointhere' and rotate the 'arrow' (remember to use the right rotation center) +90 degrees - so that it's aligned with the vector. After that go to the KeyFramer's properties and write 'pointhere' in theTargetName field.
Last thing we want to do is have the arrow cast shadows as it travels. You can't do that with a normal light, so go to the light's properties and change it's class type to 'KeyFramerLight'.
Then under the KeyFramer's properties set Lightning to the name of the light (if you left it's default it should be 'Light0').
In the properties of the 'arrow' change BlockLight to 'True'.
This should work already (remember to turn on 'Shadows' and 'Light Animations' when processing), but to make it look better you can set UseShadowMaps in the KeyFramerLight's properties to false, and give every Key more LightFrames.
Note: There seems to be a problem with the KeyFramerLight, which causes it not to work after saving and reloading in a level. You should therefor only use it for cutscenes. Maybe I did something wrong, so if you know what: Please tell me.
The properties of the KeyFramer are:
Pos: The absolute position of the KeyFramer object.
Rotation: The rotation of the KeyFramer object.
ObjectName: This field holds the name of the object that shall be moved.
BaseKeyName: Holds the BaseName of the Keys that make up the path. Keys are named BaseName0, BaseName01, BaseName02, BaseName03 and so on.
PushObjects: If set to 'True' the KeyFramer (i.e. the Object that is moved) will push objects in it's path. You need to set this if you want to create keyframed moving platforms the player can stand on.
StartActive: The KeyFramer will start active instead of a waiting for a trigger message.
StartPaused: The KeyFramer will start in pause mode.
Lopping: The KeyFramer will restart at the first Key after it reached the last one.
AlignToPath: Not quite sure.
IgnoreOffsets: The KeyFramer object will acquire the absolute position of the Keys that make up the path, instead of trying to 'smooth' the movement.
TargetName: The KeyFramer will try to keep his forward facing vector pointing to this object.
TargetOffset: Here you can enter an Offset to the TargetObject given above.
ActiveSound: The sound that is played constantly while the KeyFramer is moving.
SoundRadius: The area in which this sound can be heard.
RotationWave: Not supported.
TotalPathTime: This setting overrides the TimeStamps of the Keys. It will take the KeyFramer this amount of time to get from the first Key to the last.
Linear: The speed of the movement is linear.
Sine: The KeyFramer will accelerate at the start and decelerate at the end.
SlowOff: The KeyFramer will only decelerate at the end.
SlowOn: The KeyFramer will only accelerate at the start.
Lightning: Here you can enter the name(s) of KeyFramerLight(s) for animated shadows.
The properties of the Key are:
Pos: The absolute position of the Key object.
Rotation: The rotation of the Key object sets the direction of the forward facing vector of the KeyFramer when it reaches this Key.
TimeStamp: The time it takes the KeyFramer to get to this Key from the one before (if not overridden by TotalPathTime).
SoundName: A sound file that will be played when the KeyFramer reaches this point.
SoundRadius: The area in which this sound can be heard.
MessageTarget: A message can be sent to the desired target when the KeyFramer reaches this Key.
MessageName: The message that will be sent.
BPrintMessage: Not supported.
BezierPrev: Not sure.
BezierNext: Not sure.
LightFrames: Sets how many LightFrames are used for this Key if animated lightning is used.
This tutorial describes how to create an elevator using the KeyFramer. It's a good practise in message sending and controlling a KeyFramer.
An elevator created by using the door objects internal moving abilities has the basic disadvantage of beeing limited to two floors, because the door has only two states: open and closed. So using the KeyFramer with it's virtually unlimited amout of Keys is a better, although a little tricky solution (well, as far as I know). But I guess after one practised this a bit, it's actually a more elegant solution - and a good practise in using the KeyFramer itself.
MOVING THE CABIN
The movement itself is very basic stuff. The Elevator cabin itself consists of a few brushes setting up a box, bound to a Door object. Set all the State Flags to 'false', so the Door won't work as a door in any way. Now set the IsKeyframed flag to 'true'. I suggest aligning the Door Object to the top of the cabin floor.
Now place a KeyFramer somewhere and set it up to move the cabin (Door). I already described on how to set up a KeyFramer to move an object (ObjectName,BaseKeyName and setting up Keys) in the KeyFramer tutorial.
Set the first two Keys (key0 and key01) at the same position as the cabin, i.e. Door object. Due to the fact that the first Key is aligned with the Door object (and the cabin floor) you can place the rest of the Keys exactly at ground height of the other floors in your building, setting up a straight vertical path (for a normal elevator that is - you can have it move around any way you want). Also place another Key after the last one at your last stop point (at same position if you want). Why we need the additional first and last Key will be explained later.
At last set PushObjects and StartActive to 'true'. PushObjects is needed because the cabin should move the player, StartActive is explained later.
Set the timestamps of the Keys to your desire (how long it takes to get from one floor to the next).
Now you have the basics together. The KeyFramer, i.e. the cabin can be moved to every floor (no matter where it currently is) by sending it a 'moveto keyx' message. They cabin stops there and waits for the next 'moveto' command.
THE PROBLEMS WITH MOVING
There are two problems I came across:
First the KeyFramer won't react to the moveto command if doesn't start active, even starting paused and sending a 'resume' message didn't work for some reasons. As workaround I suggest simple having it start active and placing a trigger at PlayerStart which directly sends a 'moveto' message to send the cabin to the floor (Key) it should start on.
Second the KeyFramer refuses to react to the moveto command any more if it (at any time) reaches the first or last Key of the path. That's why we added the two extra Keys: They should never be used!
In both cases I would be really happy if someone proves me wrong...
I will continue this later (i.e. how to set up the triggers, adding doors and stuff)...
(Reposted here for availability)