Help us understand the problem. What is going on with this article?

VRC PanoramaをGoogle Apps Scriptで活用する

More than 1 year has passed since last update.

はじめまして、nyakome(@nyakome306)といいます。Qiitaはほぼ初投稿です。
これはVRChat Advent Calendar 2018 10日目の記事です。
解説記事を書くのは初めてなので、読みづらかったり至らない点があると思いますがよろしくお願いします。

はじめに

 VRChatのコンポーネントの一つであるVRC_Panormaは指定したURLの画像を読み込めるのでVRChat内から外のインターネットを叩いて遊べますが、サーバー用意したくないのでGAS使う話です。

何ができるの?

こういうのです。

主にGASで指定した日時にURL先の画像を更新して、それをVRC Panoramaで表示して実現してます。

VRC_Panoramaでできること

 本来はパノラマ画像を表示する用途らしいですが、URL先の画像を読み込んで表示する用途で使ってます。
 PanoramasのテクスチャやURLで指定した画像を表示できて、複数URLを指定するとUnityのコンポーネントのButtonでNextPano()を発火させることで複数の画像を切り替えて表示できます。

技術メモに詳細があります。
https://vrcworld.wiki.fc2.com/wiki/VRC_Panorama

GoogleAppsScript (GAS)って?

 Googleのサーバー上に実行環境がある、Javascriptを元にした言語
 Google DriveとかスプレッドシートなどのGoogleが提供するサービスを簡単に操作できて、Webアプリとか作れます。
 スクリプトの実行時間等に制限はありますが無料で使えて、他のPaaSと比べると開発環境もブラウザで行えてサクッと作れるのが特徴です。
 今回は主にGASでGoogle Driveを操作します。

GASとVRC Panoramaの組み合わせ

 先にも少し書きましたが、VRC Panoramaに設定したURL先の画像(Google Drive上の画像)をGASで書き換えて、VRC上で表示される画像を変更するのが主な使い方です。
 この記事では主にVRC Panoramaで表示するため設定とGASを使った画像ファイルの操作について書いていきます。

VRC Panoramaの設定

VRC Panorama用のマテリアルを新規作成し、UnityのQuadに下の画像のように設定すれば動きます。
Unity 5.6.3p1 Personal (64bit) - Home_Kit_Assembled.unity - vrchat_home - PC, Mac & Linux Standalone _DX11_ 2018_12_06 9_19_40 (2).png

そのままだとVRCPanoramaの仕様でガンマ補正が二重に掛かってて画像が普通より明るく表示されてしまいます。逆ガンマ補正を掛けて表示するシェーダーを作ったので置いておきます。
https://www.dropbox.com/s/2g7e4jc4ss9ea8a/unlit_vrc_panorama.shader?dl=0
・12/20追記
12/12にVRChatがUnity2017.4.15.f1に移行し、そのタイミングでVRCPanoramaのガンマ補正のバグが修正されたため、このシェーダーは必要ありません。

ちなみにVRC PanoramaはVRChatを起動しなくてもUnityのPlay押すだけで動作します。

GASの導入

以下のURLにアクセスし、左上の新規スクリプトをクリックするとエディタが開きます
https://script.google.com
12.png
11.png

APIの有効化

また今回はDrive APIとGoogle Slides APIを使うため、
リソース→Googleの拡張サービスよりDrive APIとGoogle Slides APIの横のトグル(表示が壊れてますね…)をクリックして有効にしてください。
15.png
16.png

スクリプトの初回実行時

GoogleのAPIを使う場合、スクリプトの実行ボタンを押すと、初回はプロジェクトの認証のためのウィンドウが出ます。使っているアカウントを選択して矢印の通りにクリックしてください。
5.png
6.png
7.png
8.png

Google Driveに置いた画像をVRC Panoramaで表示する

VRC Panoramaで指定するURL

 上の例は、GoogleDriveに置いた画像ファイルのURLをPanoramasに入力し、ファイルをGASで定期的に更新して実現してます。
 VRC_Panoramaに指定するURLは画像の直リンクでないと表示できないため、直接画像を表示できるリンクを取得します。
 GoogleDriveで画像ファイルを開いて右上のその他の操作→新しいウインドウで開くをクリックすると、URLは以下のようになります。

