Temporarily disabling collision?
by Dreamer · in Torque Game Engine · 06/02/2005 (12:58 pm) · 6 replies
I'm curious to know if there is a way to temporarily disable collision on an object.
I have a loop that will spawn roughly 50 aiPlayers, at random places on the map, at random times, however for some reason every single time I run, anywhere from 1-10 of these players will spawn at exactly the same point, thereby being "stuck" inside one another, since each has a loop to pick a new direction and start running as soon as a collision occurs, this causes them all to spin around frantically in a ball, that while humorous to watch, causes my logfile to bloat to immense proportions. I figure if I can count how many times a collision has occured in a set time period (say 5 seconds), that would give me an indication as to whether or not the poor guy is stuck, and when he is stuck, just have him turn off collision for a few seconds, and magically pass through the rest of the mess.
Anyways, if you know how to solve this or know if there is an even better way to solve this I would be very greatful to know.
Thanks in advance!
I have a loop that will spawn roughly 50 aiPlayers, at random places on the map, at random times, however for some reason every single time I run, anywhere from 1-10 of these players will spawn at exactly the same point, thereby being "stuck" inside one another, since each has a loop to pick a new direction and start running as soon as a collision occurs, this causes them all to spin around frantically in a ball, that while humorous to watch, causes my logfile to bloat to immense proportions. I figure if I can count how many times a collision has occured in a set time period (say 5 seconds), that would give me an indication as to whether or not the poor guy is stuck, and when he is stuck, just have him turn off collision for a few seconds, and magically pass through the rest of the mess.
Anyways, if you know how to solve this or know if there is an even better way to solve this I would be very greatful to know.
Thanks in advance!
#2
06/02/2005 (3:21 pm)
I'm already doing that, but if 2 or more objects spawn at the same time, then they will spawn at exactly the same location, and have tangled up collision boxes.
#3
The above function names are Way Off (as well as most of the parameters I'd imagine), but the idea seems sound. The explosion test in particular will be Just Plain Wrong. It takes at least 3 parameters, and I have no idea what its return value is.
Goofy Workarounds:
GW #1: Don't spawn more than 2 at the same time. You might be able to get away with setting up a number of spawns with the scheduler within a tenth of a second (or whatever). They'd seem simultaneous to a human, but we'd know better. ;) But its possible you'd need to wait for a game tick between spawns, which may be too slow (based on machine specs and the number of AIs being spawned).
GW #2: Keep a list of previous spawn locations so you don't need to depend on game geometry for "nearness tests". Loop through all the previous locations and bail if any of them are within X of the current one. A bit of sorting would speed this sort of thing up quite a bit (pun intended).
GW #3: Partition the spawn area into some kind of grid and only allow each 'cell' to be used once.
If you had a 5x10 grid, you could stick an AI at the center of each one, then ofset them from the center of their cell by some random amount (but keep the distance small enough to avoid collisions with neighbors). If you want a variable density (so its possible to have most of the AIs on one half of the map), you could have more cells than AIs, and just make sure to use each cell only once. With a fine enough grid, you could just use their centers rather than throwing in a random offset... though you don't want your grid to be so fine that two adjacent cells could have overlapping AIs.
-------
HEY!
I'd also advise taking a long look at your Random Number Generator (RNG). Unless you're operating inside some kind of probability distortion field, the odds of up to 1/5 of your spawns at random locations being EXACTLY THE SAME are vanishingly small (unless the area they're spawning in is Very Small).
But addressing only the RNG means it'll still happen from time to time, though seldom with more than two AIs at the same location. Still funky.
06/02/2005 (11:47 pm)
So this sort of thing won't work?for( i = 0; i < 50; ++i) {
badSpot = true;
while(badSpot) {
genLoc = BuildRandomLocation();
if (useExplosionFunctionThingy( genLoc, someRadius) == hitAPlayer) {
badSpot = false;
}
}
spawnAIPlayerAtLocation( genLoc );
}The above function names are Way Off (as well as most of the parameters I'd imagine), but the idea seems sound. The explosion test in particular will be Just Plain Wrong. It takes at least 3 parameters, and I have no idea what its return value is.
Goofy Workarounds:
GW #1: Don't spawn more than 2 at the same time. You might be able to get away with setting up a number of spawns with the scheduler within a tenth of a second (or whatever). They'd seem simultaneous to a human, but we'd know better. ;) But its possible you'd need to wait for a game tick between spawns, which may be too slow (based on machine specs and the number of AIs being spawned).
GW #2: Keep a list of previous spawn locations so you don't need to depend on game geometry for "nearness tests". Loop through all the previous locations and bail if any of them are within X of the current one. A bit of sorting would speed this sort of thing up quite a bit (pun intended).
GW #3: Partition the spawn area into some kind of grid and only allow each 'cell' to be used once.
If you had a 5x10 grid, you could stick an AI at the center of each one, then ofset them from the center of their cell by some random amount (but keep the distance small enough to avoid collisions with neighbors). If you want a variable density (so its possible to have most of the AIs on one half of the map), you could have more cells than AIs, and just make sure to use each cell only once. With a fine enough grid, you could just use their centers rather than throwing in a random offset... though you don't want your grid to be so fine that two adjacent cells could have overlapping AIs.
-------
HEY!
I'd also advise taking a long look at your Random Number Generator (RNG). Unless you're operating inside some kind of probability distortion field, the odds of up to 1/5 of your spawns at random locations being EXACTLY THE SAME are vanishingly small (unless the area they're spawning in is Very Small).
But addressing only the RNG means it'll still happen from time to time, though seldom with more than two AIs at the same location. Still funky.
#4
1, Move your spawn point some height above the ground and have a slight delay between spawns so that the first aiplayer would have time to fall to the ground away from the spawn point before the next aiplayer spawned there.
2, Apply an impulse to each aiplayer as they are spawned in a horizontal direction (perhaps on a loop 1st one North, 2nd East, 3rd South, 4th West, 5th one North again etc etc) to push them away from the spawn point before the next aiplayer spawned.
3, Use a random small distance offset (perhaps looped N,E,S,W again) to add variation to the exact spawn points.
06/03/2005 (9:21 am)
@ Dreamer - A couple of ways I could think of trying off the top of my head :-1, Move your spawn point some height above the ground and have a slight delay between spawns so that the first aiplayer would have time to fall to the ground away from the spawn point before the next aiplayer spawned there.
2, Apply an impulse to each aiplayer as they are spawned in a horizontal direction (perhaps on a loop 1st one North, 2nd East, 3rd South, 4th West, 5th one North again etc etc) to push them away from the spawn point before the next aiplayer spawned.
3, Use a random small distance offset (perhaps looped N,E,S,W again) to add variation to the exact spawn points.
#5
Will place them within the radius specified in the spawnsphere object on the ground with no collisions occuring with the rotation of the spehere.
06/03/2005 (11:11 am)
My only suggestion..function getTerrainLevel(%pos, %rad)
{
while(%retries < 500)
{
%x = getWord(%pos, 0) + mFloor(getRandom(%rad * 2) - %rad);
%y = getWord(%pos, 1) + mFloor(getRandom(%rad * 2) - %rad);
%z = getWord(%pos, 2) + mFloor(getRandom(%rad * 2) - %rad);
%start = %x @ " " @ %y @ " 5000";
%end = %x @ " " @ %y @ " -1";
%ground = containerRayCast(%start, %end, ($TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType), 0);
%z = getWord(%ground, 3);
%z += 3.5;
%position = %x @ " " @ %y @ " " @ %z;
%mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType |
$TypeMasks::StaticShapeObjectType | $TypeMasks::PlayerObjectType);
if (ContainerBoxEmpty(%mask, %position, 3.5))
{
//error ("Position Is Good");
return %position;
}
else
%retries++;
}
return "0 0 300 1 0 0 0";
}
function pickSpawnPoint()
{
%groupName = "MissionGroup/PlayerDropPoints";
%group = nameToID(%groupName);
if(%group != -1)
{
%count = %group.getCount();
if (%count != 0)
{
%index = getRandom(%count-1);
%spawn = %group.getObject(%index);
%trans = %spawn.getTransForm();
%pos = getTerrainLevel(%spawn.getPosition(), %spawn.radius);
%rot = getWord(%trans, 3) SPC getWord(%trans, 4) SPC getWord(%trans, 5) SPC getWord(%trans, 6);
return( %pos SPC %rot );
}
else
error("No spawn points found in " @ %groupName);
}
else
error("Missing spawn points group " @ %groupName);
// If we can't find any group or spawn points, stick the player at mission center
return "0 0 300 1 0 0 0";
}Will place them within the radius specified in the spawnsphere object on the ground with no collisions occuring with the rotation of the spehere.
#6
Instead of
06/03/2005 (11:17 am)
One other note. Calling the spawn function via a loop directly is going to cause problems. What you want to do call a schedule to the function in the loop instead at a time of 0. I would try this before re-writing the spawn code.for(%i = 0; %i < 50; %i++) schedule(0, 0, "spawnBot");
Instead of
for(%i = 0; %i < 50; %i++) spawnBot();
Torque Owner Mark Storer