Advertisement

AI go to a point, why is it not working today!

Started by October 17, 2007 06:59 PM
5 comments, last by ChrisPepper1989 17 years, 4 months ago
Ok im very a much a noob at anything to do with AI but ive just tried to do something i have done before in a different project, which worked, where an ai character follows a target. however for some reason today, even with many different methods to find the angle to rotate by, it refuses to work! ive been staring at it for so long now that i really need someone to cast a fresh eye over it! is my logic just totally messed up? is there a better way of doing it? any suggestions on different ways of approaching this?

RVector diff = this->Target->getPos() - this->getPos(); //difference between destination point and current point
		float distFrom = sqrt(diff.x*diff.x + diff.y*diff.y + diff.z*diff.z); //distance between two points
		if(distFrom > this->Target->BoundingSphere+this->BoundingSphere)  //if it is not already close enough to its target
		{
			RVector aPos = this->Target->getPos();							
			aPos.y = 0;
			
			
			float dirToTarget;									//direction angle to target 

			diff.y = 0.1;										//this stops errors in normalize
			diff.Normalize();
			dirToTarget = (diff.Angle(RVector(0,0,-1)));		//this is meant to give me the angle of the vector from the enemy to the player in relation to the neg z axis, i think this is where the problem is but it has worked before
			

			float sinYaw = (float)sin(dirToTarget);
			float cosYaw = (float)cos(dirToTarget);
	//     
	//		//change pos
			RVector position = this->getPos();
			float theSpeed = this->getSpeed();
			position.x += (float)((cosYaw) * theSpeed);			//facing that way move along by speed
			position.z += (float)((sinYaw) * theSpeed);
			this->setPos(position);


above is a snippet of code that is the current state of it, its very messy as they all used to be in neat other parts of the program but ive just hacked it all together in one bit just to see if it will work an so far it hasnt! at the moment, the ai character will start moving at what seems like a 45degree angle down z (as if its following line x = z) and if the target (i.e. me the player) gets in the way of that path the object moves around me anticlockwise, which is interesting behavoir and no doubt useful for something else but not for what i want! i want the AI character to come to me not move around me to go to some random area on the map! i have tried different ways of getting the angle including this very long way round:

RVector aPos = Target->getPos();
			  RVector a = RVector(this->getPos().x,1,this->getPos().z);
            RVector b = RVector(aPos.x,1,aPos.z);
            RVector c = RVector(aPos.x,0,this->getPos().z);
            float sides[2];
            sides[0] =  (a-c).Length();
            sides[1] =  (a-b).Length();

            float Angle = (acos(sides[0]/sides[1]));
            this->setAngle(Angle);

which did pretty much the same thing, so im assuming that my logic is flawed but im sure this how i have done it time and time again! any help would be greatly appreciated, the problem could be staring me right it the face but i just cant see it, im sure im being very dumb and i will probably kick myself when someone posts an answer! Thank you for taking the time to look at my post and thank you in advance for any replies! p.s. im very tired so excuse the terrible grammer and spelling!
Ditch angles, learn to use vector algrebra. Instead of using an angle for the facing of your agent, use a facing vector.

There is ever hardly any reason to use an angular value in AI logic except when comparing to some threshold, in which case you just do a quick dotproduct.

But every new programmer's reflex is to use angles, because in school they teach you trigonometry before they teach you linear algrebra.
Advertisement
what about when i physically want to rotate the shape itself would i do some of those functions in reverse?

can you point me in the direction of good resources for this?

is it something like CurrentPosVector += DestinationVector*time?

because i tried that thinking that would work and got some very wierd results!

Thank you for the quick reply!
Quote:
Original post by ChrisPepper1989
what about when i physically want to rotate the shape itself would i do some of those functions in reverse?


You could use a rotation matrix, for example


is it something like CurrentPosVector += DestinationVector*time?
Quote:
Original post by ChrisPepper1989



Im not sure what you mean. At the simplest, the facing toward your target is just the "diff" vector in your code.
true, im so used to using glrotate(angle...) that i always think i need an angle to rotate a physical object! my only problem with settin the direction to destination straight away is that the character would instantly turn around, it would be nice to rotate him slowly, im currently trying to do this by:

float x;// = this->dest.Unit().getX(); 	float y;// = this->dest.Unit().getY();	RCoord u1 = this->dest.Unit();	x = u1.getX(); //get unit vector	y = u1.getX();	float x2 = this->getDirUnit().getX();  //get the unit vector of the direction relative to posistion	float y2 =  this->getDirUnit().getY();		float accur = 1000;	//accuracy variable	int xi = x*accur;	int yi = y*accur;	int x2i = x2*accur;	int y2i = y2*accur;	//	x = (float)xi / 1000;	//	y = (float)yi / 1000;	while(x2i != xi && y2i != yi) //atempt to change direction until facing that of the destination. 	{		this->angle+=0.01;		if(angle > 360)		{			angle = 0;		}			setDirByAngle(angle);	//modify direction vector		x2 = this->getDirUnit().getX(); //get back updated x2i		y2 =  this->getDirUnit().getY();		x2i = (x2)*(accur);		y2i = (y2)*(accur);		/*x2 = (float)x2i / 1000; decided to work in ints so that i can effectivly round the points		y2 = (float)y2i / 1000;*/	}	}

which works (assuming that i dont get the line facing the other way first), the direction vector eventually faces the right way, however i assumed that to move the object from its current pos to/past its destination point i could do this:
void RVector::goToDest() {	while(pos.getX() < this->dest.getX() && pos.getY() < this->dest.getY())	{		this->pos.setXY(this->pos.getX() + this->dir.getX(),this->pos.getY() + this->dir.getY());	}	}

but it doesnt seem to work, for example in a test where pos was equal to 10,5 and destination was equal to 70,50, after running the first function and then the second pos ended up at 74,38!

so im a litle confused, im pretty sure ill just be doing something stupid! ill just have to look over it a few times!

figured out the reason the results were off, i was because the end result wasnt accurate enough, but i figure once something close enough has been reached then the direction can be set as the destinations unit vector, this seems to work fine! thanks for your help, vectors does seem the right way to go, and this little investigation into them has helped me understand more about sample code ive previously looked at!
Advertisement
figured out the reason the results were off, i was because the end result wasnt accurate enough, but i figure once something close enough has been reached then the direction can be set as the destinations unit vector, this seems to work fine! thanks for your help, vectors does seem the right way to go, and this little investigation into them has helped me understand more about sample code ive previously looked at!

This topic is closed to new replies.

Advertisement