Generic Object Movement Script

by snYpir

What this script is

This script allows you to move any object in the game through 'waypoints' which you set in the editor. This includes camera objects, allowing you to do scripted cutscenes without relying so heavily on raw X,Y,Z coordinates.

I suggest you download the example mission (at bottom of page) right now if you are unclear on what I am talking about.

This script is 'generic' in that any object with a name can be moved. The movement is done via a loop and a setpos command. You can specify the speed at which the object moves, as many waypoints as you wish, the pause at each quasi-waypoint, and the target to lock the camera on if you are moving a camera object.

How to use

At this point in time I expect you to have opened up the example mission in the mission editor and checked it all out. You can see that there are two groups of game logic units, a couple of triggers and the player's start position.

Moving a normal object

Lets look at the top group first. Don't be afraid of the game logic units - they are just what I have used as 'waypoints'. I am going to move that helicopter (chopper) through wp1, wp2, wp3, wp4 then w5. If you have a look at wp5 you'll see I have set the game logic unit to be 50m up in the air at the start. I have also set 'special' to 'none' for all of the game logic units. There is nothing special about the helicopter, it's just named 'chopper'. There is a trigger set to activate on radio alpha with the following command:

[chopper,[wp1,wp2,wp3,wp4,wp5],1,0,false] exec "move.sqs";

