飴屋

WPF/日記5

リソース辞書の作成

前回Identityで作成した アニメーション3Dモデルデータは、プログラム上でユーザのチャット空間への入退室に連動して動的に追加したり削除したりする必要があります。なので、少し手を加えてプログラムから呼び出しやすいようにしてあげる必要がありそうです。調べてみると、XAMLにはResourceDictionaryという仕組みが用意されており、名前から推測するにリソース(この場合はアバタ)を必要に応じて呼び出せるように登録しておく辞書なのではないかと思われます。既にIdentityで生成されたXAMLファイル内にはというタグがついているのでこれを参考にしつつ、ファイルを整形してみます。

ResourceDictionaryタグ

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
........
........
</ResourceDictionary>

上記のような内容のファイルを用意しておくと、ResourceDictionaryタグで囲まれた「........」の部分がリソースとして呼び出し可能になるようです。なので、ここにモデル形状やアニメーションの設定を書いておきます。Identityから出力されたファイルには、Viewport3Dタグやカメラの設定情報、アニメーションのトリガ情報も含まれているので、これらは不要という判断の元削除しておきました。結果、ResourceDictionaryタグの中身は、

  • ResourceDictionaryタグ(マテリアル情報、メッシュ情報が入っている)
  • ModelVisual3Dタグ(モデルオブジェクト情報)
  • Storyboard(アニメーション情報)

となりました。ResourceDictionaryが入れ子になる形となりましたが、問題があるかどうかは後で検証することにします。2番目のModelVisual3Dから1番目の
ResourceDictionaryの中のマテリアル情報やメッシュ情報を参照しているようです。
このファイルの情報にアクセスするための識別子が必要なようなので、2番目のModelVisual3Dに「x:Key="myMan"」という属性をつけておきました。Identityのデフォルト出力で既に「x:Name="Character_man_Character_0"」という属性もついていたのですが、まだよく理解できていないので何でもかんでもつけておくことにしました。

編集したファイルを、「man.xaml」という内容でプロジェクトに追加します。ソリューションエクスプローラより「追加」→「新しい項目」→「リソースディクショナリ(WPF)」という手順で追加できました。このファイルをPage1.xamlから呼び出せるようにしなくてはいけないので、

<Viewport3D.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="man.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Viewport3D.Resources>

という記述をViewport3Dタグの中に追加しました。これでOKかと思ったら、man.xamlの中にエラーがあるためうまくリソースが読み込めないとのメッセージが出てしまいました。どうもResourceDictionaryの中にResourceDictionaryを入れ子で置いておいたのが問題だったようでした。その他にもResourceDictionaryの中ではx:Name属性をつけられないとかなんとか。ModelVisual3Dタグがx:Name属性を持っていたのでそれを削除しました。識別はx:Key属性でやればいいですからね。

VC#が意味不明なエラーを出すので困惑してしまいましたが、試しに「デバッグ開始」ボタンを押してみると、ビルドも通りエラーメッセージも消えました。VC#の挙動を正確に把握しきれていないので、変なところでつまずくことが多いです。

モデルの追加

リソース辞書にアバタが登録できたようですので、これを動的に呼び出して画面に表示してみることにします。アバタを表示するViewPort3Dに「x:Name="ChatWorld"」と名前をつけてみました。追加すべきリソースは辞書の中に「x:Key="myMan"」と名前をつけておきましたので、この名前をつかってCSファイルの中でこれらを操作するスクリプトを書いてみます。

その前にModelVisual3Dオブジェクトを使うためにPage1.xaml.csファイルに一行追加します。

using System.Windows.Media.Media3D;

そして、Page1.xamlのデザインビューの白い部分を適当にダブルクリックすると、勝手にPageがロードされたときのイベント関数がPage1.xaml.csに追加されるので、その中にコードを書いていきます。

private void Page_Loaded(object sender, RoutedEventArgs e)
{
ModelVisual3D mv3d = (ModelVisual3D)ChatWorld.FindResource("myMan");
ChatWorld.Children.Add(mv3d);
}

ModelVisual3Dオブジェクトを新規に生成して、myManという名前のリソースを当てはめて、「ChatWorld」に追加しているだけです。ビルドも通ったので実行してみると、追加されたと思ったアバタが見当たりません。原因は・・・

  1. アバタのリソースがおかしい
  2. きちんとアバタが追加されていない
  3. 追加されたが、表示するには別の処理が必要
  4. カキワリの後に隠れている
  5. カメラの向いている方向にアバタがいない

のどれかでしょうか。とりあえず、今日はここまで。

WPF