0

我正在编写我正在制作的 3d 游戏的敌人类,并且正在努力让敌人跟随玩家。我希望敌人基本上每一帧都朝着玩家的方向旋转一点,每帧向前移动一点。我尝试使用 Lerping 来完成此操作,如下面的代码所示,但我似乎无法让它工作。玩的时候,敌人根本不会出现在我的视野中,也根本不会追我。这是我下面敌人类的代码。

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

我当前的策略是在敌人的前向向量和玩家的位置向量3 之间找到方向向量,然后将其调整为由速度变量确定的量。然后,我尝试找到由敌人的前向向量和我称为 midVector 的新 lerped 向量确定的平面的垂直向量。然后,我更新我的四元数以使玩家围绕该垂直向量旋转。下面是代码:

 //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;
    }

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

4

1 回答 1

0

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

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

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

你需要做这样的事情:

enemyCurrentOrientation = Quaternion.Concatenate(lastFrameQuat, thisNewQuat);

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

于 2016-04-15T11:56:17.993 回答