unity3d Magnetic move particles

Unity3D 2014. 11. 5. 14:50
반응형

http://www.youtube.com/watch?v=VCEe4PgD4ZQ&feature=youtube_gdata_player

 

 

http://answers.unity3d.com/questions/64932/creative-way-to-attract-particles.html

 

 

You have the particle position already, and the script automatically comes with a link to it's own position (via transform). So it's a simply a matter of checking if the particle is in range of the affector object before applying your position change.

 

Sorry if there are any errors, i did not test it, but this should be the general idea...

public ParticleEmitter p; public Particle[] particles; public float affectDistance; float sqrDist; Transform thisTransform;

void Start() { thisTransform = transform; p = (ParticleEmitter)(GameObject.Find("StrangeParticles").GetComponent(typeof(ParticleEmitter))); particles = p.particles; sqrDist = affectDistance*affectDistance; }

void Update() { float dist; for (int i=0; i < particles.GetUpperBound(0)) { dist = Vector3.SqrMagnitude(thisTransform.position - particles[i].position); if (dist < sqrDist) { particles[i].position = Vector3.Lerp(particles[i].position,transform.position,Time.deltaTime / 2.0f); } } p.particles = particles; }

 

 

 

Hello, I'm new to C# and Unity and have visited this page many, many times looking for a way to make a particle attractor script. I took Pyro's advice re the smoothing and implemented a feature to try and remove some hanging particles (which needs improvement) and have been at this for a week! But I learned a lot! Excuse the notorious amount of comments, they were mostly for me as I slowly gained an understanding of what was going on.

Here is the script, instructions at the bottom. UPDATE removed all comments, neater script now, also implemented timer function.

  1. using UnityEngine;
  2. using System.Collections;
  3. public class ParticleAttractTimed : MonoBehaviour
  4. {
  5. public float PullDistance = 200;
  6. public Transform MagnetPoint;
  7. public int TimeUntilPull = 0;
  8. private bool waitCalled = false;
  9. IEnumerator ParticleWait ()
  10. {
  11. waitCalled = true;
  12. yield return new WaitForSeconds(TimeUntilPull);
  13. TimeUntilPull = 0;
  14. Debug.Log("TimeUntilPull set to 0");
  15. }
  16. void ParticlePull ()
  17. {
  18. float sqrPullDistance = PullDistance * PullDistance;
  19. ParticleSystem.Particle[] x = new ParticleSystem.Particle[gameObject.particleSystem.particleCount+1];
  20. int y = particleSystem.GetParticles(x);
  21. for (int i = 0; i < y; i++)
  22. {
  23. Vector3 offset = MagnetPoint.localPosition - x[i].position;
  24. //creates Vector3 variable based on the position of the target MagnetPoint (set by user) and the current particle position
  25. float sqrLen = offset.sqrMagnitude;
  26. //creats float type integer based on the square magnitude of the offset variable set above (faster than .Magnitude)
  27. if (sqrLen <= sqrPullDistance)
  28. {
  29. x[i].position = Vector3.Lerp(x[i].position, MagnetPoint.localPosition, Mathf.SmoothStep(0, 2, (Time.deltaTime / 0.1F)));
  30. /*Lerping moves an object between two vectors (syntax is FromVector, ToVector, Fraction) by a given fraction. In our example
  31. we take the position of particle i, of particle system x, and the local position of the MagnetPoint transform, and move the
  32. particles in from x[i] towards MagnetPoint over time. Lower the Time.deltaTime / # value to increase how fast the particle attracts*/
  33. if ((x[i].position-MagnetPoint.localPosition).magnitude <= 30)
  34. {
  35. x[i].lifetime = 0;
  36. }
  37. }
  38. }
  39. gameObject.particleSystem.SetParticles(x, y);
  40. return;
  41. }
  42. //Use this for initialization
  43. void Start ()
  44. {
  45. Debug.Log("Time until pull equals " + TimeUntilPull);
  46. }
  47. /*Update is called once per frame and is good for simple timers, basing changes off frame rate and recieving input.
  48. Note that if one frame takes longer to process than the next, Update will not be called consistently*/
  49. void Update ()
  50. {
  51. if ((TimeUntilPull > 0) & (waitCalled == false))
  52. {
  53. Debug.Log("Coroutine called");
  54. StartCoroutine(ParticleWait());
  55. }
  56. else if (TimeUntilPull == 0)
  57. ParticlePull();
  58. }
  59. }
  60.  
  1. You will need to create a particle emitter (or other object that can be passed as a transform) to act as a magnet point for your particles if you don't already have one. I tested this script with mine set to a size of 1, no shape, no emission - only Renderer remained checked inside the Unity inspector. This script uses a localPosition call for the MagnetPoint so you may need to make it a child of another emitter, which contains both this transform and the particle system you want to manipulate.
  2. Select the particle emitter you want to manipulate (the one whose particles you want to go somewhere) and attach this script to it (add component, script, this script).
  3. Drag the particle emitter you created in step 1 to the public variable space titled 'Magnet Point'.
  4. Set the pull distance as desired. Keep in mind it will need to be relative to the scale of your particle effect and what you want to achieve - for example - in my effect, the magnet point was at the centre of a bunch of emitted particles and only those particles that were close enough to the magnet point were drawn in (so some float away, and others draw into the centre point).

Enjoy my first unity script!

반응형

'Unity3D' 카테고리의 다른 글

Excel to json converter  (0) 2014.11.25
Return random `list` item by its `weight`  (0) 2014.11.05
Texture size and performance  (0) 2014.10.02
Execution Order of Event Functions  (0) 2014.07.25
TextEncodingConverter  (0) 2014.07.15
: