- Home /
Scale Shuriken Particle System with Parent Transform
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?
Answer by MakinStuffLookGood · Jan 21, 2014 at 02:17 AM
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.
Thanks for the reply! I figured there were more options than that, but both of those seem to be unavailable in the limited interface http://docs.unity3d.com/Documentation/ScriptReference/ParticleSystem.html
Answer by FM-Productions · May 01, 2017 at 09:02 AM
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.
https://docs.unity3d.com/ScriptReference/ParticleSystemScalingMode.html
@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.
@Gf$$anonymous$$ No one cares about the scale of the particle. What matters now is the scale of the parent when you set the scale mode to "Hierarchy".
Answer by varfare · Jun 27, 2014 at 08:32 PM
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.
Answer by DigitalBeach · Apr 03, 2015 at 09:11 PM
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;
}
}
}
}
Answer by Metall_East · Nov 20, 2019 at 10:43 AM
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;
}
}
}