UnityでAR 検証4回目
JAL都道府県シールを画像マーカーにしてUnity×vuforiaのARを検証するのも今回で4回目です。
今回の目標は
「2つの画像マーカーの間オブジェクトを表示。距離に応じてオブジェクトのスケールを変化させる」
前回まではローカル座標とワールド座標の関係を検証しましたが、単体の画像マーカーの中で完結していました。
今回は複数の画像マーカー間での座標の検証をしたいと思い目標設定しました。
それでは早速検証を始めます。
前回までの検証をまだ読んでない方は是非読んでみてください。
>>UnityでAR 画像マーカーで複数のオブジェクトを表示させる[Vuforia]
>>UnityでAR マーカーに追従しないでその場に留まるオブジェクト[vuforia]
画像マーカーが2つとも認識されたら、3個目のオブジェクトを表示する
「Osaka」 と 「Hiroshima」 の2つの画像マーカーを使います。
Hierarchyの構成は
-tutenkaku
-center_obj
– -flexibility_cube
ImageTarget_Hiroshima
-genbaku_dome
「center_obj」の名前でEnptyオブジェクトを作ってその下に表示させるオブジェクト
「flexibility_cube」を配置しました。
ImageTarget_Osakaにアタッチしたスクリプトに、
「tutenkaku」のオブジェクトと「genbaku_dome」のオブジェクトが
同時に表示されたら
「flexibility_cube」のオブジェクトを表示するコードを書きました。
public GameObject tutenkaku;
public GameObject genbaku_dome;
public GameObject flexibility_cube;
void Update()
{
MeshRenderer tutenkaku_meshRenderer = tutenkaku.GetComponent<MeshRenderer>();
MeshRenderer genbaku_dome_meshRenderer = genbaku_dome.GetComponent<MeshRenderer>();
MeshRenderer flexibility_cube_meshRenderer = center_obj.GetComponent<MeshRenderer>();
if (tutenkaku_meshRenderer.isVisible && genbaku_dome_meshRenderer.isVisible)
{
flexibility_cube_meshRenderer.enabled = true;
}
else
{
flexibility_cube_meshRenderer.enabled = false;
}
}
スクリプトコードの説明
if (tutenkaku_meshRenderer.isVisible && genbaku_dome_meshRenderer.isVisible)
「tutenkaku」と「genbaku_dome」のMeshRendererをチェックして両方とも Visible 見える状態になったら
flexibility_cube_meshRenderer.enabled = true;
「flexibility_cube」を表示します。
実行します。
Osakaの画像マーカーの単体の時は「tutenkaku」しか表示されませんが、「genbaku_dome」も表示されると「flexibility_cube」が現れました。
3個目のオブジェクトを2つの画像マーカーの中間に表示する
無事に「flexibility_cube」を表示させることが出来ました。
出現地点は何も設定していないので「tutenkaku」と同じ位置です。
今度は、Osaka と Hiroshima の画像マーカーの中央地点に配置したいとおもいます。
ImageTarget_Hiroshima_X + ImageTarget_Osaka_X /2
ImageTarget_Hiroshima_Z + ImageTarget_Osaka_Z /2
で座標は取得できるはずなので以下のコードを書きました。
「center_obj」にアタッチしたスクリプトに
public GameObject imageTarget_Osaka;
public GameObject imageTarget_Hiroshima;
void Update()
{
Transform iT_Osaka = imageTarget_Osaka.GetComponent<Transform>();
Transform iT_Hiroshima = imageTarget_Hiroshima.GetComponent<Transform>();
Vector3 iT_Osaka_pos = iT_Osaka.transform.position;
Vector3 iT_Hiroshima_pos = iT_Hiroshima.transform.position;
float center_obj_pos_x = (iT_Osaka_pos.x + iT_Hiroshima_pos.x) / 2;
float center_obj_pos_z = (iT_Osaka_pos.z + iT_Hiroshima_pos.z) / 2;
Vector3 center_obj_pos = new Vector3((center_obj_pos_x - iT_Osaka_pos.x)*20, 0.0f , (center_obj_pos_z - iT_Osaka_pos.z)*20);
this.transform.localPosition = center_obj_pos;
}
スクリプトコードの説明
float center_obj_pos_x = (iT_Osaka_pos.x + iT_Hiroshima_pos.x) / 2;
float center_obj_pos_z = (iT_Osaka_pos.z + iT_Hiroshima_pos.z) / 2;
ImageTarget_Osaka と ImageTarget_Hiroshima のXとYの値をそれぞれ足して2で割りました。
Vector3 center_obj_pos = new Vector3((center_obj_pos_x - iT_Osaka_pos.x)*20, 0.0f , (center_obj_pos_z - iT_Osaka_pos.z)*20);
this.transform.localPosition = center_obj_pos;
取得した値はワールド座標ですが「center_obj」はローカル座標で配置します。中央地点の座標とImageTarget画像マーカーの座標の差を出して20(※実物の画像マーカーのサイズから)を乗算しました。
※画像マーカーのサイズについての関連記事
UnityでAR マーカーに追従しないでその場に留まるオブジェクト[vuforia]
実行します。
ブレはありますが、ほぼ中央に配置されてそうです。
2つの画像マーカーの距離に応じてオブジェクトを伸び縮みさせる
2つの画像マーカーの距離を出して「flexibility_cube」のデフォルト値に乗算したらいけるのかな?
「flexibility_cube」にアタッチしたスクリプトに以下のコードを書きました。
public GameObject ImageTarget_Osaka;
public GameObject ImageTarget_Hiroshima;
void Update()
{
Transform iT_Osaka = ImageTarget_Osaka.GetComponent<Transform>();
Transform iT_Hiroshima = ImageTarget_Hiroshima.GetComponent<Transform>();
Vector3 iT_Osaka_pos = iT_Osaka.transform.position;
Vector3 iT_Hiroshima_pos = iT_Hiroshima.transform.position;
this.transform.LookAt(iT_Hiroshima_pos);
float distance_target = Mathf.Sqrt((iT_Hiroshima_pos.x - iT_Osaka_pos.x) * (iT_Hiroshima_pos.x - iT_Osaka_pos.x) + (iT_Hiroshima_pos.z - iT_Osaka_pos.z) * (iT_Hiroshima_pos.z - iT_Osaka_pos.z));
float root_obj_Scale_z = System.Math.Abs(1.0f * distance_target * 20);
Vector3 root_obj_Scale = new Vector3(0.40773f, 0.40773f, root_obj_Scale_z);
this.transform.localScale = root_obj_Scale;
}
スクリプトコードの説明
this.transform.LookAt(iT_Hiroshima_pos);
「ImageTarget_Osaka」「ImageTarget_Hiroshima」どちらかを向く様にしました。今回はImageTarget_Hiroshimaを向くように設定しました。
float distance_target = Mathf.Sqrt((iT_Hiroshima_pos.x - iT_Osaka_pos.x) * (iT_Hiroshima_pos.x - iT_Osaka_pos.x) + (iT_Hiroshima_pos.z - iT_Osaka_pos.z) * (iT_Hiroshima_pos.z - iT_Osaka_pos.z));
float root_obj_Scale_z = System.Math.Abs(1.0f * distance_target * 20);
Mathf.Sqrt()を使って「ImageTarget_Osaka」と「ImageTarget_Hiroshima」の距離を取得
「flexibility_cube」のスケールのデフォルト値1.0f(と仮定して)に取得した距離の値を掛けました。
※20は実物の画像マーカーのサイズから
Vector3 root_obj_Scale = new Vector3(0.40773f, 0.40773f, root_obj_Scale_z);
this.transform.localScale = root_obj_Scale;
「flexibility_cube」のZ値のスケールを変化させます。
それでは実行してみましょう。
距離を表示するTextオブジェクトを追加しました。
それっぽくはなってるでしょうか。画像マーカーの距離に応じでスケールが変化しています。
まだまだ詰めきれてないけど今回はここで終了
まとめ
それっぽい結果にはなりましたが、きちんと理解した状態ではなく課題が見えた検証でした。
ImageTargetを作ると画像のサイズに合わせてスケールが自動で設定され、
何の何処のスケール値なのか等よくわからなかったり
画像マーカーの回転に対応してなかったり。
まだまだ検証する必要がありますね。
|
UnityでAR マーカーに追従しないでその場に留まるオブジェクト[vuforia] 「画像マーカーを移動しても出現位置に留まるオブジェクト」画像マーカーはワールド座標で表示されたオブジェクトはローカル座標なのでその部分の |
UnityでAR 画像マーカーの周りを回転するオブジェクト[vuforia] 「画像マーカーに2つのオブジェクトを出して、1つは固定もう1つは周りを回転」です。画像マーカーを認識して表示させたオブジェクトを個別にコントロールしたいという目的です。 |
|
|
BTOパソコンの草分け的ブランドFRONTIER(フロンティア) 3DCG/動画編集/ゲーム用途に合わせてCPUやGPUなどパーツを自由に選べてコスパにもこだわる方にオススメ。 |
|
|
|
|
|