#はじめに
VisualEffectGraph12から別の方法(GraphicsBufferを用いる)でもできるようです。
そちらを調べる前に一旦今自分の知っているやり方を整理する目的で書いてます。
#参考文献
https://edom18.hateblo.jp/entry/2021/01/08/081203
#動画
#グラフの中身
#軽く解説
上記画像の2枚目が重要です。
スクリプトからStateMapというテクスチャをこのVFXGraphに渡して、そこからパラメータを取り出すということをやっています。
今回の例ではパラメータは1コしか与えていませんが(タイトル詐欺)、1枚のテクスチャにつき4つのパラメータまで渡すことが出来ます。もっと多くのパラメータを与えたい場合はテクスチャの数を増やしていけばよいです(StateMap2とか)。
今回はStateという要素数9のintの値を取り出して、それにより色とサイズを変化させています。
テクスチャを渡す部分も一応コードを載せておきます。(ほとんど参考文献と同じですが...)
↓vfx側のスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
public class MagicOrb : MonoBehaviour
{
VisualEffect vfx;
//Orbの状態を表す
//0:緑色 1:赤色 2:青色
int[] orbState = new int[9];
public int[] OrbState
{
get { return orbState; }
set { orbState = value; }
}
private void Start()
{
vfx = GetComponent<VisualEffect>();
}
Color State2Color(int state)
{
return new Color(state, 0, 0);
}
Texture2D State2Map()
{
float r = Mathf.Sqrt(9);
int size = (int)Mathf.Ceil(r);
var tex = new Texture2D(size, size, TextureFormat.RGBAFloat, false);
tex.filterMode = FilterMode.Point;
tex.wrapMode = TextureWrapMode.Clamp;
Color[] StateColor = new Color[size * size];
for (int i = 0; i < 9; i++)
{
StateColor[i] = State2Color(orbState[i]);
}
tex.SetPixels(StateColor);
tex.Apply();
tex.name = "StateMap";
return tex;
}
public void SetMap2VFX()
{
vfx.SetTexture("StateMap", State2Map());
}
}
↓キューブ側(VRコンテンツの手のイメージ)のスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
public class OrbInteractor : MonoBehaviour
{
[SerializeField] bool left = false;
[SerializeField] MagicOrb magicOrb;
bool change = false;
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Orb"))
{
//object名の数字部分を切り出す
string name = other.gameObject.name;
int num = int.Parse(name.Substring(4));
change = false;
if (left && magicOrb.OrbState[num] != 2)
{
magicOrb.OrbState[num] = 2;
change = true;
}
else if (!left&&magicOrb.OrbState[num] != 1)
{
magicOrb.OrbState[num] = 1;
change = true;
}
if (change)
{
magicOrb.SetMap2VFX();
}
}
}
}
ちょっと補足すると、スフィアのエフェクトのある部分にRoot0,Root1...みたいな空のオブジェクトがあり、それらがコライダーをもっています。Root0とかのオブジェクトはエフェクトの初期位置を与えるのにも使用しています。(VFX Property BinderのMultiple Position Binder)
#終わりに
パラメータをテクスチャを介して渡す部分は参考文献が素晴らしかったので特に迷うことは無かったのですが、
グラフの方でpositionとして直接利用するのではなく、enum的にエフェクトの状態を切り替えるやり方はちょっと悩みました。