「MonoGameで外部のXNBファイルを読み込む」の版間の差分
ナビゲーションに移動
検索に移動
imported>Administrator |
|||
(3人の利用者による、間の4版が非表示) | |||
1行目: | 1行目: | ||
− | [[MonoGame]]で作っている[[ゲーム]]に起動時データ更新を実装し、[[プログラム]]以外の画像や音楽などだけであれば自動更新するようにしたいわけだ。 | + | [[MonoGame]]で作っている[[ゲーム]]に起動時データ更新を実装し、[[プログラム]]以外の画像や音楽などだけであれば自動更新するようにしたいわけだ。[[スマホ]]の[[ゲーム]]によくあるアレである。むしろ[[プログラム]]の細かい部分も[[NeoLua]]に投げるようにしてしまいたい。 |
− | |||
− | そうなると外部から各種[[データ]] | + | そうなると外部から各種[[データ]]を読み込む必要が出てくる。しかし[[MonoGame]]で扱う各種[[データ]]の基本は[[プログラム]]に組み込まれた「Content」である。 |
− | |||
− | ==Xamarin.Android== | + | == Xamarin.Android == |
− | [[MonoGame]] | + | [[MonoGame]]の[[ソースコード]]をざっと見た感じ、[[Xamarin.Android]]ではContentManagerクラスでアセット以外の[[ファイル]]へはアクセスできないようだ。ContentManagerクラスの[[ソースコード]]をみると幸いにもvirtualやらがチラホラ見受けられ継承してoverrideする前提の構造になっている。なので細かいことは考えずにoverrideしてしまえと考えた。 |
− | |||
− | |||
ついでに各種パラメータを保存した[[csv]]や[[json]]などのxnb以外の[[ファイル]]も同様の手順で読み込めるように、xnbパーサを経由しない裏口も用意すると捗った。 | ついでに各種パラメータを保存した[[csv]]や[[json]]などのxnb以外の[[ファイル]]も同様の手順で読み込めるように、xnbパーサを経由しない裏口も用意すると捗った。 | ||
− | |||
<source lang="csharp"> | <source lang="csharp"> | ||
61行目: | 56行目: | ||
} | } | ||
− | |||
− | |||
− | |||
stream = File.OpenRead(path); | stream = File.OpenRead(path); | ||
92行目: | 84行目: | ||
使い方は普通のContentManagerと大して変わらない。 | 使い方は普通のContentManagerと大して変わらない。 | ||
− | <source> | + | <source lang="csharp"> |
// Androidであれば「/data/data/アプリID/files」あたりが返ってくるはず。 | // Androidであれば「/data/data/アプリID/files」あたりが返ってくるはず。 | ||
− | var | + | var rootdir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); |
− | var cm = new ExternalContentManager(this.Content.ServiceProvider, | + | var cm = new ExternalContentManager(this.Content.ServiceProvider, rootdir); |
var font = cm.Load<SpriteFont>("IPA-Gothic"); | var font = cm.Load<SpriteFont>("IPA-Gothic"); | ||
</source> | </source> | ||
− | ==関連項目== | + | == 関連項目 == |
− | *[[ | + | * [[MacOS版のMonoGameのPipeline.appで3Dモデルをビルドできない]] |
+ | * [[MonoGameで使う3DモデルをFusion360で作成する]] | ||
+ | * [[MonoGameのカメラを作る]] | ||
[[category:MonoGame]] | [[category:MonoGame]] | ||
[[category:Xamarin.Android]] | [[category:Xamarin.Android]] |
2018年10月26日 (金) 05:23時点における最新版
MonoGameで作っているゲームに起動時データ更新を実装し、プログラム以外の画像や音楽などだけであれば自動更新するようにしたいわけだ。スマホのゲームによくあるアレである。むしろプログラムの細かい部分もNeoLuaに投げるようにしてしまいたい。
そうなると外部から各種データを読み込む必要が出てくる。しかしMonoGameで扱う各種データの基本はプログラムに組み込まれた「Content」である。
Xamarin.Android[編集 | ソースを編集]
MonoGameのソースコードをざっと見た感じ、Xamarin.AndroidではContentManagerクラスでアセット以外のファイルへはアクセスできないようだ。ContentManagerクラスのソースコードをみると幸いにもvirtualやらがチラホラ見受けられ継承してoverrideする前提の構造になっている。なので細かいことは考えずにoverrideしてしまえと考えた。
ついでに各種パラメータを保存したcsvやjsonなどのxnb以外のファイルも同様の手順で読み込めるように、xnbパーサを経由しない裏口も用意すると捗った。
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
public class ExternalContentManager : Microsoft.Xna.Framework.Content.ContentManager
{
public ExternalContentManager(IServiceProvider serviceProvider, string rootDirectory)
: base(serviceProvider, rootDirectory)
{
}
public ExternalContentManager(IServiceProvider serviceProvider)
: base(serviceProvider)
{
}
protected override Stream OpenStream(string assetName)
{
string assetPath;
if (Path.GetExtension(assetName) != "xnb")
{
assetPath = assetName + ".xnb";
}
else
{
assetPath = assetName;
}
return OpenRead(assetPath);
}
public Stream OpenRead(string fileName)
{
Stream stream = null;
string path;
try
{
if (Path.IsPathRooted(fileName))
{
path = fileName;
}
else
{
path = Path.Combine(RootDirectory, fileName);
}
stream = File.OpenRead(path);
// Read the asset into memory in one go. This results in a ~50% reduction
// in load times on Android due to slow Android asset streams.
var memStream = new MemoryStream();
stream.CopyTo(memStream);
memStream.Seek(0, SeekOrigin.Begin);
stream.Close();
stream = memStream;
}
catch (FileNotFoundException fileNotFound)
{
throw new ContentLoadException("The content file was not found.", fileNotFound);
}
catch (DirectoryNotFoundException directoryNotFound)
{
throw new ContentLoadException("The directory was not found.", directoryNotFound);
}
catch (Exception exception)
{
throw new ContentLoadException("Opening stream error.", exception);
}
return stream;
}
}
使い方は普通のContentManagerと大して変わらない。
// Androidであれば「/data/data/アプリID/files」あたりが返ってくるはず。
var rootdir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var cm = new ExternalContentManager(this.Content.ServiceProvider, rootdir);
var font = cm.Load<SpriteFont>("IPA-Gothic");