Search Unity

Resolved Unable to set Particle System's start frame via script

Discussion in 'Scripting' started by noam_2000, Oct 5, 2020.

  1. noam_2000

    noam_2000

    Joined:
    Sep 14, 2017
    Posts:
    18
    Hey everyone,
    I've come across an issue that stumped me and I'm unable to even get a clue of what might be wrong.

    I have a Particle System with Texture Sheet Animation enabled, set up this way:


    The speed range is set to 0, as I do not want the sheet to animate. Instead, I want to be able to pick an index and set it in Start Frame to get the desired sprite, and when setting it manually through the inspector, it works perfectly.

    However, whenever I try to set it using a C# script, if the value isn't 0, it always puts "7.9992" in the Start Frame.

    The code is as simple as this:

    Code (CSharp):
    1. public void SetEmoteIndex(int index)
    2. {
    3.    var ts = ps.textureSheetAnimation;
    4.    ts.startFrame = index;
    5. }
    I've done some debugging, I've tried doing this a million other ways and even tried just straight up replacing "index" with a float number, but the results are all the same. 0 is the only value I can input that this doesn't happen on.

    I'm using Unity 2019.3.0f6.

    Is this a bug, or am I missing something here? Thank you for your time!
     
    Last edited: Oct 5, 2020
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,105
    Can you give some more context? Show us the texture for example. How did you set it up?
    Also you don't seem to have set up textureSheetAnimation in code. Have you seen the example?
    You're likely supposed to set everything through that property.
    I can't really tell before trying it on my own, but I am pretty sure it's not a bug.
     
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,105
  4. noam_2000

    noam_2000

    Joined:
    Sep 14, 2017
    Posts:
    18
    Hey Orion,

    Everything should be set up properly. In case it wasn't obvious, "ps" in my code is a reference to a Particle System.
    I'm not sure what you mean by not having textureSheetAnimation set up, as it is an interface, and according to the example my code should be perfectly fine.

    And yes, although they implicitly cast the value, I tried using ParticleSystem.MinMaxCurve as well, but I've only gotten the same results.

    I think that's about as much context as I can give. I've reproduced this on an entirely clean GameObject with only a ParticleSystem (with texture sheet animation enabled and set up like in the screenshot above) and the following script:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class particleStartFrame : MonoBehaviour
    4. {
    5.     public ParticleSystem ps;
    6.     private int frameCycle = 0;
    7.  
    8.     private void Update()
    9.     {
    10.         if (Input.GetKeyDown(KeyCode.N))
    11.         {
    12.             frameCycle += 1;
    13.             var ts = ps.textureSheetAnimation;
    14.             ts.startFrame = frameCycle;
    15.         }
    16.     }
    17. }
    From what I can gather, the value assigned to startFrame is dependent on the "Tiles" setting in the texture sheet animation, so if say, you have 4x4, it would return "15.9992", or if you have 4x2, it would return "7.9992".

    So I think unless anyone manages to solve this mystery, I'm gonna assume it's a bug, at least in my version of Unity. :)
     
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,105
    ok, honestly, I would have to try this for myself. can't really tell if it's your fault somehow, but I still have a strong hunch it's not a bug either. I don't think they've changed the particle system in the recent versions, and this would likely get caught when they introduced it.

    I really think it's just a configuration issue, there is some relationship between the values, and you maybe skipped some part that is messing with the result.

    I'm not sure if you got what I said, but I think you should inject all of your parameters through code.
     
  6. noam_2000

    noam_2000

    Joined:
    Sep 14, 2017
    Posts:
    18
    Finally managed to figure it out. I really need to remind myself to use the debug inspector more often..

    "startFrame" is actually a scalar that remaps input from 0 to 1, the inspector and the example led me to believe you can just simply input the integer index of the desired start frame, which is not quite accurate.

    For anyone else who might be struggling, here's my example code:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class particleStartFrame : MonoBehaviour
    4. {
    5.     public ParticleSystem ps;
    6.     private ParticleSystem.TextureSheetAnimationModule ts;
    7.  
    8.     private float maxSheetValue;
    9.     private float stepValue;
    10.     private float startFrame = 0;
    11.  
    12.     private void Start()
    13.     {
    14.         ts = ps.textureSheetAnimation;
    15.         maxSheetValue = ts.numTilesX * ts.numTilesY;
    16.         stepValue = 1f / maxSheetValue;
    17.     }
    18.  
    19.     private void Update()
    20.     {
    21.         //cycle through the frames
    22.         if (Input.GetKeyDown(KeyCode.G))
    23.         {
    24.             startFrame += stepValue;
    25.  
    26.             if (startFrame > (1 - stepValue))
    27.                 startFrame = 0;
    28.  
    29.             ts.startFrame = startFrame;
    30.         }
    31.     }
    32. }