Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to raycast via a touch screen to hit very small objects?

Discussion in 'Scripting' started by Rainking, May 19, 2014.

  1. Rainking

    Rainking

    Joined:
    Jun 10, 2013
    Posts:
    41
    Hey all,

    I got a problem. May be some of you have an idea or work around for this anoying issue.

    My setup: I have a space game on an android platform. The player selects objects on screen via touch (with his or her big fingers ;) ). In case my objects are far away from the player (so objects are quiet small) it is really difficult to hit this objects with a raycast. The player has to try several times to get it.

    I found SphereCast having a ray with a diameter, but it does not work with the option "isTrigger " so I can not use it.

    Another idea was fireing a grid of raycasts but I am not sure if this is bad for ths system performance because of the calculations for every single ray.

    Any ideas?
    Thanks a lot!
    Tino
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    OK, this may get a little complicated.

    first, have a look at this documentation:
    http://docs.unity3d.com/Documentation/ScriptReference/GeometryUtility.TestPlanesAABB.html

    Basically this uses a bunch of planes and calculates if any portion of a bounding box is in that plane.

    You can make planes by using points...
    http://docs.unity3d.com/Documentation/ScriptReference/Plane-ctor.html

    OK, so in order to get points, you will need to get 4 rays. I would use the x and y position from the screen and add an extents to it. Say 16 pixels. Next, take each of those rays and get two points from them which correspond to Camera.nearClipPlane and farClipPlane. Now, you will have 8 points. Take two points from each ray, and match it up with 1 point from the next. (4 times over, and that will give you 4 of the 6 planes you need. The other 2 come from the low and high values of the rays.

    Code (csharp):
    1.  
    2.     Plane[] GetProjection(int x, int y, int extents){
    3.         List<Vector3[]> r = new List<Vector3[]> ();
    4.         r.Add(GetProjection (x - extents, y - extents));
    5.         r.Add(GetProjection (x + extents, y - extents));
    6.         r.Add(GetProjection (x - extents, y + extents));
    7.         r.Add(GetProjection (x + extents, y + extents));
    8.  
    9.         Plane[] p = new Plane[6];
    10.         p [0] = new Plane (r [0] [0], r [0] [1], r [1] [0]); // top plane
    11.         p [1] = new Plane (r [1] [0], r [1] [1], r [3] [0]); // right plane
    12.         p [0] = new Plane (r [3] [0], r [3] [1], r [2] [0]); // bottom plane
    13.         p [0] = new Plane (r [2] [0], r [2] [1], r [0] [0]); // left plane
    14.         p [0] = new Plane (r [0] [0], r [1] [0], r [2] [0]); // near clip plane
    15.         p [0] = new Plane (r [0] [1], r [1] [1], r [2] [1]); // far clip plane
    16.  
    17.         return p;
    18.     }
    19.  
    20.     Vector3[] GetProjection(int x, int y){
    21.         Vector3[] v = new Vector3[2];
    22.         Ray ray = Camera.main.ScreenPointToRay (new Vector3 (x, y, 0));
    23.         v [0] = ray.GetPoint (Camera.main.nearClipPlane);
    24.         v [1] = ray.GetPoint (Camera.main.farClipPlane);
    25.         return v;
    26.     }
    27.  
    Now, with those planes, you can use this:

    http://docs.unity3d.com/Documentation/ScriptReference/GeometryUtility.TestPlanesAABB.html

    to test if anything is in them. Then test them for nearest point to the camera or however you want to test them.
     
  3. pdehn

    pdehn

    Joined:
    Oct 17, 2013
    Posts:
    6
    Have you considered simply using larger colliders?
     
  4. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    This is close to your solution. Increase the size of colliders proportionate to distance away, but have them at their normal size when closer than a certain distance.
     
  5. Rainking

    Rainking

    Joined:
    Jun 10, 2013
    Posts:
    41
    Thank you! I'll try both ideas (bigmisterb's and the larger colliders). I like the idea of larger colliders directly proportional with growing distance to camera. Especially because my colliders are just triggers, so they do not interfere physically... I will get some issues with my mesh colliders.
    Thank you again! It was a great help!
     
  6. Rainking

    Rainking

    Joined:
    Jun 10, 2013
    Posts:
    41
    It works well with Dameon_'s solution! Thanks a lot!