Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question [Solved] VFX called from script not visible in game /in the scene

Discussion in 'Visual Effect Graph' started by Aziz-, Nov 20, 2021.

  1. Aziz-


    Feb 11, 2019
    My goal is this: When I click anywhere in the scene with my mouse, I want a Visual Effect I made to appear at the point where I clicked.

    The problem is that with the way I have tried to make this work the visual effect doesn't appear. I don't get any errors in the console either. The VFX works by itself though. When I just place it in the scene it works fine. It just doesn't work when I try to call it from a script and try to set its position before playing it.

    This is how I set it up:


    I exposed a Vector3 property which I later access in a script to set its position. I made the visual effect asset into a prefab:


    Which I then store in the following class:

    Code (CSharp):
    1. [CreateAssetMenu(fileName = "newSpell", menuName = "Data/Magic/Spell")]
    2. public class Spell : ScriptableObject
    3. {
    4.     public string Name;
    5.     public Sprite SpellIndicator;
    6.     public int Damage;
    7.     public VisualEffect Vfx;
    9. }
    Which I then access in another script:

    Code (CSharp):
    1. public class SpellCaster : MonoBehaviour
    2. {
    3.     public Spell PrimarySpell;
    5.     public Spell SecondarySpell;
    8.     public void CastPrimarySpell(Vector3 spellLocation)
    9.     {
    10.         var vfx = PrimarySpell.Vfx.GetComponent<VisualEffect>();
    11.         vfx.SetVector3(Shader.PropertyToID("TargetPosition"), spellLocation);
    12.         vfx.Play();
    13.     }
    14. }

    The Vector3 spellLocation is provided by another class which listens for where I click in the scene and passes that point into this method when calling it. Passing the click location works fine though, it corresponds with where I actually clicked. I just don't understand why the VFX isn't visible. I wonder if that's because I'm storing the visual effect asset in a prefab? Anyway, any help is appreciated. Let me know if I left out anything important and I'll update the thread.

    Attached Files:

  2. Aziz-


    Feb 11, 2019
    This is how the visual effect gets assigned to a spell object:

  3. Qriva


    Jun 30, 2019
    TargetPosition is not position of particle, it is helper attribute and what you want is "Set Position". I do not know exact structure of your system, but yes I don't think you can spawn particles from prefab - it must be instanced on the scene.
    Also you don't need (but you can have) property in your graph in this case, you can send position via event attribute:
    Code (CSharp):
    1. // Set position in attribute before sending event
    2. eventAttribute.SetVector3("position", spellLocation);
    3. visualEffect.SendEvent("OnPlay", eventAttribute);
    There is exmaple in event section on the bottom.

    Bonus tip: have in mind that bounds of your effect must be inside of camera frustum or your particles will not be rendered, so if you make small bounds and create vfx in (0,0,0) and trigger particles somewhere around (50,50,50) then they will not be rendered if camera can't see (0,0,0).
  4. Aziz-


    Feb 11, 2019
    Thanks for taking the time. I swapped the target position block in the vfx graph for the set position block like you pointed out. However, I got it working without touching the eventattribute stuff. The problem was a very silly one actually. The prefabs aren't alive in the scene so I had to instantiate it first:

    Code (CSharp):
    1. public void CastPrimarySpell(Vector3 spellLocation)
    2.     {
    3.         Instantiate(PrimarySpell.Vfx, spellLocation, Quaternion.identity);
    4.         var vfx = PrimarySpell.Vfx.GetComponent<VisualEffect>();
    5.         vfx.SetVector3(Shader.PropertyToID("TargetPosition"), spellLocation);
    6.         vfx.Play();
    7.     }
    After adding the instantiate method it is working as intended. I don't know how I missed that haha. Thanks for the help. I'm going to mark this as solved.