C#和XNA - 如何使用lerp使3d模型跟随另一个3d模型

时间:2016-04-12 22:39:52

标签: c# vector xna quaternions lerp

我正在编写我正在制作的3D游戏的敌人类,正在努力让敌人跟随玩家。我希望敌人基本上每一帧向玩家的方向旋转一点点,然后每帧向前移动一点。我尝试使用Lerping来实现这一点,如下面的代码所示,但我似乎无法让它工作。在比赛时,敌人甚至不会出现在我的视野中或者根本不会追逐我。这是我下面敌人班的代码。

注意:p是对我追逐的玩家对象的引用,world是敌方对象的世界矩阵,四元数是这个敌人对象的四元数。

我目前的策略是在我的敌人的前向矢量和玩家的位置矢量3之间找到方向向量,然后按照由速度变量确定的量进行搜索。然后,我尝试找到由敌人的前向矢量确定的平面的垂直向量,以及我称之为midVector的新的向量矢量。然后,我更新我的四元数,让玩家围绕该垂直向量旋转。以下是代码:

 //here I get the direction vector in between where my enemy is pointing and where the player is located at
       Vector3 midVector = Vector3.Lerp(Vector3.Normalize(world.Forward), Vector3.Normalize(Vector3.Subtract(p.position,this.position)), velocity);
        //here I get the vector perpendicular to this middle vector and my forward vector
       Vector3 perp=Vector3.Normalize(Vector3.Cross(midVector, Vector3.Normalize(world.Forward)));

        //here I am looking at the enemy's quaternion and I am trying to rotate it about the axis (my perp vector) with an angle that I determine which is in between where the enemy object is facing and the midVector

       quaternion = Quaternion.CreateFromAxisAngle(perp, (float)Math.Acos(Vector3.Dot(world.Forward,midVector)));
        //here I am simply scaling the enemy's world matrix, implementing the enemy's quaternion, and translating it to the enemy's position
       world = Matrix.CreateScale(scale) * Matrix.CreateFromQuaternion(quaternion) * Matrix.CreateTranslation(position);


       //here i move the enemy forward in the direciton that it is facing
       MoveForward(ref position, quaternion, velocity);


    }

    private void MoveForward(ref Vector3 position, Quaternion rotationQuat, float speed)
    {
        Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
        position += addVector * speed;
    }

我的问题是,我目前的策略/实施有什么问题,是否有更简单的方法来实现这一点(第一部分更重要)?

1 个答案:

答案 0 :(得分:0)

您不是在帧与帧之间存储对象的方向。我认为您正在考虑您正在创建的四元数是面向对象的新方向。但实际上,它只是一个四元数,它只代表最后一帧和当前帧之间的旋转差异,而不是整体方向。

所以需要发生的是你的新quat必须应用于最后一帧的方向四元数以获得当前的帧方向。

换句话说,您正在创建一个帧间更新四元数,而不是最终的方向四元数。

你需要做这样的事情:

enemyCurrentOrientation = Quaternion.Concatenate(lastFrameQuat, thisNewQuat);

可能有一种更简单的方法,但如果这种方式适合您,则无需更改。