やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

DevFest Tokyo 2017に行ってきたメモ #DevFest17

10/9に開催されたDevFest Tokyo 2017に行ってきたので、雑なメモ。

f:id:nowsprinting:20171009204630j:plain
会場で写真撮ってなかったので、途中にいたユニコーンガンダム

Tangoで踊らされたオトコがARCoreと向き合う話

  • Tangoではdepthセンサー必須だったが、ARCoreでは普及機のカメラで実現できるようになった(iOS 11のARKitに追随した形)
  • 3本柱
    • モーショントラッキング
    • 水平面の推測 (Environment understanding)
    • Light estimation
  • 画像解析にによる推定
    • TangoではToF(time of flight)
  • Tango → ARCoreで難しくなったこ
  • アプリの開発は、Android Studio 2.3, Unity, UE4
    • API Level 24以上
    • 描画はAndroidネイティブではOpenGLとかになるので、Unityなどを使うほうが楽
  • 実行環境(端末)に、ARCore process appをインストールする必要がある
  • Devices: Pixel XL, Pixel, Galaxy S8
    • Pixel 2/2XL
    • ほかの機種で動かす試みをしている人はいる
  • UX: ARのソリューションでなく、モバイルのソリューションであることを意識したい
  • JAG ARCore(Tango) Working Group - Google+

developers.google.com

github.com

React Nativeアプリをリリースし続けるために、最初に行う8つの取り組み

www.slideshare.net

  • 開発部分はJSにひとでもできるが、一部、Google Play, Xcode, iTunes Connectなど、ネイティブアプリ開発の知見が必要
  • ネイティブのノウハウが必要なところ:設計〜開発の継ぎ目あたり、リリース〜保守
  • init後の作業
    • src/index.jsを作る。ios_index.jsとandroid_index.jsには、import".src/"だけ書く
      • 0.49でそうなったので、0.48以前の人向け
  • application id(Android) , bundle identifier(iOS)
    • init直後は適当なものが入っているので必ず変更する
  • version
    • Semantic Versioningを採用している
    • プラットフォーム間でバージョン番号をそろえるか?
      • そろえたほうが楽、という運用になった
        • リリースノートの書きやすさ
        • Gitのタグ付け
      • package.jsonのversionを元にコピーしている
      • Google Playの制約。version codeは加算のみを許す
        • major+minor+patchを組み立ててGradleで自動生成する案
          • Google Playにアップロードしなおすために都度patchを上げる必要がある
          • 代替案:major+minor+patch+buildという構成(2.1.3-build4 → "2010304"とか)
  • build types
    • デバッグビルド(同じapplication id)を同じ端末にインストールしたい
    • アイコン、表示名も分けないと見分けがつかないので、適切に設定する(スライド参照)
  • 運用に便利なツール
    • Fabric/Crashlytics (JSのエラーは見えない)
    • Fabric/Beta
      • AS plugin/Mac appからリリースできる
      • Google Play/ iTunes Connectでもベータ配布はできるが、タイムラグがあるのとバージョンを上げる必要があるため
      • Deploy Gateでもいい
    • faselane
      • gitにtagをつけてpush → CIサーバがfastlaneでリリースタスクを実行
    • Firebase
      • アナリティクス、ストレージ、ABテスト、プッシュ通知
      • アナリティクスのためだけに使ってる
  • JSのクラッシュレポート
    • Sentryを使う

iOS版でアイコン切り替えができていない、というお話でしたが、デバッグビルド向けのビルドターゲット作り、そこでリリース版とは別のinfo.plistを指定、その中の記述を分けることができます。『iOSアプリテスト自動化入門』のChapter 6「ビルドと配布の自動化」に書きました。

iOSアプリテスト自動化入門

iOSアプリテスト自動化入門

