Turret & AITurret classes
by Paul Dana · 04/15/2003 (11:36 am) · 85 comments
Download Code File
Turrets for TGE Paul Dana
Introduction
This resource describes how to get turrets and AI-turrets into the Torque Game Engine. A Torque turret is like a real world turret: it has a weapon mounted to it and rotating the turret aims that weapon. A player can walk up to a turret and mount it and then that player is controlling the turret instead of his character. A turret can be mounted to another object, such as a vehicle. A tank could be implemented this way if the player controlled that turret. There are options for limiting the rotational freedom a turret has in pitch and yaw.
An AI-turret is a turret that can aim and fire automatically. The AI-turret class extends the Turret class and has methods for tracking and aiming at a target object or location. It can correctly "lead shots" taking into account projectile muzzle velocity and ballistic information as well as the speed of any object the turret itself is mounted to and the speed of the target object. It can aim correctly even if the turret is mounted to another object at some odd angle or, for whatever other reason, the local Z axis of the turret does not align with the world Z axis. There is a "miss radius" option for controlling how accurate the aim is.
This resources comes with a sample turret .dts file and the Milkshape .ms3d file it came from as well as one example turret datablock and two example AI turret datablocks.
I am usually very greedy with my time. I am rarely motivated to do so much work for free and write documentation for it! I made an exception in this case because I felt the Garage Game developer community deserved it. They have done so much for me. Thank you all.
How This Resource is Organized
Some resources spell out the code changes in the resource text itself. This seems a cumbersome way of doing a resource, such as this one, which will require a large number of small alterations to the code in many different files. I have taken a different approach. I have included each file that needs to be changed in a .zip file and each of the changes that need to be made are marked by the same comment. Only those sections of the file that have changed are actually included so it's easy to see where the changes are.
IMPORTANT: The files are laid out in the same folder structure used by the Torque Game Engine itself but it's important that you DO NOT unzip this file into a folder containing Torque source code. These are not complete files after all...they only show the sections that have changed. The reason for laying them out using the same folder structure is simply to make it easier to identify exactly which files have changed. Here is a sample file:
Note that all changes begin with a line reading: "// phdana turrets ->".
Note that all changes end with a line reading: "// <- phdana turrets".
How to Add Turrets to Your Code
Unzip turrets.zip to some folder on your harddrive separate from your Torque source folder. Examine the files that were unzipped. Some C++ and Script files are new (such as turret.cc and turret.h). Just copy these files as-is into the appropriate folder and make sure you add these files to the appropriate Makefile or Project file. Most of the files in the .zip file already exist (such as player.cc) and need to have changes merged into them. For each such file that was unzipped, open it up and search for "// phdana ". Now open the same file in your Torque folder, find the same section, and insert the appropriate lines of code into your source. Use the same process to merge changes to the Script files as well. Some files are new data files (such as smallTurret.dts). Just copy these files as-is to the appropriate folder.
How to Test Mounting the Turret as a Player
Once you have merged the necessary code and data files you should be able to add the test turret that comes with this resource to your mission. Run your game, enter the World Creator mode in the Mission Editor and choose to place a Shape. You should see a "Turrets" section. Place a GenericTurret somewhere on the ground in your mission.
To test the turret, enter the game as a Player and walk up to the turret. Once you touch it you should "mount" it and now your mouse motions control the turret, and the player is mounted, sitting, on the turret. You can hit TAB to enter 3rd person view to get a better look. To dismount from the turret hit the SPACEBAR or whatever key you have bound to the "jump" command.
How to Test an AI Turret
Once you have merged the necessary code and data files you should be able to add the test AI-turret that comes with this resource to your mission. Run your game, enter the World Creator mode in the Mission Editor and choose to place a Shape. You should see a "Turrets" section. Place a GenericAITurret somewhere on the ground in your mission.
To test the AI-turret, enter the game as a Player or as a Vechicle. Once you come within the "triggerRadius" of the AI Turret it should activate and then start aiming at you and eventually fire at you. If you die, since it cannot find any more targets, it should deactivate and return to zero pitch and yaw.
How to Mount a Turret on a Vehicle
It is possible to mount a turret on a vehicle. In the vehicles "onAdd()" script function you would create a new turret object and mount it to the vehicle. If you do that then the first person to touch the vehicle will mount the driver's seat and the second person to touch the vehicle will mount the turret.
It is also possible to mount a turret on a vehicle and have only one person control both the vehicle and the turret. You would do this by modifying a vehicle class (or creating your own) who's movement is controlled by the keyboard. You would expose a method to script so the script can tell the vehicle what turret is mounted to it. You would mount a turret to the vehicle using the same method as above. In this vehicle class's updateMove() method you would pass the move's pitch and yaw to the turret you mounted. Use the method outlined above to mount the turret, and in the vehicles ::onAdd() script method you would call the method you exposed to tell the vehicle about the mounted turret.
It is also possible to mount an AI-turret on a vehicle and let that turret pick it's own targets. There is nothing special you need to do in this case. Note that an AI-turret can correctly aim itself no matter what it's orientation in the world. This means a turret will aim correctly even when mounted on a wheeled vehicle climbing a hill, or on a flying vehicle in a banking curve. Mount the turret using the method outlined above but create an AITurret and set the datablock appropriately.
How to Build a Turret
The turrets presented in this resource are equivalent to the Turrets that were found in Tribes 2 in that they are mountable and can be mounted, etc. However they are built a little differently. In Tribes 2 turrets the artist had to provide two blend animation sequences called Turn and Elevate that were used by the turret code to actually aim the turret. In the turrets presented here those two animation sequences are not needed, and the artist simply has to indicate which nodes are to be used for rotating the turret by giving them the special names: codeTurret and codeWeapon. This will be explained in more detail below.
There are three advantages to this method and only one real drawback. One advantage is a simplified art-path. The artist merely has to construct the turret in a turret-like way and then indicate which nodes are to be used for rotation. The second advantage is that it requires two less threads at runtime. The third advantage, and the one most important to me, is that Turrets designed in this fashion can be constructed using Milkshape which is unable to make the blend animation sequences required by the Tribes 2 method. The drawback is that neither of these two specially named nodes can contribute to an animation. These nodes can be part of a bone system that is animated, they just cannot contribute to it. Thanks to Clark Fagot and Joe Maruschak of Brave Tree software for sharing the code that implements this method of turret rotation. This is the same method they used in their Torque based game, Think Tanks. The convention of prefixing nodes that are controlled by code with the string "code" also comes from them.
Turret requirements:
A turret must have a node (called a 'joint' in Milkshape) called codeTurret. The turret code will rotate this node about it's Z axis to control the turret's yaw. The artist should attach everything to this node that only rotates about the Z axis. This would typically be some sort of support structure that would come up from the turret base and support the rest of the turret.
A turret must have a node called codeWeapon. The turret code will rotate this node about it's X axis to control the turret's pitch. The artist should attach everything to this node that rotates up and down about the X axis to aim the gun. The codeWeapon node must be attached to the codeTurret node.
A turret must have a node called mount0. The turret code will mount the "barrel" of the turret to this mount point. A barrel is just a weapon (ShapeBaseImage) that has been mounted to a turret and is no different in any other way from any other weapon in Torque.
A turret can optionally have a node called mount1 if you want a person to be able to walk up to the turret and mount it.
A turret can optionally have an animation sequence called Activate. The turret code will play this animation forwards when activating the turret, and will play it backwards when deactivating the turret. The speed this animation sequence plays back at is controlled by parameters in the datablock for a turret.
Known Problems and Issues
1. When mounting the test turret as player, in first person view the turret's barrel disappears for certain pitch angles. I am not sure what causes this. The turret still functions...you just can't see the barrel at those angles in first person view.
2. The net code is not optimized. More bits are sent down the wire than is really necessary to control the turret.
3. I need to add sounds that will automatically be played when the turret is Activated and Decativated.
4. The net code does not currently do any client side "warping". If the server and client should ever disagree on the turret rotation values then the turret motion will be "choppy". This does not currently present a problem because there are no server side forces that affect the turret's rotation that do not also exist on the client.
5. For some odd reason two sets of datablock information shows up for the turret in the mission editor. If you click on a turret in Inspector mode and expand it's datablock fields you will see two Transform sections and two Misc sections. The duplicate sections always show the same information and their presence does not seem to affect the correct operation of the turret.
Summary
I've suffered for my art....now it's your turn.
I never really wanted to write a full-featured turret class for Torque. I started because I agreed to help Anthony Rosenbaum with a project he was working on. He had turrets in his game, he said, but they did not rotate and could I help? Sounded simple enough. He wanted turrets so he could mount them to a vehicle to make a tank. Robert Brower mentioned that he needed turrets mounted to vehicles, but AI turrets that could aim. Once word got out that I was "working on turrets" it was like a feeding frenzy.
While this was going on I decided on what commercial game Crimson Games would be working on next. As it turned out this game could take advantage of AI Turrets simply placed on the ground. I figured heck...since I need some form of turrets I might as well go ahead and make a full featured turret class since a lot of Torque developers seemed to need one. When I made that decision I did not realize how hard it would be to complete a full featured Turret class so I stupidly agreed to make one. You now have the result of that stupidity. Use it wisely.
If you have any questions email me at paul@crimsongames.com. I also idle in the #garagegames and #crimsongames channels on the irc.maxgaming.com IRC network.
Turrets for TGE Paul Dana
Introduction
This resource describes how to get turrets and AI-turrets into the Torque Game Engine. A Torque turret is like a real world turret: it has a weapon mounted to it and rotating the turret aims that weapon. A player can walk up to a turret and mount it and then that player is controlling the turret instead of his character. A turret can be mounted to another object, such as a vehicle. A tank could be implemented this way if the player controlled that turret. There are options for limiting the rotational freedom a turret has in pitch and yaw.
An AI-turret is a turret that can aim and fire automatically. The AI-turret class extends the Turret class and has methods for tracking and aiming at a target object or location. It can correctly "lead shots" taking into account projectile muzzle velocity and ballistic information as well as the speed of any object the turret itself is mounted to and the speed of the target object. It can aim correctly even if the turret is mounted to another object at some odd angle or, for whatever other reason, the local Z axis of the turret does not align with the world Z axis. There is a "miss radius" option for controlling how accurate the aim is.
This resources comes with a sample turret .dts file and the Milkshape .ms3d file it came from as well as one example turret datablock and two example AI turret datablocks.
I am usually very greedy with my time. I am rarely motivated to do so much work for free and write documentation for it! I made an exception in this case because I felt the Garage Game developer community deserved it. They have done so much for me. Thank you all.
How This Resource is Organized
Some resources spell out the code changes in the resource text itself. This seems a cumbersome way of doing a resource, such as this one, which will require a large number of small alterations to the code in many different files. I have taken a different approach. I have included each file that needs to be changed in a .zip file and each of the changes that need to be made are marked by the same comment. Only those sections of the file that have changed are actually included so it's easy to see where the changes are.
IMPORTANT: The files are laid out in the same folder structure used by the Torque Game Engine itself but it's important that you DO NOT unzip this file into a folder containing Torque source code. These are not complete files after all...they only show the sections that have changed. The reason for laying them out using the same folder structure is simply to make it easier to identify exactly which files have changed. Here is a sample file:
void MissionAreaEditor::onRender(Point2I offset, const RectI & updateRect)
{
... etc more code.
dglClearBitmapModulation();
dglDrawBitmapStretch(mTextureHandle, rect);
// draw all the objects
Vector<SceneObject*> objects;
// phdana turrets ->
U32 mask = InteriorObjectType | PlayerObjectType | VehicleObjectType |
StaticShapeObjectType | WaterObjectType | TriggerObjectType |
TurretObjectType;
// <- phdana turrets
gServerContainer.findObjects(mask, findObjectsCallback, &objects);
... etc more code
}Note that all changes begin with a line reading: "// phdana turrets ->".
Note that all changes end with a line reading: "// <- phdana turrets".
How to Add Turrets to Your Code
Unzip turrets.zip to some folder on your harddrive separate from your Torque source folder. Examine the files that were unzipped. Some C++ and Script files are new (such as turret.cc and turret.h). Just copy these files as-is into the appropriate folder and make sure you add these files to the appropriate Makefile or Project file. Most of the files in the .zip file already exist (such as player.cc) and need to have changes merged into them. For each such file that was unzipped, open it up and search for "// phdana ". Now open the same file in your Torque folder, find the same section, and insert the appropriate lines of code into your source. Use the same process to merge changes to the Script files as well. Some files are new data files (such as smallTurret.dts). Just copy these files as-is to the appropriate folder.
How to Test Mounting the Turret as a Player
Once you have merged the necessary code and data files you should be able to add the test turret that comes with this resource to your mission. Run your game, enter the World Creator mode in the Mission Editor and choose to place a Shape. You should see a "Turrets" section. Place a GenericTurret somewhere on the ground in your mission.
To test the turret, enter the game as a Player and walk up to the turret. Once you touch it you should "mount" it and now your mouse motions control the turret, and the player is mounted, sitting, on the turret. You can hit TAB to enter 3rd person view to get a better look. To dismount from the turret hit the SPACEBAR or whatever key you have bound to the "jump" command.
How to Test an AI Turret
Once you have merged the necessary code and data files you should be able to add the test AI-turret that comes with this resource to your mission. Run your game, enter the World Creator mode in the Mission Editor and choose to place a Shape. You should see a "Turrets" section. Place a GenericAITurret somewhere on the ground in your mission.
To test the AI-turret, enter the game as a Player or as a Vechicle. Once you come within the "triggerRadius" of the AI Turret it should activate and then start aiming at you and eventually fire at you. If you die, since it cannot find any more targets, it should deactivate and return to zero pitch and yaw.
How to Mount a Turret on a Vehicle
It is possible to mount a turret on a vehicle. In the vehicles "onAdd()" script function you would create a new turret object and mount it to the vehicle. If you do that then the first person to touch the vehicle will mount the driver's seat and the second person to touch the vehicle will mount the turret.
function YourVehicleData::onAdd(%this,%obj)
{
// etc. ...
// mount turret
%turret = new Turret()
{
dataBlock = GenericTurret;
};
// mount turret at whatever mount point
%obj.mountObject(%turret,3);
}
%obj.mountedTurret = %turret;
// etc....
}
function YourVehicleData::onRemove(%this, %obj)
{
// etc...
// free mounted turret
if (isObject(%obj.mountedTurret))
{
%obj.mountedTurret.schedule(300,"delete");
MissionCleanup.Add(%obj.mountedTurret);
}
}It is also possible to mount a turret on a vehicle and have only one person control both the vehicle and the turret. You would do this by modifying a vehicle class (or creating your own) who's movement is controlled by the keyboard. You would expose a method to script so the script can tell the vehicle what turret is mounted to it. You would mount a turret to the vehicle using the same method as above. In this vehicle class's updateMove() method you would pass the move's pitch and yaw to the turret you mounted. Use the method outlined above to mount the turret, and in the vehicles ::onAdd() script method you would call the method you exposed to tell the vehicle about the mounted turret.
function YourVehicleData::onAdd(%this,%obj)
{
// etc. ...
// mount turret
%turret = new Turret()
{
dataBlock = GenericTurret;
};
// mount turret at whatever mount point
%obj.mountObject(%turret,3);
}
%obj.mountedTurret = %turret;
// call our new method so the C++ code knows about the turret
%obj.setMountedTurret(%turret);
// etc....
}It is also possible to mount an AI-turret on a vehicle and let that turret pick it's own targets. There is nothing special you need to do in this case. Note that an AI-turret can correctly aim itself no matter what it's orientation in the world. This means a turret will aim correctly even when mounted on a wheeled vehicle climbing a hill, or on a flying vehicle in a banking curve. Mount the turret using the method outlined above but create an AITurret and set the datablock appropriately.
function YourVehicleData::onAdd(%this,%obj)
{
// etc. ...
// mount AI-turret
%turret = new AITurret()
{
dataBlock = GenericAITurret;
};
// mount turret at whatever mount point
%obj.mountObject(%turret,3);
}
%obj.mountedTurret = %turret;
// etc....
}How to Build a Turret
The turrets presented in this resource are equivalent to the Turrets that were found in Tribes 2 in that they are mountable and can be mounted, etc. However they are built a little differently. In Tribes 2 turrets the artist had to provide two blend animation sequences called Turn and Elevate that were used by the turret code to actually aim the turret. In the turrets presented here those two animation sequences are not needed, and the artist simply has to indicate which nodes are to be used for rotating the turret by giving them the special names: codeTurret and codeWeapon. This will be explained in more detail below.
There are three advantages to this method and only one real drawback. One advantage is a simplified art-path. The artist merely has to construct the turret in a turret-like way and then indicate which nodes are to be used for rotation. The second advantage is that it requires two less threads at runtime. The third advantage, and the one most important to me, is that Turrets designed in this fashion can be constructed using Milkshape which is unable to make the blend animation sequences required by the Tribes 2 method. The drawback is that neither of these two specially named nodes can contribute to an animation. These nodes can be part of a bone system that is animated, they just cannot contribute to it. Thanks to Clark Fagot and Joe Maruschak of Brave Tree software for sharing the code that implements this method of turret rotation. This is the same method they used in their Torque based game, Think Tanks. The convention of prefixing nodes that are controlled by code with the string "code" also comes from them.
Turret requirements:
A turret must have a node (called a 'joint' in Milkshape) called codeTurret. The turret code will rotate this node about it's Z axis to control the turret's yaw. The artist should attach everything to this node that only rotates about the Z axis. This would typically be some sort of support structure that would come up from the turret base and support the rest of the turret.
A turret must have a node called codeWeapon. The turret code will rotate this node about it's X axis to control the turret's pitch. The artist should attach everything to this node that rotates up and down about the X axis to aim the gun. The codeWeapon node must be attached to the codeTurret node.
A turret must have a node called mount0. The turret code will mount the "barrel" of the turret to this mount point. A barrel is just a weapon (ShapeBaseImage) that has been mounted to a turret and is no different in any other way from any other weapon in Torque.
A turret can optionally have a node called mount1 if you want a person to be able to walk up to the turret and mount it.
A turret can optionally have an animation sequence called Activate. The turret code will play this animation forwards when activating the turret, and will play it backwards when deactivating the turret. The speed this animation sequence plays back at is controlled by parameters in the datablock for a turret.
Known Problems and Issues
1. When mounting the test turret as player, in first person view the turret's barrel disappears for certain pitch angles. I am not sure what causes this. The turret still functions...you just can't see the barrel at those angles in first person view.
2. The net code is not optimized. More bits are sent down the wire than is really necessary to control the turret.
3. I need to add sounds that will automatically be played when the turret is Activated and Decativated.
4. The net code does not currently do any client side "warping". If the server and client should ever disagree on the turret rotation values then the turret motion will be "choppy". This does not currently present a problem because there are no server side forces that affect the turret's rotation that do not also exist on the client.
5. For some odd reason two sets of datablock information shows up for the turret in the mission editor. If you click on a turret in Inspector mode and expand it's datablock fields you will see two Transform sections and two Misc sections. The duplicate sections always show the same information and their presence does not seem to affect the correct operation of the turret.
Summary
I've suffered for my art....now it's your turn.
I never really wanted to write a full-featured turret class for Torque. I started because I agreed to help Anthony Rosenbaum with a project he was working on. He had turrets in his game, he said, but they did not rotate and could I help? Sounded simple enough. He wanted turrets so he could mount them to a vehicle to make a tank. Robert Brower mentioned that he needed turrets mounted to vehicles, but AI turrets that could aim. Once word got out that I was "working on turrets" it was like a feeding frenzy.
While this was going on I decided on what commercial game Crimson Games would be working on next. As it turned out this game could take advantage of AI Turrets simply placed on the ground. I figured heck...since I need some form of turrets I might as well go ahead and make a full featured turret class since a lot of Torque developers seemed to need one. When I made that decision I did not realize how hard it would be to complete a full featured Turret class so I stupidly agreed to make one. You now have the result of that stupidity. Use it wisely.
If you have any questions email me at paul@crimsongames.com. I also idle in the #garagegames and #crimsongames channels on the irc.maxgaming.com IRC network.
#82
And is there a fix for the turret not showing at certain angles in first person yet?
07/20/2008 (10:23 am)
I don't know if this is a mistake I made, but whenever I enter a flying or wheeled vehicle and move, the first person view is extremely choppy--I'd see the vehicle moving rapidly back and forth. It's fine in the third person view. Has anybody else gotten this?And is there a fix for the turret not showing at certain angles in first person yet?
#83
If anyone has been able to get it to work for 1.4.2 I would really appreciate some help. I am at a total loss what to do there are so many errors I dont know where to start I have tried a few things with no avail.
I followed the instructions to the letter but mayb its not compatible for 1.4.2. So if anyone knows what to do please help thanks in advance.
12/17/2009 (4:33 am)
What version was this resource for? I am currently running 1.4.2 TGE and I get many errors when trying to compile it.In vehicle.cc I do not have this code ((static U32 sDirtySetMask = PlayerObjectType |))If anyone has been able to get it to work for 1.4.2 I would really appreciate some help. I am at a total loss what to do there are so many errors I dont know where to start I have tried a few things with no avail.
I followed the instructions to the letter but mayb its not compatible for 1.4.2. So if anyone knows what to do please help thanks in advance.
#84
Hi everybody!! i have a question that concerns cameraFov and the Turret Class that i cant solve.
I am using the turret class on torque 3D beta 3, and the turret works fine.. the problem happens for me, when the player is mount on the turret, because it dont takes the "cameraDefaultFov" that i set (in this case "140.0"), i set this value on the player.cs that is located on the datablocks folder.. when the player is unmount it takes the cameraFov value that i set before on the player.cs.... so i dont know why is this happening? the cameraFov change when the player is mount on the turret again. Its supose to be the same camerafov when it is unmount and when it is mount on the turret... if i previously set the value on the player.cs, i dont know whats happening, i hope you could help me, Thanks in advance..
Regards
03/18/2011 (12:18 am)
Hi everybody!! i have a question that concerns cameraFov and the Turret Class that i cant solve.
I am using the turret class on torque 3D beta 3, and the turret works fine.. the problem happens for me, when the player is mount on the turret, because it dont takes the "cameraDefaultFov" that i set (in this case "140.0"), i set this value on the player.cs that is located on the datablocks folder.. when the player is unmount it takes the cameraFov value that i set before on the player.cs.... so i dont know why is this happening? the cameraFov change when the player is mount on the turret again. Its supose to be the same camerafov when it is unmount and when it is mount on the turret... if i previously set the value on the player.cs, i dont know whats happening, i hope you could help me, Thanks in advance..
Regards
#85
I hope you're able to shed some light on this for me.
05/04/2015 (8:50 pm)
@Paul, did you ever try mounting two or more turrets to a vehicle? Also would you know it if is possible to make a turret both AI/Player capable on the same vehicle? I hope you're able to shed some light on this for me.

Torque Owner Bryce
Tactical AI Kit