Get meshes or GameObjects from particleSystem

Hello,

I am making a particleSystem with dropping cards. I want to click on a card and move them to the camera. I have a few questions:

  • How can I get the meshes? In all the examples, there aren’t any examples on how to do this :frowning:
  • If this isn’t possible, how can I get the exact position of a particle in the world?

[35176-screen+shot+2014-11-13+at+3.44.19+pm.png*|35176]

Here’s my code:

void LateUpdate () {

		if(Input.GetMouseButtonDown(0))
	{
			GameObject cam = GameObject.Find("Main Camera");


			Vector3 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);

			getSelectedParticle(position);
			
		}
	}

	Vector3 getSelectedParticle(Vector3 position)
	{
		Vector3 r = Vector3.zero;
		particleSystem.GetParticles (particles);
		GameObject model = GameObject.Find("Plane");

	
		for (int i = 0 ;i < amountParticles ; i++ )
		{
			ParticleSystem.Particle particle = particles*;*
  •  	float dist = Vector3.Distance(position,particle.position);*
    
  •  	Vector3 newPos = new Vector3(particle.position.x, -particle.position.y, particle.position.z);*
    
  •  	Debug.DrawRay(position,particle.position);*
    
  •  	Debug.DrawLine(position,newPos,Color.red);*
    
  •  	if (dist < 20) {* 
    

// particle position is not equal to model position

  •  		model.transform.position = particle.position;*
    
  •  		print (particle.position);*
    

// rotation is quarternion, how to translate this?

  •  		//var rotation = Quaternion.Euler(0, 30, 0);*
    
  •  		//model.transform.rotation = particle.rotation;*
    
  •  		break;*
    
  •  	//	break;*
    
  •  	}*
    
  •  }*
    
  •  return r;*
    
  • }*

This is an example of world to screen translation of the particle positions. No luck yet!
[35180-screen+shot+2014-11-13+at+5.10.14+pm.png|35180]*
*
*

Here is some example code on how it can be done. This code require a specific setup to work, and therefore will need to be tuned for other setups. It works by cycling through the particles and generating a normal to the surface. Using the position, normal, and Unity’s mathematical Plane class, the position of a hit on the infinitie plane is calculated. Then the position of that hit is check against the bounds of the quad to see if the hit is on the particle.

Setup:

For a mesh, it uses a vertical plane of size 1 x 1 anchored at the center create by the [CreatePlane editor script from the Unity Wiki.][1]

The simulation space for the ParticleSystem must be ‘World’.

The following code deletes the particle clicked on:

#pragma strict

 // width and height of the mesh used when scaled to (1,1,1)
 public var baseWidth = 1.0;
 public var baseHeight = 1.0;
 
 private var ps : ParticleSystem;
 private var particles : ParticleSystem.Particle[];
 private var count : int;
 
 function Start() {
     ps = particleSystem;
     particles = new ParticleSystem.Particle[ps.maxParticles];
 }
 
 function Update() {
	if (Input.GetMouseButtonDown(0)) {
		var i = HitTest();
		
		if (i != -1) {
			Debug.Log("Hit particle "+i);
			particles*.lifetime = -1;*
  •  	ps.SetParticles(particles, count);*
    
  •  }*
    
  • }*
    }

// Returns the index of the particle hit or -1 if none are hit
function HitTest() : int {

  • var plane : Plane;*

  • var dist : float = Mathf.Infinity;*

  • var iHit = -1;*

  • var ray = Camera.main.ScreenPointToRay(Input.mousePosition);*

  • count = ps.GetParticles(particles);*

  • for (var i = 0; i < count; i++) {*
    _ var p = particles*;_
    _
    var q = Quaternion.AngleAxis(p.rotation, p.axisOfRotation);_
    _ var v = q * Vector3.back; //<— Use axis as appropriate to mesh_
    _
    plane = new Plane(v, p.position);_
    _
    var distance : float;_
    _
    if (plane.Raycast(ray, distance)) {_
    _
    var point = ray.GetPoint(distance);_
    _
    var d = (Camera.main.transform.position - point).magnitude;_
    _
    if (d < dist) {_
    _
    var vv = point - p.position;_
    _
    // Normalize to local coordinates*_
    _ vv = Quaternion.Inverse(q) * vv;_

_ var width = baseWidth * p.size / 2.0;
var height = baseHeight * p.size / 2.0;_

* if (Mathf.Abs(vv.x) < width && Mathf.Abs(vv.y) < height) {*
* iHit = i;*
dist = d;
* }*
* }*
* }*
* }*
* return iHit;*
}
Note you ask about getting the rotation of each particle. The is an (undocumented?) variable for particles called ‘axisOfRotation’. This can be combined with the ‘rotation’ of a particle in AngleAxis() to produce a Quaternion rotation of that particle.
I never know without testing whether making function calls to UnityEngine routines is faster or slower than C# code. But if you want to do the raycast by hand, you will find line/plane intersection code in the [Math3D class in the Unity Wiki][2].
_[1]: http://wiki.unity3d.com/index.php/CreatePlane*_
[2]: http://wiki.unity3d.com/index.php/3d_Math_functions*