1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

VFXGraphに複数のパラメータを渡して状態を切り替えるやつ

Last updated at Posted at 2021-08-29

#はじめに
VisualEffectGraph12から別の方法(GraphicsBufferを用いる)でもできるようです。
そちらを調べる前に一旦今自分の知っているやり方を整理する目的で書いてます。
#参考文献
https://edom18.hateblo.jp/entry/2021/01/08/081203

#動画

#グラフの中身

image.png

image.png

#軽く解説
上記画像の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的にエフェクトの状態を切り替えるやり方はちょっと悩みました。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?