メタバース空間でレースクイーンになったからよくある傘をメタバース空間に持ち込みたい

## はじめに
はーい、みゅみゅです。

前回、メタバース空間でレースクイーンになったのでよくあるSofmap背景をバックに写真を撮ったのですが、何かが足りないです。

https://qiita.com/miyumiyu/items/137800e7afa068881669

そう、レースクイーンは雨も降ってないのにみんな傘を持ってます。
ということで今回はレースクイーンに必要不可欠な傘を世の中にある定義に当てはめればどう考えてもメタバースな[バーチャルキャスト](https://virtualcast.jp/broadcast/)でに持ち込みたいと思います。
そして前回のSofMap背景をバックに写真を撮って完全無欠なレースクイーンを目指します。

**なお当方、モデリングの知識はまったくありません。**

## 傘のモデルについて

傘のモデルはレースクイーンになるために購入しましたこちらの商品に付随しておりました。
[作者さま](https://twitter.com/tr96c_thor)　感謝です！

https://booth.pm/ja/items/3330792

購入しダウンロードして展開を行ったら、**【UmbrellaOpen_RacingBikini.fbx】** というFBXモデルが付属してましたので、こちらを利用してバーチャルキャスト内に持ち込みたいと思います

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/6c87c3fd-8252-6e31-f820-1c3cef583cba.png)

## １．UniVCIのダウンロードとインストール
内容は[前回](https://qiita.com/miyumiyu/items/137800e7afa068881669#1-univci%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
)とまったく同じです。
以下、前回の記事のリンクに飛ぶのがめんどくさい人向けのコピペです。

---
VCI制作にはUniVCIというUnity Packageが必要となります
UniVCIのダウンロード
https://github.com/virtual-cast/VCI/releases

こちらから最新のUniVCI(UniVCI-???.unitypackage)と付属の**UniVRM**(UniVRM-???.unitypackage)をダウンロードします。

1. UniVRM
2. UniVCI
この順番でインストールします。
（ファイルをダブルクリックするとインストールが始まります）

※途中何か言われたら【Accept All】で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/807caefb-e42b-8c39-5319-f9fcf6c41331.png)

## 2.Unityの上に作業用フォルダを作りそこに必要な素材を入れる
今回、傘を作るのでUnity上にフォルダを作りそこにオブジェクトなどの必要な素材を入れていきます。

【Assets】を右クリックでCreate→Folder 選択してフォルダーを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/271772fe-26b0-aa50-5f3b-eab795f50fb4.png)

フォルダー名は今回は傘を作るので **【kasa】** にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/40149a7b-80a2-2b97-da16-8da4b854f672.png)

作ったフォルダー（**kasa**)の中に今回使う素材を入れます。
ここで注意しないといけないが、FBXファイルの他にテクスチャのイメージ素材も必要になります。
なので今回は
- オブジェクトファイル（FBX）
- テクスチャファイル（pngなどイメージ）
この2つが素材として必要です。

展開したファイルの中に **【UmbrellaOpen_RacingBikini.fbx】** がありますので、そのファイルを先程作成しました **【kasa】** にドラック＆ドロップで入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/1fb4d402-223a-f880-3581-b06ca207006a.png)

同じく、textureというフォルダにある **【RacingBikini_TEX.png】** も先程作成しました【kasa】にドラック＆ドロップで入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/56c13044-ee49-9777-4c40-cfc10ab102e9.png)

**【kasa】** のフォルダはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/4647020b-2480-0b5a-e169-26cdbdb9ffe8.png)


## 3.傘をシーン上でそれっぽく出す
傘をUnity上で出してみましょう！
先程ドラック＆ドロップした **【UmbrellaOpen_RacingBikini】** をHierarchyにドラック＆ドロップしてみましょう。
Hierarchyにドラック＆ドロップすると、Unityという世界に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/951e579a-2f23-2ce3-4414-f2e5a7d44590.png)

