PlayCanvas レンダリングコンポーネントの特徴を利用した簡単なキャラアニメーション制御

PlayCanvasへ3Dモデルデータをアップロードした際に、メッシュ情報は1つのオブジェクトへ統合され、各メッシュインスタンスへのアクセスはできませんでした。また、ボーン(rig)の情報へアクセスする際も、コンソールから確認する方法がとられてきました。
しかし、モデルインポートパイプラインから新しいレンダリングコンポーネントへ移行され、個別にメッシュ/ボーン階層を保持した状態でPlayCanvasへアップロードすることが可能になりました。

PlayCanvas.jpのブログ内で2021年7月5日に公開された以下のドキュメントを翻訳したものが掲載されています。
[モデルインポートパイプラインから新しいレンダリングコンポーネントへの移行](https://support.playcanvas.jp/hc/ja/articles/4403256355481-%E6%96%B0%E3%81%97%E3%81%84%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A8%E3%83%95%E3%82%A3%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89API%E3%81%B8%E3%81%AE%E7%A7%BB%E8%A1%8C)

新しいレンダリングコンポーネントへ移行されたことにより、複雑な3D形状を個別に管理、操作することが可能となりました。


この記事では以下のものを見ていきます。

:::note info
モデルをインポートした際の内容を見てみる
:::
:::note info
ボーンヒエラルキーでキャラクターに何か持たせてみる
:::
:::note info
アニメーション＆物理制御でオブジェクトをぶっ飛ばしてみる
:::

#モデルをインポートした際の内容を見てみる
建造物やキャラクターをPlayCanvasへインポートした際のモデルコンポーネントとレンダリングコンポーネントの違いを見てみましょう。
settingsのassetetask欄の中の、[Model Import Setting]項目内、[Import Hierarchy]にチェックが入っていない状態はレガシーなモデルコンポーネント。チェックが入っている状態がレンダリングコンポーネントとなります。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/5ee9083f-1a31-b710-e0bd-eae4e6318a12.png)
##モデルコンポーネントで読み込んだ場合
モデルコンポーネント(Import Hierarchyにチェックが無い状態)では、各メッシュが1つに統合されていまっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/5e517838-f877-1614-e6ed-b78c4d9f052f.png)

##レンダリングコンポーネントで読み込んだ場合
レンダリングコンポーネント(Import Hierarchyにチェックが有る状態)では、各メッシュ情報を個別に保持し、階層構造がある場合はその階層構造も保持された状態でインポートされます。
また、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/90b1356f-545a-edfe-8db2-92b3e72fd302.png)
また、インポートされたデータは[.glb]をコンテナ化されたものになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/d559d6fd-9870-7181-a506-394bb38d4857.png)

#ボーンヒエラルキーでキャラクターに何か持たせてみる
ボーンがセットアップされたキャラクターをレンダリングコンポーネントでインポートすると、ボーン階層を保持した状態でインポートされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/10e54660-5d24-2c55-962c-7fee56d8fa83.png)
赤枠：新規オブジェクト[Box]を作成して[HIERARCHY]の[Right wrist]へ[Box]を移動＆スケールと位置を調整。
緑枠：[Right arm]の回転の数値を変えると、腕と[Box]が追従して動いているのが確認できます。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/45ba5a4d-52b4-f3b8-9a37-dba13df37b57.png)

#アニメーション＆物理制御でオブジェクトをぶっ飛ばしてみる
床と破壊用のオブジェクト、コリジョン(物理判定)とリジッドボディ(物理制御)を設定してみます。とてもシンプルな手順です。

ボックスを変形させて床と破壊用オブジェクトを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/904920a2-c7bb-8381-1b24-19e4a65aaed5.png)

床にコリジョンとリジッドボディを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/2716dd88-33b2-216d-a5ed-8f95e60b121a.png)

破壊用のボックスにもコリジョンとリジッドボディを設定。リジッドボディの[Type]を[Dynamic]へ変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/0cde15a8-1d54-56c2-b3ee-04f57c4ce84a.png)

最初にヒエラルキー内で[Right wrist]へリンクさせた[Box]にも同様の設定をします。この際リジッドボディの[Type]を[Dynamic]へ変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/1fde408a-cc24-8a6c-5c99-810ab9330232.png)

##アニメーションの設定
レンダリングコンポーネントへ移行したことで、アニメーションもState Graphベースのものに変更されました。
新規Anim State Graphを作成し、下記画像の様に[idle]と[attack]のアニメーションを繋げます。
parametersに新規で[attack]を作成します。[Type]を[Trigger]へ変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/519e326f-076e-bd07-9fd4-56820057f70f.png)
[Idle]から[Attack]のTransitionを設定します。[New Condition]で[attack]を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/a91c4ccf-b939-ab25-688e-bfb14add451a.png)
[attack]から[Idle]へのTransitionを設定します。
Duration:0.2
Exit Time:1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/517d0b6a-4ccf-ce59-ed55-35f6de0a6997.png)
Graphエディターを閉じて、[Add Component]から[Anim]を選択し、[State Graph]を空きスロットへdrag＆dropします。
アニメーションデータを[idle][attack]の空きスロットルへdrag＆dropします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341892/49db9f72-617c-c31a-f8bc-f5d982b3156b.png)
スクリプトはとてもシンプルです。

```Javascript
var Motion = pc.createScript('motion');

// initialize code called once per entity
Motion.prototype.initialize = function() {

};

// update code called every frame
Motion.prototype.update = function(dt) {
//キーボード[A]を押したら攻撃する
if(this.app.keyboard.wasPressed(pc.KEY_A)){
        this.entity.anim.setTrigger('attack');
    } 
};
```
[A]キーを押すとアニメーションを1回再生して[Idle]へ戻り。[Idle]をループ再生します。

https://playcanv.as/p/CtwrA2Ss/

以上がレンダリングコンポーネントの特徴と、それらを活かしたキャラクターの簡単な制御になります。
モデルコンポーネント時はボーン情報にアクセスするにも、コンソールから階層を辿っていかなければなりませんでした。
キャラクターに何かを持たせても、コリジョンやリジッドボディが追従してこなかったり。。。
このレンダリングコンポーネントが実装されたことで、3Dモデルの扱いがかなり楽に簡単になったと思います。
あとはモーフィングのデータにササっとアクセスできればなぁ。。