Search Unity

Raycasting on particles?

Discussion in 'Scripting' started by Steel Arm, Jan 4, 2011.

  1. Steel Arm

    Steel Arm

    Joined:
    Dec 7, 2010
    Posts:
    50
    I used a particle system to generate stars in my galaxy, and I want to be able to select stars with my mouse. Can anyone tell me the best way to go about this? Does the physics system's raycasting work on particles?
     
    shikekaka likes this.
  2. Steel Arm

    Steel Arm

    Joined:
    Dec 7, 2010
    Posts:
    50
    Does anyone know at all?
     
  3. Mike L

    Mike L

    Joined:
    Sep 14, 2010
    Posts:
    1,035
    I dont think you can do that, unless it has something to do with world particle collider or something
     
  4. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    You could add a World Particle Collider to your particle system, and it will give your particle system's particles colliders, and you should be able to register raycast hits on them then.

    However, I'm not sure what your idea of "selecting" the stars will entail, as I'm not sure how you'd go about modifying an individual particle of a particle system.
     
  5. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    It is actually possible to modify individual particles' properties. The particle emitter's particles array contains an object for each live particle which specifies its position and other properties which can be changed from a script. The main issue is in identifying which particle in the array is the one that has been clicked. Probably the best way is to check which particle is nearest to the position of the raycast hit but this could cause problems where particles can overlap or obscure each other.
     
  6. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Interesting... insightful bit of info there. Thanks, Andeeee.
     
  7. Steel Arm

    Steel Arm

    Joined:
    Dec 7, 2010
    Posts:
    50
    Thanks for the replies. I know individual particles can be altered since that's how I created the stars in my scene (and I also have my stars' data kept in a separate data structure to track info about them.)

    To be honest though, I don't quite understand how to accomplish this. You said I should identify which particle has been clicked by checking against the array of particles of which is nearest to the raycast hit. But how do I get the raycast hit? Like how legend411 was saying? If I have a large number of stars(particles) though, this sounds possibly very CPU intensive.
     
    Last edited: Jan 5, 2011
  8. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    I've never actually used a particle collider, but I assume it would work similarly to other colliders... but judging from what andeeee said, I imagine each collider in a particle system with a world particle collider component isn't directly associated with any one particle in the system, so you'd have to just get the point where the ray and the particle collider collided, and then find the nearest particle to that point? (That's all on you, since as I mentioned, I didn't even know you could modify individual particles :) )
     
  9. Steel Arm

    Steel Arm

    Joined:
    Dec 7, 2010
    Posts:
    50
    I still need help with this, I can't seem to get it working properly.

    I have a particle emitter populated with particles that represent stars, and attached to the particle emitter is a world particle collider with these settings:
    Code (csharp):
    1. Bounce Factor: 0.5
    2. Collision Energy Loss: 0
    3. Collides With: User Layer 8 (SelectStars)
    4. Send Collision Message: No
    5. Min Kill Velocity: 0
    And here is my code for raycasting:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GalaxyGUI : MonoBehaviour {
    5.     GameObject SelReticle;
    6.     GalaxyData GalData;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.         SelReticle = GameObject.Find("SelReticle");
    11.         GalData = GameObject.FindWithTag("Galaxy").GetComponent<GalaxyData>();
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update () {
    16.         RaycastHit hit = new RaycastHit();
    17.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    18.         Starsystem star = null;
    19.         if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 8)) {
    20.             Debug.Log("HIT!");
    21.             star = LocateStar(hit.point);
    22.             if (star != null) {
    23.                 Debug.Log("FOUND!");
    24.                 SelReticle.active = true;
    25.                 SelReticle.transform.position = star.Position;
    26.             }
    27.             else {
    28.                 Debug.Log("NOT FOUND!");
    29.                 SelReticle.active = false;
    30.             }
    31.         }
    32.         else {
    33.             SelReticle.active = false;
    34.         }
    35.  
    36.        
    37.         return;
    38.     }
    39.    
    40.     Starsystem LocateStar(Vector3 pos) {
    41.         float dist, prevdist = 9999999.0f;
    42.         Starsystem result = null;
    43.         foreach (Starsystem star in GalData.StarList) {
    44.             dist = Vector3.Distance(pos, star.Position);
    45.             if (dist < prevdist) {
    46.                 prevdist = dist;
    47.                 result = star;
    48.             }
    49.         }
    50.         return result;
    51.     }
    52. }
    53.  
    However, it never even registers a hit. What am I doing wrong?
     
  10. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    To my knowledge no, Particle Colliders don't work with Raycast.

    If I were approaching this I would build a custom "Particle" emitter and add a Mesh Collider. When raycasting, I could then identify the star that was clicked on by the Triangle number (2 tris per quad right? they should be in a linear index so every 2 tris = diff star)

    If your stars need to *move* dynamically (within the mesh/system itself) ... you are in for a bit more work as Mesh Collider doesn't rebuild itself every frame so you'd need to remove and add the MeshCollider component every time the mesh changed.
     
  11. Steel Arm

    Steel Arm

    Joined:
    Dec 7, 2010
    Posts:
    50
    The stars don't need to move their position, but they do have to be facing the camera, so I guess that would need to rebuild the collider?

    So this custom emitter, would essentially be a mesh where each particle is as you say, a quad. I would have to build each quad myself I guess?

    Would this method work.... Since the graphical portion of the stars are rendered already as particles, do you think I would take a big hit to frame rate if I put an empty game object at each location of a star and added a collider to them? Sphere collider for instance.
     
  12. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    How big a slice of the heavens are you taking? :)

    also - its fairly easy to test this one heh; only one way to find out.

    if you have any other physics going on in your scene I would advise you put all the star-colliders into a single layer then disable layer collision between all other layers and that layer (with exception to raycast)
     
  13. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    231
    Sorry to revive this thread but is this still the case in 2018.3.x that raycasts don't work with particle systems? My raycast/linecast attempts do not seem to be hitting any of my billboard particles, but are hitting e.g. my ocean/water mesh. I'm raycasting from a moving VR camera, if that makes any difference.

    Code (CSharp):
    1.     Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward * 150f);
    2.     if (Physics.Raycast(ray, out rayHit, Mathf.Infinity)) {
    3.         Debug.Log("Hit by: " + rayHit.transform.gameObject.name);
    4.     }
    5.  
    Collision settings:
    The particles otherwise collide fine with other colliders (mesh and sphere) in the scene and call OnParticleCollision() as expected.

    I've also tried attaching the raycasting script to the Camera and the Particles and other gameObjects in the scene, not that it should matter. I've also played with Physics Layer Collision Matrix.
     
  14. christougher

    christougher

    Joined:
    Mar 6, 2015
    Posts:
    558
    Instead of a Raycast what I do is instantiate an object that is basically a long skinny rod with a collider that travels forward whereever I tap/click and thus triggers the particle's collision messages.
     
    gromiczek likes this.