XNAでゲームリソースをどのように管理しますか?


7

昔はあちこちで使っContent.Load<type>("filename");てきました。これはすぐに管理の悪夢になり、さらに悪いことに、同じアセットの複数のコピーを複数の異なる場所にロードし始めます。

次に、基本的に次のようなResourcesクラスの使用に移りました。

public class Resources
{
    public static Texture2D particle01;
    ...
    public static Texture2D particle93;

    public static Effect shader01;
    ...
    public static Effect shader32;

    public static Load(ContentManager content, GraphicsDevice device)
    { //load all the resources }

    public static Unload()
    { //unload all the resources }
}

次にResources.particle01、同じ名前空間内のどこからでもリソースへの参照を取得するために単に使用できます。

これは、私が過去に持っていた重複を排除したので、素晴らしいアプローチでした。また、すべてのロードは単一のクラスで行われたため、リソースを追跡するのは簡単でした。最後に、たとえば右クリックして、particle93[すべての参照を検索]をクリックして、そのテクスチャを使用したすべての場所を見つけることができます。

しかし、このアプローチには問題があり、より良い解決策があるかどうか知りたいです。

回答:


8

まず、XNAのコンテンツマネージャーは同じアセットを2回ロードしません。何かが既にロードされている場合は、参照を返します。

リソースアプローチについては、基本的にコンテンツアセットをゲームにハードコーディングするので、それが本当に進むべき道かどうかはわかりません。

問題の考えられる解決策は、ファクトリーパターンです。XMLとして保存されたレベルをロードしたいとします。LevelFactory.Construct(xml);を実行して、XMLファイルをロードし、レベルをロードします。このファクトリーはXMLファイルを検査し、そのレベルに関連付けられたすべてのアセットをロードして、それらをワールドに配置します。NPCのような世界のサブパートは、NPCファクトリーを呼び出し、XMLファイルの一部を渡すことにより、レベルファクトリーによって構築され、NPCファクトリーがどのテクスチャーとモデルをロードするかを知ることができます。

このアプローチを使用すると、コンテンツ(XMLファイルとXMLファイルによって参照されるファイル)とコード(ファクトリー)を明確に分離できるように、すべてデータ駆動型の「カスケードシリーズ」のファクトリーが得られます。コンテンツのロードコードを他のコードから遠ざけます。あなたは今やする必要はありませんPlayer = new Player(textureA、textureB、textureC); もう、ファクトリーに新しいプレーヤーを要求するだけで、あとは残りがわかります。

ヒント:デフォルトオブジェクトには常にいくつかのメソッドを設定できます。XMLで何も指定されていない場合は、フォールバックを設定できます。

お役に立てれば!


3

ScreenRedという素晴らしいコンセプトを持つFlatRedBallを使用しました。テクスチャのロード/アンロードについて心配する代わりに、代わりに次のようなコードを記述します。

Sprite s = this.addSprite("spaceship");

そして、コンテンツのライフサイクルを処理します。私はこのアプローチを自分のフレームワーク、Radiant Wrenchでも使用しています。管理を最小限に抑え、邪魔にならないようにしています。

スプライトを管理するためのコードはそれほど簡単ではありません(最初にスプライトクラスとスクリーンクラスが必要です)。そのため、FRBまたはRWを試してみることをお勧めします。あなたは常に物事を行うための新しい方法(時にはより良い方法)を学ぶことから利益を得ます。


2

これは一部の人にとっては好ましくないと思われるかもしれませんが、リソースを必要とするGameStateに対してローカルにリソースを保持する傾向があり、各GameStateには一種のResourcePoolがあります。メニューの背景は本当に必要ないので、これはレベルアセットを分離しておくのに良い方法です。Resourcesクラスは構造としてより適切に機能し、GameStateがロードとアンロードを担当します。

XNAのリソース管理の一部は、最初にコンテンツをインポートする方法によって部分的に決定されます。多くの人々は、ビルドのコンテンツ処理フェーズでテクスチャとエフェクトをモデルにバインドします。それらはメッシュのみを管理し、残りはすでに内部で参照されています。

より古典的な「ミックスアンドコンバイン」アプローチを採用して柔軟性を高めているように見えるため、基礎となる作業をブラックボックス化し、長期的に記述しなければならないコードを削減するアプローチが必要です。私はFlatRedBallを使用していませんが、ここに書かれた短い説明からわかるように、遅延読み込みパターンのように聞こえます。これは、多くのリソースを管理して人生を楽にしたい場合に検討する価値のある概念です。


小さなコメント、非値型への参照を持つ構造体はあまり役に立ちません。
Roy T.

1

Assetsというパブリック静的クラスを使用します。これには、アセット、モデル、エフェクト、スプライトフォントなど、各種の辞書が含まれています。コンテンツフォルダで「テクスチャ」、「モデル」などのフォルダを探し、すべてのアセットを読み込むロード機能があります。次に、Assetを呼び出したいときは、Assets.Textures ["SpriteSheetX"]のようなものを使用します。

これが悪い習慣かどうかはわかりませんが、とても簡単です。私はほとんどの場合、ファイル名の文字列を渡し、コアの深部でAssetsからアセットをロードします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.