Goによるプロダクト開発 〜設計、テスト、Go2に向けて〜

  • GAE/Goのaetestが遅い件
    • Travis CIからCircle CIに移行して少し早くなった
  • package構成
  • 実装の歴史的経緯を伝えるためにもペアプロは便利
  • 鵜飼さんのスライドを読む
  • 正規表現使いすぎない、map使いすぎない(LLの習慣でやりがち)
  • aetestが遅いので、テストを増やすと遅くなるので余り書けていない
  • メルカリUSはカバレジ80%くらい
  • AWAも80%くらい
  • テストを書いていくといい設計になる
  • Go2

FlutterでAndroid/iOS両対応のアプリ開発

speakerdeck.com

github.com

Unreal Fest East 2017に行ってきたメモ #ue4fest

10/8に開催されたUE4のイベントUNREAL FEST EAST 2017に行ってきたので雑なメモ。主にVR系セッションを聴講してきました。

f:id:nowsprinting:20171010070858j:plain
会場で写真撮ってなかったので、クイーンズスクエアにオープンしていたSHAKE SHACK

「VR ZONE SHINJUKU 極限度胸試しハネチャリ」ゲーム会社×映像会社で作るヤバイVR体験

「VR ZONE SHINJUKU」の知見、全て吐き出します!

  • 釣りVR
    • 「釣った」と「釣れた」は大違い。ほとんどの釣りゲームは技<運
    • 技>運にすると、インタフェースが増える(感覚を数値化する必要があるので)
    • 立つ、しゃがむがゲーム性に直結
      • しゃがむと有利だが、反射で水中が見えない。立つとバレやすい等
  • 恐竜サバイバル
    • やりたかったこと:多人数で、人間同士の協力や裏切り
    • 可動ベースでも酔う。ヨーイングをなめてた
      • 速度が遅いほど悪化
      • 障害物が近いほど悪化(ジャングルは最悪のシチェーション)
    • ボトムズの知見:暗くして、障害物を減らし、被写界深度を狭めることで酔いを回避
      • これを適用したら、マップがほとんど見えない、迷うようになった → ルートを一本道に変更
    • 8人でやると楽しくなってしまった → バラバラに → 脱出病棟みたいな体験になってしまった
  • ハネチャリ
    • 空を自由に飛べるようにしたが、物足りない(つまらない)
    • 顕在しているニーズ:空を自由に飛びたい
    • 潜在しているニーズ:人間は飛べない
      • スタートを一本橋にして、飛べない(落ちる)ところからスタート。これだけで以降のシーンの印象が変わる
      • 反射行動(条件反射、無条件反射)で動かす。あとから感情がついてくる
      • 油断するとちゃんと墜落する仕様
    • リアルだから取り乱すのではなく、取り乱すからリアルに感じる
  • マリオカート
    • 既存ゲームのVRアクティビティ化
    • 1〜2ヶ月でとりあえず動いたが「これでいいのか?」
    • VRアクティビティ化への3レイヤ
      • UE化
      • VR化(酔い対策)
      • 取り乱す化(体験デザイン) これをVR化とは分けて考える
    • UE化:解像度足りない → オリジナルエンジンからUE化。実在感への寄与は大きかった
    • VR化:主観視点化+体験の快適さ確保
      • ジャンプしてドリフト、水中で画面がゆがむ等は酔うので削除
      • 周回コースにはしない(ヨーイングを避ける)、急カーブは作らない
      • アイテムを当てた側がら見えるヒットリアクションは派手に、でも当てられた側は視点は変えずカートだけ回転
        • これでは当てられたほうが気づかないので、視界が炎上するようにした
      • 体感マシンで帳尻合わせ(映像でできるだけやった後)
    • 取り乱す化:既存ゲームだと特に、体験の想像がついてしまう
      • 体験デザイン、絶叫体験
      • すでにできている「遊び」「仕様」「データ」を変更する注文になるので、開発チームには嫌がられる
      • 「信じさせる」
        • 自然に行動できる → 世界を信じられる
        • 違和感行動は、夢から覚めるきっかけ
      • 「叫ばせる」
        • 実際にあのコースを走ったら、とんでもない体験に
        • 巨大なやつが襲ってくる:パックンフラワードッスン
          • 十分に予感させないと恐怖は発生しない → 遠くから見える、地面がえぐれているなどで、手前から恐怖をあおる
        • ジャンプ台は、一旦、自由落下で落とす(すぐにカイトを開かない)
          • あらかじめ、カートの重さを信じさせる。スタート直後の段差で落ちる、クッパの体当たり
      • 風船にぶら下がるアイテム、ハンマーで直接叩く動作
  • 絶叫がモチベーションを生む
    • スタッフのモチベーションが高い
    • 接客の自己改善が発生
  • 感情の爆発
    • 号泣などいくつかあるが、そのうちのひとつが絶叫
    • エンタメにとって最高評価

