XNA 3D 边界框碰撞不触发
XNA 3D Bounding Box Collision Not Triggering
我已经浏览了大约一个半小时左右的时间来寻找这个问题的解决方案。我确实在 Xbox Live Indie Development 论坛上看到了一些帖子,但实际的论坛没有加载(它们是否已被删除?)而且我在其他任何地方都找不到答案。
我遇到的问题是我无法在两个边界框之间触发任何类型的相交。我在 3D space 中创建了一个立方体,然后在相对的顶点放置了一个盒子,从我在输出中可以看出的内容来看,这个盒子似乎没问题。与相机的 BoundingBox 一样 <-- 为此,我在 min/max 的每个轴上取了玩家的位置和 +- 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
}
}
接下来是主游戏中的更新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);
}
现在转到 Cube 的 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);
}
最后是相机的 class。
void UpdateBoundingBox()
{
cameraBox = new BoundingBox(cameraPosition + new Vector3(-1, -1, -1), cameraPosition + new Vector3(1,1,1));
}
如果您需要任何其他信息,请告诉我:) 感谢您的帮助,谢谢
问题出在你的碰撞盒的最小和最大坐标上。碰撞框最小值在 [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。
我已经浏览了大约一个半小时左右的时间来寻找这个问题的解决方案。我确实在 Xbox Live Indie Development 论坛上看到了一些帖子,但实际的论坛没有加载(它们是否已被删除?)而且我在其他任何地方都找不到答案。
我遇到的问题是我无法在两个边界框之间触发任何类型的相交。我在 3D space 中创建了一个立方体,然后在相对的顶点放置了一个盒子,从我在输出中可以看出的内容来看,这个盒子似乎没问题。与相机的 BoundingBox 一样 <-- 为此,我在 min/max 的每个轴上取了玩家的位置和 +- 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
}
}
接下来是主游戏中的更新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);
}
现在转到 Cube 的 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);
}
最后是相机的 class。
void UpdateBoundingBox()
{
cameraBox = new BoundingBox(cameraPosition + new Vector3(-1, -1, -1), cameraPosition + new Vector3(1,1,1));
}
如果您需要任何其他信息,请告诉我:) 感谢您的帮助,谢谢
问题出在你的碰撞盒的最小和最大坐标上。碰撞框最小值在 [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。