https://drive.google.com/file/d/{ID}/view

これを{ID}を用いて、以下のように書き換えたURLをVRC Panoramaのurlに入力すると表示されます。

http://drive.google.com/uc?export=view&id={ID}

ファイルの共有設定

またVRChatからアクセスできるようにするため、表示する画像ファイルの共有設定をする必要があります。
ファイルを右クリックして共有→共有可能なリンクを取得をクリックしてください。
※ここで取得したURLはVRC Panoramaでは使えません。

13.png
14.png

GASを使った画像ファイルの取得、更新

外部サイトからの画像取得と画像ファイル更新部のスクリプトがこちらです。
指定したIDのファイルの中身をimageURL先の画像に書き換えます。

 スクリプトをエディタにコピペして更新するファイルのIDを指定して実行(三角形のやつ)をクリックし、プロジェクトを認証すると動きます。

function myFunction() {
  var updateFileId = "更新するファイルのID";
  var imageURL = "https://booth.pximg.net/ed52788c-0b3b-4e38-9ded-1e5797daf0ef/i/922954/ff456ba0-f4ee-4753-8d18-81f229f44b00_base_resized.jpg";

  //画像取得
  var image=UrlFetchApp.fetch(imageURL).getBlob();

  //画像更新
  updateFileById(DriveApp.getFileById(updateFileId).getName(),updateFileId,image);
}


//指定したidのファイルの内容をblobで上書きする
function updateFileById(title,id,blob) {
  var body = {
    title: title,
    mimeType: 'image/png'
  };
  file = Drive.Files.update(body,id, blob);
}

 UrlFetchApp.fetch(imageURL).getBlob()で指定したURLの画像を取得して、Drive.Files.update(body,id, blob)でファイルの更新をしてます。
上のフォトフレームのように、指定したフォルダ内のファイルの取得はフォルダIDを指定して

var files = DriveApp.getFolderById(id).getFiles();
while(files.hasNext()){
  file = files.next();
}

で行えて、更新日時が新しい順で取得されます。
またgetFilesByName(String)で指定した名前と一致するファイルを取得できます。

Google Slidesを使って文字列や表を含む画像を生成する

APIから取得した情報の表示など、文字や図形を扱う場合はGoogleSlidesを利用します。
上記のカレンダーの場合、編集元として下の画像のような表を予め作成し、表にGASで値を代入しています。
17.png

GASでGoogle Slidesの編集については他の方が解りやすく解説されてますのでここでは書きません。
またこの記事の最後にカレンダーのスクリプトのリンクを載せています。

Google Slidesから画像を取得

VRC Panoramaで表示するには編集したスライドを画像に変換する必要があるので、APIを使ってサムネイルを取得します。

var response = Slides.Presentations.Pages.getThumbnail(presentationId, SlidesApp.openById(presentationId).getSlides()[0].getObjectId());
var blob = UrlFetchApp.fetch(response.contentUrl).getBlob();

 Slides.Presentations.Pages.getThumbnail(presentationId,slideId)にサムネイルを取得したいGoogle SlidesのファイルのIDとスライドのObjectIdを指定するとサムネイル画像の一時的なURLが生成され返されるので、UrlFetchApp.fetch(url).getBlob()でサムネイルを取得します。
 そしてDrive.Files.update(body,id, blob)でVRC Panoramaで表示する画像を生成したものに書き換えて完了です。

自動実行(cron)の設定

最後に、作成したスクリプトを指定した時間に起動させるには、ストップウォッチみたいなボタンをクリック
18.png
すると起動トリガーの管理画面になるので、右下のトリガーを追加をクリックして、起動する時間の間隔などを設定して保存すればOKです。
19.png

まとめ

GASはTwitterなど外部APIも使えるので、組み合わせたら面白いものが作れると思います。

他の皆さんのUnityやBlenderの記事の中、ほぼGASのことしか書いてないので場違い感ありますね・・・
記事を書くのはほぼ初めてで、大変なところもありましたが楽しかったです。ここまで読んでくれた方に感謝します。

参考にしたページなど

Google Slides関連

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away