VirtualCast上にUnityちゃんを表示してアニメーションさせる

[VirtualCast](https://virtualcast.jp/)では、VR空間上にユーザーが作った3Dオブジェクトを配置し、Luaスクリプトから自由に操作できます。このインタラクティブな3Dオブジェクトを**VCI(Virtual Cast Interactive)**と言います。

VCIのSDKである**UniVCI**は、v0.21から複数のアニメーションを再生させる機能が追加されました。この機能を用いて、Unityちゃんの3Dモデルをスクリプトによってアニメーションさせてみます。

VCIの詳細は、こちらをご覧ください。
https://virtualcast.jp/wiki/doku.php

UniVCIは、こちらからダウンロードできます。
https://github.com/virtual-cast/VCI/releases

Unityちゃんの3Dモデルはこちらからダウンロードします。
http://unity-chan.com/

今回は**SDユニティちゃん 3Dモデルデータ 1.01**を用います。

## プロジェクトの作成と準備

必要なファイルは、以下の2つです。

- SD_UnityChan-1.unitypackage (http://unity-chan.com/)
- [UniVCI-0.21.unitypackage](https://github.com/virtual-cast/VCI/releases/download/v0.21/UniVCI-0.21.unitypackage)

Unityは**2018.4.8**を使用します。

1. Unityで新規に3Dプロジェクトを作成してください。

2. **PlayerSetting** の **Api Compatibility Level** を **.NET 4.x** にしてください。
![2019091201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/97c5ce27-d715-4aef-57e5-d6f71224acf9.png)

3. **SD_UnityChan-1.unitypackage** と **UniVCI-0.21.unitypackage** をダブルクリックして、プロジェクトに導入してください。

これで準備は完了です。

## 3Dモデルの準備

Unityちゃんの3DモデルをVirtualCast上で表示させるには、マテリアルとアニメーションの変換が必要になります。

1. **Assets/UnityChan/SD_Unitychan/Models/Materials**にある5つのマテリアルのShaderを**VRM/MToon**に変更してください。

![20190912_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/8b500721-239b-328b-a11c-da00179977c9.png)

2．**Assets/UnityChan/SD_Unitychan/Animations/SD_unitychan_motion_Generic**にある、以下のアニメーションクリップを複製し、**Legacy**のチェックを有効にしてください。

- **Standing@loop**
- **Running@loop**
- **Salute**

それぞれのアニメーションクリップを選択し、**Edit/Duplicate**で複製し、インスペクタの右上のメニューからDebugモードを選択すると、Legacyプロパティが表示されるので、チェックを入れてください。

手順がよくわからない場合は、こちらのエディタ拡張を使ってください。

[AnimationConverter.cs](https://gist.github.com/fumobox/f9446d682edbcaa3ac1c0561755437ce)

アニメーションクリップを右クリック→**Animations/CopyAnimationClipAsLegacy**をクリックすると、Asset以下に、Legacy設定のアニメーションクリップが複製されます。

## VCIの作成とエクスポート

変換した3Dモデルを使ってVCIを作成し、VCIファイルとしてエクスポートします。

1: シーンを新規作成し、**GameObject/VCI/Plain VCI**を選択し、空のVCIオブジェクトを作成してください。

VCIObjectが作成されます。

2: VCIObjectに**Assets/UnityChan/SD_unitychan/Prefabs/SD_unitychan_generic.prefab**をドラッグアンドドロップしてください。

SceneビューにUnityちゃんが表示されます。

![2019-09-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/e2f9c208-a28f-d9e2-a88e-bd7f50488eca.png)

3: Hierarchy上の**SD_unitychan_generic**を右クリック→**Unlock Prefab Completely**を選択し、Prefab化を解除してください。

4: **SD_unitychan_generic**のInspectorを表示し、アタッチされているComponentを全て外してください。

![2019-09-13 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/f206d9a6-2eb5-b146-4dbd-ad334f5ee7d8.png)

5: **SD_unitychan_generic**のGameObject名を**Unitychan**にリネームしてください

6: UnitychanのGameObjectにAnimationコンポーネントをアタッチして、Inspectorから、AnimationsのSizeを**3**にして、さきほど複製したアニメーションを**Standing@loop、Running@loop、Salute**の順にセットしてください。

7: Animationの**Play Automatically**のチェックを外してください。

UnitychanのInspectorは、このような表示になっていればOKです。
![2019-09-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/323b2e81-d4f4-acb0-e3eb-0aa6fbee6437.png)

8: VCIObjectのInspectorを以下のように設定してください。

**Title**と**Author**の欄に適当な値を入力してください。

**Scripts**の**Source**に、以下のコードを貼り付けてください。

```lua
local subItem = vci.assets.GetSubItem("Unitychan") -- アイテムを取得
local anim = subItem.GetAnimation() -- アニメーションを取得
local currentAnimationId = 0 -- 再生中のアニメーションID
local timer = 0 -- アニメーションを切り替えるためのタイマー

function update() -- UnityのUpdateと同じく毎フレーム実行される
    if timer > 0 then -- タイマーが0より上ならタイマーを減算
        timer = timer - 1
        return
    end

    local axis = vci.me.GetAxisInput() -- キーボードの軸入力を取得
    axis.y = 0 -- y軸の入力は無効化

    if axis == Vector3.zero then -- 軸入力がない時
        SwitchAnimation(0, true) -- アイドルアニメーションを再生
    else -- 軸入力がある時
        local currentPos = subItem.GetLocalPosition() -- 現在位置を取得
        local nextPos = currentPos + axis * 0.05 -- 次の位置を決める
    
        subItem.SetLocalPosition(nextPos) -- 次の位置をセット
    
        local rot = Quaternion.LookRotation(axis, subItem.GetUp()) -- 次の回転を設定
        subItem.SetLocalRotation(rot) -- 次の回転をセット

        SwitchAnimation(1, true) -- 走るアニメーションに切り替える
    end

    if vci.me.GetButtonInput(1) then -- 数値キーの1が押された時
        timer = 70 -- タイマーをセット
        SwitchAnimation(2, false) -- 敬礼のアニメーションを再生
    end
end

function SwitchAnimation(id, loop) -- アニメーションを切り替える
    if currentAnimationId ~= id then -- 再生中のアニメーションを停止
        anim.Stop()
    end
    anim._ALL_PlayFromIndex(id, loop) -- 新しいアニメーションを再生
    currentAnimationId = id -- 再生中のアニメーションIDを更新
end
```

**Model Data License Type**を**Other**にして、ユニティちゃんライセンスを貼り付けてください。

```
© Unity Technologies Japan/UCL
```
参考: http://unity-chan.com/contents/guideline/

**Script License Type**の設定は任意です。本記事のサンプルコードは自由に使ってください。

Scriptを実行中に編集したい場合は、**Script Settings**の**Script Write Protected**のチェックを外し、**Script Enable Debugging**のチェックを有効にしてください。

VCIObjectのInspectorは、このような表示になっていればOKです。

![insp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/80e38365-deda-efa8-2d86-0ff770028b53.png)

9: VCIObjectのInspector下部にあるExport VCIボタンから、VCIのデータをファイルに出力してください。

![expt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/29906506-95b8-8fe0-bce0-222c37713ce9.png)

VCIObject.vciという名前で出力されます。

## VCIのアップロード

VCIをVirtualCastで表示させるために、[The Seed Online](https://seed.online/)にVCIをアップロードします。VirtualCastはThe Seed Onlineから、VCIをダウンロードしてスタジオ上に表示させます。

アップロード方法の詳細は、こちらをご覧ください。
https://virtualcast.jp/wiki/doku.php?id=seed:top

## 動作確認

VirtualCastを起動して、タイトル画面でThe Seed Onlineと連携を行った後にスタジオに入り、リングUIのカスタムアイテムメニューを表示すると、アップロードしたVCIが表示されます。VCIを選択するとUnityちゃんが表示されます。

![res.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37449/ad796e19-ebc3-5a92-b5ef-45a3c4b4181b.jpeg)

このサンプルでは、何もしていないときはアイドルアニメーション、カーソルキーを押すと走るアニメーション、数値の1キーで敬礼のアニメーションが再生されます。VirtualCastのウィンドウが最前面にない場合、キー入力を受け取れないのでご注意ください。

今回作成したVCIは、こちらから取り込めます。
https://seed.online/items/438bebc29aa4a80a09d5555ce162c132bd951891e2dfc98f3c05402b5cca184a