vrzone-pic.com

VRゲーム"Airtone"制作事例 ~VRを活かす3つのゲームデザイン的挑戦~

  • 与えたい体験を先に決める
  • 王道の音ゲー+遊び
  • アウトゲーム(部屋)を先に見る。ここでは実在槓のあるシェーディング、影をつける
  • インゲームはモーショングラフィック系
  • 部屋
    • 壁紙変更、物理を使った遊びなど、おもしろギミック
    • 音の遮蔽をoff。ネオンちゃんの足音など、正しい方向からのみ聴こえるように
    • 部屋のスピーカを部屋の中央に
  • Wwiseを使用している

音ゲー部分のデザインの話は(私の)メモが乱雑すぎたので割愛。講演動画が配信されるはずなので、そちらを参照してください。

store.steampowered.com

www.oculus.com

LINE Messaging APIでグループメンバーのプロファイルを取得する新API #linebot

今年5月、グループ/トークルーム内のトークを発信したユーザのIDをLINE Messaging APIで取得できるようになりましたが、ユーザIDからそのユーザのプロファイル*1を取得できないケースがありました。

新たに7月に追加されたエンドポイントでは、グループ/ルームのメンバーであれば制限なくプロファイルを取得できるようになりました。

過去記事のフォローアップとして、新エンドポイントについてまとめます。

Get profile APIの制約

ユーザのプロファイルを取得するには、GET https://api.line.me/v2/bot/profile/{userId}golang SDKではlinebot.Client.GetProfile())を使用します。

しかし、このAPIでは、指定したユーザがBotと友だち登録した状態でないと404エラー(golang SDKではlinebot: APIError 404 Not found)が返ります*2

グループ/ルームにメンバーとしてBotを追加して運用するケースにおいて、「すべてのメンバーがBotとの友だち登録を必要とする」というのは現実的ではありませんでした。

この(従来の)方式についての詳細は、下記エントリの「プロファイル取得の制限」セクションを参照してください。

nowsprinting.hatenablog.com

Get group/room member profile API

7月に、グループ/ルームメンバーのプロファイルを取得するためのエンドポイントが追加されました(golang SDKへの追加は9月)。

  • グループの場合、GET https://api.line.me/v2/bot/group/{groupId}/member/{userId}golang SDKではlinebot.Client.GetGroupMemberProfile()
  • トークルームの場合、GET https://api.line.me/v2/bot/room/{roomId}/member/{userId}golang SDKではGetRoomMemberProfile()

こちらを使用すれば、友だち登録状況に関係なくプロファイルを取得できます。パラメタとして、対象のユーザIDに加えて、グループ/ルームのIDが必要です。

友だち登録していないユーザ、また、友だち登録後ブロックしたユーザで試しましたが、いずれもこのAPIでプロファイルを取得できました。

簡単な(汚い)サンプルコードを公開していますので、参考にしてください。

github.com

Get group/room member user IDs API

7月の更新では、グループ/ルームのメンバー全員のユーザIDを取得できるAPIも追加されています。しかしこちらは「認証済みLINE@アカウントまたは公式アカウント専用機能」とのことで、未検証です。

