Search Unity

Raycast problems

Discussion in 'Scripting' started by Richard_B, Aug 18, 2005.

  1. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    I am trying to raycast from an object but if the object has a sphere collider the ray seem to hit the sphere collider (ie if doesn't go beyond the object), but if I change the collider to a mesh collider then the ray seems to intersect objects beyond the object the script is attached to.

    Is this correct ie that you can only have a mesh collider?

    thanks,
    Richard.
     
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The mesh collider doesn't get hit in this particular case because you are probably hitting a triangle from behind and not from the front.
     
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    I changed the wiki page to account for a bug in the sample script.
     
  5. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    My situation is a little more complex. I have several bots all casting rays to sense their environment. So, I guess in each Update call I have to switch the current bot to a different layer and set the layermask to the other layers. I tried the following sort of thing:

    Code (csharp):
    1.    
    2. private   LayerMask feelRays = 9;  
    3. private   LayerMask ignoreRays = 8;
    4. private   LayerMask rayLayer;
    5.  
    6. void Update () {
    7.     RaycastHit hit  ;
    8.     // put the caster in the ignore layer
    9.      layer = ignoreRays;
    10.      // intersect with all other layers      
    11.      rayLayer = ~ignoreRays;
    12.      if (Physics.Raycast (transform.position, Vector3.forward, out hit,rayLayer)) {
    13.             distanceToHit = hit.distance;
    14.             print("The ray hit something");
    15.         }
    16.       layer = feelRays;
    17.     }    
    18.  
    however, I get the compile error "The name `layer' could not be found in `myScript'". I also tried creating a public GameObject variable (called "me") so that I could drag the object the script was attached to on to it and use "me.layer = ignoreRays;". The latter script compiled fine, but Unity immediately crashed when I started "Play" :)
    thanks,
    Richard.
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Please report a bug about that crashbut you were getting.

    I will add support for giving a collider to ignore when casting a ray, in Unity 1.1.x
    Ignore a single collider when casting is a really what you need most of the time.
     
  7. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    I really can't get this to work - even if I try with just one player and maunally assign the layers - keeps crashing :( Will post report shorty.

    I'll switch to js to see if I can get it to work (but really need to use C# beacuse of th "switch" and "for" problems in js).


    Ignore self would definitely be a good option :)

    thanks,
    richard.
     
  8. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    What problems are you running into with for?

    I realize switch is not supported at the moment, but switch can always be replaced with a bunch of ifs.
     
  9. klindeman

    klindeman

    Joined:
    Jun 13, 2005
    Posts:
    295
    Aren't If's a bit slower then a switch statement? I seem to remember a problem like that in my uDG entry last year. I was doing a bunch of if's that I was able to turn into some switches and it made it run a lot faster...
     
  10. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Not in JavaScript or C#.
     
  11. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Originally I couldn't get "for" to work since I was using <=, but now realise the problem is the "=" bit and should just stick with "<". I am about to write a fare amout of code and nervous about starting out with js in case there are other problems.

    Richard.

    PS Just fixing up the project for the bug submission now..
     
  12. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The <= operator bug is fixed in javascript as well.

    But i can definately understand your sentiment about using C#.
     
  13. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Ok - the bug wasn't listed in the release report so I assumed it was still broken - sorry - should have tested it.

    Richard.
     
  14. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    My fault.
     
  15. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Not a problem - I know how difficult it is to track all these things - been there myself :)

    Richard.
     
  16. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Using your Wiki js script and it works fine! I am happy (for the moment) :)

    thanks,
    Richard.
     
  17. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    It appears the "for" bug is still there:

    Code (csharp):
    1. for(var i=1;i< numEyes;i++) {
    2.        
    3.         if (Physics.Raycast (transform.position, lookDir, hit, Mathf.Infinity, layerMask)){
    4.             Debug.DrawRay (transform.position, lookDir * hit.distance, Color.yellow);
    5.             gameObject.layer = 0;
    6.          } else {
    7.                 Debug.DrawRay (transform.position, lookDir *1000, Color.red);
    8.          }
    9.      }  
    does not generate an error, but (replacing "<" with "<="):
    Code (csharp):
    1.  
    2. for(var i=1;i<= numEyes;i++) {
    3.        
    4.         if (Physics.Raycast (transform.position, lookDir, hit, Mathf.Infinity, layerMask)){
    5.             Debug.DrawRay (transform.position, lookDir * hit.distance, Color.yellow);
    6.             gameObject.layer = 0;
    7.          } else {
    8.                 Debug.DrawRay (transform.position, lookDir *1000, Color.red);
    9.          }
    10.      }  
    does generate an error :-(

    Richard.
     
  18. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Going back to the C# :)-( ). I don't really understand the "out" thingy in the raycast declaration:

    Code (csharp):
    1. bool Raycast (Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float distance = Mathf.Infinity, int layers = kDefaultRaycastLayers)
    Is is some sort of constructor? because I notice that there doesn't appear to be a constructor for the RaycastHit class ie. variations on

    Code (csharp):
    1.  RaycastHit myInfoBlock = new RaycastHit(???)
    all seem to generate a compile error.

    thanks,
    Richard.
     
  19. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Sorry - just rechecked with my C# book - "out" says the variable is passed ny reference - so I guess a constructor for RaycastHit isn't needed and the Raycast method just keeps the RaycastHit memory block around for the script to query?

    thanks,
    Richard.
     
  20. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    RaycastHit hit;
    Physics.Raycast (Vector3.zero, Vector3.forward, 1, out hit);

    out means the value is written to on return.
     
  21. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Sorry - anouther problem. I think this must be a bug (or I am missing something): I am raycrasting from an empty object (ie a transform) and rotating it after each cast. If the raycast in the direction of a rigidbody with a capsule collider it correctly registers a hit, however, it also registers a hit with the same rigidbody if it casts in a direction pointing 180 degrees AWAY from the rigidbody.

    If however, I replace the capsule collider with a mesh collider then the 180 raycast doesn't register (ie the raycasting works correctly).

    Richard.
     
  22. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Capsule colliders are volumes. Thus if you cast from inside, you will get a hit.
    Mesh colliders are more like surfaces and mesh-ray collision only hit when you hit cast the ray throug triangle that faces towards the ray origin. Backfacing triangles are ignored in the raycast.


    Does that explain what you are seeing?
     
  23. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    Uuum I don't think so - I'll post a screenshot illustrating the effect... after I have downloaded rc1 :)

    thanks,
    Richard.
     
  24. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    The movie shows a transform-only object (ie no mesh at all) which has a raycasting script which uses Physics.Raycast and Debug.DrawRay. The drawn ray is one of two colours - red if it hits an object with *no* rigidbody and yellow otherwise. As you can see the raycasting object is also rotating as it casts the rays. Now, in the screen capture below I have tried to illustrate that the raycaster is claiming (because it turns yellow) that there is a rigidbody at positon "A", when in fact the is NO object there at all. Notice that the "ghost" object at "A" is 180 degrees from the real rigidbody. This happens whereever I place the real rigid body - the ghost object is always 180 around.

    Now, the rigidbody that gives rise to the ghost object has a capsule collider, if, however, I replace the capsule collider with a mesh collider the problem goes away ie all works fine.

    Am I doing some silly?
    many thanks,
    Richard.
     

    Attached Files:

  25. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    I tried reproducing this, but cant trigger the bug. Please submit a bug report on this with sample project or sample scene.
     
  26. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    I found the problem with the C# script and the crashing. My fault entirely - in the line
    Code (csharp):
    1. rayLayer = ~ignoreRays;
    the "~" is a descructor, not a negation :( Apologies for wasting your time.

    Richard.
     
  27. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The crash shouldn't be in any case.
    Do you have the script that makes it crash?
     
  28. Richard_B

    Richard_B

    Joined:
    Jul 22, 2005
    Posts:
    436
    The following script when attached to an object will crash Unity:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class crasher : MonoBehaviour {
    5.    
    6. private  LayerMask ouch = 0;
    7. private  LayerMask eep;
    8.  
    9.   void Update () {
    10.      eep = ~ouch;
    11.   }
    12. }
    13.  
     
  29. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203