0

別のクラスでモデルを描画しようとしています。別のクラスでモデルを描画しようとしました。ただし、私のモデルは、私が作成したコードではまったくレンダリングされません。

ここにGame1 のコード: (注:これらのコードは Game1 に適しています)

private Vector3 position = new Vector3(0, 0, 0);
private Matrix world;
private Matrix view;
private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 600f, 0.1f, 100f);
private Model car;
SpriteBatch spriteBatch;
GraphicsDeviceManager graphics;
public Game1()
{

    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
    Vector3 transformedReference = Vector3.Transform(new Vector3(0, 5, 15), Matrix.CreateRotationY(0f));
    view = Matrix.CreateLookAt(position + transformedReference, position, Vector3.Up);
}
protected override void Initialize()
{
    Components.Add(new Car(this, view, projection));
    world = Matrix.CreateTranslation(position);
    Vector3 transformedReference = Vector3.Transform(new Vector3(0, 5, 15), Matrix.CreateRotationY(0f));
    view = Matrix.CreateLookAt(position + transformedReference, position, Vector3.Up);
    base.Initialize();
}
protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    car = Content.Load < Model > ("car\\car");
}
public void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{

    foreach(ModelMesh mesh in model.Meshes)
    {
        foreach(BasicEffect effect in mesh.Effects)
        {

            effect.EnableDefaultLighting();
            effect.PreferPerPixelLighting = true;
            effect.World = mesh.ParentBone.Transform * world;
            effect.View = view;
            effect.Projection = projection;
        }

        mesh.Draw();
    }
}
protected override void Update(GameTime gameTime)
{
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();
    world = Matrix.CreateTranslation(position);
    base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    DrawModel(car, world, view, projection);
    base.Draw(gameTime);
}

ここに私の別のクラスのコードがあります: (注:これらのコードはうまく機能しないか、Game1 グラフィックでモデルをレンダリングできません)

         public class Car: DrawableGameComponent
{
    public Model CarModel
    {
        get;
        set;
    }
    private Vector3 position = new Vector3(0, 0, 0);
    private Matrix World = Matrix.CreateTranslation(new Vector3(0, 0, 0));
    public Matrix Camera
    {
        get;
        set;
    }
    public Matrix Projection
    {
        get;
        set;
    }
    public Game1 GameParent
    {
        get;
        set;
    }
    public Car(Game1 game, Matrix view, Matrix projection): base(game)
    {
        view = Camera;
        Projection = projection;
        Camera = view;
        GameParent = game;

        World = Matrix.CreateTranslation(position);
        base.Initialize();
    }

    public static void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
    {
        foreach(ModelMesh mesh in model.Meshes)
        {
            foreach(BasicEffect effect in mesh.Effects)
            {

                effect.EnableDefaultLighting();
                effect.PreferPerPixelLighting = true;
                effect.World = mesh.ParentBone.Transform * world;
                effect.View = view;
                effect.Projection = projection;
            }

            mesh.Draw();
        }
    }
    protected override void LoadContent()
    {
        CarModel = GameParent.Content.Load < Model > ("car\\car");
        base.LoadContent();
    }
    public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
    }
    public override void Draw(GameTime gameTime)
    {
        DrawModel(CarModel, World, Camera, Projection); //DOESN'T WORK WELL!!
        base.Draw(gameTime);
    }
}

OK、私のポイントは、別のクラスで 3D モデルを描画したいだけです,,

さて、これを解決するにはどうすればよいですか?

私はあなたが私を助けても構わないと願っています.

4

1 に答える 1

2

1 つのコードに 2 つのバージョンが含まれているため、コードの何が問題なのかを確認するのは困難です。少しきれいにします。いくつかのヒントを次に示します。

私の経験では、個々のオブジェクトに DrawableGameComponent を使用したくありません。独自のクラスを作成し、それらをコレクションなどに配置することに固執してください。このように、XNA が更新を開始して描画するというブードゥー教に対処する必要はありません。自分でコントロールしたほうがいい。

CAR で View-Matrix と Projection-Matrices を処理したくありません。それらを Game クラスに残して (今のところ、代わりに camera クラスがあるはずです)、Car.Draw メソッドに渡します。コンストラクターで渡しているようですが、私が覚えている限り、マトリックスは値型であるため、コードの他の部分でビューを変更しても車には反映されません。

Car.Draw を次のように変更します。

public void Draw(Matrix view, Matrix projection)
{
    DrawModel(view, projection);
}

描画への私の変更からわかるように、モデルとワールドを受け取る必要がないように、DrawModel を通常のメソッドにする (静的を削除する) 必要もあります。

あなたの車は、回転のためにクォータニオンまたは類似のものを持っている必要があります。したがって、Car.World は次のように記述できます。

Matrix World = Matrix.Identity;

//In update:
World = Matrix.FromQuaternion(Rotation) * Matrix.CreateTranslation(Position);

Car のコンストラクターが Model をパラメーターとして受け取るようにします。そうすれば、「GameParent」と LoadContent-Method を捨てることもできます。

あなたのゲームクラスで:

静的な DrawModel メソッドを捨てます。フィールドの世界と車を捨ててください。彼らは現在カークラスに属しています。

車のフィールド (プロパティではないクラスレベルの変数) を作成します。

Car MyCar = null;

Game1.LoadContent では:

MyCar = new Car(Content.Load<Model>("car//car"));

Game1.Update で:

MyCar.Update(gameTime);

Game1.Draw で:

GraphicsDevice.Clear(Color.CornFlowerBlue);
MyCar.Draw(View, Projection);

編集;

ゲーム エンジンの場合、通常、現在不足している「パーツ」がいくつかあります。

  • ゲームの状態システム (メニューは状態の 1 つのタイプで、NormalLevel と BossLeve はその他の例です)
  • カメラ サービス (現在のビュー/プロジェクション マトリックスをどこからでも取得できるようにするため) - タイミング サービス (どこからでも (float)gameTime.ElapsedGametime.TotalSeconds を取得できるようにするため)
  • 入力サービス (更新ごとの入力値をどこからでも取得できます)

カメラシステムは、次のように単純にすることができます。

public interface ICamera
{
    Vector3 Position { get; }
    Matrix View { get; }
    Matrix Projection { get; }

    void Update(float deltaTime);
    void Target(Vector3 targetPosition);
}

public class CameraService
{
    public static ICamera ActiveCamera { get; private set; }

    public static void ActivateCamera(ICamera camera)
    {
        if (ActiveCamera != null)
            camera.Target(ActiveCamera.Target);

        ActiveCamera = camera;
    }

    public static Update(float deltaTime)
    {
        if (ActiveCamera != null)
            ActiveCamera.Update(deltaTime);
    }
}

public class BasicCamera: ICamera
{
    public Vector3 Position { get; protected set; }
    public Matrix View { get; protected set; }
    public Matrix Projection { get; protected set; }

    public void Target(Vector3 targetPosition)
    {
        View = Matrix.CreateLookAt(Position, targetPosition, something something);
    }

    public BasicCamera(Vector3 position, Vector3 target)
    {
        //Set shit up
    }
}
于 2013-03-15T08:26:54.743 に答える