UnityでAR 検証3回目
■今回の目標
「画像マーカーを移動しても出現位置に留まるオブジェクト」
画像マーカーはワールド座標で表示されたオブジェクトはローカル座標なのでその部分の検証をしたい。
vuforiaの座標についてもっと詳しく知りたくて今回の目標にしました。
早速検証を始めます。
前回の検証の環境を引き継ぐので、まだ読んでない方は是非よんでみてください。
|
vuforiaでマーカーを使ったARの座標
ワールド座標:
カメラの位置が0地点
カメラから見て右側が + 左側が -
カメラから奥に離れると +
ローカル座標:
マーカーの中心が0地点
右側が + 左側が -
奥が + 手前が -
画像マーカーの移動距離
移動先の位置 - 元の位置 = 位置の差
これで移動距離は取得できるはずなので早速書いてみます。
ひとまず X値 だけ試してみます。
public GameObject imageTarget_Osaka;
void Update()
{
float imageTarget_Osaka_bornPos_x = 0.0f;
float imageTarget_Osaka_now_pos_x = imageTarget_Osaka.transform.position.x;
float new_pos_x = (imageTarget_Osaka_now_pos_x - imageTarget_Osaka_bornPos_x);
Vector3 new_pos = new Vector3(-new_pos_x, 0.0f, 0.0f);
this.GetComponent<Transform>().localPosition = new_pos;
}
実行します。
?? なんとなくその場に留まろうとしている感じですがまだ画像マーカーに追従していますね。
ワールド座標とローカル座標の数値差は画像マーカーのサイズが大事
画像マーカーの移動方向と逆方向に移動させますが、その移動量が全然足りませんでした。
取得した移動量の数値を何倍にしたら良いのでしょう。
vuforiaで画像の登録した時のサイズ
vuforiaで画像マーカーに使用する画像を登録する時にAdd Target で、
マーカーにする Type、登録する File、 画像のサイズ Width
の入力を求められました。
この時のサイズが重要になります。
Widhtは、実際にマーカー画像にするモノの大きさの数値を入力します。
1m は 1、 10cm は 0.1、1cm は 0.01
都道府県シールはだいたい5cmなので 0.05 にしました。
1 * 0.05 = 20
20倍にすればワールド座標とローカル座標のスケールの数値差を補えそうです。
public GameObject imageTarget_Osaka;
void Update()
{
float imageTarget_Osaka_bornPos_x = 0.0f;
float imageTarget_Osaka_now_pos_x = imageTarget_Osaka.transform.position.x;
float new_pos_x = (imageTarget_Osaka_now_pos_x - imageTarget_Osaka_bornPos_x) * 20;
Vector3 new_pos = new Vector3(-new_pos_x, 0.0f, 0.0f);
this.GetComponent<Transform>().localPosition = new_pos;
}
実行します。
きちんと中心に留まらせることができました。
.isVisibleで出現タイミングを取得
位置を留めさせる事は出来ましたが、出現位置が画像マーカーの位置ではありません。
画像マーカーをカメラの右側で認識させても中心に紫のボールが出現してしまいます。
Z値も追加して修正します。
public GameObject imageTarget_Osaka;
public float imageTarget_Osaka_bornPos_x;
public float imageTarget_Osaka_bornPos_z;
bool ar_testball_visible = true;
void Update()
{
MeshRenderer ar_testball = this.GetComponent<MeshRenderer>();
if (ar_testball_visible == ar_testball.isVisible)
{
imageTarget_Osaka_bornPos_x = imageTarget_Osaka.transform.position.x;
imageTarget_Osaka_bornPos_z = imageTarget_Osaka.transform.position.z;
Vector3 tf_bornpos = new Vector3(0.0f, 0.0f, 0.0f);
this.GetComponent<Transform>().localPosition = tf_bornpos;
ar_testball_visible = false;
}
float imageTarget_Osaka_now_pos_x = imageTarget_Osaka.transform.position.x;
float imageTarget_Osaka_now_pos_z = imageTarget_Osaka.transform.position.z;
float new_pos_x = (imageTarget_Osaka_now_pos_x - imageTarget_Osaka_bornPos_x) * 20;
float new_pos_z = (imageTarget_Osaka_now_pos_z - imageTarget_Osaka_bornPos_z) * 20;
Vector3 new_pos = new Vector3(-new_pos_x, 0.0f, -new_pos_z);
this.GetComponent<Transform>().localPosition = new_pos;
Vector3 tf_Rotate = new Vector3(0.0f, 3.0f, 0.0f);
this.GetComponent<Transform>().Rotate(tf_Rotate);
}
説明
Update()の中で出現したタイミングで出現ポイントの座標を取得します。
bool ar_testball_visible = true;
void Update()
{
MeshRenderer ar_testball = this.GetComponent<MeshRenderer>();
if (ar_testball_visible == ar_testball.isVisible)
紫のボールが表示されてるかの判定をします。
imageTarget_Osaka_bornPos_x = imageTarget_Osaka.transform.position.x;
imageTarget_Osaka_bornPos_z = imageTarget_Osaka.transform.position.z;
Vector3 tf_bornpos = new Vector3(0.0f, 0.0f, 0.0f);
this.GetComponent<Transform>().localPosition = tf_bornpos;
出現したタイミングで画像マーカーのpositionを取得して
紫のボールのlocalpositionを画像マーカーの位置に変更
ar_testball_visible = false;
出現したタイミングの一度だけの処理にしたいので false にします。
実行します。
なんとか出現位置に留まらせることができてるようです。
|
まとめ
なんとか目標は達成できvuforiaの座標に付いても少し学べました。
ただ今回の検証では回転の要素は入っていません、カメラも固定です。
特にカメラの移動を考慮に入れたらグンッとハードルが上がるでしょう。
ただ、ローカル座標のオブジェクトでも頑張ればワールド座標の画像マーカーと連携させて動かす事に期待はもてました。
vuforiaにも空間座標を扱うマーカーレスARもあるので、そちらと連動させたいのですが同時には扱えなみたいで残念です。
一緒に扱うにしても、「最初はマーカーで認識してマーカーレスに切り替え」のような使い方になりそうです。
それでは今回の検証は終わりです。
まだまだ検証は勧めていきます。
「画像マーカーに2つのオブジェクトを出して、1つは固定もう1つは周りを回転」です。 |
豊富なカスタマイズメニューで、あなた好みの1台が購入できます。
人気の秘密は何と言ってもコスパの高さ。
最新のCPU・GPUパーツを搭載したモデルを驚きの価格で提供。
山口県の自社工場で組み立てられ徹底した試験・検査後に出荷。
無償修理サービスもありサポート体制も安心。
コスパに徹底的にこだわる方は公式サイトへ >> 【FRONTIER】
|
|
BTOパソコンの草分け的ブランドFRONTIER(フロンティア) 3DCG/動画編集/ゲーム用途に合わせてCPUやGPUなどパーツを自由に選べてコスパにもこだわる方にオススメ。 |
|
|
|
|
|