HEXA BLOG
ヘキサブログ
プログラム
ちょっとだけARに触れてみる
こんにちは
プログラマーの
チャラメガネ
です![]()
最近ますます暑くなってきましたね![]()
気温ももちろんですが、
今、
チャラメガネ
の中で特に熱いコンテンツは
「ポケモンGO 」です![]()
このゲーム、一般的にはAR表現で有名ですね。
プログラマーとしては、ARへの好奇心が疼きます![]()
というわけで、ARのデモを作成してみました。![]()
![]()
テーマとしては、
「部屋に女の子を召喚し、観察したり撮影したりできるスマホアプリ」
です![]()
![]()
今回はお馴染みのゲームエンジン「Unity」を使い
ユニティちゃんを召喚してみます![]()
![]()
1.まずはイメージを考える
女の子を部屋に召喚して写真を撮るシチュエーション。
理想としてはこんな感じ。
しかし、ARのない現実は…
当然ですが、こんな感じですね。
この理想を叶えるためAR表現でユニティちゃんを召喚するわけです。
2.とりあえず原理から
まず、必要な物は
・ジャイロセンサー
・カメラ
最近のスマホには概ね付いています![]()
まずゲーム空間上にカメラとユニティちゃんを配置します。
この時、カメラにレンダーテクスチャをターゲット指定しておきます。
次に、ジャイロセンサーを使い
端末の傾きをゲーム空間上のカメラに伝えます。
これで、ゲーム空間に関する処理は終わりです。
次は背景テクスチャですが、
端末搭載カメラからテクスチャを取得するだけです。
最後に、
ゲーム空間のカメラのレンダーテクスチャと
端末搭載カメラから取得したテクスチャを重ねます。
原理は以上です!
これなら簡単に実装できそうですね。
背景からの平面抽出などはしていないので
端末の移動には対応していませんが、見た目は問題ないと思われます。
3.実装すると
以上を踏まえて、今回実装したコンポーネントです。
まずはゲーム空間上のカメラと
端末の傾きを同期するコンポーネントです。
CameraDeviceSync.cs
using UnityEngine;
//===========================================================================
//! @class CameraDeviceSync
//! @brief カメラと端末の同期
//! Cameraとの組み合わせで動作する。
//===========================================================================
[RequireComponent(typeof(Camera))]
public class CameraDeviceSync : MonoBehaviour
{
//-----------------------------------------------------------
//! @name 内部メソッド
//-----------------------------------------------------------
//@{
//-----------------------------------------------------------
//! @brief 初回処理
//! @return なし
//-----------------------------------------------------------
private void Start()
{
// ジャイロセンサーの有効化
Input.gyro.enabled = true;
}
//-----------------------------------------------------------
//! @brief 更新
//! @return なし
//-----------------------------------------------------------
private void Update()
{
// 端末の傾きを取得
Quaternion attitude = Input.gyro.attitude;
// attitudeは端末の画面を上に向けている状態が基準となっている。
// 今回、端末を縦持ちしている想定なので、90度回しておく。
transform.localRotation = Quaternion.Euler(90, 0, 0) * new Quaternion(-attitude.x, -attitude.y, attitude.z, attitude.w);
}
//-----------------------------------------------------------
//! @brief GUI更新
//! @return なし
//-----------------------------------------------------------
private void OnGUI()
{
#if DEBUG
// ジャイロセンサーとCameraの回転情報を表示
GUI.Label(new Rect(0, 0, 480, 20), "gyro:" + Input.gyro.attitude);
GUI.Label(new Rect(0, 20, 480, 20), "rotation:" + transform.localRotation);
#endif
}
//@}
}
次に、端末搭載カメラのテクスチャを表示するコンポーネントです。
WebCameraImage.cs
using UnityEngine;
using UnityEngine.UI;
//===========================================================================
//! @class WebCameraImage
//! @brief Webカメラの取得
//! RawImageとの組み合わせで動作する。
//===========================================================================
[RequireComponent(typeof(RawImage))]
public class WebCameraImage : MonoBehaviour
{
//-----------------------------------------------------------
//! @name 内部メソッド
//-----------------------------------------------------------
//@{
//-----------------------------------------------------------
//! @brief 初期化
//! @return なし
//-----------------------------------------------------------
private void Start()
{
// テクスチャを貼り付けるターゲットとしてRawImageを取得。
RawImage targetImage = GetComponent();
if( targetImage == null ) {
Debug.LogWarning("invalid target.");
return;
}
// カメラ情報は横向きで取得される。
// _targetImageはエディタ上で事前に回転させておき、widthとheightは逆に入れる。
targetImage.rectTransform.sizeDelta = new Vector2(Screen.height, Screen.width);
// カメラ情報はWebCamTexture型で取得可能。
WebCamDevice[] devices = WebCamTexture.devices;
if( devices == null ||
devices.Length <= 0 ) {
Debug.LogWarning("there is not device.");
return;
}
// 0番目のデバイスを使用
// 端末によっては、0番がセルフィー用カメラの可能性もあり。
WebCamDevice device = devices[0];
WebCamTexture webcamTexture = new WebCamTexture(device.name, Screen.width, Screen.height, _webCamFPS);
if( webcamTexture == null ) {
Debug.LogWarning("invalid WebCamTexture.");
return;
}
// ターゲットにテクスチャを指定し、カメラを起動
targetImage.texture = webcamTexture;
webcamTexture.Play();
}
//@}
//-----------------------------------------------------------
//! @name メンバ変数
//-----------------------------------------------------------
//@{
[SerializeField] private int _webCamFPS = 30; //!< カメラのFPS
//@}
}
他にもレンダーテクスチャをUIに送る処理など書いていますが
特筆するべきところは特にないので端折ります。
4.実行結果
こんな感じになりました!
ちょっと足元が浮いてるとか
なんかデカイとか
調整すべき項目はありますがそれっぽい見た目になっています!
さて、今後の調整項目ですが、
・影がないので接地感がない
・現実の光源とゲーム空間の光源を一致させる仕組みがほしい
・画角が狭すぎてモデルがでかく見える
・ユーザーの腕の動きが考慮されていないので回転に違和感がある
・前後移動がないので近づけない
こういったものが挙げられます。
今後も進捗あれば報告していきます![]()
それではまた次回![]()
![]()

