Jump to content

  • Log In with Google      Sign In   
  • Create Account


Wander behaviour in 3D


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 sheep19   Members   -  Reputation: 388

Like
1Likes
Like

Posted 12 September 2013 - 07:14 AM

Hi,

 

I am implementing a Wander behaviour. In the book I am studying (AI for games), the author uses a 2.5D world.

So what he does is:

Set a circle around the player and put a target that moves on edge of the circle. Then use Seek behaviour to get to it.

 

The problem is that I am in full 3D, so I need something more than a circle. I (naturally) tried a sphere, but I want to be able to define different rotation angles (i.e I want the character to rotate more left/right thatn up/down).

 

As a sphere is defined by two angles (theta and phi), I tried to use a larger value for one of the two to see what happens. But the position of the target depends on both the two angles, so it didn't turn up like I wanted to.

 

This is what I am currently doing:

public SteeringOutput GetSteering()
	{
		SteeringOutput steering = new SteeringOutput();
		
		// set linear velocity at the direction we are moving
		steering.linearVel = character.Transform().forward;
		
		// the velocity is along this direction, at full speed
		steering.linearVel.Normalize();
		steering.linearVel *= maxAcceleration;
		
		theta += Util.RandomBinomial() * maxAngle;
		phi += Util.RandomBinomial() * maxAngle ;
		
		var pos = character.Transform().position;
		pos.x += circleRadius * Mathf.Cos(theta * Mathf.Deg2Rad) * Mathf.Sin(phi * Mathf.Deg2Rad);
		pos.y += circleRadius * Mathf.Sin(theta * Mathf.Deg2Rad) * Mathf.Sin(phi * Mathf.Deg2Rad);
		pos.z += circleRadius * Mathf.Cos(phi * Mathf.Deg2Rad);
		
		target.Transform().position = pos;
		
		steering = seek.GetSteering();
		
		return steering;
	}

What can I do to get the effect I want?

 



Sponsor:

#2 Álvaro   Crossbones+   -  Reputation: 12494

Like
0Likes
Like

Posted 12 September 2013 - 07:49 AM

I have a couple of ideas, but I don't quite know what "the effect you want" is. Perhaps you should describe what you are trying to do in some detail: Is this a bird, a bug, a plane, or a spaceship? Why does it wander?


Edited by Álvaro, 12 September 2013 - 07:49 AM.


#3 sheep19   Members   -  Reputation: 388

Like
0Likes
Like

Posted 12 September 2013 - 09:21 AM

The character I am talking about is a bird.

 

It wanders because I want a behaviour where a bird can move around in space that must look natural. So I can't just make it move at a certain direction. It needs to turn sometimes (sometimes turn more etc) by a random angle.

 

2rh8hh4.png

 

 

That is the bird I talked about.

Now, in 2.5D, to implement that Wander behaviour I could create a circle that the bird is at its center.

Then, an imaginary target would be moving around the circle, each frame moved by a small angle (random).

Then that target is used as the target of a Seek behaviour to make the character (the bird) move toward it.

 

In the image above that blue dot represents the imaginary target that rotates around the player. The blue arrows show the direction at which it can move. But that is in 2.5D.

 

---

 

The above behaviour makes the bird able to rotate around the Y axis only. I want it to be able to rotate around the X axis (that would make it move up/down as well as left/right).

 

So I used a sphere to do this, but I want to be able to set the pace at which the imaginary target rotates around, so that I can make the bird move "more" left/right than up/down. Because a point on a sphere is defined by two angles in polar coordinates, I tried to make one of them smaller that the other. But because x and y of the coordinate depend on both angles, changing one affects the rotation of the target in the other "direction". I hope it is clear now smile.png


Edited by sheep19, 12 September 2013 - 09:23 AM.


#4 Álvaro   Crossbones+   -  Reputation: 12494

Like
0Likes
Like

Posted 12 September 2013 - 09:30 AM

I don't think you want to go with a sphere. This is still 2.5D in some sense, because birds fly mostly horizontally. So I would continue with the idea of the circle, and I would also have some target height, which can follow a Brownian motion similar to what you are doing with the point in the circle (i.e., apply small random increments from frame to frame). If the bird ends up getting too close to the ground, land. You can also cap the target height in some range, or bias the Brownian motion somehow so the bird stays in a reasonable range of heights.