参考

関連書籍

LINE BOTを作ろう!  Messaging APIを使ったチャットボットの基礎と利用例

LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例

*1:表示名、プロフィール画像URL、ステータスメッセージ

*2:以前は、友だち登録した後にブロックした場合でもプロファイルが取得できていましたが、現在はブロックしたら404が返るようになりました

LINE Messaging APIでグループメンバーへのメンションを送りたかった #linebot

結論から言うと「送れなかった」のですが、調査したことなどのメモ。

メンションとは

ここで「メンション」と呼んでいるのは、グループ/チャットルーム内で、"@"に続いてメンバーの名前を書くと通知が飛ぶ、という機能。

2017年2月にリリースされた機能ですが、LINE公式ブログなどでは正式な名称は書かれていませんでした。Twitterほかにならってメンションと呼ばれているようです。

official-blog.line.me

LINEアプリ上では、下のように青い文字で表示されます。

f:id:nowsprinting:20171001001204p:plain

なお、メッセージ入力欄に「@」と入力すると、メンションを送る候補としてグループメンバーの名前が表示されますが、ここにBotの名前は出てきません。

Botにコマンドを送るときに使えるのでは?と思ったのですが、ダメでした。

Webhookで受け取れるメンションを含むメッセージ

上のような、ユーザからユーザへのメンションを含むメッセージをWebhookで受け取ったとき、その内容は単なるプレーンテキストで

@テスト太郎 メンションのテスト

という文字列が受け取れました。

ユーザ名は、個々のユーザで異なるものに上書きできますが、Webhookで受け取れるものはメンションに指定されたユーザ本来のものです。

LINE Messaging APIからメンションを送ってみる

Webhookがプレーンテキストであった時点で無理そうでしたが、一応試してみました。

まず、"@"に続けてユーザID(golang SDKの場合、event.Source.UserID)を指定したケース。

f:id:nowsprinting:20171001003746p:plain

続いて、"@"に続いてユーザの名前(golang SDKの場合、linebot.Client.GetProfile()で取得したDisplayName)を指定したケース。

f:id:nowsprinting:20171001003803p:plain

ともに、メンション扱いはされませんでした。残念。

関連書籍

LINE BOTを作ろう!  Messaging APIを使ったチャットボットの基礎と利用例

LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例

Tokyo HoloLens ミートアップ vol.4に参加してきました #HoloLensJP #TMCN

Tokyo HoloLens ミートアップ vol.4に行ってきました。参加するのは通算3回目(のはず)。

hololens.connpass.com

以下、各セッションのメモ。残念ながらLT前に離脱したのでメインセッションのみ。

俺たちが作るべきMR

ゆーじ@yuujiiさんの、例のハッカソンで例のVRアーティスト賞を受賞したHololensを使ったお絵描きアプリにまつわる話。

www.slideshare.net

  • すぐ近くの3Dオブジェクトを描画しない設定であるnier clipについて。HoloLensでは0.85(より近いものは描画しない)だが、ホワイトボードに投影しながら絵を描くという性質上0.3にした
  • 0.3より低くすると、ホワイトボードに近づきすぎてしまいトラッキングを失うため、あえて0.3とした

ARもVRもMRもまとめてドドンドーン!

前本 知志@peugeot106s16さんの、KINECT等を使って位置同期を行なう話。

www.slideshare.net

  • ARアプリでは、3DモデルとKinectが捉えた物体とのzテストでオクルージョンできる
    • 現実ではオクルージョンされるのが当たり前なので、誰もすごいと言ってくれない!(気づいてもくれない!)
  • 複数KINECTでの位置同期
    • GPSと同じ三点測位で、リアル世界にある原点に対する、KINECTカメラの相対位置を求める
    • depthが取れればKINECTでなくてもできる
  • KINECT, HoloLens Tangoで位置を同期する
  • 現実世界を基準に、仮想世界もそこに重ねる。各デバイスは覗き窓となる