Unityの世界に傘が出ましたが真っ白です。
これはテクスチャが設定されてないので真っ白です。

今度はイメージ素材 **【RacingBikini_TEX】** を真っ白な傘のオブジェクトにドラック＆ドロップしてみましょう。
（HierarckyではなくSceneに表示されてる傘のオブジェクトに対して直接ドラック＆ドロップです）

そうすると、真っ白な傘がそれっぽい感じのかっこい傘に変わりました。
![a-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/9e3ce25f-2786-a991-5154-a8d3e13b5949.gif)


## 4.VCIの作成
ここからはVCIとして出力できるように設定していきます。
基本的な流れは前回と同じrootオブジェクト作成してsubitem作成、そしてコライダーを作成していきます。

### 4-1. rootオブジェクトの作成

VCIオブジェクト（アイテム）の一番最初の階層となるオブジェクトを作成します。
このオブジェクトにはVCIアイテムそのものの情報が入ります。

Hierarchky 左クリックで 【Create Empty】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/11ac4eb6-ef5b-318c-99cb-37c8254f2552.png)

これがVCIアイテムのrootオブジェクトになるのでわかりやすい名前にします
（例では kasa）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/908877bb-c6ad-d935-8615-080894ea46a7.png)

このObjectの中に【VCI Object】コンポーネントを追加します。
(このコンポーネントにVCI情報が入ります）
【Add Component】 から **【VCI Object】** を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/11661c07-ef95-e630-3c9b-6f31522059be.png)
コンポーネントの中の必須項目を入れていきます。


| 項目 | 内容 |
|:-:|:-:|
|Title   | kasa (傘だから)  |
|Version   | 1.0 （なんとなくこの数字）  |
|Author   | miyumiyu （わたしです）  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/54ad220f-a369-7bed-2132-0cd1eab217fe.png)

### 4-2. SubItemの作成
実際にオブジェクト配置を行うSubItemを作成していきます。
SubItemの階層を作り、その下に傘のオブジェクトを入れていきます。

先程作った **【kasa】** オブジェクトの下にCreate Enptyでオブジェクトを作成し、できたオブジェクトをわかりやすい名前に変更しておきます　
（例では kasa-subitem です)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/0c9c0dad-974a-3e26-1da0-4d6d839433ae.png)

作成した **【kasa-subitem】** の階層の下に、傘のオブジェクト本体 **【UmbrellaOpen_RacingBikini】** を配置します。
（【UmbrellaOpen_RacingBikini】をドラック＆ドロップで移動します）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/5bbecb00-d6f2-2353-999f-2aa40f8e6538.png)

### 4-3. コライダーを仕込む
作成したアイテムは持ち歩いたり拡大、縮小したいので手に持たすためにコライダーコンポーネントを追加しなくてはいけません。

【UmbrellaOpen_RacingBikini】を選択して、【Add Component】 から 【Box Collider】を追加します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/bfdb36ba-c4f0-e357-3428-9a6b868841a0.png)

すると、コライダーが緑色の線ででてきますのでとりあえず柄の部分に当たり判定があればいいので小さくしていきます。
【Edit Collider】のボタンを押すと緑色の線の真ん中に緑の点が出るので、その点を動かして小さくしていきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/29c91bd9-2a86-cdc8-f746-a1c6f13b0d10.png)

こんな感じで柄の部分に当たり判定（緑の枠）を入れます。
※わたしはこういうところ、結構ガバガバです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/12e45bfd-eaf3-1968-935e-e590e611d697.png)

### 4-4.レイヤーを設定
傘はもって歩いたりすることができます。
この時、正しい当たり判定（レイヤー）を設定しないと、体に当たってあらぬ方向（荒ぶるという）状態になりやすいのでレイヤーを設定します。
レイヤーの詳しい説明はこちら
https://virtualcast.jp/wiki/vci/component/unitycomponent/collider

