2016-04-12 3 views
0

Je suis en train d'écrire la classe ennemie d'un jeu en 3D que je suis en train de faire et de faire en sorte que l'ennemi suive le joueur. Je veux que l'ennemi se tourne de lui-même dans la direction du joueur un peu chaque image et avance un peu chaque image. J'ai essayé d'utiliser Lerping pour accomplir ceci comme vu dans le code ci-dessous, mais je n'arrive pas à le faire fonctionner. En jouant, les ennemis n'apparaissent même pas dans mon champ de vision ou me chassent du tout. Voici mon code de ma classe ennemie ci-dessous.C# et XNA - Comment faire un modèle 3D suivre un autre modèle 3d en utilisant lerp

Note: p est une référence à un objet joueur que je poursuis, le monde est la matrice du monde de l'objet ennemi, le quaternion est le quaternion de cet objet ennemi. Ma stratégie actuelle consiste à trouver le vecteur de direction entre le vecteur direct de mon ennemi et le vecteur de localisation3 du joueur, puis à lier cela d'une quantité déterminée par la variable de vitesse. Ensuite, j'essaie de trouver le vecteur perpendiculaire au plan déterminé par le vecteur avant de l'ennemi et ce nouveau vecteur lerped que j'appelle midVector. Ensuite, je mets à jour mon quaternion pour que le joueur tourne autour de ce vecteur perpendiculaire. Voici le code ci-dessous:

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

Ma question est à la fois, ce qui ne va pas avec ma stratégie/mise en œuvre actuelle et est-il un moyen plus facile pour moi d'y arriver (la première partie est plus importante)?

Répondre

0

Vous ne stockez pas l'orientation de votre objet d'une image à l'autre. Je pense que vous pensez que le quaternion que vous créez est orienté dans la nouvelle direction des objets. Mais en fait, c'est juste un quaternion qui représente seulement la différence de rotation entre la dernière image et la trame courante, et non l'orientation générale.

Donc, ce qui doit arriver est que votre nouveau quat doit être appliqué à la quaternion d'orientation de la dernière image pour obtenir une orientation de trame en cours. En d'autres termes, vous créez une quaternion de mise à jour inter-image, pas la quaternion d'orientation finale.

Vous devez faire quelque chose comme ceci:

enemyCurrentOrientation = Quaternion.Concatenate(lastFrameQuat, thisNewQuat); 

Il y a est probablement un moyen plus facile mais si cette façon travaille pour vous, pas besoin de le changer.

+0

Cela a du sens et cela a aidé. Il y a encore quelques problèmes avec l'utilisation de mon produit scalaire, car cela provoque parfois un tremblement et une confusion de l'objet. Je pense que cela a quelque chose à voir avec le domaine du cosinus inverse mais pas sûr. – computerscience32