PDA

View Full Version : Moving my units in 3D



Firlefanz
15-08-2006, 06:49 AM
Hello,

I am currenctly working on a 3D project (for the first time 3d).

I want to release a techdemo soon for everybody to look at :)

Right now I started moving my units.

I have all houses etc stored in a 2dim array. My units are stored in kind of spritelist or meshlist with coordinates as single. They move in small steps in dependency of passed time.

I need some (hopefully simple) pathfinding now and later a collision test with their bounding boxes. Never did that in 3D so I need help.

I just downloaded the AStar sample from William Cairns.

I found two topics:

http://www.pascalgamedevelopment.com/forums/viewtopic.php?t=348

http://www.pascalgamedevelopment.com/forums/viewtopic.php?p=23808#23808

Now I wonder which of the both samples will be better and easier for me?

I want to set a target position for my untis and then they should move there step for step without visiting array fields that contain a house or something.

Right now they get an angle when getting a new target position and they go along with that angle until they arrive (I can also post code).

Thanks,
Firle

czar
15-08-2006, 07:52 AM
It sounds like you need to put the location of the house into the A* routine as unpassable or expensive nodes.

Firlefanz
15-08-2006, 08:32 AM
Sure. I just want to know which of those both fits best.

And maybe then I need some help including and using it.

Firle

Huehnerschaender
15-08-2006, 11:04 AM
Is your map tiled in squares? If so, just setting a tile where a house is placed on to unpassable is not the best approach. What if the house is smaller/bigger than the tile? If its smaller than a tile, the unit could avoid the house by driving/walking near the house, but ON that tile.

If the house is sized 2 times a tile, it covers the surrounding map tiles half, too. I hope you get my idea.

Obstacles should be observed as objects with position and size. Not as grids of the map. Otherwise you will get problems when objects don't have the size of your map grid.

I am not very good at pathfinding, but that was the first thing which appeared to me when I started giving AI to my units in TANX.
I decided to go a completely other way then. The units got sensors, which look at the near surroundings and if the sensors collide with objects, the units adjust their direction/speed.

It would be great to get some more information about you level design. This could help in giving tips on how you implement your pathfinding the best way.

Take a look at the demo of opensteer. I did not use the library, but I got the idea from there and coded my own for my needs (much simplier).

http://sourceforge.net/project/showfiles.php?group_id=77546

But as I already said, it all depends on your game. I don't know anything about your level design, just want to point you to some problems which could appear.

NecroDOME
15-08-2006, 11:15 AM
You could als place padnodes. From this you can use your units to walk beteen the nodes. (Make sure nodes "see" each other). In this case you can set pathnodes around the house so your units will move around it.

You also need to do is plan a route if you want to go from point A to point B.

Firlefanz
15-08-2006, 12:54 PM
Hi,

thank you both for the infos :)

I have a 2 dim Array where right now each obstancle has a value>0, all empty fields have 0.

My houses may be larger or smaller than one field, and trees are smaller in every case I guess.

That's why I thought I'd combine a pathfinding with a bounding box collision detection so they always do the next step and when they collide, they got set back to last position with a new pathfinding with this field marked somehow I don't know exactly. There can also be collisions with other moving meshes/units...

This is why I have some problems here.

The moving is simple, there are some fields the villagers are randomly sent to to 'work' there. they are just moving between those fields.

The monsters later should run after the villagers and kill/eat them.

Those both should not move 'trough' houses trees etc and also not 'through' other moving units.

An approach would be enough if they make a 'large' way round the house it is okay, they just should not walk right 'through' it.

Here some code of the villagers, they now always walk the shortest way set by the starting angle to the target point.



MeshBauer = class(TDJXSprite)
boolstand: boolean;
nsx,nsy,nsz,nspeed,nHOff: single;
Radius: single;
ntyp: integer;
nanimpos,nrotatey: single;
ntargetx,ntargetz: single;
procedure Process(SpeedFactor: single); override;
procedure Draw; override;
end;

procedure TForm1.add_bauer(nx,nz: single);
begin
with MeshBauer.Create(Engine) do
begin
nspeed:=0.025;
ntyp:=0;
nsx:=0.19;
nsy:=nsx;
nsz:=nsx;
x:=nx;
z:=nz;
get_bauerntarget(ntargetx,ntargetz);
Radius:=15;
nrotatey:=GetAngle(x,z,ntargetx,ntargetz);
end;
end;