今回は、持つアイテムなので **【VCIPickUp】** を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/2b005fb2-eb6a-fa7a-77ba-758a87654bd9.png)

### 4-5. VCI SubItemの設定
SubItemとして設定したkasa-subitemに **【VCI Sub Item】** コンポーネントを追加して動き方を指定します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/6c4f8c37-0a18-90f3-63f5-30adf204a0d1.png)

【VCI Sub Item】コンポーネントを追加すると【Rigidbody】コンポーネントも追加されます。

持ちたいので Grabbable ON
拡大、縮小を行いたいので ScalableはON
拡大、縮小を行うときはすべての辺で同じだけスケール値を変えたいので Uniform ScalingはON
引き寄せは特に必要ないのでAttractableはOFF
重力は必要ないので Use GravityはOFF
物理挙動はいらないので Is Kinematic はON

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/61237d79-bc19-b2fc-8ce7-637333922922.png)

### 4-6. 全体的に位置合わせを行う
これで大体出来上がったのですが、位置や回転をちゃんとしていきたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/a6177d4d-9c67-41d8-d925-e51c1481877b.png)
このような階層になったと思いますので

kasa
kasa-subitem
UmbrellaOpen_RacingBikini

これらすべてのTransformのPosition、Rortationをすべて0にします　（０でリセット）
そうすると傘が寝転ぶと思います。
この状態でVCIを作成すると、バーチャルキャスト上にもこのような状態で出現してたいていの場合は地面に埋まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/922b31f2-c636-9153-522e-c58acec63745.png)


ちょっと不便なので【kasa-subitem】のTransformをちょっと変更して下の図のように数字を入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/35a29bba-b349-f39f-4363-589bfc9a9781.png)

そうすることで傘が立ち上がり、地面からすこし浮いた位置になると思います

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/103a649c-e45c-6f40-a867-b244ad5cf449.png)



### 4-7. エクスポートしてVCIを作成
rootオブジェクト(`kasa`)を選択して、上のメニューから【VCI】-【Export VCI】を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/a85cff42-7208-1116-1277-27d8d65cbf93.png)
ファイル名と保存場所が聞かれるので自分の好きな場所に置きます

## 5.THE SEED ONLINEにアップロードします
THE SEED ONLINEにVCIアイテムとしてアップロードします
アップロードするとこんな感じでアイテムの状態が見えます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/b556a7e3-c335-d4e1-da5a-31402fdc1a19.png)


## 6.バーチャルキャストでアップロードしたVCIを出します
バーチャルキャスト上でカスタムアイテムから先程アップロードしたVCIアイテムを選択します
問題なければ作成したVCIアイテムが出現します

![2022120220474104_DevFes公演会場_みゅみゅ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/6aa5ae37-21c9-dca2-496a-36798e2df2cc.png)

コンポーネント追加して、VCI出力するとさくっとVR空間にアイテムを持ち込むことができます。


## 7.自分好みにカスタマイズしていきたい
ここらへんはお好みです。
せっかくがんばって作ったアイテム、自分好みに色々改造したいきたいなーと

### 7-1.色が暗いので明るくしたい
できた傘をバーチャルキャスト内に持っていったら、なんとなく暗くてキャラクターの色の質感と違うので明るくしていきたいと思います。

Hierarchyから **【UmbrellaOpen_RacingBikini】** を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/5279efee-4655-9fe6-52bf-e1fafea7c2b0.png)
その中で Shaderとある部分に　**【VRM/MToon】** を選択します。
これは、VRMモデルで使われてるシェーダで一緒にあわせていくと質感も同じになるかなぁ　と
（ここらへんは好みの問題もあると思うのですが、私はこれが好みです　えっへん）

ついでにデフォルトだと影の部分がピンクっぽくなるので、影の色（Shade Color)をRGBそれぞれ0.9ぐらいにします（ちょとだけ暗く）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/56802ff1-7c1d-64ec-723f-de2e81acc967.png)

