人がいるほど成長するアイテムを作る

# どんな物を作るか
下記のような物が成長するVCIを作ります。
* VR空間で木のように徐々に成長する
* 全員退室しても成長度合いが保存される

用途：自分のルームにどのぐらい人が来ていたかを体感しやすいアイテムになります

実物のVCIはこちらになります。
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">人がいる程成長していく木です。<br>ルームなどに設置してみんなで大きく育ててみましょう。<br><br>成長する木 / らーめん / VCI <a href="https://t.co/4Z3tHHGoBy">https://t.co/4Z3tHHGoBy</a> <a href="https://twitter.com/hashtag/VirtualCast?src=hash&amp;ref_src=twsrc%5Etfw">#VirtualCast</a> <a href="https://twitter.com/hashtag/%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#バーチャルキャスト</a> <a href="https://twitter.com/hashtag/VC%E3%82%B9%E3%83%88%E3%82%A2?src=hash&amp;ref_src=twsrc%5Etfw">#VCストア</a> <a href="https://t.co/wcJYnqgf2b">pic.twitter.com/wcJYnqgf2b</a></p>&mdash; らーめん (@priramen) <a href="https://twitter.com/priramen/status/1730803059260068198?ref_src=twsrc%5Etfw">December 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## VCIの下準備
VCIに必要なオブジェクトを作ってVCI出力します
```
Root --成長アイテムのサブアイテム
┗ Origin --Cubeの中心座標を下部にするための調整オブジェクト
  ┗ Cube --Cubeモデル(成長していくモデル)
SaveItem --成長度合いを同期・記録するアイテム(空オブジェクト)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620136/5ba5e9db-a66e-ff2e-dc43-a8b291b8862f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620136/2053974a-d134-687f-90be-c44ac67cf310.png)

## スクリプト

### 時間毎に成長する
まずはシンプルに毎フレームCubeを成長させてみましょう。
```lua
--成長スピード
local GROW_SPEED = 0.001
--スケールを変更して成長を表現するオブジェクト
local origin = vci.assets.GetTransform("Origin")
--成長度合いの同期・記録をするセーブ用サブアイテム
local saveItem = vci.assets.GetTransform("SaveItem")

function updateAll()
    --成長度合いを更新する
    --LocalPositionのY座標を成長度合いのデータとして使用する
    local grow = saveItem.GetLocalPosition().y

    --セーブの管理者はアイテムの成長度合いを増やす
    if saveItem.IsMine then
        saveItem.SetLocalPosition(Vector3.__new(1, grow + GROW_SPEED, 1))
    end
    
    --成長処理
    origin.SetLocalScale(Vector3.__new(1, grow, 1))
    print("成長率" .. grow)
end
```
![2023-11-14_22-59-53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620136/5335344d-350f-219d-ee11-b75bd7c43c56.gif)

このスクリプトで少しずつCubeが成長していくのがわかります。成長度合いの保存はサブアイテムの位置情報が担ってくれるので、このサブアイテムの移動だけで同期と保存の機能が実はできています。

### 1秒毎に成長する
この速度だとすぐに巨大なオブジェクトになってしまうので、今度は成長速度を制限してみましょう。
下記のスクリプトでは、時計上で秒の値が変わったタイミングで成長処理を行うため、ゆっくりと成長していきます。
```lua
--(変数定義省略)
---現在の秒数
local currentSec = 0

function updateAll()
    local date = os.date("*t")
    if currentSec ~= date.sec then
        --現在の秒数を更新
        currentSec = date.sec
        
        --成長度合いを更新する
        --(省略)
        print("成長率" .. grow)
    end
end
```

モデルによっては成長度合いが遅い・早いがあると思うので、成長速度を見ながら**GROW_SPEED**の値を変えてみましょう。

## 部屋にいる人数によって成長速度を増加させる
部屋にいる人数が多いほど成長しやすくすると、みんなで成長させている感が出ます。
成長処理の部分を下記のように修正してみましょう。
（人数はvci.studio.GetAvatars()のデータ数から調べれます。）

```lua
--セーブの管理者はアイテムの成長度合いを増やす
if saveItem.IsMine then
    local avatars = vci.studio.GetAvatars()
    saveItem.SetLocalPosition(Vector3.__new(1, grow + (GROW_SPEED * #avatars), 1))
end
```

## 成長速度の目安
いかがでしょうか。
VCIを出しながら作っている場合は、その間もどんどんと成長を続け、いつの間にか大きくなっているのがわかると思います。
今回の例では1秒間に0.001ずつ大きくなっていきますが、これは1人で1時間居続けていれば3.6ｍ成長する速度になります。もっと長期的に成長を見ていきたいのであれば更に1/10の速度にしても良いでしょう。

## 応用編
この成長度合いは数値化できるので、今回の木に見立てたCube以外にも色が変わる、ロケーションの風景が変わる、みんながいっぱい来てくれたというアンロック要素として扉の鍵が開くなど様々なギミックに応用が効きますので、自分のルームで変化を持たせたい場合はこの仕組みを使ってみてはいかがでしょうか。