AI Aim Speed
by Nicolai Dutka · in Torque Game Engine · 10/27/2007 (12:17 pm) · 9 replies
I need my bot to aim like instantly. How do I do that?
Here is my real problem:
I am doing a sort of golf game with a group at school and need the player's to be aiming at the hole at the beginning of their turn. We spawn an AI "aiming bot" and have it aim at the hole, set the player's transform equal to the aiming bot transform, then delete the aiming bot. Problem is, the aiming bot doesn't aim fast enough so the player ends up aiming the wrong way.
Is there a better way to force the player to look at an object?
Here is my real problem:
I am doing a sort of golf game with a group at school and need the player's to be aiming at the hole at the beginning of their turn. We spawn an AI "aiming bot" and have it aim at the hole, set the player's transform equal to the aiming bot transform, then delete the aiming bot. Problem is, the aiming bot doesn't aim fast enough so the player ends up aiming the wrong way.
Is there a better way to force the player to look at an object?
#2
I see new doorways opening...
:)
10/30/2007 (11:57 am)
Wow. Totally off topic, but thank you for explaining that! :P Is the matrix you describe the way Torque stores stuff by default? All the times you see mat.getColumn(3,point)?I see new doorways opening...
:)
#3
If anyone has this already or at least a head start, please post what you have here. I don't know how long it will be before I can even start this, but once finished, I am sure it is something that could be used in almost ANY game for a wide variety of things.
Of course, I will post back here when I have something. (My next post will hopefully be a link to a resource!) :D
10/30/2007 (1:01 pm)
I am planning to write a 'lookAtTarget' function as follows:function lookAtTarget( %this, %target )
{
//code will eventually go here to make %this look at %target given that both are valid objects in the world
}If anyone has this already or at least a head start, please post what you have here. I don't know how long it will be before I can even start this, but once finished, I am sure it is something that could be used in almost ANY game for a wide variety of things.
Of course, I will post back here when I have something. (My next post will hopefully be a link to a resource!) :D
#4
Also, @Daniel, this is exactly how Torque uses matrices.
This is a quick rough draft from memory.. Maybe I used some script functions wrong or maybe I used the wrong names for a function or two, or maybe it works. I dunno.
Optionally something like this works too:
10/30/2007 (4:20 pm)
Lol, thats not off topic. Thats exactly how to solve his problem.Also, @Daniel, this is exactly how Torque uses matrices.
This is a quick rough draft from memory.. Maybe I used some script functions wrong or maybe I used the wrong names for a function or two, or maybe it works. I dunno.
function lookAtTarget( %this, %target )
{
%forward = VetorSub(%target.getPosition(), %this.getPosition());
VectorNormalize(%forward);
%up = "0 0 1";
%right = mCross(%forward, %up);
%forward = mCross(%up, %right);
[b] %transform = // build the matrix. not sure how to do this from script[/b]
%this.setTransform(%transform);
}Optionally something like this works too:
function lookAtTarget( %this, %target )
{
%forward = VetorSub(%target.getPosition(), %this.getPosition());
%x = getWord(%forward, 0);
%y = getWord(%forward, 1);
%angle = -mAtan(-%x, %y);
// make trans from position, axis and angle
%trans = %target.getPosition();
%trans = %trans SPC "0 1 0" SPC %angle;
%this.setTransform(%trans);
}
#5
We echo out the %trans before adding the angle and after adding the angle and then we echo the player's transform at the end.
The player's rotation always echoes out to "1 0 0 0" even though we are setting it to "0 1 0 %angle"....
10/31/2007 (8:43 am)
After some trial runs and inserting some echo statements, we have determined that the angle is not being effected.function lookAtTarget( %this, %target )
{
%forward = VetorSub(%target.getPosition(), %this.getPosition());
%x = getWord(%forward, 0);
%y = getWord(%forward, 1);
%angle = -mAtan(-%x, %y);
// make trans from position, axis and angle
%trans = %target.getPosition();
%trans = %trans SPC "0 1 0" SPC %angle;
%this.setTransform(%trans);
}We echo out the %trans before adding the angle and after adding the angle and then we echo the player's transform at the end.
The player's rotation always echoes out to "1 0 0 0" even though we are setting it to "0 1 0 %angle"....
#6
Turns out we were simply rotating on the wrong axis. Here it is and it works!
10/31/2007 (8:49 am)
OMG!Turns out we were simply rotating on the wrong axis. Here it is and it works!
function lookAtTarget( %this, %target )
{
%forward = VectorSub(%target.getPosition(), %this.getPosition());
%x = getWord(%forward, 0);
%y = getWord(%forward, 1);
%angle = -mAtan(-%x, %y);
// make trans from position, axis and angle
%trans = %this.getPosition();
%trans = %trans SPC [b]"0 0 1"[/b] SPC %angle;
%this.setTransform(%trans);
}
#7
11/07/2007 (3:22 pm)
Ya so it turns out this only rotates %this left and right to look at %target. Next, we need something to make %this look up/down at the %target as well. Any thoughts?
#8
The previous section (in AIPlayer) deals with pitch. Lets have a go in script:
I hope this works!
For some reason before I was thinking you didn't need the pitch.... Sorry :)
11/07/2007 (7:26 pm)
As it turns out, I've taken the above code from the AIPlayer and modified for your use in TorqueScript.The previous section (in AIPlayer) deals with pitch. Lets have a go in script:
function lookAtTarget( %this, %target )
{
// C++ code
// F32 vertDist = diffVec.z + 1.0f;
// F32 horzDist = mSqrt(diffVec.x * diffVec.x + diffVec.y * diffVec.y);
// F32 newPitch = mAtan( horzDist, vertDist ) - ( M_PI / 2.0f );
// diff.normalize();
// F32 newYaw = mAtan( diffVec.x, diffVec.y);
%diff = VectorSub(%target.getPosition(), %this.getPosition());
// normalizing prevents yaw from going over/under 360 degrees
%forward = VectorNormalize(%diff);
%dX = getWord(%diff, 0);
%dY = getWord(%diff, 1);
%dZ = getWord(%diff, 2);
%vD = %dZ + 1.0;
%hD = mSqrt(%dX * %dX + %dY * %dY);
%pitch = mAtan(%hD, %vD) - (3.14159265358 * 0.5);
%fX = getWord(%forward, 0);
%fY = getWord(%forward, 1);
%yaw = -mAtan(-%fX, %fY);
// create matrix from eulers since we have yaw and pitch
%trans = MatrixCreateFromEuler(%pitch SPC "0" SPC %yaw);
%trans = %this.getPosition() SPC getWords(%trans, 3);
%this.setTransform(%trans);
}I hope this works!
For some reason before I was thinking you didn't need the pitch.... Sorry :)
#9
...just like this post. Meh.
11/08/2007 (7:34 am)
Brian: No, I meant I was off topic, not you. I didn't really contribute anything useful to the thread......just like this post. Meh.
Torque Owner Michael Bacon
Default Studio Name
I don't know that you could make this work without showing the bot for a split second.
What you should really do is figure out the direction to face your player and rotate him properly.
So...
How about this.
I'm only going to describe the process, your gonna have to figure out how to put it into torquescript.
You want to get a forward vector (aka 'facing' vector). This vector points in the direction you want to face.
In your case: (holePosition - playerPosition).normalize()
Next lets get an Up vector (which way is up?). In our case Torque Up is (0,0,1). Since our player's always stand straight up this will do (if your players lean or conform to terrain you'll need one more step that I wont explain unless you need it).
Then we need a right vector. The handy dandy cross product will give us this given our Forward and our Up. Forward X Up (the crossproduct between forward and up) gives us Right.
Finally we need to recorrect our forward vector (we want to take out any pitch) otherwise the matrix could get skewed.
So cross Up and Right to re-get a new Forward.
Now put it all together in a matrix.
Each column in a matrix represent something..
Column 0: Right
Column 1: Forward
Column 2: Up
Column 3: Position
If you'd like to see this work in code look at MathUtils.cc the method createOrientFromDir().
This method will produce a matrix that is orientated straight up and down (z axis is aligned with world) but will rotate to face any direction.