【Unity】【LWRP】 Point Light 2Dでゆらゆらさせたかっただけなのに
久しぶりのUnityです
お久しぶりです。ぐーるです。
のーらいふです。
最近Unity 2019.3.0f3まで上げて使ってて見た目が随分変わっててびっくりしました。
アイコンとか慣れないです。
LWRPで2D Lightを使ってみたいと思い、触ってみました。
そしてTwitterに投稿しました。
久しぶりのUnity投稿です。
— ぐーる👾のーらいふ (@uuha_goul) 2020年1月17日
Unity2019.3.0f3でLWRPで2D Lightを使ってみた。
それだけだとつまんないのでTilemapと組み合わせて
洞窟探索するようなイメージでゲームっぽくしてみました。
Lightが重なってる所だとキャラクターの光具合が
強くなるのがわかりますかね?#unity #gamedev #LWRP pic.twitter.com/qG5zK0PIy7
そこで一点気になった事があったので記事にしてみます。
LWRPを設定する
LWRPを設定するとSpriteがLightの影響を受けるようになるらしい。
おおこれはやってみたい!ということで先人の知恵をお借りします。
(いつもお世話になっています。)
自分でも軽く設定の仕方だけ書いておきます。
1. 新規プロジェクトを作成する
Unityは2019.3.0f3を使用。(2019.2.18f1でも確認はしました)
2. PackageManagerでLWRPをインストールする
上部メニュー Window > Package Managerで PackageManagerを開く
Lightweight RPをインストールする
(ここではv7.1.7)
3. 必要なAssetを作成する
ProjectのCreateからPipeline Asset , 2D Rendererを作成する
ProjectのCreate > Rendering > Universal Render Pipeline > Pipeline Asset(Forward Renderer) ProjectのCreate > Rendering > Universal Render Pipeline > 2D Renderer(Experimental)
を作成します。
この時
「UniversalRenderPipelineAsset」
「UniversalRenderPipelineAsset_Renderer」
「New 2D Renderer Data」
の三つのファイルが作られます。
4. LWRP Setting
UniversalRenderPipelineのGeneral > RenderList
に2D Renderer(Experimental)で作成したNew RenderDataをセット。
(特にパラメータをいじる必要はありません。)
そして
上部メニューEdit > Project Settings で Project Settingsを開き
GraphicsのScriptable Render Pipeline Settingsに
「UniversalRenderPipelineAsset」ファイルをセットすればOKです。
5. 2D Lightに対応したSpriteを確認する
その後
適当にSpriteRendererを作成すると、
Materialが「Sprite-Lit-Default」になっており、真っ暗になります。
GameObject > Light > 2D > Point 2D Light(Experimental)
などで2D Lightを作成すると、Lightの影響を受ける2Dスプライトが確認出来ます。
(上がSceneです)
2D Lightをゆらゆらさせたい!
ここからが本題。
こういうの作ったら、揺らめく炎を作りたくなるもの。
Point Light 2D
Inspectorでパラメータいじってみると以下のような関係がわかる
・Outer Radius : 光の大きさ
・intensity : 光の強さ
・falloff Intensity : 境界線の強さ
なるほど、falloff Intensityをいじるといい感じに揺らめくな、
じゃあこれをスクリプトで触ればいいや
(getterしかない。なんで?)
で、触ってみるとこれ、アクセサーがgetしかない。
なんでええええ?何か別の値から計算して求めているのかな?
詳しいことまではわかりませんでしたが、とにかく揺らめかしたいので、リフレクションで触ることにしました。
美味しいとこだけ抜き出し
// Light2Dに値をセットするが、リフレクションでprivateフィールドにアクセスする…(なんでset無いんだ?) private void SetFalloffIntensity(Light2D light2D , float value) { System.Type light2DType = light2D.GetType(); // "m_FalloffIntensity"は sourceコードから拾ってきた // https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.universal/Runtime/2D/Light2D.cs#L146 // privateだからBindingFlags System.Reflection.FieldInfo falloutIntensity = light2DType.GetField("m_FalloffIntensity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); falloutIntensity.SetValue(light2D, value); }
ソースコード全体としてはこんな感じ。
UnityEngine.Experimental.Rendering.LWRPではなく、UnityEngine.Experimental.Rendering.Universalになります。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Experimental.Rendering.Universal; public class LightModule : MonoBehaviour { // Light2D Object [SerializeField] private Light2D _light2D; [Header("暗くなる度合い")] [SerializeField] private float _maxIntensity = 0.8f; [Header("明るくなる度合い")] [SerializeField] private float _minIntensity = 0.3f; [Header("明暗変化速度")] [SerializeField] private float _addIntensity = 0.001f; private float _intensity = 0; private bool _isForward = true; // Start is called before the first frame update void Start() { _intensity = _minIntensity; _isForward = true; } // Update is called once per frame void Update() { if (_isForward) { _intensity += _addIntensity; if(_intensity > _maxIntensity) { _intensity = _maxIntensity; _isForward = false; } } else { _intensity -= _addIntensity; if (_intensity < _minIntensity) { _intensity = _minIntensity; _isForward = true; } } SetFalloffIntensity(_light2D , _intensity); } // Light2Dに値をセットするが、リフレクションでprivateフィールドにアクセスする…(なんでset無いんだ?) private void SetFalloffIntensity(Light2D light2D , float value) { System.Type light2DType = light2D.GetType(); // "m_FalloffIntensity"は sourceコードから拾ってきた // https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.universal/Runtime/2D/Light2D.cs#L146 // privateだからBindingFlags System.Reflection.FieldInfo falloutIntensity = light2DType.GetField("m_FalloffIntensity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); falloutIntensity.SetValue(light2D, value); } }
これで揺らめく炎を2D Lightでも実現できました。
久しぶりにUnityやったなぁ~、やっぱ2D RPG風なのいいですね。