2016-04-12 28 views
0

Yaptığım bir 3d oyunun düşman sınıfını yazıyorum ve oyuncuyu takip ederek düşman üzerinde çalışıyorum. Düşmanın temelde oyuncu tarafından her kareyi biraz döndürmesini ve her kareyi biraz ileriye taşımasını istiyorum. Aşağıdaki kodda görüldüğü gibi bunu gerçekleştirmek için Lerping kullanmayı denedim, ancak işe almak için görünmüyor olabilir. Oynarken, düşmanları görüş alanımda bile görünmüyor ya da beni hiç takip etmiyor. Aşağıda benim düşman sınıfımdaki kodum var.C# ve XNA - 3d model nasıl yapılır? Kullanarak başka bir 3d modeli takip edin.

Not: p takip ettiğim bir oynatıcı nesnesinin bir referansıdır, dünya düşman nesnesinin dünya matrisi, kuaternion bu düşman nesnenin kuaterniyonudur.

Şu anki stratejim, düşmanın ön vektörü ile oyuncunun konum vektörü3 arasındaki yön vektörünü bulmakta ve sonra hız değişkeni tarafından belirlenen bir miktarda bunu belirlemektedir. Sonra, düşmanın ileri vektörü ve ortadaki yeni vektöre eklediğim midVector dediğim düzleme dik vektör bulmaya çalışıyorum.O zaman, oyuncuya o dik vektör hakkında dönecek olan kuaterniyonumu güncelliyorum.

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

Sorum hem, benim şimdiki strateji/uygulamasıyla yanlış ve bana bunu yapmanın daha kolay bir yolu var ne (ilk bölüm daha önemlidir): İşte aşağıda kodudur?

cevap

0

Nesnenin yönünü çerçeveden çerçeveye saklamıyorsunuz. Bence, yarattığın kuaternionun nesneler yeni yönüne yöneldiğini düşünüyorsun. Ama aslında, sadece son çerçeveyle mevcut çerçeve arasındaki dönme farkını temsil eden bir kuaternion, genel yönelim değil.

Peki, gerçekleşmesi gereken şey, yeni bir çerçevenin geçerli bir çerçeve yönlendirmesi elde etmek için son çerçevenin yönlendirme katsayısına uygulanması gerektiğidir. Başka bir deyişle, son yönelim dörtlüsünü değil, çerçeve arası bir güncelleştirme dörtlemesi yaratıyorsunuzdur.

enemyCurrentOrientation = Quaternion.Concatenate(lastFrameQuat, thisNewQuat); 

Orada muhtemelen daha kolay bir yoldur ancak bu şekilde sizin için sürekli çalışan eğer, gerek bunu değiştirmek için:

Böyle bir şey yapmak gerekir.

+0

Bu mantıklı ve bu yardımcı oldu. Nokta ürün kullanımımda hala bazı sorunlar var, çünkü bazen nesnenin titremesine ve karışmasına neden oluyor. Bence ters kosinüs alanıyla ilgili bir şey var ama emin değilim. – computerscience32