Search Unity

What on Earth is going on with Particle Modules

Discussion in 'Editor & General Support' started by JamesArndt, Mar 29, 2017.

  1. JamesArndt

    JamesArndt

    Joined:
    Dec 1, 2009
    Posts:
    2,932
    I am literally copy-pasting every single code sample I can get from Unity's blog and documentation. I get console log errors for every single code snippet. https://blogs.unity3d.com/2016/04/20/particle-system-modules-faq/
    It's the same error over and over:
    "do not create your own module instances get them from a particle system instance"

    I even found official documentation for Unity 5.5, created by Unity called "Exhaust Smoke from a Vehicle"
    https://docs.unity3d.com/Manual/PartSysExhaust.html

    Yep you guessed it, same error:
    "do not create your own module instances get them from a particle system instance"

    What on god's good earth is going on here? I am referencing the particle system instance I set up as a variable.

    I really just want to set the amount of particles coming out of the exhaust of a go-kart depending on engine revs. Should it be this difficult to do something so simple? I mean that's what Unity USED to be all about...making difficult things easier and more simple. Hiding the highly technical stuff behind the scenes so I can just make stuff. I hope someone can chime in with a proven code snippet that will not error when I attempt to hit the "play" button.
     
  2. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    Step 1. In the heirarchy, Create -> Particle System in your scene.
    Step 2. In the Inspector, Add Component -> New Script on your new particle system.
    Step 3. Edit Script and add the example code.

    Do you still get the errors? I don't.
     
    JamesArndt likes this.
  3. JamesArndt

    JamesArndt

    Joined:
    Dec 1, 2009
    Posts:
    2,932
    Okay now I'm even more weirded out because, yes that worked. When I pasted this exact snippet into my own existing script it constantly had errors. Now that it's a standalone script by itself it works.

    EDIT - Okay I think I tracked down why. Using the method you suggest here I applied the script directly to the particle system. However yesterday I was assigning the script to the root player object and dragging the particle system into a variable slot on that script. That method still appears to throw this error. So anyone know why the script would only work if directly applied to the particle system itself?
     
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,566
    Unity particle modules violate principle of least astonishment. Basically, you do not create new modules yourself using "new". You grab a module from particle system, and THEN access their fields.

    The reason why it violates principle of least astonishment is because particle system modules are value types. So you'd expect them to be assignable, but nope. They're value type handles to internal components of particle system.

    Basically... you should use
    Code (csharp):
    1.  
    2. var someModule = particleSystem.someModule;
    3. someModule.field = newValue;/* <--- This will adjust internal settings of particle system from which the module was received.*/
    4.  
    And not
    Code (csharp):
    1.  
    2. var someModule = new SomeModule;
    3. someModule.field = newValue;
    4. particleSystem.someModule = someModule;//<---don't do that
    5.  
    -----

    If this doesn't address your problem, you'll need to post code sample that triggers the error.
     
    Martin_H likes this.
  5. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    That's not normally what Unity expects you to be doing. You don't have a script and an object sitting next to one another. You attach the script to the object it works on. Most of the samples you'll find expect you to be doing this as a normal operation, so they don't say outright to do it.

    This is a typical case of everybody working a specific way with the tool, so they forget there are other ways to do it.
     
    JamesArndt likes this.
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    The blog post you linked to should help to explain why you are getting that error. You dont need to re-assign the struct when you change its values. Yes we know this is unintuitive and we are working on improving this. We hope to change over to using classes in the future and potentially(although its still needs prototyping so no gurantee at this stage) allow for sharing modules.
     
    JamesArndt likes this.
  7. JamesArndt

    JamesArndt

    Joined:
    Dec 1, 2009
    Posts:
    2,932
    Yeah I normally work with managers, that have slots for references to groups of things that are related. Very rarely do I actually assign scripts to all of the actual little objects in a given scene. Really I work this way for my own sanity and to keep things organized in a fashion that suits my own brain :)
     
    GarBenjamin likes this.
  8. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    I think a large part of the issue is that a lot of Unity behaviour is never meaningfully documented.

    I have a Panel object that I want to enable and disable. I write a function called "TogglePanel" which calls SetActive(!ActiveSelf) and it doesn't work. So I go oh, okay, and I change it to declare a GameObject go = GetComponent<GameObject>(). But I get an error that there is no GameObject attached to a Panel. However, I can declare a public GameObject go and drag the panel into it in the editor. Then it's a GameObject and I can call go.SetActive(). Similarly, I can change my method to TogglePanel(GameObject go) and drag the Panel into it as the parameter.

    My problem is solved, for all practical purposes, but I don't understand why. The editor can find the GameObject on a Panel, but I can't. If I can drag a Panel into a GameObject variable, why can I neither call GameObject methods on it directly, nor GetComponent<GameObject> to access them? If this is not a GameObject and does not have one attached, where does the GameObject the editor gives me come from?

    It is not easy to find the answer to that.
     
    GarBenjamin likes this.
  9. JamesArndt

    JamesArndt

    Joined:
    Dec 1, 2009
    Posts:
    2,932
    My problem is I'm a non-technical person, coming from an art background. A lot of this stuff has to be broken down Barney style for me. I can handle technical stuff of course, but some stuff is just too deep for me. I think of things in terms of problems I need to solve in the simplest way possible. I need to change the amount of particles coming out of an exhaust based on vehicle RPMs. I have everything set up the way I normally access things, etc but for some reason accessing the particles is not behaving in the normal way other data is accessed in Unity. Almost everything I can drag and drop onto a script and do things to it. This turned out to not be that simple.

    For example that blog post doesn't help me understand why my normal method of declaring a public variable for a ParticleSystem, dragging that ParticleSystem onto the variable slot, and then accessing and setting properties on that Particle System is not working like other stuff does. I don't need fancy animation curves, etc...I just need to set emission by a single float value.

    PS - I realize that I am spoiled by Unity and have been for a while. Game development is a highly technical process and I understand that. Unity hides a lot under the hood so I don't have to worry about it.

    Could we simply have a dedicated particle editor window like the Animator has and just set properties in that window and have scripts set values to those properties?
     
  10. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    I think what gets lost a lot of the time is that this isn't actually the problem. It's that the process hasn't been clearly explained even if you are coming from a technical background, and the nontechnical people are thinking it's because they're not technical... but that doesn't actually matter.

    I have a certain sense that far too many technical people are quietly covering up the fact that they don't understand it, either, but their technical background has allowed them to sneak behind not understanding it and get the job done anyway.
     
    JamesArndt and Martin_H like this.
  11. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    That should work. https://docs.unity3d.com/ScriptReference/GameObject.SetActive.html
    Code (CSharp):
    1. public class ExampleClass : MonoBehaviour {
    2.     void Example() {
    3.         gameObject.SetActive(false);
    4.     }
    5. }
    GameObject is not a component so calling GetComponent wont work, it is however accessible from all scripts by calling the gameObject property. https://docs.unity3d.com/ScriptReference/Component-gameObject.html
     
    angrypenguin likes this.
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    What do you mean? We do have a dedicated particle window.
    upload_2017-3-30_17-40-32.png
    Click `Open Editor` although I'm not sure this is what you want?
    You can access all the values in here and you can also animate them if you want.

    To do what you need should be something like this:
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class TestProgress : MonoBehaviour
    5. {
    6.     public ParticleSystem particleSystem;
    7.     ParticleSystem.EmissionModule emissionModule;
    8.  
    9.     void Start()
    10.     {
    11.         // Grab the emission module
    12.         emissionModule = particleSystem.emission;
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         float rpm = 100;  // TODO: Calculate the RPM here!
    18.         emissionModule.rateOverTime = rpm;
    19.     }
    20. }
    The scripting docs have examples to help if you are unsure:
    https://docs.unity3d.com/ScriptReference/ParticleSystem.EmissionModule-rateOverTime.html

    Also take a look at the learn section or the example assets we provide.
     
    Hoorza and JamesArndt like this.
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    Indeed... The error message @cdarklock described may be technically correct, but it's still misleading and the situation can be easily improved. In that particular case I'd expect generic type constraints to stop me from requesting invalid types to begin with, rather than letting them through and hoping a runtime error will clear things up later.
     
  14. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    Well, see, when you say "gameObject.SetActive(false)" there... I don't know what "gameObject" is. It could be a member you "obviously" declared previously in the script, which you don't mention because we should totally know that.

    Example scripts frequently do this, just as @JamesArndt found when the example script never told him to attach it to the particle system. Of course you attach it to the particle system; everybody knows that. What else would you do?

    And yet, when you call GetComponent<GameObject>, you do not get a message to that effect. The message you get is that there isn't one attached, which kind of implies that one could be attached.

    There could easily be a special case in GetComponent that detects this, and either (a) gives a better error message, or (b) just returns the gameObject that every script necessarily has. Either way, someone is going to complain that you didn't just hand him the GameObject you totally knew he wanted, or that you have inappropriately treated a class property as a component when it is totally not. But mostly, a lot of frustrated people will be less frustrated.

    A fact which may be determined by reading the documentation for MonoBehaviour's parent object, Behaviour, which I was apparently expected to do at some point. I've been through a rather large number of Learn tutorials on the site, and I have never seen this mentioned, even though it seems to be rather basic.

    "I can't find the right way to do this" is not something that can be solved by telling everyone who says this out loud how to do it. The problem isn't the not knowing, but the inability to find. I needed to know the answer to find the place where the question could be productively asked, because once I knew what it was, I could look everywhere it might conceivably be until it was found. But until then, I had to look literally everywhere.

    Similarly, there is an inherent assumption through a lot of tutorials that everyone has a "game manager" scene, but it's not something I've ever seen taught. They just say something like "normally this would go in your game manager." It's like the tutorial inherently admits "I'm doing this wrong, but surely you already know how to do it right and you'll fix it."

    Shouldn't we have a "how to do it right" tutorial somewhere? That seems like a Good Idea. We have a rather large set of common practices that people talk about only in vague, general terms without ever actually explaining anything.
     
  15. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    It's also listed under "Inherited members" section in the MonoBehaviour page itself.
     
  16. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    Well, I'll be. The 76th item in that list of 103 items is, indeed, the inherited gameObject member. How could I have missed it?
     
    JamesArndt likes this.
  17. JamesArndt

    JamesArndt

    Joined:
    Dec 1, 2009
    Posts:
    2,932
    I have been using Unity since 2008 and I've never seen the particle editor. I feel really "non technical" right about now. Of course thats a nice way of saying something else. This thread has been very helpful though.
     
    Martin_H and karl_jones like this.
  18. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    To be fair, I'd expect that programmers working in Unity spend the few minutes required to read that page in its entirety. It's the default base class of all scripts, it's our business to make ourselves familiar with it (and the other commonly used classes).

    That said, while they're some of the better ones I've used, I still agree that there are places where the docs or tutes could be improved. (Trivia: most of my recent bug reports are on the documentation.)
     
  19. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    That's precisely the attitude that I can't stand in the open source / community-supported software world.

    "We never told you to do this, but if you don't do it, all the problems you have are your fault."

    Community-based blame is not something I want in my software.
     
  20. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    I couldn't agree more, so I can't help but say that you shouldn't be engaging in it yourself.

    If that comment was directed at my expectation that programmers read the API docs for things that they use, I wasn't "blaming" you for anything. To the contrary, you did read them - and for the parent class, too! - and just happened to miss something. I was pointing out where it was because that "Inherited members" section often has really important stuff in it, so it's worth keeping an eye out for.


    @karl_jones, I've just skimmed through the Working in Unity -> Creating Gameplay -> GameObjects and Scripting -> Scripting Overview -> Controlling GameObjects sections (and subsections) of the manual. I didn't see anything there clearly explaining that Components all have direct access to the GameObject they're attached to, which is pretty important. While I may have missed something in my skimming, I believe I saw reference to the .transform property appear before any explanation as to what that is (it is explained that every GameObject has a Transform Component, and it is explained how to find Components by type, but I didn't see anything about the .transform property). Also, the GameObject and Transform manual pages have "Switch to Scripting" buttons that bring up the API docs for the relevant class, but I saw nothing similar on the pages that talk about MonoBehaviour. Finally, I'd suggest splitting the "Creating and Using Scripts" section into two pages - one about creating them and attaching them to GameObjects, and another one about MonoBehaviour itself (which is where that "Switch to Scripting" button would then go).
     
  21. cdarklock

    cdarklock

    Joined:
    Jan 3, 2016
    Posts:
    455
    I'm not blaming anyone. I'm saying there is a problem that should be fixed. I don't care who created the problem.

    It was, because your expectation is largely worthless when it comes to Unity. See, look: my Panel is misbehaving. Let me look that up.

    It doesn't take many results like that before I stop relying on the documentation altogether. I also expect programmers to read the documentation, but when the documentation for some objects doesn't exist, how much can I trust the rest of it?

    Even if you're not blaming me, you've laid a groundwork for placing blame. It's not about spending a few minutes reading the page with your answer on it. It's about figuring out which pages might have your answer on them, then spending a few minutes reading each of those pages - without even knowing what your answer looks like. You can easily spend an hour or more looking for an answer you've already seen, because you didn't know that what you just saw was the answer.

    Case in point: Unity told me my Panel did not have a GameObject attached. That implied Behaviour.gameObject was going to be null anyway, so that didn't seem like it would solve my problem. In fact, my understanding of the problem was that the Panel was somehow being detached from its GameObject. Probably by something I was doing in the editor.

    Nothing in that sequence is in any way irrational. You can play perfectly and still lose. Like many similar projects, Unity frequently relies on you to know the magic words. But they are never taught.
     
  22. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,279
    T
    Thanks for the feedback. I'll pass it on to the docs team.
     
    angrypenguin likes this.
  23. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    If you say so...