Trying to get the angle of the target in AiPlayer.cs
by Katrina Rose · in Torque Game Engine · 08/23/2004 (7:11 am) · 13 replies
Hi,
I am trying to use "onAttackTargetEnterLOS(%this,%obj)" to determine if you (the player) are in front of the bot or behind the bot. I have tried every forum post on here trying all the various codes. I have tried the code contained in "aisensetutorial.cs", and the one with the vector subtract. I am having trouble in using the math to use an if statement for the angle. I know that:
Marrion Cox
I am trying to use "onAttackTargetEnterLOS(%this,%obj)" to determine if you (the player) are in front of the bot or behind the bot. I have tried every forum post on here trying all the various codes. I have tried the code contained in "aisensetutorial.cs", and the one with the vector subtract. I am having trouble in using the math to use an if statement for the angle. I know that:
%vec = vectorSub($myPlayer.getTransform(),%obj.getTransform()); %vecDir = vectorNormalize(%vec);will return the vector from the bot(%obj) to me($myPlayer), but I don't know what value is Left, Right, Front, and Back, because It returns 3 values. I am not even sure if the method is getting called at a time when I can use the value for the determination. The value could be off if the bot turns before the method is called. Any help would be apreciated.
Marrion Cox
About the author
#2
08/23/2004 (10:03 am)
Is target the getposition or the gettransform(normalized)?
#3
08/23/2004 (10:15 am)
Target should first be set to the x,y,z position of the player. Then you subtract the bot's position from that vector, then you normalize.
#4
Thanks for all your help
08/23/2004 (10:50 am)
I think you are right. It might be better to do this in the engine. How do I make a reference to the player and bot in the aiPlayer.cc files? I would like to know how to adapt your code to work under the "void AIPlayer::scanningPlayers() { // Jimomighty".Thanks for all your help
#5
Thanks for your help
, but I get an
08/23/2004 (11:02 am)
This is what I have so far:void AIPlayer::scanningPlayers() { // Jimomighty
// SCAN!
if (mScanningPlayers && !mAttackTargetObject) {
F32 tagDistance = mScanningPlayersDistance;
Player *tagPlayer = NULL;
VectorF v1(0,0,0), v2(0,0,0);
v1 = getPosition();
SimGroup *g = Sim::getClientGroup();
SimGroup::iterator j;
for (j = g->begin(); j != g->end(); j++)
{
GameConnection *client = static_cast<GameConnection*>(*j);
Player *player = NULL;
if (! client->getControlObject())
continue;
player = dynamic_cast<Player*>(client->getControlObject());
if (! player)
continue;
// Istead of follow it should be team but thats not done yet.
//if (mPlayer != player && mFollowTargetObject != player) {
if (mFollowTargetObject != player) {
v2 = player->getTransform().getPosition();
VectorF v = v2 - v1;
float dist = mSqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
if ( dist <= mScanningPlayersDistance && dist < tagDistance) {
tagDistance = dist;
tagPlayer = player;
}
}
}
// MCOX adding code to determine if the player is in front of the bot
Point3F pos = getPosition();
Point3F front;
getTransform().getColumn(1, &front);
front.normalizeSafe();
//create target vector
Point3F target = tagPlayer;
target -= pos;
target.normalizeSafe();
//determine angle difference
F32 angle = mRadToDeg(mAcos(mDot(target, front)));
// We have a player?
if (tagPlayer && angle > 270 && angle < 90) {
clearAttackTarget();
setAttackTargetObject( tagPlayer );
}
}
}I get a "cannot convert from 'player *' to 'Point3F'Thanks for your help
, but I get an
#6
Should be:
secondly, "angle > 270" will never be a true statement, dot products will always be in the range 0-180, meaning the difference will always be "the shortest way around" if the difference is actually 270, then angle will == 90 changing the if statement to:
should catch all of the "in front of" cases.
EDIT: oh yeah, you might want to check that tagPlayer is not null before trying to call getposition on it. Acctually, you probably want to skip over the whole angle computation part if the player is null.
08/23/2004 (11:51 am)
I think Point3F target = tagPlayer;
Should be:
Point3F target = tagPlayer->getPosition();
secondly, "angle > 270" will never be a true statement, dot products will always be in the range 0-180, meaning the difference will always be "the shortest way around" if the difference is actually 270, then angle will == 90 changing the if statement to:
if (tagPlayer && angle < 90)
should catch all of the "in front of" cases.
EDIT: oh yeah, you might want to check that tagPlayer is not null before trying to call getposition on it. Acctually, you probably want to skip over the whole angle computation part if the player is null.
#7
function GetAngle(%sourceObj,%targetObj)
{
%eyeVec =VectorNormalize(%sourceObj.getEyeVector());
%toObjVec =VectorSub(%targetObj.getPosition(),%sourceObj.getPosition());
%dot =VectorDot(%eyeVec,VectorNormalize(%toObjVec));
%rad =mAcos(%dot);
return mRadToDeg(%rad);
}
08/23/2004 (12:24 pm)
Here is my angle function. Only returns 0-180 cause it doesn't calc left or right side. 'Cross eyeVect with a 0,0,1 vector and then check the dot on that value to determine which side the target is on? Or is their a better way?'function GetAngle(%sourceObj,%targetObj)
{
%eyeVec =VectorNormalize(%sourceObj.getEyeVector());
%toObjVec =VectorSub(%targetObj.getPosition(),%sourceObj.getPosition());
%dot =VectorDot(%eyeVec,VectorNormalize(%toObjVec));
%rad =mAcos(%dot);
return mRadToDeg(%rad);
}
#8
to:
This is my final product:
Thanks for your help also george.
Marrion cox
08/23/2004 (12:55 pm)
Very Cool. I had to change:Point3F target = tagPlayer->getPosition();
to:
Point3F target = player->getTransform().getPosition();It was crashing the engine because tagPlayer was not set yet.
This is my final product:
// MCOX adding code to determine if the player is in front of the bot Point3F pos = getPosition(); Point3F front; getTransform().getColumn(1, &front); front.normalizeSafe(); //create target vector Point3F target = player->getTransform().getPosition(); target -= pos; target.normalizeSafe(); //determine angle difference F32 angle = mRadToDeg(mAcos(mDot(target, front))); if (mFollowTargetObject != player && angle < 90)Thanks for all your help. I can sleep much better now. You are awsome Drew.
Thanks for your help also george.
Marrion cox
#9
!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!
08/24/2004 (5:55 am)
Still wondering how a non-SDK owner is posting in the SDK forums!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!
#10
Marrion Cox
08/24/2004 (5:59 am)
Who is a non-SDK owner? The company I work for purchased 4 comercial licenses. I am on a team of 4 people.Marrion Cox
#11
08/24/2004 (6:01 am)
Then GG should update your profile to reflect such a thing. It's very confusing to those of us that make it a point to look for such oddities before handing out source code info or other such assistance.
#12
08/24/2004 (6:03 am)
Where on the profile is it listed?
#13
It's not something you can add yourself - it's an automated thing that GG controls - keeps people honest.
In your case, if you are using a team seat - and aren't the person who purchased the licenses - that's why your profile doesn't show it. ;-)
Just email the GG crew - they can clear it up in a jiffy - otherwise you're going to get htis a lot around here. ;-)
08/24/2004 (6:10 am)
In the "Notes" section.It's not something you can add yourself - it's an automated thing that GG controls - keeps people honest.
In your case, if you are using a team seat - and aren't the person who purchased the licenses - that's why your profile doesn't show it. ;-)
Just email the GG crew - they can clear it up in a jiffy - otherwise you're going to get htis a lot around here. ;-)
Torque Owner Drew Hitchcock
(this is C++, it's a chunk of my vehicle AI. It's very similar in script, though.)
In this block "mSteeringHelper" is the bot's target, you would want to swap the player's position in for that. Also, the "getTransform" and "getPosition" are for the BOT, not the player.
I apologise for the messy code (and post), but basically what's going on here is we find the normalized front vector, then we find a normalized "target" vector by subtracting the position from the target and normalizing. We then take the dot product of both normalized vectors, which returns the cosine of the angle between the vectors. Naturally, we want the angle, not the cosine, so we take the arc cosine of that value, and then convert it from radians into degrees. After all that, we have the angle between the two objects, in the range 0-180. If the angle is greater than 90, the player is "behind" the AI.
Normalizing the front vector might be overkill, since it's probably normalized to start with, and the last line is sort of...dense. But hopefully this will help you out. I'm no vector math guru, but I believe this should work out.
EDIT: I've never got that onAttackEnterLOS or whatever function to even get called. I would just have a scheduled think function check things out every once in a while. Also, if the player is set as the AI's target, with the default AI code, I think that has the side effect of making the AI always face the player...never tried it myself, but that's what I've read around these forums. If that's the case, the above code will always return 0.