2000+ Bullets in one scene damage detetection

As the title says, i am making a space rts and in 2v2 multiplayer match where each player can have up to 320 units at the same time, i managed to make the basic targeting scripts and movement+selection work in such a way that i can run the game at about 60+(with v sync) fps but when i try implementing bullets , the physics is simply too much even for my 3.3 ghz hexacore. any idea on a system that requires less physics or another implementation? I considered making one big particle system and even combining all bullets in a skinned mesh but… the skinned mesh is over my level and shuriken doesn’t have collisions.

So you mean to say that each bullet is an object that is launched, has a collider etc etc?

That is way too much. I would instead launch a raycast from the unit and store the position where it hits, then lerp a bullet particle across the distance it needs to travel. If there is a hit, play whatever script you find fit on the enemy.

But then would there be a way to check of the enemy unit dodged the bullet? as in moves out of its path. like a small fighter dodging a enemy plasma canon. and the plasma cannon hitting an allied ship who was accidently in the way?

Oh, so that is your plan…

Well, how are you working it out now? Does every object have an OnCollide or similar event? Each bullet a rigidbody?

The best way I can think of, and a friend of mine told me should work, is creating a list of bullets and iterating through them, applying a raycast the lenght of (speed/Time.deltaTime) – if no collision, move the bullet, if collision, do something. This way, you don’t need a ton of rigidbodies swooping around. Make sure the bullets are the last to be checked though. And I’m not sure the ray detects if it is inside the object (f.e. a large ship drives into a plasma ball from the side or behind.)

I advice you to not use complete physic for that. One possibility is to manage all the bullets by yourself in a script.

  • Do not look for full bullet mesh colllision, instead use only bullet’s position and some math to detect impact with ships.
  • You can aggregate the bullets in groups. For example battleship A fires 3 missiles to battleship B, but you consider the 3 missiles as only one and explode them all on collision. On a space RTS the player will not see the difference.
  • You should use a layer system to check collisions of teamA’s missiles only with teamB’s structures.

Don’t mean to hijack the thread, but regarding the whole thing with collisions, is there a way not involving iterating through all gameobjects to check if a bullet collided with a spaceship from any direcition?

Example:

Bullet moves forward, a ship hits it from the right (literally drives into it). Would the ship cast a ray and detect the bullet? If yes, would the bullet only have to have a collider? (no rigidbody)

There’s many examples on these forums on how to use raycasts, but still have visible bullets with actual speed.

I’ve done it myself and the way I did it was to move my bullet object forwards every frame and the raycast from the position it was in the last frame to the position it is in the current frame. This was I would always get correct collisions and my bullet could move very slow or very fast depending on my needs.

However, I don’t think I had 2000 bullets at once, but I did have a minigun that fired 100 rounds per second so I’m sure I was close and it worked fine for me. :slight_smile:

Doing it with particle systems is also possibility. All the bullets and impacts in this “game” is the same particle system so it’s just 1 draw call: http://twiik.net/unity/gridwars-clone

Using a space partitioning algorithm can be a good way to avoid testing something like bullets^units each frame.

just tested out Nems idea with the mathematical approach by simulating the worst scenario complexion : 960*1280 if i decide to add bots. just added this code in the update loop of every turret (I don’t how how to add code brackets) :

function test()
{
for(var i =0; i<960;i++)
{
var q= 3+5;
var a= 3+5;
var f= 3+5;
var g= 3+5;
var t= 3+5;
}

}

got 60-ish fps , so a medium PC would get 20 + ; Also regarding the particles, does anyone know how expensive is a particle collider relative to the number of particles, as in is it the equivalent of one Collider per particle or is it more efficient. Also, tikk, mind if you send me the script you put on that particle system you put on that game of yours? is just seems wickedly perfect for what I`m trying.
Also i have no idea how a space partitioning algorithm works.

Hummm…

If you need computation power, I would suggest you to use strict typing even in JS, make use of temp variable (so avoid to allocate memory in a loop) and use some partitioning algo to cut down collision tests.

In C# (wihtout space partitioning) :

void LateUpdate()
{
for(int i = 0; i < 960 ; ++i)
{
        Projectile proj = projectileArray[i];    // an array not a list
        for(int j = 0; j < battleshipCount; ++j)
        {
                Battleship ship = battleshipArray[j];
                if(ship.mathematicalCollisionCheckOnVerySimplifiedShipShape(proj.position))
                {
                        proj.OnHit(ship);
                }
        }
}
}

And :

private Vector3 tempVector;
public bool mathematicalCollisionCheckOnVerySimplifiedShipShape(Vector3 bulletPos)
{
        tempVector = bulletPos - shipPos;
        return tempVector.sqrMagnitude < this.sqrDetectionRadius;
}

Notice the LateUpdate use instead of Update.

void LateUpdate()
{
Projectile proj ;
for(int i = 0; i < 960 ; ++i)
{
        proj = projectileArray[i];    // an array not a list
        for(int j = 0; j < battleshipCount; ++j)
        {
                Battleship ship = battleshipArray[j];
                if(ship.mathematicalCollisionCheckOnVerySimplifiedShipShape(proj.position))
                {
                        proj.OnHit(ship);
                }
        }
}
}

Without 960 memory allocation per update :slight_smile:

I believe the compiler optimizes this, and in some cases may be optimized faster if Projectile is defined inside the loop (for example, if placed inside the loop compiler can place it in a register). So if the compiler is doing the optimizations I would expect it to do, then your suggestion of placing the variable outside the loop is slower.

http://stackoverflow.com/a/2056349

Damn, you’re right :slight_smile:

Why would you use an array when the number of objects is variable? I believed that you cannot dynamically add to an array?

Could be that it was just an example, or they have a fixed array for performance reasons.

quoted, because it’s the answer with that many bullets.

That’s .net, not mono. They don’t use the same compiler at all. They use the same language though. You’ll need to do actual tests.

Compilers (in general) tend to perform these type of optimizations, so it’s sort of expected from modern compilers, but I def agree with hippo; there’s no better source of knowledge than actually doing your own test.

no we don’t, i didn’t bother numbering every single bullet, that’s why i said 2000+ its a number which is anywhere between 1 and 4 k since you can have up to 1280 ships shooting at a time and a turret might shoot again before a bullet reaches its target. and yes you can ad to arrays using .push()

In case of mono i wouldn’t assume that. Especially with an old Mono version as Unity3d uses (Mono 2.6 iirc, current MonoDevelopment is at 2.10.8 (Mono got new GC with 2.8 iirc).

Also Microsoft uses specialists, so they have more likey optimization mono doesn’t have. And from what I got (and observered so far), Unity doesn’t seem to use JIT, which removes many of the runtime optimizations the .NET Framework usually does (no idea about mono) and this can be very problematic, when you are “rely” on the JITter to inline certain Property calls for increased performance.