Making sure target is in the FOV of "player"
by Joseph Jonathan · in Torque Game Engine Advanced · 02/19/2010 (12:21 am) · 14 replies
Hey everybody,
I am fairly experienced with Torque script but I am still learning C++.
I am using [url=http://www.torquepowered.com/community/blogs/view/13809]this[url] resource plus some minor changes I have made to make missiles track the target.
I had to port it into 1.8.2 but it all now works without a hitch.
The problem, however, is that I don't want the "player" (in this case a flying vehicle) to be able to lock onto any target and fire a missile with no consideration to where the target it. It is not realistic to lock onto an enemy that is right on your tail and kill him with missiles so I am wanting the code to make it only possible to lock onto the target when it is in the FOV of the eye node and will unlock when the target leaves the FOV of the eye.
I don't need the exact code, of course that would still be helpful :) , so any information that can point me in the right direction to get this completed. I have taken a look in the AI target enter LOS stuff but I am not exactly sure how to add this into my code.
Any help is appreciated.
I am fairly experienced with Torque script but I am still learning C++.
I am using [url=http://www.torquepowered.com/community/blogs/view/13809]this[url] resource plus some minor changes I have made to make missiles track the target.
I had to port it into 1.8.2 but it all now works without a hitch.
The problem, however, is that I don't want the "player" (in this case a flying vehicle) to be able to lock onto any target and fire a missile with no consideration to where the target it. It is not realistic to lock onto an enemy that is right on your tail and kill him with missiles so I am wanting the code to make it only possible to lock onto the target when it is in the FOV of the eye node and will unlock when the target leaves the FOV of the eye.
I don't need the exact code, of course that would still be helpful :) , so any information that can point me in the right direction to get this completed. I have taken a look in the AI target enter LOS stuff but I am not exactly sure how to add this into my code.
Any help is appreciated.
#2
So I would put an if() statement in the projectile.cpp onFire function that makes sure the dot is small enough?
I knew it had to be something like that I just wasn't sure where and how to put it into the coding.
02/19/2010 (5:36 pm)
ah ok. So instead of not letting the client lock onto the target the missile just will not follow it if it is not close enough to the front of the fighter? I think I get it.So I would put an if() statement in the projectile.cpp onFire function that makes sure the dot is small enough?
I knew it had to be something like that I just wasn't sure where and how to put it into the coding.
#3
02/20/2010 (1:43 am)
I was actually referring to scripts - I don't think the projectile class itself has any concept of 'onFire'. There should be an onFire function in your weapon scripts, where you could control whether the projectile locks on - unless your lock-on system is different to the resource I know. If you describe how you handle projectile tracking I could offer a better solution specific to you.
#4
http://www.torquepowered.com/community/resources/view/6778
In my onFire function I have,
The actual code that controls the target lock is this in commands.cs
Does that give you a better picture?
Thanks for your help.
02/20/2010 (2:08 am)
Well this is the base resource I used for my missile tracking.http://www.torquepowered.com/community/resources/view/6778
In my onFire function I have,
function MQ90Image::onFire(%data, %obj, %slot)
{
%projectile = %data.projectile;
%muzzleVector = %obj.getMuzzleVector(%slot);
%objectVelocity = %obj.getVelocity();
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %projectile.muzzleVelocity),
VectorScale(%objectVelocity, %projectile.velInheritFactor));
%muzzle = %obj.getMuzzlePoint(%slot);
%Target = %obj.client.reticleTarget;
echo("Target ID: " @ %Target );
%p = new (%data.projectileType)() {
dataBlock = %data.projectile;
initialVelocity = %muzzleVelocity;
initialDirection = %obj.getMuzzleVector(%slot);
initialPosition = %muzzle;
sourceObject = %obj;
sourceSlot = %slot;
vehicleObject = %vehicle;
client = %obj.client;
target = %Target;
};
MissionCleanup.add(%p);
if (0 != %obj.client.reticleTarget) // set target only if target is a valid object
{
//%p.setNewTarget(%obj.client.reticleTarget);
if (isObject(%obj.client) && ! %obj.client.reticleTarget.client.isAIControlled())
commandToClient(%obj.client.reticleTarget.client, 'MissileFire', %p);
}
return %p;
}The actual code that controls the target lock is this in commands.cs
function serverCmdSetReticleTarget(%client, %clientGhostId)
{
if (%clientGhostId != 0)
{
%reticleServerTargetId = %client.ResolveGhost(%clientGhostId);
//error("Server reticle target id: " @ %reticleServerTargetId @ " / clientGhostId: " @ %clientGhostId);
%client.reticleTarget = %reticleServerTargetId;
if (!%client.isAIControlled()) // send only to humans
{
// these are events sent to the reticle target and to the one that actually locks the target.
// Can be used to play weapon lock / warning sounds and alike.
commandToClient(%reticleServerTargetId.client, 'MissileLockOn');//, %client, %client.player.getShapeName());
commandToClient(%client, 'TargetLockedOn');
%target = %client.reticleTarget.getShapeName();
}
}
else
{
//error("Server reticle target = 0!");
%client.reticleTarget = 0;
%target = "None";
}
%client.setTargetNameHud(%target);
}Does that give you a better picture?
Thanks for your help.
#5
I haven't tested that, but I think you should be right ;P.
02/20/2010 (3:09 am)
Okay, you're using the resource I was thinking of.%Target = %obj.client.reticleTarget;If this is letting you select targets that are behind you, then you'll need to add the dot check here. Here's something off the top of my head and modified, see below.
%target = %obj.client.reticleTarget; //Vector from us to our target: %vectorToTarget = VectorSub(%target.getPosition(),%obj.getPosition()); //Make it a normal vector (1 unit in length) %vectorToTarget = VectorNormalize(%vectorToTarget); //Get the direction we're facing %forwardVector = %obj.getForwardVector(); //Do the dot product %dot = VectorDot(%vectorToTarget,%forwardVector); //When you dot two normal vectors, the result ranges from -1 to +1 // -1: the vectors are opposite - parallel but pointing in different directions // 0: the vectors are perpendicular // +1: the vectors are the same - parallel and going the same direction //The dot product also equals the cosine of the angle between the two vectors, so: //45 degree aiming cone (note that's 45 degrees either side of centre) %angle = mDegToRad(45); //Cosine it so it ranges from -1 to +1 %angle = mCos(%angle); //If the angle's outside our desired sweet-spot, forget the target if(%dot < %angle) %target = -1;
I haven't tested that, but I think you should be right ;P.
#6
Now that I know how to do it here I think I can also figure out how to not let the target get locked in the first place.
02/20/2010 (3:30 am)
Ok Thank you so much. That worked. I just had to change mDot to VectorDot.Now that I know how to do it here I think I can also figure out how to not let the target get locked in the first place.
#7
02/20/2010 (6:57 am)
That would be a better solution ;P. It makes sense that if you've locked a target, you can pin a missile to it - it just doesn't make sense to be able to lock onto a target behind you. Anyway, glad it worked for you! I'll change the dot function in the script for others who might benefit from this.
#8
Here is my code
The is is a sample of what I get in the console.
Target Vector: -1 0 0
Forward Vector: 0.089653 0.992796 -0.0777982
Angle: 0.872665
Dot: -0.089653
Target ID: -1
no mater what I always get -1 0 0 for the target vector. I also tried to take the mCos(%angle); part out but that didn't work. what exactly does that do?
02/20/2010 (5:19 pm)
Ok I think I spoke too soon. Sometimes it works but then sometimes it doesnt and I dont know why.Here is my code
%target = %obj.client.reticleTarget;
%vectorToTarget = %target.getPosition() - %obj.getPosition();
%vectorToTarget = VectorNormalize(%vectorToTarget);
echo("Target Vector: " @ %vectorToTarget );
%forwardVector = %muzzleVector;
echo("Forward Vector: " @ %forwardVector );
%dot = VectorDot(%vectorToTarget,%forwardVector);
%angle = mDegToRad(50);
//%angle = mCos(%angle);
echo("Angle: " @ %angle );
echo("Dot: " @ %dot );
if(%dot < %angle)
{
%target = -1;
}The is is a sample of what I get in the console.
Target Vector: -1 0 0
Forward Vector: 0.089653 0.992796 -0.0777982
Angle: 0.872665
Dot: -0.089653
Target ID: -1
no mater what I always get -1 0 0 for the target vector. I also tried to take the mCos(%angle); part out but that didn't work. what exactly does that do?
#9
The mCos is correct, you need that to be able to compare with the dot product. Alternatively, you could inverse-cos the dot product, so you're comparing two angles rather than two dot products, but I wasn't sure what the inverse-cos function in script was :P.
02/20/2010 (6:11 pm)
Hmm. Try echoing out %target and %obj before using them,and echo their individual positions. Does the code work if you happen to be facing the right direction? (i.e., -1 0 0?)The mCos is correct, you need that to be able to compare with the dot product. Alternatively, you could inverse-cos the dot product, so you're comparing two angles rather than two dot products, but I wasn't sure what the inverse-cos function in script was :P.
#10
Sometimes the code works and sometimes it doesnt. I sometimes fly the same path and it only works some of the time. Sometimes when I am inverted it works too.
Is target vector always supposed to be -1,0,0?
02/20/2010 (6:28 pm)
Well when I echo the target and obj positions I get what I am looking for, so I know it is working up to there.Sometimes the code works and sometimes it doesnt. I sometimes fly the same path and it only works some of the time. Sometimes when I am inverted it works too.
Is target vector always supposed to be -1,0,0?
#11
02/20/2010 (6:31 pm)
I did a test and let the target (the Kork AI) move but I just stayed still on the ground firing missiles. No matter where Kork moved the dot was the same which I don't think is right.
#12
%vectorToTarget = %target.getPosition() - %obj.getPosition();
02/20/2010 (10:52 pm)
do a vectorsub here instead ?%vectorToTarget = %target.getPosition() - %obj.getPosition();
#13
I don't get -1, 0, 0 anymore and the missiles track when I am looking at the target at onFire.
02/20/2010 (11:47 pm)
Thanks JANR, that seems to work.I don't get -1, 0, 0 anymore and the missiles track when I am looking at the target at onFire.
Torque Owner Daniel Buckmaster
T3D Steering Committee
I'd just dot the forward vector of the firer with the direction vector of the target that would be locked-on, and only if the dot is small enough do you actually pass the target object to the missile.