When I instantiate a prefab containing a particle system, I can set its localScale to be 1,1,1, relative to its parent.
However the particle system appears to ignore localScale. Is there a way to fix this?
When I instantiate a prefab containing a particle system, I can set its localScale to be 1,1,1, relative to its parent.
However the particle system appears to ignore localScale. Is there a way to fix this?
I know this is an old question, but I stumbled upon it while searching for an answer to the same question.
In newer versions of Unity, it is possible to set the “Scaling Mode” of the Particle System directly in the Editor. If the Scaling Mode is set to “Hierarchy” the Particle System and the emitted Particles will also scale if the parent scales and if the Mode is set to “Local”, the Particle System should only scale if the GameObject that the system is attached to is scaled.
I don’t believe you can scale the particle system just by changing the scale of the transform. You could try programatically changing the size of particles being emitted and their speed based on the local scale.
_
Updating this answer for newer versions of Unity: this is now totally possible. It’s exposed as “Scaling Mode” on the main module, and accessible via code, see ParticleSystem.MainModule.scalingMode.
As far as I know that is not possible to do from code. Unity does not give you access to emitter size which is a key to scale the particle system (don’t ask me why, they simply don’t provide such thing). I am working on a project where I had to scale up two times every single game asset. What I ended up doing is scaling particle systems by hand. For example: if I had to scale up particle system twice I was manually inserting values multiplied by two. The values you need to multiply are (if they are used):
-emitter size
-speed
-size
-velocity over lifetime
-force over lifetime
-limit velocity over lifetime
-color/rotation by speed
-particle speed scale if “stretched” is enabled
As bad as it sounds there is no easy way to scale particle system. I have seen two tools aviable on asset store which do that but they don’t work at runtime.
This may not help you but it worked for us. Since all the particle settings are instanciated then if you change them they stay changed, we save off a list of all the settings we care about at awake time, then when we change the parent scale, we call an UpdateScale function to set the parameters we cared about. That was startSize,lengthScale, and velocityScale.
Here is code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
// Handles dynamically scaling of particles attached to objects.
// Goes through all the sub particle systems storing off initial values.
// Function to call when you update the scale.
public class ScaleParticles : MonoBehaviour {
private List<float> initialSizes = new List<float>();
void Awake() {
// Save off all the initial scale values at start.
ParticleSystem[] particles = gameObject.GetComponentsInChildren<ParticleSystem>();
foreach (ParticleSystem particle in particles) {
initialSizes.Add(particle.startSize);
ParticleSystemRenderer renderer = particle.GetComponent<ParticleSystemRenderer>();
if (renderer) {
initialSizes.Add(renderer.lengthScale);
initialSizes.Add(renderer.velocityScale);
}
}
}
public void UpdateScale() {
// Scale all the particle components based on parent.
int arrayIndex = 0;
ParticleSystem[] particles = gameObject.GetComponentsInChildren<ParticleSystem>();
foreach (ParticleSystem particle in particles) {
particle.startSize = initialSizes[arrayIndex++] * gameObject.transform.localScale.magnitude;
ParticleSystemRenderer renderer = particle.GetComponent<ParticleSystemRenderer>();
if (renderer) {
renderer.lengthScale = initialSizes[arrayIndex++] *
gameObject.transform.localScale.magnitude;
renderer.velocityScale = initialSizes[arrayIndex++] *
gameObject.transform.localScale.magnitude;
}
}
}
}
@Eicher That may well be implied by the documentation, but either it doesn’t work, or we both don’t understand it because your solution just doesn’t work. The scale of child particle systems remains unchanged.
I resolve this problem by attaching this script to parent object (which contains deep childs with particles and Hierarchy Scaling Mode have no effect):
using System.Collections.Generic;
using UnityEngine;
public class ChildParticlesScaler : MonoBehaviour
{
float scale;
List<ParticleSystem> particles = new List<ParticleSystem>();
void Start()
{
scale = transform.localScale.x;
particles.AddRange(GameObject.FindObjectsOfType<ParticleSystem>());
foreach (ParticleSystem ps in particles)
ps.transform.localScale *= scale;
}
void Update()
{
if (transform.hasChanged)
{
float curScale = transform.localScale.x;
foreach (ParticleSystem ps in particles)
ps.transform.localScale *= curScale / scale;
scale = curScale;
transform.hasChanged = false;
}
}
}