KeyNotFoundException was unhandled

Topics: Developer Forum, Project Management Forum, User Forum
Apr 7, 2010 at 12:16 AM

So, I got some polygons out there as static walls.  And I got some bullets flying around.  I wanted to replace the collision detection of the engine with that of my own, since I don't want bullets bouncing off walls and people, I want them to hit and do damage (if applicable). 

So first I add in my own collision delegate to the Geom.OnCollision event:

this.m_geom.OnCollision += new CollisionEventHandler(Projectile_Collision);

I throw in my "do damage" method and it works.  Now the problem is I have to get rid of the bullet, here's where the problem happens.

When there is a collision, with whatever, I want to destroy my projectile.  The method I have doing that is this:

public override void Destroy()
{
	base.Destroy();

	SpriteManager.RemoveSprite(m_sprite);
	m_sprite = null;

	m_level = null;
	m_targetUnit = null;

	Commodore.curLevel.removeShot(this);
}

 Below is the base.Destroy from above:

public virtual void Destroy()
{
	SpriteManager.RemovePositionedObject(this);

	if (m_body != null)
	{
		Commodore.physicsSimulator.Remove(m_body);
		m_body.Dispose();
		m_body = null;
	}

	if (m_geom != null)
	{
		//Commodore.physicsSimulator.Remove(m_geom);
		//m_geom.InSimulation = false;
		m_geom.Dispose();
		m_geom = null;
	}
}

Now, my geometries for the walls are close together, and I've noticed that if the projectile collides at a spot where two walls meet, then I get a "KeyNotFoundException was unhandled" message in the DistanceGrid.Collide(...) method.

Here are some images:

Screenshot  Code

I'm not sure if it's a bug or just something I'm doing wrong.  I imagine it happens because there are two collisions on the corner and I remove the shot in the first one and it's not available for the second one.  If there's a better way of removing the geometry and body from the simulator please let me know!

Apr 8, 2010 at 7:48 PM

no one?  How do you usually remove a geometry form the simulator?

Apr 8, 2010 at 8:25 PM

The approach I've seen recommended and use is not to remove and add it to the simulator, but just to enable and disable it.  Heard there was less performance impact that way.  (My personal experience is mixed on this.  Seems I get better performance sometimes by removing it, but haven't adequately stress tested that to see if something else is at work.)

Apr 9, 2010 at 12:49 AM
Edited Apr 9, 2010 at 2:31 AM

I also get this error when I try to run farseer in it's own thread.  Although it happens earlier in the function:

 

 

    public void Collide(Geom geomA, Geom geomB, ContactList contactList)
        {
            int vertexIndex = -1;

            //Lookup distancegrid A data from list
            DistanceGridData geomAGridData = _distanceGrids[geomA.id]; <-------- The Error happens on this line: KeyNotFoundException.

            //Iterate the second geometry vertices
            for (int i = 0; i < geomB.worldVertices.Count; i++)
            {
                if (contactList.Count == PhysicsSimulator.MaxContactsToDetect)
                    break;

                vertexIndex += 1;
                _vertRef = geomB.WorldVertices[i];
                geomA.TransformToLocalCoordinates(ref _vertRef, out _localVertex);

                ...

 

The same exact project does not throw this error if I run farseer in the main thread.

EDIT:

Alright, I put in pools and now I only disable geoms and bodies, and I don't run into this problem anymore.