Camera Following Projectile HELP
by Loubert McGeurkinberger · in Torque Game Engine · 12/30/2008 (4:06 pm) · 12 replies
What I am trying to create is a missile projectile, that becomes controllable by the player via a first-person 'missile-cam' after it is fired. If anyone has played Perfect Dark (the slayer) or Unreal Tournament (the nuke launcher) they will know what I mean. Right now I am just working on getting the camera following a projectile, but even that seems to be failing. I have spent quite a bit of time searching through the forums, looking through the camera and projectile documentation, echoing out my diagnostics and fiddling with my weapon script but I still can't figure it out.
I have followed the advice given at http://www.garagegames.com/mg/forums/result.thread.php?qt=12578 , and the camera does indeed follow the projectile, but the angle is completely off, I want the angle to be forward-facing (i.e: a pilot guiding a plane, not a passenger looking out the side)
At the end of CrossBowImage::onFire() I have inserted this:
However, %p.getTransform() always seems to return the same vector, " 0 0 0 1 0 0 0", should it be doing this? Is the transform of the projectile relative to the transform of the weapon? Also, there is also a weird bug that if I shoot the crossbow, then spawn the player (F7) without rotating the camera the player is spawned facing a constant angle every time. Then, if I shoot the crossbow at this 'perfect'angle, the camera will track the projectile on the angle desired. I have also tried setOrbitMode() according to the transform of the camera, the player, the weapon or my own custom vectors but nothing seems to work. I was wondering if perhaps it would be easier to just scrap the projectile idea entirely and just have the weapon spawn a player object that simulates a projectile. I am utterly confused at this point, someone please help me!
I have followed the advice given at http://www.garagegames.com/mg/forums/result.thread.php?qt=12578 , and the camera does indeed follow the projectile, but the angle is completely off, I want the angle to be forward-facing (i.e: a pilot guiding a plane, not a passenger looking out the side)
At the end of CrossBowImage::onFire() I have inserted this:
%obj.client.setControlObject(%obj.client.camera);
echo("Projectile Transform =" SPC %p.getTransform() SPC "\n");
%obj.client.camera.setOrbitMode(%p, %p.getTransform(), 0.2, 0.2, 0.1);
return %p;However, %p.getTransform() always seems to return the same vector, " 0 0 0 1 0 0 0", should it be doing this? Is the transform of the projectile relative to the transform of the weapon? Also, there is also a weird bug that if I shoot the crossbow, then spawn the player (F7) without rotating the camera the player is spawned facing a constant angle every time. Then, if I shoot the crossbow at this 'perfect'angle, the camera will track the projectile on the angle desired. I have also tried setOrbitMode() according to the transform of the camera, the player, the weapon or my own custom vectors but nothing seems to work. I was wondering if perhaps it would be easier to just scrap the projectile idea entirely and just have the weapon spawn a player object that simulates a projectile. I am utterly confused at this point, someone please help me!
About the author
#2
12/30/2008 (5:25 pm)
Thanks for the quick reply, however wouldnt the flying vehicle object still have to have a setOrbitMode set somewhere? Also I'm assuming you are not mounting the player to the vehicle? Could you please post some snippet(s) (or the entire file) of the weapon script or flying vehicle you created, I'm rather new to TGEA and just trying to get a grasp on this.
#3
As far as your question about setting setOrbitMode for the vehicle missile I would say no. All you would really need to do is transfer control and camera from the player object to the vehicle object and then back again - no mounting involved (although looking at the vehicle mounting code will give you a indication of how to transfer control). This will (should) give you 1st person control of the missile instead of having the camera simply following a fixed trajectory missile.
12/30/2008 (10:23 pm)
Since what I had was for Tribes and it was several computers ago it may take me while to round up that old mod. But reading this did get me interested in seeing if I could do the same thing in Torque - may be a while before I can take the time though, I'll post back here if I can get to it within the next few days.As far as your question about setting setOrbitMode for the vehicle missile I would say no. All you would really need to do is transfer control and camera from the player object to the vehicle object and then back again - no mounting involved (although looking at the vehicle mounting code will give you a indication of how to transfer control). This will (should) give you 1st person control of the missile instead of having the camera simply following a fixed trajectory missile.
#4
12/31/2008 (1:47 pm)
Alright, I've followed your generous advice and I've managed to get my own FlyingVehicle replacing the projectile a milisecond after it's created and it can indeed fly around first-person however I still have a few problems. The first is, I can't figure out for the life of me how to get it to constantly propel itself forward, I have tried a bunch of different things, trying to hack keybinds, continuously scheduling %obj.mThrustDirection = ThrustForward; %obj.mThrust = 1;, I was thinking of even manually hijacking updateMove and figuring out the vector math myself if it comes down to it. The second problem with the FlyingVehicle is that even when I set
// Ground Impact Damage (uses DamageType::Ground) collisionTol = 0.1; // Collision distance tolerance contactTol = 0.1; minImpactSpeed = 0; // If hit ground at speed above this then it's an impact. Meters/second speedDamageScale = 100; // Object Impact Damage (uses DamageType::Impact) collDamageThresholdVel = 0.1; collDamageMultiplier = 60;my ::onDamage and ::onCollision functions never seem to get called, and the missile never actually explodes no matter how hard I smash it into the ground. I have been fiddling around with the various physics variables and I can make it somewhat stable, however the thing still is very difficult to control, has a tendancy to start flipping over violently and doesnt handle like a missile should at all, but more like toy RC helicopter (i.e: dipping into turns instead of just rotating directly, hovering, death spirals etc). If anyone could help me I would really appreciate it!
#5
Now to get it to actually explode and not go into death spirals...
12/31/2008 (6:06 pm)
Alright, after a bit more tinkering I got it moving by hijacking the player movement variable (as the missile becomes the player) and giving it a constant velocity:function propel(%this, %obj) {
%obj.setVelocity(30);
$mvForwardAction = 1;
schedule(1, %this, propel, %this, %obj);
}
function Missile::onAdd(%this, %obj) { schedule(1, %this, propel, %this, %obj); }Now to get it to actually explode and not go into death spirals...
#6
Did you figure out how to make it explode? Blowing things up is something that I do well. Torque can automatically track damage to (most) objects even if it's not being used anywhere. Shapebase objects have three damage states: "Enabled", "Disabled", "Destroyed". To set it up all you need to add the following to your vehicle datablock:
And you will need some damage handling functions to make it all work.
With those settings your missile will explode on impact with anything. I didn't show my TakeControl or ReleaseControl funtions (I actually pass control back to the player object from a Vehicle::onDisabled callback), since it sounds like you already have that taken care of.
On a side note: once that fix above for the orbit Camera bug is applied it's very easy to attach a camera to a projectile for a "bullet cam" effect.
01/08/2009 (2:58 pm)
The handling and maneuvering issues are a problem because of how Torque handles vehicles and your control device, but much of it can be alleviated by tweaking the datablock settings for the vehicles. I finally got around to seeing if I could get this to work a little while ago today and well...it would be much better to create a new projectile class that you can control (preferred), or add a minimum forward speed to your vehicle (easier). I had never noticed that Torque vehicles didn't have a minSpeed setting, only a maxForwardSpeed. Your propel script will work but can introduce movement problems depending on how you transfer control of the POV missile from the player to the missile and back to the player -- though it's simple enough to add a check for if you are controlling a player class object or a vehicle class object.Did you figure out how to make it explode? Blowing things up is something that I do well. Torque can automatically track damage to (most) objects even if it's not being used anywhere. Shapebase objects have three damage states: "Enabled", "Disabled", "Destroyed". To set it up all you need to add the following to your vehicle datablock:
// Damage control and explosions maxDamage = 1.1; destroyedLevel = 1.0; renderWhenDestroyed = false; // don't render normal shape when destroyed, only debris shape explosion = CrossbowExplosion; underwaterExplosion = CrossbowExplosion; debrisShapeName = "~/data/shapes/crossbow/projectile.dts"; debris = CrossbowExplosionDebris; // the debris datablock explosionDamage = 40; // How much damage is applied through a radiusDamage function call explosionRadius = 20; // the radius for the radiusDamage function call damageType = ExplosionDamage; // the damage type caused by the explosion damageImpulse = 2000; // amount of impulse/kickback from explosionI also added in radius damage and impulse effect - what's the point of blowing something up if doesn't cause damage to the surrounding area?
And you will need some damage handling functions to make it all work.
function POVmissileVehicle::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
if (%obj.getDamageState() $= "Destroyed")
return;
%obj.applyDamage(%damage);
}
function POVmissileVehicle::onDamage(%this, %obj)
{
%damage = %obj.getDamageLevel();
if(%damage >= %this.maxDamage)
{
%obj.setDamageState(Destroyed);
radiusDamage(0, %obj.getWorldBoxCenter(), %this.explosionRadius, %this.explosionDamage, %this.damageType, %this.damageImpulse);
}
}
function POVmissileVehicle::onImpact(%this, %obj, %collidedObject, %vec, %vecLen)
{
if(%vecLen > %data.minImpactSpeed)
%obj.damage(0, VectorAdd(%obj.getPosition(),%vec),%vecLen * %this.speedDamageScale, "Impact");
}With those settings your missile will explode on impact with anything. I didn't show my TakeControl or ReleaseControl funtions (I actually pass control back to the player object from a Vehicle::onDisabled callback), since it sounds like you already have that taken care of.
On a side note: once that fix above for the orbit Camera bug is applied it's very easy to attach a camera to a projectile for a "bullet cam" effect.
#7
already have the firing, control, explosion and controlreset functions BUT
when I fire my "Missile"/FlyingVehicle it spawns in the center of the level and only the Rotation is being set and not the angle...
Basically Angle and Position of the "Missile" being spawned are incorrect.
Note: this code is only a slightly modified SpawnVehicle with the missile front fixed outward from the character.
Followed by this error:
04/05/2010 (6:27 am)
I've actually been trying to get this to work myself,already have the firing, control, explosion and controlreset functions BUT
when I fire my "Missile"/FlyingVehicle it spawns in the center of the level and only the Rotation is being set and not the angle...
Basically Angle and Position of the "Missile" being spawned are incorrect.
function serverCmdCreateMissile(%client)//fixme
{
%player = %client.player;
if(%client.player$="")
return;
if(%client.player)
if(%client.player.isMounted())
return;
%vehicle = new HeliVehicle()
{
dataBlock = Missile;
};
%vehicle.mountable = true;
%vehicle.setEnergyLevel(60);
// Spawn the car 10 units in front of the player rotated so that the driver-side
// door is facing them and taking the terrain height into account
// Get the position of the player's eye
%pos = %client.player.getMountedImage($WeaponSlot).getMuzzleTransform($WeaponSlot); //FIXME
// Use the ForwardVector calculate a 10 unit offset vector
%offset = VectorScale( %client.player.getForwardVector(), 1.25 );
// Add the offset to the position to get a point 1.25 units in front of the player
%spawn = VectorAdd( %pos, %offset );
// Now get the terrain height at that point to avoid spawning the car inside a hill
// getTerrainHeight() takes an x and y position
%xy = getWord( %spawn, 0 ) SPC getWord( %spawn, 1 );
// Get a spawn point 1.25 units in front of the player but
// at the height of the terrain plus a little extra padding
%spawn = getWord(%spawn, 0) SPC getWord(%spawn, 1) SPC getTerrainHeight(%xy) + 2;
// Get the transform
%trans = %client.player.getTransform(); //default
//%trans = %client.player.getMountedImage($WeaponSlot).getMuzzleVector($WeaponSlot);
// Get the rotational axis
%axis = getWord( %trans, 3 ) SPC getWord( %trans, 4 ) SPC getWord( %trans, 5 );
// Get the ang that the player is rotated around the axis
// Compensate for inverted axis
if (getWord(%axis, 2) < 0)
%ang = -getWord( %trans, 6 );
else
%ang = getWord( %trans, 6 );
// Add the rotation to make the door face the player (270 degrees in radians)
%ang += 6.3; //default // exec("./common/scripts/server/core/commands.cs");
//%ang += 0;
// Now set the transform we calculated
%vehicle.setTransform( %spawn SPC "0 0 1" SPC %ang );
//%vehicle.setGravity(0);// Optional recommended :)
%vehicle.nextWeaponFire = 1;
//%vehicle.schedule(5500, "playThread", $ActivateThread, "activate");
MissionCleanup.add(%vehicle);
// Set newly spawned missile as ControlObject here
////messageClient( %client, 'MsgMountSuccess', 'c2Entering missile- %1.', %vehicle.getDataBlock().nameTag);
%client.setControlObject(%vehicle);
%player.MissileControl(%player);
////return;
}Note: this code is only a slightly modified SpawnVehicle with the missile front fixed outward from the character.
Followed by this error:
common/scripts/server/core/commands.cs (804): Unknown command getMuzzleTransform. Object MissileImage(671) MissileImage -> WeaponImage -> ShapeBaseImageData -> GameBaseData -> SimDataBlock -> SimObject
#8
That should return an XYZ coordinate :]
04/05/2010 (8:19 am)
@CSMP: Try this insteadpos = %client.player.getMuzzlePoint($WeaponSlot);
That should return an XYZ coordinate :]
#9
Thanks Bryce, the code worked... now the only thing that I need is to pass the angle of Fire to the angle of the Missile upon being spawned.
Always appreciate the help!
BTW: If I can get the Angle to work I would be more then willing to post a resource on "Player Controlled Missiles/TV Guided Weaponry"!
04/05/2010 (8:18 pm)
Wow, I must've tried every variation of that line of code and I still couldnt figure it out.Thanks Bryce, the code worked... now the only thing that I need is to pass the angle of Fire to the angle of the Missile upon being spawned.
Always appreciate the help!
BTW: If I can get the Angle to work I would be more then willing to post a resource on "Player Controlled Missiles/TV Guided Weaponry"!
#10
04/05/2010 (8:29 pm)
Install this resource, and you can use %vehicle.setForwardVector(%client.player.getMuzzleVector(0));
#11
I'll browse through the scripts and start printing up a resource, though I cant promise it'll look pretty. :)
Edit: I'm testing the scripts and source for installation on a vanilla copy of TGE1.5.2, I'll post it once I can get everything working correctly.
04/06/2010 (4:40 am)
Awesome, it worked...I'll browse through the scripts and start printing up a resource, though I cant promise it'll look pretty. :)
Edit: I'm testing the scripts and source for installation on a vanilla copy of TGE1.5.2, I'll post it once I can get everything working correctly.
#12
http://www.torquepowered.com/community/resources/view/19617
04/06/2010 (6:22 pm)
Resource is up.http://www.torquepowered.com/community/resources/view/19617
Associate Michael Hall
Big Kid Games
It was a bit of a hack but it worked rather well.
setOrbitMode is actually broken in TGE. 1.5.2 Orbit Camera Bug