【问题标题】:Can't seem to get smooth 3D collision XNA似乎无法获得平滑的 3D 碰撞 XNA
【发布时间】:2016-12-13 11:18:26
【问题描述】:

我正在制作一个 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给出的invert方法了。但我似乎找不到正常的。我试图将相机平行于墙壁移动。但我无法做到这一点。任何帮助都表示赞赏。

【问题讨论】:

    标签: c# visual-studio-2015 3d xna collision-detection


    【解决方案1】:

    如果您发现一个点与边界框相交,则必须检查入口点位于六个面中的哪一个。这可以按以下方式完成:在旧相机位置和新相机位置之间构建一条线段:

    p = (1 - t) * oldPos + t * newPos
    

    ,您只使用oldPosnewPos 的尺寸,这对脸部很有趣(例如,对于左/右脸,取 x 坐标)。 p 是人脸的对应坐标。计算每个面的t 并找到t 最大的面,忽略该点已经位于其后面的面(即面法线的点积和从面到点的方向为负)。这将是您的切入点所在的面。然后,您需要做的就是调整相关坐标(同样是左/右脸的 x 坐标等),使其不在边界内(例如,为右脸设置 newPos.x = boundingBox.MaxX)。这相当于点在边界框表面上的投影,相当于只使用与边界框平行的运动矢量的分量(如果发生相交)。

    顺便说一句,上式的解是:

    t = (p - oldPos) / (newPos - oldPos)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-10
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多