XNA Frameworkブログ
 

June, 2009

  • ひにけにXNA

    XNA Game Studio 3.1のSoundEffect変更点

    • 0 Comments

    XNA Game Studio 3.1のSoundEffect

    ゲームで使用する効果音を簡単に再生するためにXNA Game Studio 3.0で導入されたSoundEffect機能がありますが、この機能は以下の二つのシナリオを実現するようにデザインされました。

    • 簡易再生(Fire & forget): プログラムは単にPlayメソッドを呼ぶだけ。後は効果音が鳴り終わった後に自動的にメモリ開放処理をしてくれる機能
    • 生成と設定(Create & configure): 効果音を鳴らしている間に、音量、再生ピッチ、パンなどのさまざまなパラメーターを自由に設定できる機能。細かい設定ができる代わりに、プログラム側で再生中のインスタンスの保持、管理をする必要がある

    この二つのシナリオを実現する為に、XNA GS 3.0ではSoundEffect.PlaySoundEffect.Play3DメソッドはSoundEffectInstanceオブジェクトを返すようになっていました。再生中に設定を変更したい場合は、このインスタンスに対して処理をします。簡易再生させたい場合はインスタンスを保持しないでおきます。この場合、次にガーベージコレクション(GC)が発生した時に再生が終了したインスタンスを破棄するようになっていました。

    この方法には以下の二つの問題がありました。

    • Play/Play3Dメソッドには、プログラムが簡易再生をしたいのか、細かい設定をしたいのかを知る術がないので常にSoundEffectInstanceを生成していました。これは簡易再生をしている場合に常に不必要なメモリ確保が起きていることになります。
    • 確保されたSoundEffectInstanceはGCが発生された時に再生が終了しているインスタンスを自動的に破棄されるようになっています。GCがいつ発生するかはゲームがどのようにメモリを確保するかによって左右されます。GCの不必要な発生はゲームのパフォーマンスに影響するので、極力GC発生を抑えるようにプログラミングするのが望ましいのですが、GC発生数が少ないと、SoundEffectinstanceを開放する機会が減るのことになるので、最終的には同時再生できる効果音の上限に達してしまいます。

    XNA GS 3.1では、この二つのシナリオを明確に分けることで、この問題を解決しました。

    • SoundEffect.Playメソッドは簡易再生専用のメソッドとなり、SoundEffectInstanceではなく、bool値を返すようになりました。このbool値は単純に再生が成功したかを示します。これで不必要なメモリ確保がなくなりました。また、このメソッドを使った場合はループ再生ができないようになっています。
    • 生成と設定のシナリオ用にSoundEffect.CreateInstanceメソッドが追加されました。このメソッドはSoundEffectInstanceを返すので、このオブジェクトを介して音量、ピッチ、パンなどを設定することができます。

    SoundEffect.Play3Dメソッドは無くなりました。3Dサウンドを再生する場合は、SoundEffect.CreateInsntaceメソッドを使い、SoundEffectInstance.Apply3Dメソッドを使用します。3Dサウンドは簡易再生することができません。

    また、XNA GS 3.0では再生数が上限に達したときに更に効果音を再生しようとするとInstancedPlayLimitException例外が発生しました。XNA GS 3.1でもCreateInstanceメソッドを使った場合には同じように例外が発生しますが、簡易再生の場合は例外を発生せずに単にbool値を返すようになっています。ですから、簡易再生時にいちいちtry~catchブロックを書く必要がなくなりました。

    原文:
    http://blogs.msdn.com/shawnhar/archive/2009/06/12/soundeffect-changes-in-xna-game-studio-3-1.aspx

  • ひにけにXNA

    アバターを使おう その3:喜怒哀楽

    • 0 Comments

    警告:画像が沢山あるので、重いかも。

    アバターの表情(Expression)を自由に設定する

    AvatarRenderer.Drawメソッドにはアバターのボーンと表情を指定することができます。基本アニメーションを使っている場合はAvatarAnimation.Expressionを指定しますが、ボーンと同じく、AvatarExpressionも自由に作ることができるので、アバターの表情を自由に変えることができます。

    AvatarExpressionには以下のプロパティがあります。

    • LeftEye (左目)
    • LeftEyebrow (左眉)
    • Mouth (口)
    • RightEye (右目)
    • RightEyebrow (右眉)

    LeftEye、RightEyeにはAvatarEye列挙型、LeftEyebrow、RightEyebrowにはAvatarEyebrow列挙型、MouthにはAvatarMouth列挙型を設定することができます。

    左右の目や眉に独立した値を設定できるので、ウィンクさせるといったことも可能です。眉と目、そして口のパターンと合わせると約6万9千通りの表情を設定することができます。これだけの数があるので、喜怒哀楽といった基本的な表情の他にも多彩な表情を表現することができるようになっています。

    以下はそれぞれの列挙型の値と、その説明です。

    AvatarEyebrow列挙型

    説明

    Angry 怒り、眉を吊り上げる
    Confused 困惑、眉を曲げる
    Neutral 自然な眉のかたち
    Raised 眉をあげる。驚いたときなどに使える
    Sad 悲しみ、眉がさがる。眠たい表情にも使える

    AvatarEye列挙型

    説明

    Angry 怒り、目がつりあがっている
    Blink まばたき、目を閉じている状態
    Confused 困惑、より目、または見上げている感じ
    Happy ハッピー、目が大きくひらき、目尻が下がっている
    Laughing 笑い、目を細めている
    LookDown 下を見る
    LookLeft 左を見る
    LookRight 右を見る
    LookUp 上を見る
    Neutral 自然な目の形
    Sad 悲しみ、目尻が下がる
    Shocked 驚き、目が点になる
    Sleeping 眠り、目を閉じている
    Yawning あくび、眠そうな目

    AvatarMouth列挙型

    説明

    Angry 怒り、歯をくいしばってる感じ
    Confused 困惑、口がゆがめている
    Happy ハッピー、口の両端が上がっている
    Laughing 笑い
    Neutral 自然体、すこし口が開いている
    PhoneticAi リップシンク用、英語のAの発音、日本語の「あ」と「え」の中間
    PhoneticDth リップシンク用、英語のDまたはThの発音、唇を歯で軽く噛んで発音、日本語では使われない
    PhoneticEe リップシンク用、英語のEの発音、日本語では「い」の発音
    PhoneticFv リップシンク用、英語のF、Vの発音、下唇を噛んで発音、日本語では使われない
    PhoneticL リップシンク用、英語のLの発音、舌のを歯のうらに当てて発音、日本語の「れ」に近い
    PhoneticO リップシンク用、英語のOの発音、日本語では「お」の発音
    PhoneticW リップシンク用、英語のWの最後の部分の発音、日本語では「う」の発音
    Sad 悲しみ、口の両端が下がっている
    Shocked 驚き、「あ」と口をあけて驚いている

    百聞は1スクショにすぎず

    前回の基本アニメーションと同じく、男性、女性アバターにいろいろな表情を設定したものを画像にしてみました。

    まずは、眉、目、口で共通するものが多い表情パターンです。

    myxbox-72自然な表情(Neutral)
    Eyebrow.Neutral
    Eye.Neutral
    Mouth.Neutral

    myxbox-74怒り(Angry)
    Eyebrow.Angry
    Eye.Angry
    Mouth.Angry

     

    myxbox-75

     

    困惑(Confused)
    Eyebrow.Confused
    Eye.Confused
    Mouth.Confused

    myxbox-76笑い(Laughing)
    Eyebrow.Neutral
    Eye.Laughing
    Mouth.Laughing

    myxbox-78

    ハッピー(Happy)
    Eyebrow.Neutral
    Eye.Happy
    Mouth.Happy

    myxbox-73

    悲しみ(Sad)
    Eyebrow.Sad
    Eye.Sad
    Mouth.Sad

    myxbox-77

     

    驚き(Shocked)
    Eyebrow.Raised
    Eye.Shocked
    Mouth.Shocked

     

    つづいて、目特有の表情パターンです。上下左右を見るというパターンがあるので、画面内の物を目で追うといったこともできます。

    myxbox-85まばたき(Blink)
    Eyebrow.Neutral
    Eye.Blink
    Mouth.Neutral

    myxbox-79

     

    あくび(Yawning)
    Eyebrow.Neutral
    Eye.Yawning
    Mouth.Shocked

    myxbox-80
    ねむり(Sleeping)
    Eyebrow.Neutral
    Eye.Sleeping
    Mouth.Happy

    myxbox-81
    上を見る(LookUp)
    Eyebrow.Neutral
    Eye.LookUp
    Mouth.Neutral

    myxbox-82
    下を見る(LookDown)

    Eyebrow.Neutral
    Eye.LookDown
    Mouth.Neutral

    myxbox-83左を見る(LookLeft)
    Eyebrow.Neutral
    Eye.LookLeft
    Mouth.Neutral

    myxbox-84
    右を見る(LookRight)

    Eyebrow.Neutral
    Eye.LookRight
    Mouth.Neutral

     

    最後に口特有の表情パターンです。表情パターンというよりも、リップシンク用のデータです。プレイヤーが操る以外のアバターには自由に喋らせることができるので、その時に使うパターンです。

    myxbox-87
    PhoneticAi

    myxbox-92
    PhoneticDth

    myxbox-88
    PhoneticEe

    myxbox-89
    PhoneticFv

    myxbox-86
    PhoneticO

    myxbox-91  PhoneticL

    myxbox-90 
     PhoneticW

     

    リップシンク用のデータはもともと欧米向けのデータなので、日本語を喋らせるときには近い口の形を流用することになります。以下は日本語で「あいうえお」の口の形に近いものを順に並べてみました。

    myxbox-93 あ (Shocked)

    myxbox-88い (PhoneticEe)

    myxbox-90う (PhoneticW)

    myxbox-87え (PhoneticAi)

    myxbox-86

    お (PhoneticO)

     
  • ひにけにXNA

    アバターを使おう その2:基本アニメーション

    • 0 Comments

    アバターの基本アニメーション

    AvatarAnimationを生成するときに指定するAvatarAnimationPreset列挙型には31種類の基本アニメーションが宣言されています。内訳として、11種類の男女共通のアニメーションと、性別毎に違うアニメーションが10種類となっています。

    男性アバター向けのアニメーションはMaleで始まり、女性アバター向けのアニメーションはFemaleで始まるようになっています。通常はAvatarDescription.BodyTypeによって性別ごとにアニメーションを切り替えて使用しますが、アニメーションは性別に関係なく使えるので、意図的に男性アバターに女性アバターのアニメーションを再生させるということもできます。

    男女共通のアニメーション

    以下は男女共通アニメーション名と、その説明です。

    アニメーション名

    説明

    Stand0 基本姿勢アニメーション、身体的アニメーションは殆どなく、瞬きする程度。
    Stand1 基本姿勢アニメーションに加えて、数秒間軽く上を見上げる動作。
    Stand2 基本姿勢アニメーションに加えて、左、上方向に顔を向ける動作。
    Stand3 基本姿勢アニメーションに加えて、左右を見渡した後に軽く首をかしげる動作。
    Stand4 軽く右足を上げて、つま先を見つめる。
    Stand5 両手を広げて、前後に振る。
    Stand6 足元を見回す動作。
    Stand7 頭を左右に傾けた後に、首を回す動作。
    Clap 笑顔で拍手する。
    Wave 笑顔で手を振る。
    Celebrate 喜びの動作。アバター生成画面でアバターを選択したときにするアニメーションと同じもの。

    性別によって違うアニメーション

    以下は性別によって異なるアニメーションをまとめた表です。殆どのアニメーションはMaleLaugh、FemaleLaughといった感じで同じタイプのアニメーションが用意されています。例外としてはMaleIdleCheckHand,FemaleIdleCheckNails,MaleIdleStretch,FemaleIdelFixShoeの四つのアニメーションがあります。

    同じタイプのアニメーションでも、例えば笑うアニメーションの場合、男性はひざを叩いて笑う動作をするのに対して、女性は手を前にかざして笑うといった違いがあります。

    男性用アニメーション名

    女性用アニメーション名

    説明

    MaleIdleCheckHand FemaleIdleCheckNails 男性は肩を軽くまわした後に自分の手を見つめる動作。
    女性は爪を見つめる動作。
    MaleIdleLookAround FemaleIdleLookAround あたりを見回す動作。
    FemaleIdleShiftWeight MaleIdleShiftWeight 重心を左右の足に移動する動作。
    MaleIdleStretch FemaleIdleFixShoe 男性はストレッチ動作、女性は靴の様子を見る動作。
    MaleAngry FemaleAngry 怒る。
    MaleConfused FemaleConfused 困惑。
    MaleLaugh FemaleLaugh 大笑い。
    MaleCry FemaleCry 泣く。
    MaleSurprised FemaleShocked 驚き。
    MaleYawn FemaleYawn あくび。男性は手を口に当ててあくび。女性は手を広げてあくび。


    百聞は一動画にしかずということで、全ての基本アニメーションを再生した動画を作ってみました。男性、女性アバターを並べて、それぞれのアニメーションを二回再生するようになっています。

  • ひにけにXNA

    3.1用プロジェクトへのアップグレード

    • 0 Comments

    XNA Game Studio 3.1ではXNA Game Studio 3.0のプロジェクトを3.1用にアップグレードすることができます。3.0で作ったプロジェクトをVisual Studioで開き、ソリューション・エクスプローラーで更新したいソリューションを右クリックで表示されるメニューの「Upgrade Solution…」を選択すると、3.1のプロジェクトへアップグレードします。

    image

    一旦3.1へアップグレートした後は、3.0のプロジェクトにダウングレードする方法は提供されていないので、3.0のプロジェクトを何らかの理由で残しておきたい場合は更新する前にバックアップしておくといいでしょう。

    今まで紹介してきた以下のサンプルをXNA Game Studio 3.1用のプロジェクトにアップグレードしたので、以下に記事と新しいプロジェクトへのURLをまとめておきました。

    基本的にはプロジェクトの更新のみですが、ソースコードファイルのエンコーディングをシフトJISからUnicode (UTF-8 シグネチャ (BOM) 付き) - コードページ 65001へ変更してあります。これはサンプルプログラムを日本語以外の環境で開くとコンパイルできないという問題を解決するためのものです。Visual Studioやメモ帳などのアプリケーションではUTF-8に対応しているので問題はありませんが、対応していないエディターでコードを開くときには日本語部分が正しく表示されないので注意してください。

    vFetchでスキンアニメーション

    http://higeneko.net/hinikeni/sample/xna31/vFetchSkinningSample.zip

    頂点テクスチャでスキンアニメーション

    http://higeneko.net/hinikeni/sample/xna31/TexSkinningSample.zip

    クォータニオンでスキンアニメーション

    http://higeneko.net/hinikeni/sample/xna31/QuatSkinningSample.zip

    デバッグサンプル

    http://higeneko.net/hinikeni/sample/xna31/DebugSample.zip

    Gamefest Japan 2008 デモプログラム

    http://higeneko.net/hinikeni/sample/xna31/GamefestJapan2008Demo.zip

    簡単(かもしれない)日本語表示

    http://higeneko.net/hinikeni/sample/xna31/SimpleMessage.zip

    Content Pipeline その3 そのカスタマイズ(日本語表示サンプル)

    http://higeneko.net/hinikeni/sample/TextMessageSample31.zip

  • ひにけにXNA

    アバターを使おう その1:アバターを表示する

    • 4 Comments

    アバターをゲーム画面内に表示する

    アバターをゲームt画面内に表示するには以下の三つのクラスが重要な役割を果たします。

    • AvatarDescription
    • AvatarAnimation(必ずしも必要ではない)
    • AvatarRenderer

    AvatarDescription

    AvatarDescriptionはアバターの性別、容姿、服装といった情報を保持しています。AvatarDescriptionのプロパティには男性(Male)、女性(Female)を表すBodyType、メートル単位の身長を表すHeightがあります。AvatarDescriptionを得るには以下の三つの方法があります。

    1. SignedInGamer.Avatarからゲーマータグのアバター情報を取得する
    2. AvatarDescription.CreateRandomメソッドを使ってランダムにアバターを生成する
    3. AvatarDescription(byte[] data)コンストラクタを使って生成する

    1はゲーマータグに関連付けられたらアバター情報をSignedInGamer.AvatarからAvatarDescriptionを取得して使う方法で、自分のアバターをゲーム内で使う方法です。

    2の手法は、自分のアバター以外をゲーム内で使ったり、複数の違った体形のアバターを自分のゲーム内で表示しても問題がないようにテスト目的として使う方法です。

    3の方法は、アバター情報をネットワークを介して転送する時に使用します。実際にはByte[]型であるAvatarDesciprion.Descriptionプロパティの情報をネットワークを介して転送し、転送されたデータをAvatarDescription(byte[])コンストラクタに渡すことで同じアバターを生成することができます。

    また、2の方法ではランダムにアバターを生成しますが、ゲームの雰囲気にあったアバターを自由に作りたいという時があります。この場合、ダッシュボード上で仮のゲーマープロファイルを生成、好きなアバターを編集します。そして、作ったアバターでサインインした状態でXNA Game Studioを起動、デバッガ上で該当するアバターのAvatarDescription.Descriptionプロパティの値を保存しておくことで自分の好きなタイプのアバターをゲーム内で使うことができます。

    AvatarAnimation

    XNA GS 3.1ではアバター用に31種類のアニメーションが用意されています。このアニメーションを再生する為に使うのがAvatarAnimationクラスです。AvatarAnimationクラスには現在のアニメーション再生位置、ボーン情報、表情(Expression)などの情報などが含まれます。AvatarAnimationクラスはAvatarAnimationPreset列挙型を指定して生成、通常はAvatarAnimation.Updateメソッドを使用してアニメーション再生をすることができます。

    また、AvatarAnimation.CurrentPositionプロパティは現在のアニメーション再生位置を取得することに使いますが、任意の再生位置を設定することで自由にアニメーションすることもできます。

    AvatarRenderer

    アバターをゲーム画面に描画するにはAvatarRendererクラスを使用します。AvatarRendererクラスはBasicEffectクラスとや同じように描画するアバターのWorld、View、Projection行列や、環境光源(AmbientLightColor)や平行光源(LightDirection, LightColor)を指定することができます。BasicEffectと違うところは描画するときにアバターのボーン情報や表情を指定できることです。通常はAvatarAnimationのBoneTransformsExpresssionプロパティを指定します。

    また、指定するボーン情報はIList<Matrix>型なので、自分で作った自由なアニメーションを設定することができます。アバターのボーン数は71あり、これ以外の数のボーンを指定すると例外が発生することに気をつけてください。カスタムアニメーションサンプルは近日中にクリエーターズ・クラブのサイトで公開予定です。

    サンプルコード

    アバターはGamerServicesを利用するので、アバター機能を使うときにはGamerServiceComponentを追加するのを忘れないようにしましょう。忘れた場合はGamerService機能を初期化することを促す例外が発生します。

    Components.Add(new GamerServicesComponent(this));

    次にアバターを使うのに必要なオブジェクトを生成します。

    // アバター情報をランダムに生成する
    avatarDescription = AvatarDescription.CreateRandom();
    
    // アバターアニメーションの生成
    avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Celebrate);
    
    // アバター描画用のオブジェクトの生成
    avatarRenderer = new AvatarRenderer(avatarDescription);

    次にゲームのアップデート内でアニメーションを以下のようにして更新します。

    avatarAnimation.Update(gameTime.ElapsedGameTime, true);

    最後にAvatarRendererにアバターを描画するのに必要な行列を設定し、ボーンと表情を指定することでアバターをゲーム画面内に描画することができます。

    // アバター描画に必要な行列の設定
    avatarRenderer.World = Matrix.CreateRotationY(MathHelper.ToRadians(180.0f));
    avatarRenderer.Projection = 
        Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(30.0f),
        GraphicsDevice.Viewport.AspectRatio,
        1, 1000);
    avatarRenderer.View = Matrix.CreateLookAt(
        new Vector3(0, 1, 4),
        new Vector3(0, 0.7f, 0),
        Vector3.Up);
    
    // ボーンと表情を指定してアバターを描画する
    avatarRenderer.Draw(avatarAnimation.BoneTransforms, avatarAnimation.Expression);

    上記のコードを実行すると、以下のようにアバターが画面に表示されます。このコードではランダムにアバターを作っているので実行するたびに違うアバターが表示されます。

    itoxe1-78

    アバターを使う上での注意点

    • GamerServiceComponentを追加するのを忘れないこと
    • 現状でアバターはXbox 360上でのみ動作するようになっています。ただし、アバター関連のコードをWindows上で走らせても例外が発生することなく動作します。
    • ゲーム内で使用するときには、背の高いのから低いのまで、痩せ型から太り気味といったさまざまなタイプのアバターが存在居るということに気をつける必要があります。例えば、アバターを矩形内に表示させたい時に身長の低いアバター向けに調整してしまうと、背の高いアバターを表示させると頭の上が途切れてしまうという問題があります。

    参考URL:

    http://blogs.msdn.com/dejohn/archive/2009/05/08/avatar-api-preview-for-xna-game-studio-3-1.aspx

    http://blogs.msdn.com/dejohn/archive/2009/05/11/what-to-do-while-an-avatar-loads.aspx

    http://blogs.msdn.com/dejohn/archive/2009/05/18/lights-camera-avatar.aspx

    http://blogs.msdn.com/dejohn/archive/2009/05/20/avatardescription-isvalid-when-why-the-description-returned-is-invalid.aspx

    http://blogs.msdn.com/dejohn/archive/2009/05/28/avatardescription-description.aspx

  • ひにけにXNA

    自動XNBファイルシリアライズ

    • 3 Comments

    コンテントタイプライター/リーダーを書くのは面倒

    XNA Game Studioのコンテント・パイプラインでのデータの流れは下図のようになっています。オフラインプロセスは開発しているVisual Studio上でビルドしたときにWindows上で処理されるプロセスで、オフラインプロセスはWindows、Xbox 360、Zune上でゲームを実行したときに処理されるプロセスです。

    cp-001

    元からサポートされているデータをそのまま扱う場合には良いのですが、カスタムデータを扱う場合に書かないといけないのが、ContentTypeWrite/ContentTypeReaderでした。特に面倒だったのが、読み込みと書き込みという対称的な処理をするのにContentTypeWriterはオフラインプロセス側、ContentTypeReaderはオンラインプロセス側と別々の場所で書かないといけないことでした。

    この面倒臭さを解決する為に、XNA GS 3.1では自動XNBシリアライズ機能が追加されました。この機能を使うことで、多くの場面でContentTypeWriter/ContentTypeReaderを書く必要がなくなりました。

    自動XNBシリアライズ機能の使い方

    自動XNBシリアライズは.Netのリフレクション機能を使って実装されています。ContentTypeWriter/ContentTypeReaderが指定されていない場合、自動XNAシリアライズが発生し、以下のルールに沿って動作します。

    • 公開(public)メンバー、プロパティがシリアライズの対象になる
    • シリアライズしたくないメンバーがある場合は、[ContentSerializerIgnore]属性を指定することで、シリアライズしないように指定できる
    • private, protected, internalなどの非公開メンバーをシリアライズしたい場合は[ContentSerializer]属性を指定する
    • シリアライズしたいデータ構造が再帰的な参照を含む場合は[ContentSerializer(SharedResource = true)]を指定する
    • コンテント・パイプライン内とランタイム時の型が違う場合、[ContentSerializerRuntimeType(“タイプ名”)]を指定する

    シンプルな例

    例えば以下のようなデータをゲームで扱うとします。ゲームとコンテント・パイプラインで共有するデータなので、ゲームプロジェクトの他に共有するデータを入れるためのプロジェクトを作る必要があります。例えばMyDataTypesという名前のプロジェクトです。

    // ねこクラス
    public class Neko
    {
        public string Name;     // 名前
        public float Weight;    // 体重
        public int Tails;       // 尻尾の数
    }

    このデータをコンテント・パイプライン内に読み込むために以下のようなXMLファイル、cats.xmlを書きます。

    <?xml version="1.0" encoding="utf-8" ?>
    <XnaContent>
      <Asset Type="MyDataTypes.Neko[]">
        <Item>
          <Name>たま</Name>
          <Weight>8</Weight>
          <Tails>1</Tails>
        </Item>
        <Item>
          <Name>ねこまた</Name>
          <Weight>12</Weight>
          <Tails>2</Tails>
        </Item>
      </Asset>
    </XnaContent>
    
    

    作ったXMLファイルをコンテントとして追加した後に、そのデータを読み込むコードをゲーム側のコード(LoadContentメソッド内など)に以下のコードを追加します。

    Neko[] cats = Content.Load<Neko[]>("cats");

    後は、F5を押すだけで変数catsには必要なデータが読み込まれます。3.0以前のようにContentTypeReader/ContentTypeReaderを書かなくても良いので、データ構造の宣言、データファイルの生成、読み込み部分のコードをゲーム内に追加という単純な作業でカスタムデータをゲーム内で読み込むことができます。

    オフラインとランタイムで型が違う場合

    XNA GS 3.1のコンテント・パイプライン内で使われる型の図を見ると、コンテント・パイプライン内ではTexture2DContentだけど、ゲーム内ではTexture2Dのように、オフライン時とランタイム時では型が異なるケースがあります。例えば、ゲーム内では以下のデータ構造にしたい場合があるとします。

    // ねこクラス
    public class Neko
    {
        public string Name;         // 名前
        public Texture2D Texture;   // テクスチャ
    }

    この場合、Textureはコンテント・パイプライン内で使う型がTexture2DContentとなるので、以下のようにContentSerializerRuntimeType属性を使ってランタイム時の型を指定します。

    // ねこコンテント
    [ContentSerializerRuntimeType("MyGame.Neko, MyGame")]
    public class NekoContent
    {
        public string Name;         // 名前
        public Texture2DContent Texture;   // テクスチャ
    }

    パフォーマンス

    以上のように自動XNBシリアライズ機能は非常に便利な機能ですが、前述のようにデータの書き込みと読み込み時にリフレクション機能を使用するのでContentTypeWriter/ContentTypeReaderに比べると不必要なメモリ確保や、ボクシングなどが発生し、処理時間も多く掛かるので理論的にはロード時間が以前より長くなります。

    ですが、現実的にはカスタムデータの多くがゲーム内のパラメーターなど、他のコンテントに比べると数は少ないものなので、ロード時間が長くなるといっても無視できる範囲のことが多いと思われます。

    ただし、カスタムデータを数百、数千の配列で持つようなケースでは極端にロード時間が長くなる場合もあります。その場合は、今までどおりContentTypeWriter/ContentTypeReaderを使うことによってリフレクションによる速度低下を防ぐことができます。便利さを優先するには自動XNBシリアライズ、速度を優先するならContentTypeWriter/ContentTypeReaderといった感じに上手に使い分けましょう。

    サンプル・コード

    自動XNBシリアライズ機能を使ってコンテント・パイプラインの紹介の時に作った日本語表示のサンプルを3.1用に書き換えてみました。元のサンプルと比べると、共有するデータ型を記述するプロジェクト自体を書く必要がなくなり、ContentTypeWriter/ContentTypeReaderを書く必要が無くなったのでシンプルになっています。

    http://higeneko.net/hinikeni/sample/TextMessageSample31.zip

    元ネタ:http://blogs.msdn.com/shawnhar/archive/2009/03/25/automatic-xnb-serialization-in-xna-game-studio-3-1.aspx

  • ひにけにXNA

    AppWeek

    • 1 Comments

    XNAプラットフォーム&ツールチームの主な作業はXNA Game Studioを作ることですが、リリースの直前には、実際に作ったものに問題がないか、また使いやすいかを確認するために開発中のフレームワークを使って実際にゲームを作ってみるAppWeekというものがあります。

    XNA GSE 1.0の頃に作られた物の中にはCatapultMinjiといったサンプルとして公開されているものもあります。XNA GS 3.0の時は忙しすぎてAppWeekをする暇がなかったのですが、今回のXNA GS 3.1ではAppWeekがありました。

    今回のAppWeekは4日間という短期間でしたが15個のゲームが作られました。特に3.1で追加された機能のテストを兼ねているので今回はアバターとビデオを使ったゲームが殆どでした。

    Shawn Hargreaves氏はCreators Club Onlineサイトにあるサンプルコードを組み合わせて作った「Super Avatar Sample Smashup EXTREME! ‘Capture the Cat’ edition」を作りました。このゲームではフィールド内の相手陣地のねこを自陣までつれてくるのが勝利の条件で、一匹のねこをめぐって宇宙船やら、戦車を使った争奪戦を繰り広げるネットワーク対応のゲームでした。

    Brandon Bloom氏の作った「Avatar Boxing」は、アバターを使ったボクシングゲームでした。アバターの各ボーンを自由に変更することで任意のアニメーションを設定で機能を使ったものでした。ちなみにこのゲームを作るときにはBoundingSphere.Transformがサポートするのは平行移動のみの行列でしたが、それでは不便ということで3.1では平行移動、回転、スケールの行列もサポートするようになりました。

     

    私も3日間だけ時間が取れたので、アバターを使ったゲームを作ってみました。タイトルは「Columns Flash」、落ちものパズルゲームにアバターを組み合わせたものです。今回は贅沢にすべてのブロックを3Dにしてみました。

    ブロックを消すと、下のスクリーンショットのようにアバターが拍手するアニメーションしたり、

    itoxe1-71

    コンボゲージが溜まったときにYボタンを押すと、下のスクリーンショットのようにコンボアタックを発動して対戦相手に対していじわる攻撃を繰り出すことができます。

    itoxe1-69 

    こちらはLv1コンボアタックの「ゆさぶり」で、相手のボード全体がふらふらと揺れてプレイししづらくなります。もちろん、アバターも困った顔をしています。3Dで描画しているので、コンボアタックも3Dならではの攻撃になっています。

    itoxe1-70

     

    こちらは、Lv2コンボアタックの「ちぢこまり」です。ボードが小さくなるだけなのですが、この攻撃をされた対戦相手は画面が良く見えなくなるので、モニタの前に張り付く姿が笑えます。

     itoxe1-73

    で、こちらはLv3コンボアタックの「ひっくりがえし」です。ボードが180度回転して、ブロックの上下が逆さまになります。この手のゲームでは連鎖のタネをばら撒くのが勝つコツですが、そういった計画を文字通りひっくりがえしてしまう攻撃です。アバターも驚いた表情をします。

     itoxe1-76

    対戦が白熱してくると、やられたらやり返すという場面が増えてくるので、二人同時にコンボアタック発動して下のように派手な画面になることもしばしばあります。

    itoxe1-74

    そして、ゲームオーバーになると、下の画面のように負けたほうのブロックが飛び散り、勝ったプレイヤーのアバターは喜びのアニメーション、負けた方はうなだれたアニメーションをするようになっています。

    itoxe1-75

     

    このゲームではアバターの基本描画と、基本アニメーションセットしか使っていませんが、それでも自分のアバターがそのままゲーム内でさまざまなリアクションをするというのは楽しいものでした。また、今回のゲームは絵も含めてフルスクラッチ(背景の写真はハイキングへ行ったときに撮った写真)で制作しましたが、3日間という短期間でここまでのゲームを作ることができるという、C#を使った開発効率の高さにはいまだに感心させられます。

  • ひにけにXNA

    XNA GS 3.1のコンテント・パイプラインで使われる型

    • 2 Comments

    以前、Shawn Hargreaves氏のブログでXNA GS 2.0のコンテント・パイプライン内でデータが変換される過程図が紹介されました。

    http://blogs.msdn.com/shawnhar/archive/2007/10/10/content-pipeline-types.aspx

    XNA GS 3.1がリリースされたので、それに合わせて元の図を翻訳し、SoundEffect、Video等の新しい型を追加した図を作ってみました。アセットファイルがどのようにインポートされ、プロセッサで処理され、ContentTypeWriterからXNBファイルとして書き出されるまに使われる型情報を網羅しているので、カスタムインポータや、カスタムプロセッサを作るときに役立つと思います。

    左側の水色の部分はコンテント・パイプライン内で処理される部分で、右側の黄色い部分はゲーム実行時に処理される部分です。

    ContentPipelineTypes

  • ひにけにXNA

    動画再生

    • 1 Comments

    かんたん動画再生機能

    XNA GS 3.1で動画を再生するには以下のステップを踏みます。

    • 再生したい動画をコンテントとして追加する
    • Video情報をContent.Load<Video>で読み込む
    • VideoPlayerクラスを使って再生
    • VideoPlayer.GetTexture()メソッドを使って現在のフレームのテクスチャを取得し描画する

    変数宣言

    動画再生するには、Videoクラスと、VideoPlayerクラスを使います。Videoクラスには再生する動画ファイル情報、動画のサイズやフレームレートなどの情報を含んでいます。VidoPlayerクラスは実際に動画再生するためのクラスで、このクラスを介して動画の再生、停止、一時停止、ループ再生の設定、現フレームをテクスチャとして取得することができます。

    // 再生する動画
    Video video;
    
    // 動画再生用のプレイヤーインスタンス
    VideoPlayer videoPlayer = new VideoPlayer();

    動画情報の読み込みと再生

    動画情報の読み込みは他のアセットと同様、コンテントマネージャーを介して行います。読み込んだ動画情報をビデオプレーヤーに渡すことで動画再生をすることができます。

    Xbox 360の上で、デコーディングなどの動画再生処理は別スレッドで行われているのでゲームのメインスレッドへの影響は最小限になっています。

    // 動画情報の読み込み
    video = Content.Load<Video>("bear");
    
    // ループ再生の設定
    videoPlayer.IsLooped = true;
    
    // 指定のビデオを再生する
    videoPlayer.Play(video);

    再生フレームの取得

    動画の音声部分は自動的に再生されますが、画像部分を表示するにはビデオプレイヤーから現在のフレームをテクスチャとして取得し、SpriteBatch等を使って描画します。GetTextureを呼ぶタイミングは動画のfpsに関係なくいつでも取得することができます。

    XNA GS 3.1の動画再生では常に実時間に合わせて動画再生を行うように実装されています。例えば高解像度の動画を性能の低いPC上で再生した場合は動画のフレームレートは落ちるけど、時間的には正しい動画再生をするようになっています。

    取得するテクスチャは別スレッドでデコードされた時間的に最も近い動画フレームです。ですから、30fpsの動画を60fpsで動作しているゲーム内で取得した場合は、2フレームが同じ動画フレームを取得することになり、逆に60fpsの動画があった場合、30fpsで動作しているゲーム内で動画フレームを取得した場合は動画データのフレームがスキップすることになります。

    // 現在の再生フレームをテクスチャとして取得
    Texture2D texture = videoPlayer.GetTexture();
    
    // 取得したテクスチャを使って描画
    spriteBatch.Begin();
    spriteBatch.Draw( texture, pos, Color.White);
    spriteBatch.End();

    以下は、Windowsについてくるbear動画をXNA GS 3.1上で再生したものです。10行以下のコードで簡単に動画を再生できるようになっています。

    itoxe1-59

    また、再生フレームはテクスチャとして使えるので、取得したテクスチャを3Dモデルに適応することもできます。下の図を見て複数の動画が再生していると気づいた人もいると思いますが、VideoPlayerのインスタンスは複数作ることができ、それぞれに別々の動画を再生することもできます。ただし、それぞれの動画をデコード処理するのに時間が掛かるので、複数のHD動画再生するにはかなりのCPUパワーを必要とすることに注意してください。

    itoxe1-60

     再生フォーマット

    XNA GS 3.1で再生できる動画の条件として以下があります。

    1. DRM(デジタル著作権管理)が施された動画は再生できない
    2. WMV-9 “Main”プロファイル、VC-1エンコードされたもの
    3. CBR(固定ビットレート)
    4. 音声トラックがあること
    5. 音声トラックはWMAエンコード、1パスCBR
    6. XNA GSがサポートする最大ビットレートは以下の通り
    プロファイル レベル 最大ビットレート 解像度とフレームレート
    Main Low 2 Mbps 320 x 240 @ 24Hz (QVGA)
      Medium 10 Mbps 720 x 480 @ 30Hz (480p)
    720 x 576 @ 25Hz (576p)
      High 20 Mbps 1280 x 720 @ 30Hz (720p)
  • ひにけにXNA

    XNA Game Studio 3.1がリリース

    • 0 Comments

    XNA Game Studio 3.1がリリースされました。

    http://www.microsoft.com/downloads/details.aspx?FamilyID=80782277-d584-42d2-8024-893fcd9d3e82&displaylang=en

    インストール時の注意点

    インストールするときの注意として、3.0をアンインストールしてから3.1をインストール必要があります。XNA GS 3.1では3.0、3.1の両方をサポートしているので、3.0で作ったゲームがそのまま遊べますし、3.0で作ったプロジェクトもそのまま読み込むことができます。また、プロジェクトメニューから3.1用のプロジェクトへの更新もできるようになっています。

    新機能

    XNA GS 3.1では以下の新機能が追加されました。

    • アバター(Xbox 360のみ)
    • 動画再生
    • XNBファイルの自動シリアライズ
    • Xbox Live Party (Xbox 360のみ)

    アバターAPIではゲーマープロフィールのアバター情報から、アバターを描画することができ、いくつかの基本的なアニメーションを再生することができます。また、任意のボーンデータを設定することで自分のアバターをゲーム内でキャラクターとして使用することもできます。

    動画再生ではWMVファイルをコンテントとして追加することで、ゲーム内で動画再生することが可能となりました。2Dの動画再生にも使えますが、動画フレームはテクスチャデータとして取得できるので3Dモデルに貼り付けて再生することもできます。

    今まではXNBファイルに独自のデータ形式を格納するにはそれぞれの型に対応するTypeWriter/TypeReaderを作る必要がありましたが、XNBファイル自動シリアライズ機能を使うことで、TypeWriter/TypeReaderを書かなくても独自のデータ形式を簡単に使えるようになりました。

    Xbox Live Party機能、今までは複数の友人をプレイしているゲームに招待する場合に、ユーザーがひとりひとり手動で招待する必要がありましたが、LocalNetworkGamer.SendPartyInvitesメソッドを使うことでプログラム側から複数のパーティーメンバーを一気に招待することができるようになりました。ユーザーがパーティーメンバーであるかどうかを調べるにはSignedInGamer.PartySizeプロパティの内容で判断できます。

    次回からは、これらの新機能の詳しく紹介していきます。

Page 1 of 1 (10 items)