これで、再度VCIにエクスポートしてTSOにアッポロードすればキャラクターの質感に合った色になるかと思います。　やったね！

![2022120220565118_DevFes公演会場_みゅみゅ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/5d923ad5-34de-aca8-481a-239d08663e65.png)

### 7-2.傘を開閉したい
せっかくの傘なので傘を開閉したいと思います。
こちらの傘は作者様のおかげで、傘の開閉のBlendShapeが設定されていますので、ここをVCIで制御できれば傘の改変が行なえます。

![a-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/f960d262-9d70-bf62-cf48-e8de818202ac.gif)


VCIでアニメーションのスクリプトの作り方はこちらを参考に作成していきます。
https://virtualcast.jp/wiki/vci/sample/animation/tutorial2

#### Animationコンポーネントを入れる
アニメーションを行うためにはSubItemにアニメーションコンポーネントを入れる必要があります。
**【kasa-subitem】** の中にAnimationコンポーネントを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/126d5cf5-d4a6-6372-e898-69492ca58944.png)

#### Animationウィンドウを開く

kasa-subitemを選択した状態で、メニューから[ Window > Animation > Animation ]を選択して、Animationウィンドウを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/2e35eec3-8fce-9ebe-6caa-2e5a054bbb40.png)

#### 傘が開くアニメーションを作成

Createボタンを押してわかりやすいアニメーションの名前をつけます。
（ここでからは例として `kasahiraku` という名前をつけます）


Add Propaty で　UmbrellaOpen_RacingBikini → Skinned Mesh Renderer → Blend　Shapes.Close を選択します。
（傘の開閉を行いたい　→　傘の開閉は BlendShapeで行ってる　→　そのBlenSapeをアニメーションで動かせばいい）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/1d2041f3-8c43-fa9f-e236-f974a6c83e90.png)


特にこだわりはないのですが、2秒で開く、2秒で閉じるを実現したいと考えました。
1秒は60フレームなので2秒で120フレームです。

右上の数字を入れるところ（フレーム数が表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/8bcb05d9-fb3e-9d46-ea64-7294814ceb34.png)
ここに0を入れて開くアニメーションを作りたいのでBlendShapeの数字は100（最大）にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/fea76477-b2bc-5e76-eea2-381d2dd550c1.png)
すると傘が閉じるかと思います

次に2秒（= 120フレーム目）がきたら開くようにします
同じように右上のフレーム数のところには120 そして BlendShapeの値は0 を入れます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/847930d5-b37a-d2f8-dc6f-09826c2098ae.png)

これで傘が開いたと思います
Previewで確認してみましょう。
Previewの横の再生ボタンを押したら傘が閉じて開くアニメーションが確認できるかとおもいます。
![a-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/e34c5872-d1f3-da13-f30a-7f12619e3968.gif)


#### 傘が閉じるアニメーションの作成
同様に傘が閉じるアニメーションの作成を行います。

先程まで作ったので　`kasahiraku`　でしたので
こんどは `kasatoji` を作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/aea7f731-57b1-bdeb-2f3a-2c8169958c88.png)

`kasahiraku` をクリックして Create New Clip ...   先程と同じようにファイルを作成します。
（`kasatoji`を作ります）

今度は閉じるアニメーションを作成するので
0フレーム目　→ blendshapeは 0
120フレーム目　→ blendshapeは 100
と設定します。
![a-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/22a2ce0b-f0bb-9bbb-0083-5834166d736f.gif)

これで、一番最初に追加した animationコンポーネントに2つのアニメが入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/d965c75c-a2e0-6ba5-90ca-1a5b3fff594e.png)


#### アニメーションが動くようにVCIスクリプトを作成
アニメーションの準備が整いましたのでVCIスクリプトを作成します。

やりたいことを整理すると下のような内容になります。

