📚

【VCI入門】Luaを使ってスライドを作ってみる

2021/07/16に公開

はじめに

こちらは以下のチュートリアルの続きです。前回がHelloWorld VCIを作ってVキャスで表示するところまでやったので、今回ははスクリプトを使うもう少し複雑な奴をやっていきたいと思います。
https://zenn.dev/koduki/articles/7fe5f37ec17071

今回作成したコードは下記にあります。
https://github.com/koduki/example-vci/tree/v02

WhiteBoard VCI

WhiteBoard VCIの仕様

さて、Hello Worldでなんとなく一連の流れが掴めたと思うので、もう少しだけちゃんとしたVCIを作成します。とはいえ、いきなり難しいものを作っても仕方がない、と言うか私が作れないので公式アイテムのホワイトボードのようにグリップすると画像が切り替わる簡単なスライドを作ってみます。

  • グリップすると4枚の画像が順番に切り替わる
  • 最後の画像になると最初に戻る
  • 重力で自由落下せず空中に浮かぶ
  • 拡大縮小出来る

このくらいの仕様にしておきます。

WhiteBoard VCIのSceneを作成

プロジェクトの準備は前回と同様です。下記のプロジェクトをCloneして利用しても問題ありません。今回はv01タグから作成しています。
https://github.com/koduki/example-vci/tree/v01

まず、Scene を新しくプロジェクト配下の 「Assets/MyAssets/Scenes」WhiteBoard.unityとして作成します。別のプロジェクトにした方が良いのかもですが、まあ今回はバージョン管理の単位も同じで良いし、いったんScene単位でVCIを管理します。

Rootオブジェクト名はwhiteboardにしておきます。GitHubのブランチ名もdev/whiteboardにしておきます。RootオブジェクトにはVCI Objectコンポーネントを下記のように設定します。

Boardオブジェクトの作成

続いてVCIオブジェクトを作成します。今回はSubItemを画像表示用のQuartオブジェクトScreenと外輪になるScreenオブジェクトFrameの2つを組み合わせて作ります。この2つは掴んで動かすときや拡大縮小は連動させたいので、まず親になる空オブジェクトを作りBoardと設定します。そしてBox ColliderとVCI SubItemコンポーネントを追加します。各種パラメータは以下のような形。

続いてQuartオブジェクトをBoardの子として作成しScreenと設定し、同じくQubeオブジェクトをBoardの子として作成しFrameと付けます。

Screenオブジェクトの調整

Screenはスライドを表示させるので良くある16:9に対応できるようにScaleを1.6, 0.9, 1にします。また、ColliderやRigidBodyは不要なので削除してしまいます。

Screenオブジェクトに画像を貼る

続いて画像を貼りましょう。画像はまずMaterialを作り、そちらに画像をテクスチャとして紐づける必要があります。
まずAssets/MyAssets/Material配下にMaterialを追加します。名前はSlideにしました。

Slide MaterialをScreen Objectにドラッグ&ドロップして紐づけます。

前回は単純に色を変更しましたが今回は画像を貼り付けます。画像を貼り付けるにはまずAssets/MyAssets/Texturesに目的の画像をコピーします。今回はPPTXのスライドを画像に変換したSlide1.pngを配置します。

続いてSlideマテリアルを選択し Main Maps -> Albedo でAlbedoの選択をクリックして、Textureのピッカーを開き先ほど配置したSlide1.pngを選びます。

これでSlideマテリアルにSlide1テスクチャが貼り付けられました。以下のように画像が反映されているのが分かります。

Frameオブジェクトの調整

スライド表示部であるScreenはQuartオブジェクトで作りましたが、これだと完全な平面なので厚みのある外枠をQubeを使って作ります。先ほど作成したScreenを修正します。Materialも新規に作成して色を灰色にしました。また、先ほど作ったScreenの外枠に見えるようにScaleとPositionを調整しています。不要なColliderやRigidBodも削除します。


Luaスクリプトで画像を切り替える

スライド用のテクスチャを設定

今度はLuaスクリプトで画像をスライドのように切り替えたいと思います。VCIでは以下のように複数の数字が詰まった画像を作成して座標を指定する事で表示する情報を書き換えるテクニックが公式のWikiに記載されています。懐かしのCSSスプライトみたいなテクニックですね。


ref: https://virtualcast.jp/wiki/vci/script/reference/exportassets