CATEGORY
- about ヘキサ (166)
- 部活動 (6)
- CG (18)
- プロジェクトマネジメント (1)
- 研修 (5)
- 美学 (1)
- いいモノづくり道 (227)
- 採用 -お役立ち情報も- (149)
- プログラム (189)
- デザイン (99)
- ゲーム (273)
- 日記 (1,104)
- 書籍紹介 (113)
- その他 (889)
- 就活アドバイス (20)
- ラーメン (3)
- ライフハック (25)
- イベント紹介 (10)
- 料理 (23)
- TIPS (7)
- 怖い話 (3)
- サウンド (6)
- 子育て (1)
- 筋トレ (1)
- NicO (3)
- MakeS (9)
- 商品紹介 (21)
- アプリ紹介 (31)
- ソフトウェア紹介 (33)
- ガジェット紹介 (12)
- サイト紹介 (10)
- 研究・開発 (35)
- 回路図 (4)
- アナログゲーム (40)
- 交流会 (21)
- 報告会 (3)
- インフラ (25)
- グリとブラン (6)
- カメラ (9)
- クラフト (27)
- 部活 (14)
- 画伯 (15)
- カレー (6)
- 音楽(洋楽) (6)
- 映画・舞台鑑賞 (43)
- 飼育 (5)
- いぬ (8)
- ねこ (19)
ARCHIVE
- 2025年
- 2024年
- 2023年
- 2022年
- 2021年
- 2020年
- 2019年
- 2018年
- 2017年
- 2016年
- 2015年
- 2014年
- 2013年
- 2012年
- 2011年
- 2010年
- 2009年
- 2008年
- 2007年