#5 LorenzoGatti   Crossbones+   -  Reputation: 2621

Like
0Likes
Like

Posted 13 September 2013 - 02:17 AM

A bird tends to fly relatively fast and straight, so a simulated one shouldn't have much frame-by-frame noise, only a sequence of random self-assigned waypoints that it passes (or approaches) smoothly and efficiently, making a turn at each (more or less sharp depending on the next destination). The bird can easily transition from random waypoints to meaningful waypoints or directions, for example when it begins chasing a prey or landing. The random distribution of these waypoints determines movement characteristics: decreasing the distance between successive waypoints increases the frequency of turns, presumably perceived as the bird being twitchy or indecisive, while bias towards choosing waypoints in front of the bird (use the velocity vector for reference) determines how aimlessly it wanders (relatively many turns with highly biased waypoints could give the impression of catching and eating unseen insects).
Produci, consuma, crepa

#6 DrEvil   Members   -  Reputation: 1099

Like
1Likes
Like

Posted 14 September 2013 - 01:11 PM

This sounds possibly similar to the behaviors I made for the hostile boats in the Mercenaries 2 game. For that we needed boats that chase the player boat or some other target, which could also be the player flying over in a helicopter. I ended up implementing a simple behavior that was applicable and pretty good looking that applied to both.

 

Basically the boat AI would just seek to the nearest tangent position on a circle around the target. If the target was stationary, this simple behavior would cause them to drive in a circle around the target position, which was great because the guns on the boats, which were mostly able to shoot out the side of their boat, would continue to be able to shoot. If the target was moving, it meant the boat would give chase in such a way that they would be attempting to drive up along side the player, which is a nicer looking behavior than the boat trying to drive directly at the player. If the player cut across their path, they would pick up chase on the other side of your boat, as that would then be the 'nearest' tangent position.

 

This would seem to me a similar behavior potentially for a bird, as they tend to circle areas, especially birds of prey. I would treat the vertical element in a drifing sort of fashion. Allow the altitude to change randomly or with a sort of wander steering behavior where it may drift up and down. The behavior can be adapted when you want them to seek more directly to a target by zeroing out the circle radius. You could also apply a drifting value to the circle radius to add some 'noise' to both the circling behavior and the tangent offset points, which may allow it to look a bit more random and bird like and not so exacting and direct.

 

Then you can give them random points around the game world as waypoints to visit, and they would seek to each based the nearest tangent offset which would drift as the radius of the circle drifts, and it's even more useful if you want a bird to give chase to another dynamic entity or give them paths through the player position and they would fly not directly over the player but at an offset that makes them more visible and provides circling behavior all in one.

 

It's simplistic and isn't a full bird modelling technique, so it depends on what fidelity one is going to be observing whether it will fit your needs.



#7 sheep19   Members   -  Reputation: 388

Like
0Likes
Like

Posted 14 September 2013 - 04:29 PM

Thanks for your replies. This is what I currently do - and it works fairly well:

SteeringOutput steering = new SteeringOutput();
		
		// set linear velocity at the direction we are moving
		steering.linearVel = character.Transform().forward;
		
		// the velocity is along this direction, at full speed
		steering.linearVel.Normalize();
		steering.linearVel *= maxAcceleration;
		
		theta += Util.RandomBinomial() * maxAngle;
		
		yVel += maxYSpeed * Util.RandomBinomial();
		
		var pos = character.Transform().position;
		pos.x += circleRadius * Mathf.Cos(theta * Mathf.Deg2Rad);
		pos.y += yVel * Time.deltaTime;
		pos.z += circleRadius * Mathf.Sin(theta * Mathf.Deg2Rad);
		
		target.Transform().position = pos;
		
		// when speed goes realy low or realy high depending on the maximum speed,
		// change its value
		if( yVel < -10 * maxYSpeed )
			yVel = maxYSpeed;
		
		if( yVel > 10 * maxYSpeed )
			yVel = -maxYSpeed;
		
		steering = seek.GetSteering();
		
		return steering;

So what I do is change the Y velocity by a random number and if it goes really low or really high I make do what do above, so ensure there will not be a chance for the bird to start moving up and then continue to move up because it got "luckily" got more/larger positive values.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS