我正在制作3D游戏。播放器是“相机”。我希望它不要穿过已实现的墙壁。但是现在我希望它能够像任何其他fps那样沿着墙“滑行”。这是代码:并提前感谢:
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
keyState = Keyboard.GetState();
camera.Update(gameTime);
if (keyState.IsKeyDown(Keys.W)) camera.moveVector.Z = 1;
if (keyState.IsKeyDown(Keys.S)) camera.moveVector.Z = -1;
if (keyState.IsKeyDown(Keys.A)) camera.moveVector.X = 1;
if (keyState.IsKeyDown(Keys.D)) camera.moveVector.X = -1;
if (keyState.IsKeyDown(Keys.Space)&&camera.Position.Y>=0.5f) camera.moveVector.Y = 0.5f;
if (camera.moveVector != Vector3.Zero)
{
//We don't want to make the player move faster when it is going diagonally.
camera.moveVector.Normalize();
//Now we add the smoothing factor and speed factor
camera.moveVector *= (dt * camera.cameraSpeed);
Vector3 newPosition = camera.PreviewMove(camera.moveVector);
bool moveTrue = true;
if (newPosition.X < 0 || newPosition.X > Map.mazeWidth) moveTrue = false;
if (newPosition.Z < 0 || newPosition.Z > Map.mazeHeight) moveTrue = false;
foreach (BoundingBox boxes in map.GetBoundsForCell((int)newPosition.X, (int)newPosition.Z))
{
if (boxes.Contains(newPosition) == ContainmentType.Contains)
{
moveTrue = false;
}
}
if (moveTrue) camera.Move(camera.moveVector);
base.Update(gameTime);
以下是推动运动的代码:
//Updating the look at vector
public void UpdateLookAt()
{
//Built a rotation matrix to rotate the direction we are looking
Matrix rotationMatrix = Matrix.CreateRotationX(cameraRotation.X) * Matrix.CreateRotationY(cameraRotation.Y);
// Build a look at offset vector
Vector3 lookAtOffset = Vector3.Transform(Vector3.UnitZ, rotationMatrix);
//Update our camera's look at the vector
cameraLookAt = (cameraPosition + lookAtOffset);
}
//Method to create movement and to check if it can move:)
public Vector3 PreviewMove(Vector3 amount)
{
//Create a rotation matrix to move the camera
Matrix rotate = Matrix.CreateRotationY(cameraRotation.Y);
//Create the vector for movement
Vector3 movement = new Vector3(amount.X, amount.Y, amount.Z);
movement = Vector3.Transform(movement, rotate);
// Give the value of the camera position +ze movement
return (cameraPosition+movement);
}
//Method that moves the camera when it hasnt'collided with anything
public void Move(Vector3 scale)
{
//Moveto the location
MoveTo(PreviewMove(scale), Rotation);
}
已经考虑过使用xna给出的反转方法。但我似乎无法找到正常的。我试图将相机平行移动到墙上。但我无法做到这一点。任何帮助都是有用的。
答案 0 :(得分:0)
如果您发现某个点与边界框相交,则必须检查入口点所在的六个面中的哪一个。这可以按如下方式完成:在旧相机位置和新相机位置之间构建一个线段:
p = (1 - t) * oldPos + t * newPos
,您只使用oldPos
和newPos
的维度,这对于脸部很有趣(例如,对于左/右脸,采用x坐标)。 p
是面部的相应坐标。计算每个面的t
并找到t
最大的面,忽略该点已经落后的面(即面法线的点积和从面到点的方向是负)。这将是您的切入点所在的面孔。您需要做的就是调整相关坐标(左/右脸的x坐标等),使其不在边界内(例如右侧面设置为newPos.x = boundingBox.MaxX
)。这等于将点投影到边界框表面上,等效于仅使用与框平行的运动矢量分量(如果发生交叉)。
t = (p - oldPos) / (newPos - oldPos)