18日目：イルミネーションで学ぶ色変更とエミッション

この記事はアドベントカレンダー「[【VCI】テーマパーク を作ろう](https://adventar.org/calendars/5855) 」の18日目の記事です。

# 今回の内容
今回は毎時間00分になると観覧車の支柱が以下のように虹色に変化する仕組みを作っていきます。
![2020122301084562.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/87cbf2fb-ea7c-17b5-b402-9db46d501c50.jpeg)

今回は学ぶ技術は以下となります。
　・スクリプトでの色変更
　・スクリプトでの発光(エミッション)


# unity設定
現在の観覧車の支柱は同じ色のゴンドラをつなぐ星マーク3つ分で構成されています。
この3つをそれぞれ異なる色にしたいため、マテリアルを3種類作成しそれぞれに設定します。
マテリアル作成の際はシェーダーにVRM/MToonを選択してください。
(スタンダードシェーダーにも光らせるためのエミッションという項目がありますが、試したところ動きませんでした)

Unityの設定は以上です

# コードの作成
今回は00分になったら観覧車のフレームが虹色に光り、01分になったら戻るように設定します。
虹色に光る際に3つの観覧車のフレームは色をずらして光るようにします。

色変更の方法については以下の公式ページを御覧ください
　・[assets.material (ExportMaterial) (マテリアル制御)](https://virtualcast.jp/wiki/vci/script/reference/exportassets/material)
　・[Color(色の指定)](https://virtualcast.jp/wiki/vci/script/reference/color)
※vci.assets(ExportAssets)にもマテリアル操作系の関数がありますが、こちらは非推奨みたいです。


## 色変更
上記のコードをもとに色を変更するようにしたいのが以下のコードです。
今回はHSVで指定してからRGBに変換していますが、もちろん直接RGBで指定することも可能です。

``` lua
--フレーム数カウント用変数。
local illminateCount = 0
--何分にイルミネーションを実行するかの設定。
local illminateMinute = 0

function updateAll()
  local minute = tonumber(os.date("%M"))
  --0分のときだけ実行
  if minute == illminateMinute then
    -- illminateCountの値ふやす
    illminateCount = illminateCount+1
    -- 3つのフレームで色をずらす
    local color1 = Color.HSVToRGB((illminateCount + 120)%360/360, 0.4, 0.9)
    local color2 = Color.HSVToRGB((illminateCount + 240)%360/360, 0.4, 0.9)
    local color3 = Color.HSVToRGB((illminateCount + 360)%360/360, 0.4, 0.9)
    vci.assets.material.SetColor("WheelFrame 1", color1)
    vci.assets.material.SetColor("WheelFrame 2", color2)
    vci.assets.material.SetColor("WheelFrame 3", color3)

  -- 1分立ったらイルミネーションを停止する
  elseif minute == illminateMinute+1 and illminateCount > 0 then
    vci.assets.material.SetColor("WheelFrame 1", Color.white)
    vci.assets.material.SetColor("WheelFrame 2", Color.white)
    vci.assets.material.SetColor("WheelFrame 3", Color.white)
    --フレーム数のカウントをリセットする
    illminateCount = 0
  end
end
```

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">色変更 <a href="https://t.co/4kfzmkSOz9">pic.twitter.com/4kfzmkSOz9</a></p>&mdash; ＃らいと（きょろ、ちょべりば→ぐ） (@lightjug) <a href="https://twitter.com/lightjug/status/1341435578974269441?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## エミッション
また、Emission系の関数を使うことで光らせることも可能です。
実際に光らせるコードは以下となります。

``` lua
local illminateCount = 0
local illminateMinute = 0

function updateAll()
  local minute = tonumber(os.date("%M"))

  if minute == illminateMinute then
    -- illminateCountの値ふやす
    illminateCount = illminateCount+1
    local color1 = Color.HSVToRGB((illminateCount + 120)%360/360, 0.4, 0.9)
    local color2 = Color.HSVToRGB((illminateCount + 240)%360/360, 0.4, 0.9)
    local color3 = Color.HSVToRGB((illminateCount + 360)%360/360, 0.4, 0.9)

    --いい感じに表示されるように調整。正直良くわかってない
    local emit1 = 15*(color1-Color.__new(0.54,0.54,0.54,1)) 
    local emit2 = 15*(color2-Color.__new(0.54,0.54,0.54,1)) 
    local emit3 = 15*(color3-Color.__new(0.54,0.54,0.54,1)) 
    vci.assets.material.SetEmissionColor("WheelFrame 1", emit1)
    vci.assets.material.SetEmissionColor("WheelFrame 2", emit2)
    vci.assets.material.SetEmissionColor("WheelFrame 3", emit3)
  
  -- 1分立ったらイルミネーションを停止する
  elseif minute == illminateMinute+1 and illminateCount > 0 then
    vci.assets.material.SetEmissionColor("WheelFrame 1", Color.white)
    vci.assets.material.SetEmissionColor("WheelFrame 2", Color.white)
    vci.assets.material.SetEmissionColor("WheelFrame 3", Color.white)
    illminateCount = 0
  end
end
```
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">エミッション <a href="https://t.co/BZsbABYXOR">pic.twitter.com/BZsbABYXOR</a></p>&mdash; ＃らいと（きょろ、ちょべりば→ぐ） (@lightjug) <a href="https://twitter.com/lightjug/status/1341435674101051392?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 補足
今回は3つのマテリアルを毎回処理しているため少し思いかもしれません。
フレームカウントのあまりが1の時、2の時…などで3つのマテリアルをずらして処理すれば軽くなると思います。
(その方がコードもすっきりすると思います。)


# 終わりに 
いかがでしたでしょうか？
カラーの設定はボタンの活性非活性などにも使えて便利なので、ぜひ覚えておきましょう。
次回の内容は未定です。