１．最初（出現時）は開いた状態
２．開いた状態でUSEすると閉じる（kasatoji アニメ実行)
３．開いてる状態じゃなければ（閉じた状態）USEすると開く（kasahiraku　アニメ実行）

整理するとこんな感じのスクリプトです

スクリプトを作成する前に、スクリプトをコピペする準備（VCIスクリプトを書く場所を作る）します。
rootオブジェクトの **kasa**　のコンポーネントのVCI Object この中に Scriptsという項目がありますので Sizeを0から1に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/d2faf25d-325c-db21-efba-3803d341a238.png)

変更後Source に下記のスクリプトコピペして入れます。

```lua
-- 最初（出現時）は開いた状態
local state=0 -- 0開いてる　1閉じてる
-- SubItem名から、Animationコンポーネントを求める
local Anime = vci.assets.GetTransform("kasa-subitem")
local SubitemAnime = Anime.GetAnimation()

function onUse(use)
    if use == "kasa-subitem" then   
        if state==0 then -- 開いた状態でUSEすると閉じる（kasatoji アニメ実行)
            SubitemAnime.PlayFromName('kasatoji', false)
            state=1
        else -- 閉じた状態でUSEすると開く（kasahiraku　アニメ実行）
            SubitemAnime.PlayFromName('kasahiraku', false)
            state=0
        end
    end
end
```


これで、USEで開閉する傘の出来上がりです。
![2021-07-05_1_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/4b8e6c6b-8854-7bd4-ab38-9bd39b737599.gif)

。。。ただし、この傘には問題点が一つありますので次の章で


### 7-3.傘を開閉を同期したい
傘の開閉はできたのですが、問題は自分しか閉じたり開いたりのアニメーションが見えないのです。
これは、VCIの特性上オブジェクトの位置や大きさははシステム側で同期されるが、アニメーションは同期されないからです。
（詳しくはこちらです　https://virtualcast.jp/wiki/vci/tips/sync）

そのため、アニメーションをVCIで同期を行う処理を入れないといけません。
詳しくはこちらのページを参考に、先程作ったスクリプトを魔改造していきます。


```lua
-- SubItem名から、Animationコンポーネントを求める
local Anime = vci.assets.GetTransform("kasa-subitem")
local SubitemAnime = Anime.GetAnimation()
local islocalClose = false

-- 最初（出現時）は開いた状態
if vci.assets.isMine then
    -- アイテム呼び出しユーザーでだけ初期化します
    vci.state.Set('isClose', false) -- 初期値。何もしないと nil になる
end

function onUse(use)
    if use == "kasa-subitem" then  
        -- 開いてるかどうかのフラグを取り出す
        local isClose =  vci.state.Get('isClose')
        -- フラグを反転して格納する、ここではアニメーションを実行しません
        vci.state.Set('isClose', not isClose)
    end
end

function updateAll() -- 全ユーザーで実行したいので updateAll を使います
    local isClose = vci.state.Get('isClose') -- 状態を得ます。アイテム内同期変数は全ユーザーで同期(同じ)になります。
    if isClose then -- 閉じてたら閉じるアニメーション
        if not islocalClose then
            SubitemAnime.PlayFromName('kasatoji', false)
            islocalClose = true
        end
    else -- フラグが開いてるのであれば開いてるアニメーション
        if islocalClose then
            SubitemAnime.PlayFromName('kasahiraku', false)
            islocalClose = false
        end
    end
end

```

これで。傘の開閉が同期されるようになりました。


## さいごに
モデリングができなくても好きなものが自由に作れる世の中です。
自分だけのアイテムを作って、スクリプトやらいろんな物を自分好みに魔改造していって末永く遊べるアイテムを作るのも楽しいですよ。
是非みなさんもチャレンジしてみてください！


![2022120620523411_DevFes公演会場_みゅみゅ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79067/fd716759-6ae3-2027-5d69-5c5a697ee712.png)