Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Multi RayCast function can't return the RayCastHit object

Discussion in 'Scripting' started by Kaze_Senshi, Apr 28, 2012.

  1. Kaze_Senshi

    Kaze_Senshi

    Joined:
    Feb 19, 2012
    Posts:
    243
    Hello guys, I am improving my moving and crush platforms in my 2.5D game, for this I was needing one way to make a wider raycast. How I can't do this, I did the following function:

    Code (csharp):
    1. function multiRayCast( startPt : Vector3, dir : Vector3, hit : RaycastHit, distance : float ) : boolean
    2. {
    3.     var iterations : int = 5; // Number of raycasts to be created inside this angle
    4.     var angleToCheck : float = 45.0; // This angle
    5.     var anglePartition : float = angleToCheck/iterations;
    6.    
    7.     //Starting from one extreme of the angle
    8.     var currDir : Vector3 = Quaternion.Euler( 0, 0, -1*anglePartition*(iterations/2) )*dir;
    9.    
    10.     // Rotating the raycast
    11.     for( /*nothing*/; iterations > 0; iterations-- )
    12.     {
    13.         Debug.DrawLine ( startPt , startPt + currDir*distance, Color.magenta );
    14.         if( Physics.Raycast( startPt, currDir, hit, distance ) )
    15.         {
    16.             Debug.Log("true");
    17.             return true;
    18.         }
    19.         //Rotating until rotate angleToCheck degrees
    20.         currDir = Quaternion.Euler( 0, 0, anglePartition )*currDir;
    21.     }
    22.     return false;
    23. }


    Just look the image and become easier to understand it, it just cast various raycasts in the direction given to check if there is some hit inside of that magenta area. The problem is, the function returns true but the "hit" parameter in the caller function is empty. Anyone have some idea to solve this? Thanks
     
  2. Tobias J.

    Tobias J.

    Joined:
    Feb 21, 2012
    Posts:
    423
    The code shown doesn't show how you check that the 'hit' is null, so my first question would be: Are you sure you're checking the correct 'hit'?`

    I think you may get better performance with OverlapSphere and then checking gameobject tags.
     
  3. Kaze_Senshi

    Kaze_Senshi

    Joined:
    Feb 19, 2012
    Posts:
    243
    Well I am considering that the hit is returning an empty RayCastHit because when I try to access any data from it the unity crashes.

    Code (csharp):
    1.     //if( Physics.Raycast( playerGlobalPosition, movingDirection, rayCastHit, crushDetectDistance ) )
    2.     if( multiRayCast( playerGlobalPosition, movingDirection, rayCastHit, crushDetectDistance ) )
    3.     {
    4.         Debug.Log( "raycast" + rayCastHit.transform.gameObject.name );
    5.     }
    If I use the commented normal raycast, it works okay. Also i am not using this Sphere because I can't control well like I can do with this function the parameters.
     
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I think your problem is that you are not referencing hit as an out variable. It is easily done in C#, but I cant see any documentation on how to do this in JS.


    This returns 0

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. function Start () {
    5.     var x : int = 0;
    6.     if(test(x))
    7.     print(x);
    8. }
    9.  
    10. function test(a : int) : boolean{
    11.     a = 5;
    12.     return true;
    13. }
    14.  
     
  5. Kaze_Senshi

    Kaze_Senshi

    Joined:
    Feb 19, 2012
    Posts:
    243
    @BigMisterB that is true, I read somewhere that the RayCastHit is a struct, not a reference for something, so you can't assign null for this one. Now I am curious, how the Raycast function works and change it if this is not a pointer.

    I was just copying the idea from this function when I made my multiRayCast function. I'll try to check some values from this RayCastHit to check if there is something that say that it's empty.
     
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    You could just as easily use an external hit ;)

    Code (csharp):
    1.  
    2. var hit : RaycastHit;
    3.  
    4. function multiRayCast( startPt : Vector3, dir : Vector3, distance : float ) : boolean
    5. {
    6.     var iterations : int = 5; // Number of raycasts to be created inside this angle
    7.     var angleToCheck : float = 45.0; // This angle
    8.     var anglePartition : float = angleToCheck/iterations;
    9.    
    10.     //Starting from one extreme of the angle
    11.     var currDir : Vector3 = Quaternion.Euler( 0, 0, -1*anglePartition*(iterations/2) )*dir;
    12.    
    13.     // Rotating the raycast
    14.     for( /*nothing*/; iterations > 0; iterations-- )
    15.     {
    16.         Debug.DrawLine ( startPt , startPt + currDir*distance, Color.magenta );
    17.         if( Physics.Raycast( startPt, currDir, hit, distance ) )
    18.         {
    19.             Debug.Log("true");
    20.             return true;
    21.         }
    22.         //Rotating until rotate angleToCheck degrees
    23.         currDir = Quaternion.Euler( 0, 0, anglePartition )*currDir;
    24.     }
    25.     return false;
    26. }
    27.  
     
  7. diablo

    diablo

    Joined:
    Jan 3, 2011
    Posts:
    736
    btw, for performance reasons, you may want to spread the raycasts over several frames... usually not a good idea to do more than a raycast or two per frame as they are expensive
     
  8. Kaze_Senshi

    Kaze_Senshi

    Joined:
    Feb 19, 2012
    Posts:
    243
    Ops, sorry for the bump post, but thank you @BigMisterB, that idea of the global RayCastHIt worked well, and @Diablo now I am adaptiing my moving platform to use less raycasts ;P