简体   繁体   中英

XNA 3D Bounding Box Collision Not Triggering

I've been browsing for about a hour and a half orso for a solution to this problem. I did see some threads on Xbox Live Indie Development forums but the actual forums aren't loading (Have they been taken down?) And everywhere else I look I can't find an answer.

The problem I'm having is that I can't get any sort of Intersect to trigger between two BoundingBoxes. I've created a cube in 3D space and then put a box at the opposing vertices, that box seems to be fine from what I can tell in the Output. As is the camera's BoundingBox <-- For it I took the player's position and +- 1 on every axis for the min/max. I originally intended to just re-use the playerposition for both min and max but that wasn't working so I tried this but it still doesn't work.

Here's some snippets of my code.

    void CheckCollision(Vector3 inPos, Vector3 inOldPos) //The idea for the inPos and
old position was that I'd reset the player's position to the old pos if there's a collision
    {
        if (block.collisionBox.Intersects(cam.cameraBox))
        {
            Debug.WriteLine("HELP"); //This doesn't trigger
        }
    }

The next is the Update in the main Game class.

        protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        CheckCollision(cam.Position, cam.comparisonVector);

        base.Update(gameTime);
    }

Now moving onto the Cube's class.

        private void SetUpVertices()
    {
        vertices = new VertexPositionColor[8];

        //front left bottom corner
        vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), color);
        //front left upper corner
        vertices[1] = new VertexPositionColor(new Vector3(0, 5, 0), color);
        //front right upper corner
        vertices[2] = new VertexPositionColor(new Vector3(5, 5, 0), color);
        //front lower right corner
        vertices[3] = new VertexPositionColor(new Vector3(5, 0, 0), color);
        //back left lower corner
        vertices[4] = new VertexPositionColor(new Vector3(0, 0, -5), color);
        //back left upper corner
        vertices[5] = new VertexPositionColor(new Vector3(0, 5, -5), color);
        //back right upper corner
        vertices[6] = new VertexPositionColor(new Vector3(5, 5, -5), color);
        //back right lower corner
        vertices[7] = new VertexPositionColor(new Vector3(5, 0, -5), color);

        collisionBox = new BoundingBox(vertices[0].Position, vertices[6].Position);

        vBuffer = new VertexBuffer(device, typeof(VertexPositionColor), 8, BufferUsage.WriteOnly);
        vBuffer.SetData<VertexPositionColor>(vertices);
    }

And finally the Camera's class.

        void UpdateBoundingBox()
    {
        cameraBox = new BoundingBox(cameraPosition + new Vector3(-1, -1, -1), cameraPosition + new Vector3(1,1,1));
    }

If you want anything else just let me know :) I appreciate any help, thanks

The problem is with the min and max coordinates of your collision box. The collision boxes min is at [0,0,0] and the max is [5,5,-5].

A bounding boxes max coordinate should always be greater on the x, y and z component than the min, otherwise you can create a bounding box with "negative" thickness on one or more dimensions (or commonly referred to as an inside out box).

You can get the correct min and max of your bounding box with the following modification. The idea here being to simply compare the x,y and z component of each vertex looking for the lowest x value of all of the vertices, the lowest y value and the lowest z value which becomes the new min of your box. The same is done to obtain the max coordinate. (Possibly not the most efficient code, but as a working example it gets the job done nonetheless).

Vector3 MinResult(Vector3 u, Vector3 v)
  {
     Vector3 minVec = v;

     if (u.X < v.X)
     {
        minVec.X = u.X;
     }

     if (u.Y < v.Y)
     {
        minVec.Y = u.Y;
     }

     if (u.Z < v.Z)
     {
        minVec.Z = u.Z;
     }

     return minVec;
  }

  Vector3 MaxResult(Vector3 u, Vector3 v)
  {
     Vector3 maxVec = v;

     if (u.X > v.X)
     {
        maxVec.X = u.X;
     }

     if (u.Y > v.Y)
     {
        maxVec.Y = u.Y;
     }

     if (u.Z > v.Z)
     {
        maxVec.Z = u.Z;
     }

     return maxVec;
  }

private void SetUpVertices()
{
     vertices = new VertexPositionColor[8];

     //front left bottom corner
     vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), color);
     //front left upper corner
     vertices[1] = new VertexPositionColor(new Vector3(0, 5, 0), color);
     //front right upper corner
     vertices[2] = new VertexPositionColor(new Vector3(5, 5, 0), color);
     //front lower right corner
     vertices[3] = new VertexPositionColor(new Vector3(5, 0, 0), color);
     //back left lower corner
     vertices[4] = new VertexPositionColor(new Vector3(0, 0, -5), color);
     //back left upper corner
     vertices[5] = new VertexPositionColor(new Vector3(0, 5, -5), color);
     //back right upper corner
     vertices[6] = new VertexPositionColor(new Vector3(5, 5, -5), color);
     //back right lower corner
     vertices[7] = new VertexPositionColor(new Vector3(5, 0, -5), color);

     Vector3 max = vertices[0].Position;
     Vector3 min = vertices[0].Position;

     foreach(VertexPositionColor vc in vertices)
     {
        min = MinResult(min, vc.Position);
        max = MaxResult(max, vc.Position);
     }

     collisionBox = new BoundingBox(min, max);

     vBuffer = new VertexBuffer(gd, typeof(VertexPositionColor), 8, BufferUsage.WriteOnly);
     vBuffer.SetData<VertexPositionColor>(vertices);
  }

I tried this with a camera position of [0,0,0] and it returned true for a collision between the two boxes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM