第一人称武器

时间:2014-02-17 21:32:48

标签: c# 3d xna xna-4.0

我的团队和我一直试图在屏幕上显示我们的武器一周,但没有成功:我们真的需要帮助。我们想得到的是,就像在每个FPS中一样,武器显示器在屏幕上有一点水平偏移,就像玩家拿着它一样。

我们已经尝试使用矩阵,但没有成功:武器甚至看不到,它似乎在我们身后,即使我们尝试使用这些值,我们也无法使它工作正常。

我们知道我们需要使用相机的旋转以及它的位置,但是我们无法找出获得武器世界矩阵的公式。

我们拥有的是相机作为Vector3的位置,相机作为Vector3的旋转,y坐标是水平旋转,在pi和-pi之间,x是垂直旋转。武器的缩放比例为0.1f。我们该怎么办?

非常感谢你的帮助。

修改 这是一些与我的问题相关的代码:

public void Update()
{
    weapon.Rotation = ThisPlayer.Rotation;

    weapon.WorldMatrix = WeaponWorldMatrix(
        ThisPlayer.Position, 
        ThisPlayer.Rotation.Y, 
        ThisPlayer.Rotation.X
    );

}

private Matrix WeaponWorldMatrix(Vector3 Position, float updown, float leftright)
{
    Vector3 xAxis;
    Vector3 yAxis;

    xAxis.X = SceneManager.Game.Camera.View.M11;
    xAxis.Y = SceneManager.Game.Camera.View.M21;
    xAxis.Z = SceneManager.Game.Camera.View.M31;

    yAxis.X = SceneManager.Game.Camera.View.M12;
    yAxis.Y = SceneManager.Game.Camera.View.M22;
    yAxis.Z = SceneManager.Game.Camera.View.M32;

    Position += new Vector3(1, 0, 0) / 5;  //How far infront of the camera The gun will be
    Position += xAxis * 1f;      //X axis offset
    Position += -yAxis * 0.5f;     //Y axis offset
    SceneManager.Game.DebugScreen.Debug(Position.ToString());
    return Matrix.CreateScale(0.1f)                        //Size of the Gun
        * Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(5), 0, 0)      //Rotation offset
        * Matrix.CreateRotationX(updown)
        * Matrix.CreateRotationY(leftright)
        * Matrix.CreateTranslation(Position);
}

2 个答案:

答案 0 :(得分:5)

最简单的方法是反转相机的视图矩阵,然后可以用来表示相机的世界空间位置和旋转。这个结果可以借用并略微改变,成为武器的世界矩阵。

Matrix cameraWorld = Matrix.Invert(view);

Matrix weaponWorld = cameraWorld; //gives your weapon a matrix that is co-located and co-rotated with camera


//then simply reposition the weapon matrix as necessary   
    weaponWorld.Translation += (cameraWorld.Forward * distInFrontOfCam) +                       //set to taste. moves the weapon slightly in front of cam
                               (cameraWorld.Down * amountWeaponIsLoweredFromCenterOfScreen) +   //set to taste. moves the weapon from the center of the screen to the lower part
                               (cameraWorld.Right * leftOrRightOffset);                         //set to taste. moves the weapon left or right of center if desired.

编辑。我注意到你也试图在你的武器上使用比例尺。我的建议是不要在代码中这样做。而是右键单击解决方案资源管理器中的武器模型并选择属性。在属性窗口中,单击“内容处理器”旁边的小箭头。扩大名单。找到scale属性并在那里设置比例(到你的0.1f或其他)。现在你永远不需要浪费cpu周期来在代码中扩展该模型。这会导致在将fbx转换为xnb时在构建阶段设置比例。

答案 1 :(得分:2)

我认为你可能遇到的问题是,为了让武器摆在你面前,你需要使用Z值-1,这是 Vector3.Forward 的值。但是,如果不直接使用矩阵,有更简单的方法来计算偏移量。

XNA已经提供了使用矩阵转换矢量的简单工具。例如,您可以使用 Vector3.Transform 来使用旋转矩阵(视图矩阵)旋转点。

例如,要获得你需要武器的位置,你需要一个偏移矢量,该值确定你正在寻找的武器的位置和你当前的位置。

在XNA默认使用的右手系统中,您需要为Z组件设置负值,使武器位于视图前方(Vector3.Forward),您需要一个小的负Y武器的价值低于视图。然后对于X值,您可以添加一个小值来将武器偏移到玩家的右侧。

var offset = new Vector3(0.2, -0.2, -1)

然后,您可以使用相机的视图矩阵旋转该偏移矢量来计算武器的位置,并添加玩家的位置。

var weaponPosition = Vector3.Transform(Offset, SceneManager.Game.Camera.View)
                     + ThisPlayer.Position;

最后,使用该位置可以为武器返回更简单的世界矩阵

return Matrix.CreateScale(0.1f)
       * Matrix.CreateRotationX(updown)
       * Matrix.CreateRotationY(leftright)
       * Matrix.Translation(weaponPosition);

如果之后武器仍然不在相机前面,请尝试更改偏移值或设置更高的值。武器也可能被相机的近场区域剪掉,尝试降低相机设置或投影矩阵参数中的值。对于 CreatePerspectiveFieldOfView 函数,该值是名为 nearPlaneDistance 的第三个字段。