首页 > 解决方案 > XNA 3D 边界框碰撞未触发

问题描述

我已经浏览了大约一个半小时左右来解决这个问题。我确实在 Xbox Live 独立开发论坛上看到了一些主题,但实际论坛没有加载(它们被删除了吗?)而且我在其他任何地方都找不到答案。

我遇到的问题是我无法在两个边界框之间触发任何类型的相交。我在 3D 空间中创建了一个立方体,然后在相对顶点放置了一个框,从输出中可以看出,该框似乎很好。就像相机的 BoundingBox <-- 为此,我在每个轴上取了玩家的位置和 +- 1 的最小值/最大值。我最初打算只将玩家位置重新用于最小值和最大值,但这不起作用,所以我尝试了这个,但它仍然不起作用。

这是我的代码的一些片段。

    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
        }
    }

接下来是主游戏类中的更新。

        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);
    }

现在转到 Cube 的类。

        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);
    }

最后是相机的课程。

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

如果您还想要其他任何东西,请告诉我:) 感谢您的帮助,谢谢

标签: c#3dxnamonogamexna-4.0

解决方案


问题在于碰撞盒的最小和最大坐标。碰撞框最小值为 [0,0,0],最大值为 [5,5,-5]。

边界框的最大坐标在 x、y 和 z 分量上应始终大于最小值,否则您可以在一个或多个维度(或通常称为内向外框)上创建具有“负”厚度的边界框。

您可以通过以下修改获得边界框的正确最小值和最大值。这里的想法是简单地比较每个顶点的 x、y 和 z 分量,寻找所有顶点的最低 x 值、最低的 y 值和最低的 z 值,它们成为盒子的新最小值。做同样的事情来获得最大坐标。(可能不是最有效的代码,但作为一个工作示例,它仍然可以完成工作)。

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);
  }

我用 [0,0,0] 的相机位置尝试了这个,它返回 true 表示两个盒子之间的碰撞。


推荐阅读