重いVCIアイテムがちょっと軽くなると良いな

#はじめに
こちらの記事はVCIアドカレ2019の12/7の記事です。
[VCIアドカレ2019](https://qiita.com/advent-calendar/2019/vci)

#VCIってたまに重いのが有りませんか？
このVCI良いけど、重いから使わない。
ってVCIがいくつかあったような気がしたりしなかったり。
どうして似たような事をしているのに重いのと軽いのが有るんでしょうか？

**原因はたくさんありすぎてソースコード見ないと分かりません！**

そんなことを言ってるとVCIが重くなって、VCI禁止部屋が増えていくという悲しい状況になりそうです。
そこで、簡単に軽くなるというか、これくらいはみんなやってるよねって言うのを一つ書いておこうと思います。

VCIチョットデキル方には物足りない話です、ゴメンナサイ。

#VCIのサンプル使って説明します
フルにサンプル作ってもしょうがないので、バーチャルキャストwikiに出ているこちらをちょっと変更してサンプルにします。
[バーチャルキャストのWikiのサンプル](https://virtualcast.jp/wiki/doku.php?id=vci:sample:text:tutorial)
VCIにテクスト表示が追加されたときに公開されたサンプルです。
このままだと長いので、必要なスクリプトだけちょっと変更して使用します。

```lua:Tokei.lua
-- TimerTextに時間を表示するプログラム
function updateAll()
    -- 時分秒の表示
    local time = os.date(("%H:%M:%S"))
    -- TimerText のオブジェクトに TextMeshPro がアタッチされてます
    vci.assets.SetText("TimerText", tostring(time)) 
end
```
よく見るサンプルですね、オリジナルに秒の表示を入れて時間表示にしただけです。

作ったことの無い方は、へぇ～ってなるかもしれません。
luaがチョットデキル方に見せると、これは遅いだろって怒られるかもしれません。
ごめんなさい。
![X目.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/d8d19765-03a4-d91c-b621-a40f441ad5b1.jpeg)

#VCIの動きのおさらい
早くする前にちょっとだけ、VCIの動きの説明です。
VCIの処理は意外とややこしいので簡単に書くとこんな感じだと思います。

1. VCIを出した方はVCIのオーナーになる
2. 同じ空間に居る全員のPCへ同じVCIが読み込まれる
3. VCIを握るとVCIの所有権を取得しますが、オーナーは移動しません
4. 同じ空間に居る全員のPCでLuaスクリプトが動作する

たまにオーナーのPCだけで動いていると思う方が居るようですが、同じ空間の全員のPCで動作しています。
なのでツヨツヨPCの方が一人で開発したVCIを7人居る部屋で出したり、ヨワヨワPCの方が居ると「このVCI重い」ってことが有ります。

**結局、Luaは軽いに越したことは無い!!**

#サンプルのプログラムを軽くしてみよう
先ほどのサンプルに戻って見てみましょう。

サンプルプログラムを見るとupdateAllが使われているので、全員のPCで毎フレームごとに実行される関数です。
毎フレームとは？ バーチャルキャストの最大フレームレートは90fps（1秒間に90回の処理）と言われています。
駒落ちしなければ毎秒90回のupdateAllが動作するわけです、**全員のPCで**

時間の取り込み、テクスチャの書き換え表示が毎秒90回発生します、**全員のPCで**
90fpsもあればさぞや滑らかに動く事でしょう？
![2019120420350739.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/5262903a-299f-ff65-d093-9c110e4c4545.jpeg)

残念ながら時計なので**毎秒90回も書き換える**意味が有りませんね。
サンプルは秒の表示もしているので、1秒に1回更新すれば見た目は変わりません。
そこで、upadateAll内の表示処理回数を減らしてみましょう、とりあえず1秒に1回更新にしてみます。

```lua:Tokei2.lua
-- TimerTextに時間を表示するプログラム（1秒くらいで更新）
local LoopCount = 90 -- 設定したフレームに1回動くための固定値
local Loop = 0  -- updateAllの回数をカウントするだけの簡単なお仕事です

function updateAll()
    loop = loop + 1 -- 毎フレームごとに+1します
    if LoopCount <= loop then -- loopが設定したLoopCount以上になったら表示します
        loop = 0  -- 簡単なお仕事は終了したのでリセットしておきましょう

    	-- 時分の表示 ここからはそのまま
    	local time = os.date(("%H:%M:%S"))
    	-- TimerText のオブジェクトに TextMeshPro がアタッチされてます
    	vci.assets.SetText("TimerText", tostring(time)) 

    end
end
```
これでだいたい1秒に1回時間表示の更新が行われます。
**元の処理に比べると表示回数が1/90になりました、すげぇ。**
実際にはコマ落ちなんかの関係で80fpsになっていたりしますから、時間がずれるかもしれません。

表示する秒が1秒ずれていたとして発生する影響はなんでしょう？
どうせ配信ラグで数秒のずれがありますから気にしなくてもいいでしょう。

LoopCountの値を90から120にして、動かしたところで気づく方は居ないでしょう。
でも450にすると5秒以上更新が行われないわけですから、ばれちゃいますね。

もっと軽くしたいのなら、時間の表示を分までにしてしまえば10秒に一回程度の更新でもばれないでしょう。
逆に分単位でしか更新しないのに90fpsで更新したときは、無駄な動きが多くなりますね。

この時計1個の処理はたいして重くは無いので、90fpsでも1fpsでも枠重くなったりするような体感できる速度は変わらないと思います。

では、100個のオブジェクトを移動する処理を1秒間に90回行うと滑らかに動くでしょうか？
実際は重くなってカクカクしてしまうでしょう。
作った方のPCがツヨツヨなら滑らかに動くかもしれませんが、7人の枠やたくさんのVCIが表示されたら？
ヨワヨワのPCの方がやっと動いている時に、重いVCIが出されたら？
誰かが落ちてしまうかも、カクカクになるかも。
せっかく作ったVCIなので楽しく使ってもらいたいですよね。

今回のはちょっとした処理のスキップですので、みんなやってることだと思います。
ただ、こんな感じで少し軽くする方法はいろいろ有ります。
このちょっとを組み合わせて処理を軽くすのが面白くなってきたら、あなたもプログラムチョットデキル人になっているかもしれませんね。

**そして少しでも軽くなるように作った方がみなさん幸せになれるような気がします**

たまにニコ生で配信してますので、暇な方は遊びに来てください。
![V.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/1fbffd34-daa9-e241-31a2-dda821eabde3.jpeg)

#おわりに
勢いで始めたVCIアドカレですが、もう一回書く予定です。
隙間が有ったらもう少し書くかも。
雑談多めですが、参考になったらなによりです。

まったね～