procedure MeshBauer.Draw;
var mesh: tdjxmesh;
nanim: integer;
begin
inherited;
if boolstand then nanim:=0 else nanim:=1;
mesh:=form1.MeshListBauer.Meshes[nanim];
Form1.DanJetX1.Matrices3D.ClearWorldMatrix;
Form1.DanJetX1.Matrices3D.ScaleWorld(nsx,nsy,nsz);
Form1.DanJetX1.Matrices3D.MoveWorld(x,y,z);
Form1.DanJetX1.Matrices3D.ApplyWorldMatrix;
if mesh.IsInFrustum then mesh.render(x,y,z,0,-nrotatey-pi/2,0,nsx,nsy,nsz,round(nanimpos));
nanimpos:=nanimpos+nSpeed*time_elapsed;
end;

procedure MeshBauer.Process(SpeedFactor: single);
var tx,tz: double;
begin
inherited;
if not boolstand then begin
//Falls Entfernung geringer als Geschwindigkeit direkt ans Ziel setzen
if Distance&#40;x,z,ntargetx,ntargetz&#41; < time_elapsed/36 then
begin
boolstand&#58;=true;
form1.get_innomtarget&#40;ntargetx,ntargetz&#41;;
nrotatey&#58;=GetAngle&#40;x,z,ntargetx,ntargetz&#41;;
end else begin
//Eigentliches Bewegen
tx&#58;=x;
tz&#58;=z;
form1.move_forward&#40;tx,tz,nrotatey,time_elapsed/36&#41;;
x&#58;=tx;
z&#58;=tz;
end;
Y&#58;=Landscape.Altitude&#91;X,Z&#93;+0.65;
end;
end;



Understandable? Don't care about the draw method, it is working great,
it is just how I move them now.

get_Bauerntarget just delievers the Target location to walk to.



procedure TForm1.move_forward&#40;var X, Z&#58; double; nRotate,nSpeed&#58; single&#41;;
var Dir&#58; TD3DXVector3;
begin
Dir.X &#58;= cos&#40;nRotate&#41;;
Dir.Z &#58;= sin&#40;nRotate&#41;;
X&#58;=X+nSpeed*Dir.X*time_elapsed;
Z&#58;=Z+nSpeed*Dir.Z*time_elapsed;
end;

//Berechnung der Entfernung zweier Punkte&#58;
function Distance&#40;x,y,x2,y2&#58; single&#41;&#58; Real;
begin
Result &#58;= sqrt&#40; sqr&#40;y2-y&#41; + sqr&#40;x2-x&#41; &#41;;
end;

//Winkel einer Strecke zwischen zwei Punkten&#58;
function GetAngle&#40;x, y, x2, y2&#58; single&#41;&#58; Real;
begin
Result&#58;=arctan2&#40;y2-y, x2-x&#41;;
end;


@Huehnerschaender: I am not good at C++ so I think I will not read that sample, or is it so good? 8)

Right now they don't care about any stuff in my 2dim array, it looks like this:

TLevel=Array[0..levelb,0..levelh] of byte;

where Levelb and Levelh both are 256 currently.

Thanks a lot,
firle

Huehnerschaender
15-08-2006, 03:26 PM
Ok, first your MeshBauer needs a List of points where to go next.

This is what you will get with the appropriate Pathfinding system.

The "Bauer" should always target the next point in the list. If it is reached, the point should be deleted from the list, giving the "Bauer" the next point to go to.

In case of something special (e.g. movable obstacle), the "Bauer" should react to it. This can be done by stopping and calculating a new way depending on the current situation (clear waypoint list and create the new entrys with your pathfinding algorithm again).

Thats just theory.. the pathfinding itself still needs to be done here. Maybe someone else can help here better than me (I could use this, too!).

Firle, the demo I linked has an EXE included. Just take a look at it to get an idea on how to use sensors on movable objects. I didn't take a look at the code, too, but I got ideas from the demo. The units will move much more realistic because the way isn't precalculated and the unit itself has to decide what to do when obstacles are in their way.

Firlefanz
15-08-2006, 03:37 PM
Okay Huehernschaender, I understand what you explained :D

And I guess this is the way to do it. I will look at Cairns sample and at the C++ demo, thank you :D

I will post success or no success :wink:

Firle