I'll now explain what the parameters are that make the chopper do some pretty funky things.

  • chopper - the name of the object to be moved
  • [wp1,wp2,wp3,wp4,wp5] - the quasi-waypoints that the chopper will move through. This specifies that the chopper will move through wp1, wp2, wp3, wp4 then wp5. The chopper will move from whatever position it is at at when the script is called.
  • 1 - specifies the speed that the chopper will move. Don't worry about what this is, all u need to remember is that 1 is fast, 0.5 is half that etc.
  • 0 - there will not be a pause at each waypoint
  • false - we are not moving a camera object
  • For more information check the header of move.sqs. Try moving the game logic units and re-executing radio alpha.

    Moving a camera

    Ok, now lets examine how the camera scripting works. Because a camera is just an object, you can move a camera with move.sqs just as easily.

    Firstly I set up my waypoints for the camera, these being game logic units cam_wp1 through to cam_wp4. If you double click on these game logic dudes you'll see that I have started them all up in the air. I have two wrecks set up, wreck1 and wreck2. These will be used as targets for the camera later on. I have two triggers, one that calls examplecamera1.sqs and one that calls examplecamera2.sqs (don't worry about the third trigger that calls examplecamera3.sqs just yet).

    Because the camera will move from whatever position it is at when the script is called, cam_wp1 is only used as a marker for positioning the camera at the start and will not actually be passed to the script as a waypoint.

    What I have done in 'examplecamera1.sqs' and 'examplecamera2.sqs' is make two very slightly different scripted cutscenes. Both will use move.sqs to control the camera. 'examplecamera3.sqs' is also very similar, except it also implements 'rotate.sqs' (see below) to make the camera rotate around a position before the camera follows it's waypoints.

    Open up examplecamera1.sqs in a text editor. You can see that I create a new camera, and then set the global variable 'movecamtarget' equal to the first wreck. This global variable will be used by move.sqs and MUST be set if you are going to be moving a camera object.

    You can then see I position the camera at cam_wp1, and target the wreck1 (pointing the camera at wreck1 is not really neccasary, move.sqs will do that for us anyway).

    After this I exectute the following command:

    [_cam,[cam_wp2,cam_wp3,cam_wp4],0.3,2,true] exec "move.sqs"

  • _cam - the name of the camera object to be moved
  • [cam_wp2,cam_wp3,cam_wp4] - the quasi-waypoints that the camera will move through (in that order, firstly moving from current position to cam_wp2)
  • 0.3 - specifies the speed of the camera. 0.3 is fairly slow compared to how fast I moved the chopper.
  • 2 - there will be a 2 second pause at each waypoint
  • true - we are moving a camera object
  • This code takes our newly created camera object and sends it on it's way.

    Then you can see the line:

    @movepoint == cam_wp3

    This simply waits until the global variable 'movepoint' equals our cam_wp3. This will be true when _cam reaches cam_wp3 and is about to move on to cam_wp4 (ie. the last leg). You can use the global variable 'movepoint' to keep track of where your camera object is up to.

    Then the lines:

    ; change the cameras target
    movecamtarget = wreck2

    ; wait until the script has finished
    moveexited = false
    @moveexited

    ; realign the camera object
    _cam = newcamobj

    'movecamtarget' changes the object that the camera is pointing at, in this case we are going to look at wreck2.

    The next two lines using the global variable 'moveexited' simply makes the script wait until move.sqs is complete, after which the camera is destroyed and the script exits.

    The final line in concerning the move, _cam = newcamobj, is mandatory after every call to move.sqs (or rotate.sqs below). The two movement scripts actual create new cameras to perform the movement/rotation, and hence you must realign your camera object after each script call. I apologise for this, but I have not been able to find a way around it.

    The second example camera script is very similar, except I use two calls to move.sqs to allow me to do a slow camera target change in the middle. (looks a bit nicer that quickly changing the camera's target like in examplecamera1.sqs).

    The header of move.sqs should contain all the information you need. This is an advanced script, containing some funky maths, so if you think you have a bug you are probaly better off emailing me rather than trying to fix it yourself.

    Generic Object Rotation Script

    What this script is

    This is a similar script to the movement one, however this rotates either an object or a camera around a specific point. This is great for scripted cutscenes. The example mission shows it in action. (examplecamera3.sqs).

    This script can also be used to rotate around a moving object, regardless of object type (aircraft, vehicle, soldier, whatever).

    How to use

    Check out rotate.sqs (the script that you will call to do the rotation) and examplecamera3.sqs (an example of it's use) in the example mission zip to see how it works. It is simpler to use than move.sqs.

    Again, you need to specify a number that will define how fast the object will rotate and also a true/false value. True if you are moving a camera, or false if you are moving any other object.

    You can rotate the object for greater that 360 degrees if you want.

    To rotate a normal object (not a camera) you would use the following command. This is the command that radio bravo triggers. Why you would want to do this (rotate a normal object) I don't know, but anyways here it is:

    [chopper,player,0.1,360,false] exec "rotate.sqs"

  • chopper - the name of the object that will be rotated
  • player - the name of the object that will be at the center of the rotation
  • 0.1 - the speed of rotation (use trial and error to get the right speed)
  • 360 - the angle in degrees to rotate. This can be any number. Make negative to rotate anti-clockwise. Make zero to rotate indefinatley. (use rotateexited to force exit)
  • false - we are not moving a camera object

    Ok now to rotate a camera object around a point the only real difference is the last parameter that will be 'true'. If you check out examplecamera3.sqs in a text editor you will see the following command:

    [_cam,wreck1,0.3,360,true] exec "rotate.sqs"

  • _cam - the name of the camera object that will be rotated
  • wreck1 - the name of the object that will be at the center of the rotation. The camera will focus on this object
  • 0.3 - the speed of rotation (use trial and error to get the right speed)
  • 360 - the angle in degrees to rotate. This can be any number. Make negative to rotate anti-clockwise. Make zero to rotate indefinatley. (use rotateexited to force exit)
  • true - we are moving a camera object

    The only other thing that you really need to know about rotate.sqs is the global variable rotateexited. Make this true from outside rotate.sqs to force the script to exit. You can also use this to pause your script until the rotation is complete. To do this in examplecamera3.sqs I used the following couple of lines:

    ; wait until rotation is finished
    rotateexited = false
    @rotateexited

    And then finally (as per after every call to either move.sqs or rotate.sqs when moving a camera) the following lines re-align the camera object in the calling script:

    ; realign the camera object
    _cam = newcamobj

    And that about wraps it up for rotation. Remember that the object that you want to rotate will begin rotating from wherever it is at the time the script is called. Have fun!

    Thanks to Fishion for the basic concept. A big thanks to Wozza for assistance with the maths. Build time for these scripts was about 5 hours. That damn setpos bug was a killer. For the most reliable results, in your cutscenes I recommend you use 'setpos' instead of 'camsetpos' and insert the bug fix code after each time you use it.

    download the example mission showing both move.sqs and rotate.sqs in action. Or download move.sqs or rotate.sqs seperatley.