Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Wind that affects rigidbodies and particles

Discussion in 'Physics' started by jefferytitan, Jun 4, 2015.

  1. jefferytitan

    jefferytitan

    Joined:
    Jul 19, 2012
    Posts:
    84
    Hi all,

    I want to make a wind effect that affects a selection of rigidbodies (e.g. making hanging lights sway) and also particle effects. From what I've seen the built-in Wind Zones are mainly targeted at terrain and can be made to work with particles. I don't think they can affect rigidbodies.

    Is there an approach that will work for both? Possibly some scripting would be involved. Can you get information out of a Wind Zone, e.g. what forces it would be exerting on a specific point or object, or just create something from scratch?

    Thanks,
    JT
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    974
    This script has a rigidbody follow a particle that is being affected by wind.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [RequireComponent(typeof(ParticleSystem))]
    4. public class RigidbodyParticleWind : MonoBehaviour
    5. {
    6.     public Transform obj;
    7.     ParticleSystem particlesSystem;
    8.     ParticleSystem.Particle[] particles;
    9.     Rigidbody myRigidbody;
    10.  
    11.     void Start()
    12.     {
    13.         particlesSystem = gameObject.GetComponent<ParticleSystem>();
    14.         particles = new ParticleSystem.Particle[1];
    15.         SetupParticleSystem();
    16.         myRigidbody = gameObject.GetComponent<Rigidbody>();
    17.     }
    18.  
    19.     void FixedUpdate()
    20.     {
    21.         particlesSystem.GetParticles(particles);
    22.  
    23.         myRigidbody.velocity += particles[0].velocity;
    24.         particles[0].position = myRigidbody.position;
    25.         particles[0].velocity = Vector3.zero;
    26.  
    27.         particlesSystem.SetParticles(particles, 1);
    28.     }
    29.  
    30.     void SetupParticleSystem()
    31.     {
    32.         particlesSystem.startLifetime = Mathf.Infinity;
    33.         particlesSystem.startSpeed = 0;
    34.         particlesSystem.simulationSpace = ParticleSystemSimulationSpace.World;
    35.         particlesSystem.maxParticles = 1;
    36.         particlesSystem.emissionRate = 1;
    37.         //cant set the following with code so you need to do it manually
    38.         //1 - Enable "External Forces"
    39.         //2 - Disable "Renderer"
    40.  
    41.         //the below is to start the particle at the center
    42.         particlesSystem.Emit(1);
    43.         particlesSystem.GetParticles(particles);
    44.         particles[0].position = Vector3.zero;
    45.         particlesSystem.SetParticles(particles, 1);
    46.     }
    47. }

    Add that script to your rigidbody object.
    Due to some variables not being accessible through scripting, on the particle system you will have to manually
    1 - Enable "External Forces"
    2 - Disable "Renderer"

    Then you can just use a windzone and the rigidbody now acts as if it was a particle.
     
    Last edited: Jun 5, 2015
  3. jefferytitan

    jefferytitan

    Joined:
    Jul 19, 2012
    Posts:
    84
    Wow, unexpected but awesome answer! I assume that you enable collisions on the particle because you're using MovePosition on the RigidBody? Perhaps it would make sense to instead apply a force to the RigidBody based on the offset of the particle?

     
  4. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    974
    I tried that, but there was an issue.
    If you do something like
    Code (CSharp):
    1.         myRigidbody.velocity += particles[0].velocity;
    2.         particles[0].position = Vector3.zero;
    3.         particles[0].velocity = Vector3.zero;
    or even if you remove the position part, the rigidbody just goes back and forth. However, If I put this script on an object separate from the rigidbody we are moving, and instead of myRigidbody its obj.rigidbody, then it all seems to work. Maybe the velocity of the particle is relative to its emitter and some positional information is causing issues.

    However, looking into it more, I think I found a fix.
    By changing particles[0].position = myRigidbody.position; and setting the particlesSystem.simulationSpace = ParticleSystemSimulationSpace.World;

    I will update the script in my original post.
     
    Last edited: Jun 5, 2015
    jefferytitan likes this.
  5. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    848
    If you wanted a more interesting solution you could look at MegaFlow, it allows you to author flows either directly in Unity or use fluid dynamics software such as FumeFX or Maya fluids to build really complex flows, I use it in my game to model wind flow through and around buildings in my levels so when the wind blows litter, leaves etc flow down the streets etc and the added bonus is you can have objects interact with any particles or rigid bodies being controlled so has my vehicle drives down the street the litter is picked up and blown along correctly with the car. You can see the system in action in the two videos below.