概要
前回の記事 では Vuforia の File Driver をビルドしました.
今回の記事では実際に Unity のプロジェクトに組み込んで外部カメラとしてローカルの画像ファイルを読み込ませたいと思います.
出来上がったものがこちらになります(3分クッキング的な).
※ ファイルサイズの関係で一部のみアップロードしています.
ノウハウ
基本的には Vuforia の公式サイトにある Building and Using the File Driver Sample を動かしただけなのでそんなに難しいことは無いのですがいくつか気がついた点を書いていきます.
Unity Editor では普通のカメラを使う
FileDriver は UWP もしくは Android 上でしか動きません(2018/10/08現在). そのため、 UnityEditor 上で動かそうとすると警告が表示されてしまいます.
なので UWP として実行しているときだけ FileDriver を使うように以下のようにコードを変更しました. Android の場合もよしなに #if
すれば大丈夫です.
void Awake()
{
#if UNITY_WSA && !UNITY_EDITOR
string filePath = Application.streamingAssetsPath.Replace("/", "\\");
userData = new FileDriverUserData()
{
sequenceDirectoryAbsolutePath = filePath
};
userDataPrt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileDriverUserData)));
Marshal.StructureToPtr(userData, userDataPrt, false);
VuforiaUnity.SetDriverLibrary("FileDriver.dll", userDataPrt);
#endif
VuforiaRuntime.Instance.InitVuforia();
}
常に同じ画像を使う
sequence.txt
の NumberOfImage
を 1 にして image00000.png
という画像をおいておけばその画像だけを永遠にループし続けるので静止画を認識させるときに使えます.
アニメーションの画像を作る
こちらは Photoshop の機能なのですが、2つのコマから間のコマを作って出力する事ができます. photoshop タイムライン
とかでググるとやり方が出てきます.
↑ で作った画像を image00000.png
形式にリネームするのがめんどい
こうやりました.
const fs = require("fs");
const regex = () => /.+ ([0-9]+)\.png/
const pad = 5
let dry = true
/**
*
* @param {string} path
*/
const toMap = path => {
const re = regex()
const match = re.exec(path)
const valid = match && typeof match[1] == "string" && !isNaN(parseInt(match[1], 10))
return {
valid,
path,
replacePath: valid ? `image${match[1].padStart(pad, "0")}.png`: null,
match: valid ? parseInt(match[1]) : null
}
}
fs.readdirSync(".", { encoding: "utf8" })
.map(toMap)
.filter(f => f.valid)
.sort((a, b) => a.match - b.match)
.forEach(f => {
console.log(`Rename: "${f.path}" => "${f.replacePath}"`)
if (dry === false) {
fs.renameSync(f.path, f.replacePath)
}
})