多人数同期MR体験を実現するプラットフォームDAHLES

MIRO@MobileHackerzさんの、N高入学式で使用したHoloLens数十台運用プラットフォームの話。

  • 1対nで配信
  • 大域自己位置ポジショニング
    • HoloLensのアンカーの問題点
      • 全端末がspatial mapを持ってないとできない
      • 大規模会場ではdepthが届かない(ぜいぜい数メートル)
      • 似てると間違える。列が一列ずれる。四角い部屋だと90度・180度ずれることも
      • 一度誤認識されると、なかなか再認識されない
    • 可視光マーカーを併用する
      • マーカーで大まかな位置を知り、近くのアンカーを使って精細なポジションを得る
  • 無線ネットワークトラフィック管理・配信コンテンツ管理
    • 輻輳防止
    • 隠れ端末問題
    • ブロードキャストパケットによるイベント同期
    • どうしてもムリなところは無線を強くする
  • HoloLens端末の運用管理
    • アプリケーションのデプロイ
      • Device Portalを使うと結構できるけど、無線は遅いのでつらい
      • USBでもできるようにした
    • 装着オペレーションのサポート
      • 「こう見えていれば正解」という画面を装着案内時に表示しておくのは有効

VR ZONE SHINJUKUに行ってきました

以前お台場で試験営業していたVRアクティビティ体験施設 “VR ZONE” が、新宿に新たに “VR ZONE SHINJUKU” としてリニューアルオープンしたので、早速行ってきました。

体験したアクティビティは、マリオカート、ハネチャリ、釣り、ガンダムの順。やはり全体にお台場時代からあるものの人気は低めなようで、逆に人気の高いのは(土曜18時に入場した時点で)釣りとエヴァンゲリオンが60分待ち、帰る頃にはエヴァンゲリオンのみ並んでいるような状況。

ただ、いずれのアクティビティも筐体の台数は多く(例えばマリオカートは4台×3セット)、HMDなどの着脱を行なうスタッフさんが1対1で付くかどうかで回転率は大きく変わるため、かなり柔軟にスタッフさんの移動を行って*1待ち行列をコントロールしようとされているようでした。

アクティビティ

個々のアクティビティの内容や感想は割愛しますが、総じて酔いにくく、かつ楽しめるものになっていました。特に、2台や4台セットになっているアクティビティでは、ヘッドセットにマイクが付いておりプレイヤー間で会話できて盛り上がりの一助となっていました。

それもあって集団で行くのが楽しいとは思うのですが、逆に少人数の場合2〜3人グループの空いた席に入れてもらえる率が高く、あまり待たずに回れるというメリットもありそうです。

機材面では、マリカーも釣りも、(Viveコントローラーではなく)Vive Trackerを使用。特に、釣りの竿コントローラーは前評判通りすばらしい体験でした(ハード面は下記記事を参照)。

www.nikkan.co.jp

スタッフ

上にも書きましたがスタッフさんの練度は総じて高く、ストレス無く体験できました。また写真の撮影を引き受けてくれたりもしました。感謝。

チケット

チケットはアプリ版を使ったのですが、良かったところは入場ゲートをそのまま通れるところ。逆に下記デメリットがあり利便性は今ひとつ。

  • 数人分まとめて購入した場合でも、結局全員が個々にアプリをインストールし、チケット分配機能で分配する必要がある
  • アクティビティ利用時のチケット表示のたびに通信が必要
  • アクティビティごとに必要なチケットの種類が4種(赤・青・黄・緑)あるが、該当するものをフリックで選択してスタッフさんに提示する必要がある(必要なチケットの判定ができているのだから、自動的に消し込みして欲しかった)
  • アクティビティチケット単位での譲渡はできない(端末ごと貸せばできますが、紙ほど手軽ではない)

セガさんのところのように、チケットにゲームのスコアが紐付いて後からチェックできるような付加価値でもあれば相殺していい程度の不便さなのですが、改善されると嬉しいです。

