2011-07-25 5 views
0

私はVS2010をC#とXNA 4.0と共に使用しています。私はAaron Reedの "Learning XNA 4.0"という本を読んでいます。カメラのゲームコンポーネントをプロジェクトに追加しましたが、このカメラは本当に変です。マウスを動かすと、ジャンプしてクラッシュします。私はこれを引き起こしているのか分かりません。コードは本のコードとほとんど同じであると思われます。以前はうまくいっていましたが、今はそうではありませんが、私は何かを変えるかどうか覚えていません。私はこのコンポーネントをゲームに登録するだけです。それはうまくいくはずですが、そうではありません。どんな助けも素晴らしいだろう。コードは次のとおりです:カメラに何が問題なのですか?

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Input; 

namespace MyGame 
{ 
    public class Camera : Microsoft.Xna.Framework.GameComponent 
    { 

     public Matrix View { get; protected set; } 
     public Matrix Projection { get; protected set; } 
     public Vector3 CameraPosition { get; protected set; } 
     public Vector3 CameraDirection { get; protected set; } 
     public Vector3 CameraUp { get; protected set; } 
     private MouseState prevMouseState; 

     public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up) 
      : base(game) 
     { 
      // Some initialization of camera. 
      CameraPosition = pos; 
      CameraDirection = target - pos; 
      CameraDirection.Normalize(); 
      CameraUp = up; 
      CreateLookAt(); 

      Projection = Matrix.CreatePerspectiveFieldOfView(
       MathHelper.PiOver4,     
       (float)Game.Window.ClientBounds.Width/
       (float)Game.Window.ClientBounds.Height, 
       1f, 3000f); 
     } 

     public override void Initialize() 
     { 
      // Set mouse position and do initial get state. 
      Mouse.SetPosition(Game.Window.ClientBounds.Width/2, 
       Game.Window.ClientBounds.Height/2); 
      prevMouseState = Mouse.GetState(); 

      base.Initialize(); 
     } 


     public override void Update(GameTime gameTime) 
     { 
      // Standard WSAD keyboard movement. 
      if (Keyboard.GetState().IsKeyDown(Keys.W)) 
       CameraPosition += CameraDirection; 
      if (Keyboard.GetState().IsKeyDown(Keys.S)) 
       CameraPosition -= CameraDirection; 
      if (Keyboard.GetState().IsKeyDown(Keys.A)) 
       CameraPosition += Vector3.Cross(CameraUp, CameraDirection); 
      if (Keyboard.GetState().IsKeyDown(Keys.D)) 
       CameraPosition -= Vector3.Cross(CameraUp, CameraDirection); 

      // Yaw rotation (via mouse). 
      CameraDirection = Vector3.Transform(CameraDirection, 
       Matrix.CreateFromAxisAngle(CameraUp, (-MathHelper.PiOver4/150) * 
       (Mouse.GetState().X - prevMouseState.X) 
       )); 

      // Pitch rotation (via mouse). 
      CameraDirection = Vector3.Transform(CameraDirection, 
       Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
       (MathHelper.PiOver4/100) * 
       (Mouse.GetState().Y - prevMouseState.Y) 
       )); 

      CameraUp = Vector3.Transform(CameraUp, 
       Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
       (MathHelper.PiOver4/100) * 
       (Mouse.GetState().Y - prevMouseState.Y) 
       )); 

      prevMouseState = Mouse.GetState(); 

      CreateLookAt(); 
      base.Update(gameTime); 
     } 

     private void CreateLookAt() 
     { 
      View = Matrix.CreateLookAt(CameraPosition, 
       CameraPosition + CameraDirection, CameraUp); 
     } 
    } 
} 

誰かがこのコードが彼のために働くかどうか確認してください。どんなアイデアも素晴らしいだろう!

// EDIT 1: ゲームの初期設定では、私は、コードを使用します

Camera cam = new Camera(this, new Vector3(0, 0, 100), Vector3.Zero, Vector3.Up); 
Components.Add(cam); 

をしてから、私はモデルを描きます。モデルのBasicEffectでcamのビューと投影行列を使用します。

//編集2: 何かが重大に間違っています。私はいくつかのデバッグを行い、ある時点でVector3オブジェクトのX、Y、ZプロパティがNaNに設定されているようです。私はいつ、どのように見つけることができませんでした。また、gameTimeは、経過時間が16ミリ秒(フレームをスキップするようなもの)であり、ゲームがゆっくり実行されていることを示しています。この16ミリ秒は、いつデバッグする場合でも常に同じです。

私は何とかXNA/C#の設定を混乱させる可能性はありますか?もしそうなら、誰か私に今何をすべきかのヒントを教えてもらえますか?

+1

例外はありますか?エラー?もっと詳しく? – Oded

+0

例外はありませんが、エラーはありません。それはうまくいくが、私がマウスを動かすと画面がちょっと狂ってしまう。そして、私はブルースクリーンを見るだけで、モデルは全くありません。多分 "クラッシュ"は悪い言葉ですが、それは私が意味していたことです。 :) – freakish

+0

(MathHelper.PiOver4/100)を(MathHelper.PiOver4/100.0)に変更して、それが整数変換でないかどうかを確認してください。 – djdanlib

答えて

2
// Pitch rotation (via mouse). 
    CameraDirection = Vector3.Transform(CameraDirection, 
     Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
     (MathHelper.PiOver4/100) * 
     (Mouse.GetState().Y - prevMouseState.Y) 
     )); 

    CameraUp = Vector3.Transform(CameraUp, 
     Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
     (MathHelper.PiOver4/100) * 
     (Mouse.GetState().Y - prevMouseState.Y) 
     )); 

CreateFromAxisAngleを使用するときは常に、最初のパラメータ(軸)は単位長ベクトルである必要があります。単位長さのベクトルでない場合は、歪んだ(歪んだ)マトリックスと、回転している(または下にある)マトリックスになります。

2つのベクトルを交差すると、単位長さのベクトルはほとんどありません。十字の長さの結果を作る。これを試してください: 'Normalize'を追加することによって、

を追加することで、交差の単位長ベクトルになります。ヨーラインにも同じことをすることを忘れないでください。

+0

それは働いた!正規化メソッドはvoid(少なくともXNA 4.0では)なので、あなたが書いたとおり正確ではありません。 :) どうもありがとうございました。私は本当に驚いていますが、コードは本から取られていたため、以前は問題なく動作していました。なぜそれが起こったのだろうか?とにかくありがとうございました! – freakish

+0

単位長さのベクトルを2つ交差させ、方向が90度ずれている場合、結果は単位長になります。なぜそれが以前に適切に機能したのかを考慮したのだろうか。 –

+0

はい、私は理論を知っています。外積の長さは、長さにベクトル間の角度の余弦を掛けた積に等しい。しかし、私は長さはCreateFromAxisAngleメソッドで重要ではないと思った。私は間違っていたと思います。 :)ありがとう! – freakish

関連する問題