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