まとめ

ローケーションも(新宿フェイスのすぐ近くで)良いですし、アクティビティの質・量ともにお台場時代より強化されています。お台場のとき行ったことがある人も、ない人も、行って体験してみるといいと思います!

vrzone-pic.com

*1:スタッフさんは多くのアクティビティを知っていなければならず大変だと思います

LINE Messaging APIでグループ内の発言ユーザIDが取得できるようになった件 #linebot

これまで、LINE Messaging APIで組んだBOTをグループやトークルームに参加させた場合、すべてのユーザの発言はそのグループもしくはルームが発言元となり、実際に誰の発言であるかを知ることはできませんでした。

5/31にリリースされた新機能でこの制約が解消され、グループ/ルームにおいても(groupId/roomIdとは別に)発言者のユーザID(userId)を取得することができるようになりました。

ただし、以下の制約があります。

  • 発言ユーザのクライアントのバージョンが、iOS/Androidとも、7.5.0以降であること
  • 発言ユーザが“Official Accounts Terms of Use”に同意していること

これらを満たしていれば、コールバックで受け取ったjsonsource下にuserIdが格納されます(Golang SDKの場合、eventのSource.UserIDで取得できます)。

満たしていなければ、従来通りuserIdは入ってきません。

Official Accounts Terms of Useへの同意

Official Accounts Terms of Useへの同意は、以下のような契機で表示される認証画面から行ないます。

  • 新たにBOTを友だち登録する
  • すでに友だち登録しているBOTトーク画面(グループやルームではなく、1:1のトーク)を開く

これは、必ずしもBOT個々に行なう必要はなく、例えば、謎の女子高生AI「りんな」に対して同意済みのユーザであれば、自作のBOTでもユーザIDを取得することができます。

f:id:nowsprinting:20170613045546j:plain

この画面下にある「同意する」をタップすると、同意が完了します。

正直なところ、一般の人向けのグループにBOTを混ぜて運用している場合、この手順を全員にアナウンスし実行させたり、ユーザIDが取得できないケースをBOT側で考慮する必要があるというのは少々ハードル高いですが、時間が解決してくれることに期待しましょう。

プロファイル取得の制限 [6/24追記]

上記の手続きでユーザIDは取得できますが、ユーザプロファイル(表示名、画像、ステータスメッセージ)の取得にはさらに制限があります。

ユーザプロファイルはhttps://api.line.me/v2/bot/profile/{userId}で取得しますが、これにBOTと一度も友だち登録されていないユーザのIDを指定した場合、404エラー(Golang SDKの場合linebot: APIError 404 Not found)が返ります。

"一度も友だち登録されていない"と書きましたが、一度でも当該BOTと友だち登録を行なえば、その後ブロックされても取得できるようです*1*2

[10/1追記] グループ/ルームメンバーのプロファイル取得のためのAPIが7月に追加されています。こちらのエントリを参考にしてください。

nowsprinting.hatenablog.com

多人数のグループなど、BOTとの友だち登録を徹底するのが難しい場合、あらかじめ(もしくは404を受けて)LINE Loginに誘導してログインさせてプロファイルを取得しDBに保持、BOT側ではWebhookで受け取ったユーザIDで突合*3して使うほうが運用負担は低いように思います。

※このセクションは、『LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例』の著者、立花さんとのやり取りで発覚し、調査・追記しました。

LINE BOTを作ろう!  Messaging APIを使ったチャットボットの基礎と利用例

LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例

参考

*1:ただしこの振る舞いはドキュメントに明記されているものではなく、今後アナウンスなく変更される恐れはあります。そもそも「友だち登録していなければ404」という振る舞いもどこにも書かれていないのですが。

*2:10/1時点ではこの振る舞いは変更されており、友だち登録した後ブロックした場合にも404が返されるようになりました

*3:LINE LoginとMessaging APIで受け取れるUserIdは同じユーザで同一のものが得られます