今回のスライドでも同様のテクニックを採用します。スライドをとりあえず横に並べて1枚の画像にします。大きくなると横に伸ばすだけではなく縦にも伸ばす必要がありそうですが、今回は以下のように4つほど横に単純にくっつけておきます。Slide-all.pngAssets/MyAssets/Textures保存し、Slideマテリアル -> Main Maps -> Albedo でAlbedoの選択をクリックして、Textureのピッカーを開き先ほど配置したSlide-all.pngを選びます。

このままだとスライドが4枚ともスクリーンに縮小されて表示されているだけなのでMain MapsTillingのX軸を変更します。Tillingは1を基準に指定した数値でタイルとして画像を部分的に選択する事が出来ます。今回は4枚なのでX軸を0.25に設定しました。

これで以下のようにスライドの1枚目が表示されます。

スライド切替えをLuaスクリプトで実施

それではいよいよLuaスクリプトを書きましょう。LuaスクリプトはVCI Objectコンポーネントが紐づけられたRootオブジェクトより変更します。下記の0となっているScripts/Sizeを1に変更します。

変更すると以下のようにメタ情報とソースコードを書きこむボックスが現れます。

こちらのSourceの部分に以下のLuaスクリプトを貼り付けます。

MAX_SLIDE_PAGE = 4
UseCount = 0

function onUse(use)
    UseCount = UseCount + 1
    print("onUse : "..use..UseCount)

    local index = UseCount % MAX_SLIDE_PAGE
    local offset = Vector2.zero
    offset.y = 0
    offset.x = (1.0 / MAX_SLIDE_PAGE) * index
    vci.assets._ALL_SetMaterialTextureOffsetFromName("Slide", offset)
    print("page: "..(index + 1))
end

コードの内容は後で解説するのでいったんこのまま進めます。こちらをVCIにエクスポートしてThe Seed Onlineにアップロードします。

Vキャスの中で動作確認をします。下記のようにグリップするとスライドが切り替わります。
https://www.youtube.com/watch?v=yYr3zZiJIog

VCIスクリプト(Lua)の解説

VCIスクリプト

VCIではLuaを利用してイベントの発火やVCIのパラメータの変更を行う事ができます。詳しくは下記を参照してください。
https://virtualcast.jp/wiki/vci/overview/introduction

今回のVCIではonUseイベントをフックして、このイベントに対応するロジックを書いています。VBとかDelphiとか触ったことがある人にはお馴染みのイベントドリブンのコードの書き方ですね。

    local index = UseCount % MAX_SLIDE_PAGE
    local offset = Vector2.zero
    offset.x = (1.0 / MAX_SLIDE_PAGE) * index
    offset.y = 0
    vci.assets._ALL_SetMaterialTextureOffsetFromName("Slide", offset)

こちらで_ALL_SetMaterialTextureOffsetFromNameを使ってSlideマテリアルのオフセットを変更しています。オフセットはベクタになっていて 「xはonUseが実行された回数をスライド枚数で割った数」 つまり今回であれば 0.25 ずつ増えて実行回数が4になると0に戻る形です。

Luaは組み込み用とで人気のあるスクリプト言語のでVキャス以外にも多くのところで利用されています。以下に分かりやすい文法等の解説があります。
https://virtualcast.jp/wiki/vci/script/luatutorial
https://qiita.com/wingsys/items/0be3e4a627622cd5b7c3
https://qiita.com/rohinomiya/items/abeb1d69c640a27d97c5

また、VCI特有のイベントや関数に関しては以下を参照する事が出来きます。
https://virtualcast.jp/wiki/vci/script/reference

VCI上でのLuaスクリプトの制限

Luaは本来なんでも出来るスクリプトなのですがVCIではセキュリティ観点でファイル操作やNW通信などを行う事*が出来ません。ローカルファイルとかを弄られない用にする事でVCIをベースにしたマルウェアを生み出さないようにしてるわけですね。たぶん。

Luaスクリプトの制限に関してはさっきのななさんの記事によると具体的には下記が出来ないようです。

  • 部屋(スタジオ・ルーム)をまたいだ情報の保存
  • 外部通信
  • ファイルの保存
  • 直接的な速度の設定・取得
  • physical update
  • luarockなどでインストールするような外部ライブラリインポート

以下が実際の記事の内容となり詳細が記載されています。
https://qiita.com/sakkinonana/items/f7e80d2feea193963a5d

まとめ

今回は親子関係を持つVCIの作成やLuaスクリプトを利用した動的な動きを作ってみました。次回はリモコンでスライドを切り替えるような作業を記事にしたいと思います。

Discussion