UE4でライトリグを作る

# ライトリグとは
一般的なスケルトン向けのリグではなく、複数のライトを一定のルールにそって連動した動きをさせるものです。

今回、↓こんな感じの複数のスポットライトを使ったライトリグを作っていきます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ライトリグ作り直した。次のQiitaこれにしようかな <a href="https://t.co/TEmEpzY0ef">pic.twitter.com/TEmEpzY0ef</a></p>&mdash; おく/奥川 剛 (@t_oku) <a href="https://twitter.com/t_oku/status/1180158666940416000?ref_src=twsrc%5Etfw">October 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 前置き
今回の実装は説明を簡略化させるためにすべてBPで書いていますが、実際に使う場合にはパーフォーマンスにも気を付けなければなりません。実践ではCpp実装/管理でないと厳しい部分もあります。
また、結構な量のライトを使うので、ライトチャンネルの管理や影のパラメータの管理は追加する必要があるでしょう。

## 作る機能
今回はスポットライトを用いて、対象を後ろから照らすためのライトリグアクターを作ります。
・このアクターは指定した半径のリング状にスポットライトを配置します。
・リングはアクターの中心から指定された長さだけローカルX下がります。
・スポットライトはアクターの中心を注視し、個別にON/OFFが出来るため多彩なリムライト表現ができます。

↓のようにリング状に配置されたスポットライトを後ろから当てています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/f6c0858b-9188-f80e-638b-e0493de1f47e.png)

標準的な結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/434e702b-614d-9229-c1bc-f4446357e9f4.png)
任意のライトをオフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/e89c75d7-fe5f-c5b5-d10f-1c6da1b788a8.png)
ライトとの距離を離したり、半径を大きくしたり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/bf15e22d-57d4-b0dd-bd86-46dc5575df41.png)
# 実装
## 準備
UE4上で追加しなければならないファイルは2つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/bfad71af-d945-018f-1296-92cee4647a2d.png)
### アクター
Actorを継承したBPクラスを追加します。
### 構造体
リグ内で制御するライト一つにつき一つ使用する情報を格納します。本来であれば、インテンシティーやコーンの角度など様々なプロパティを持つと思いますが、今回はシンプルに有効無効のboolと影ON/OFFのboolです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/c09a3ddd-a02b-329d-7c83-6f5ba41532e1.png)
## BP実装
### 変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/9414d0b9-ba0b-186d-d767-953acc59c7c1.png)
使う変数は6つ(うちコンポーネント2つ)です。
・Root
　まず、SceneComponentであるRootをDefaultSceneRootと置き換えます。(ムーバブル)
・RingCenter
　リングの中心にするために、子としてSceneComponentであるRingCenterを追加します。(ムーバブル)
　Construcion内で生成されるライトのアタッチ先はここになります。
・InfoArray
　先に作った構造体の配列です。この要素数によってリング内に追加されるライトの個数が決まります。
・ArmLength
　アクター中心とリングをどの位離すかを決めます。
　RingCenterの相対X座標となります。
・Radius
　リングの半径です
・AttenuetionScale
　ライトの影響距離に掛けるスケールです。ライトの位置からアクター中心までの距離が1.0で、デフォルト1.5が入っています。
### BP
基本BPの実装はConstructionScriptだけです。

#### 前半部
RingCenterにArmLengthを設定し、InfoArrayをForで回します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/c712a189-5711-d897-5b89-2a9bb08da946.png)

#### Forの中身
半径分移動させたトランスフォームを360度を要素数で割った角度で回しながら回転させます。
アクター中心を注視させるので、-ArmLengthFindした場所にLookAtRotationしています。
出来上がったトランスフォームを相対座標としてスポットライトを追加します。(ムーバブル)指定したコンポーネントにアタッチしたいのでマニュアルアタッチにチェックをいれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/023b0a3b-b9b2-d69d-cc0b-871b8b3128fc.png)

出来上がったライトコンポーネントをRingCenterにアタッチします。
影響範囲や影の有り無しの設定をして完成です。
※主にここで今後制御したいパラメータを追加していくと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/a9d9b3fa-acf7-86e3-8c5c-bdd85f200a8e.png)

## 最後に
今回はできるだけシンプルになるように実装してみました。
こういったリグはゲームのジャンルやシーンによって必要な機能や動きが全然違うので、情況によってカスタマイズする事が多いです。
前途しましたが、簡単に負荷が爆発的に増えやすい物でもあるので、常にコストは意識したほうがいいでしょう。