• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by eric_c · Dec 12, 2012 at 06:12 AM · raycastquaterniondirectionanglelocaleulerangles

Raycast across angle?

Hi, I have a javascipt in progress here :

 var anglePartition : float = maxAngle/totalRays;
 var startDir : Vector3 = transform.localEulerAngles;
      
     for (var i:int=0;i<totalRays;i++){
         
         
         var hit : RaycastHit;
         if (Physics.Raycast (transform.position, startDir, hit, distance)) 
         {
             Debug.DrawLine (transform.position, hit.point, Color.red);
             
         }
         startDir.y += anglePartition;
         
     }

I'm trying to raycast a number of times over a specified angle over the y axis. After fiddling with the code for a few hours and having no success, I figured I should ask the question here instead. I'm not an expert on scripting, nor am I in Quaternions/Angles. Does anyone care to explain what I'm doing wrong here, and what I should do?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by AlucardJay · Dec 12, 2012 at 10:04 AM

Edited :

Ok, I have written a new answer for the new information provided.

This script works by calculating a point that is at an angle to the object forward. This angle is then changed by the angle divided by the number of times (segments).

press play, and left click mouse button to briefly see the lines of the raycast (you can spam the LMB for testing just to see the lines where the Linecast is checking. While playing, change the angle and the segments, just make sure that segments is always less than theAngle. And I have made these variables integers, though floats could be used, this is probably accurate enough for what you need.

 #pragma strict
 
 public var distance : float = 5.0f;
 public var theAngle : int = 45;
 public var segments : int = 10;
 
 function Update() 
 {
     if ( Input.GetMouseButtonDown(0) )
     {
         RaycastSweep();
     }
 }
 
 function RaycastSweep() 
 {
     var startPos : Vector3 = transform.position; // umm, start position !
     var targetPos : Vector3 = Vector3.zero; // variable for calculated end position
     
     var startAngle : int = parseInt( -theAngle * 0.5 ); // half the angle to the Left of the forward
     var finishAngle : int = parseInt( theAngle * 0.5 ); // half the angle to the Right of the forward
     
     // the gap between each ray (increment)
     var inc : int = parseInt( theAngle / segments );
     
     var hit : RaycastHit;
     
     // step through and find each target point
     for ( var i : int = startAngle; i < finishAngle; i += inc ) // Angle from forward
     {
         targetPos = (Quaternion.Euler( 0, i, 0 ) * transform.forward ).normalized * distance;    
         
         // linecast between points
         if ( Physics.Linecast( startPos, targetPos, hit ) )
         {
             Debug.Log( "Hit " + hit.collider.gameObject.name );
         }    
         
         // to show ray just for testing
         Debug.DrawLine( startPos, targetPos, Color.green );    
     }        
 }

Let me know =]


Original answer

I found this question very interesting so decided to have a go =]

A list of 'nodes' is generated based on the number of segments in the arc and the range of a circle. Set the circle range with curveAmount (eg 90 = 90', 360' = full circle). Also set the radius and the number of segments (this can all be done in realtime within the script.

This is just an example with some debug lines to demonstrate. Attach script to empty gameObject, hit play and then click left-mouse-button. change the values in the inspector while playing, also change the position and rotation of the empty. The lines should show that the raycast is done relative to the objects forward.

 #pragma strict
 import System.Collections.Generic;
 
 public var radius : float = 5.0;
 public var segments : int = 12;
 public var curveAmount : float = 360.0;
 private var calcAngle : float;
 var nodes : List.< Vector3 > = new List.< Vector3 >(); // private , left out to check in inspector
 
 function Update() 
 {
     if ( Input.GetMouseButtonDown(0) )
     {
         CalculatePoints();        
         DrawLines();    // just for testing    
         CheckForHits();
     }
 }
 
 function CalculatePoints() 
 {
     nodes.Clear();
     calcAngle = 0;
     
     // Calculate Arc on Y-Z    
     for ( var i : int = 0; i < segments + 1; i ++ )
     {
         var posY : float = Mathf.Cos( calcAngle * Mathf.Deg2Rad ) * radius;
         var posZ : float = Mathf.Sin( calcAngle * Mathf.Deg2Rad ) * radius;            
         nodes.Add( transform.position + ( transform.up * posY ) + ( transform.forward * posZ ) );    
         calcAngle += curveAmount / parseFloat(segments);
     }
 }
 
 function CheckForHits() 
 {
     var hit : RaycastHit;
     for ( var i:int = 0; i < nodes.Count - 1; i ++ )
     {
         if ( Physics.Linecast( nodes[i], nodes[i + 1], hit ) )
         {
             Debug.Log( "Hit " + hit.collider.gameObject.name );
         }
     }
 }
 
 function DrawLines() 
 {
     for ( var i:int = 0; i < nodes.Count - 1; i ++ )
     {
         Debug.DrawLine( nodes[i], nodes[i + 1], Color.red, 1.5 );
     }
 }
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image eric_c · Dec 12, 2012 at 10:27 AM 0
Share

It's probably my fault for not being clear when asking the question, I should have named the title "Raycast across angle". $$anonymous$$y intention is actually not to raycast across a circle/arc, but to raycast a specified amount of times over a certain angle on the y-axis. For excample, raycast 10 times over the course of 45 degrees on the y-axis. Thanks for spending time for the answer!

avatar image AlucardJay · Dec 12, 2012 at 10:44 AM 0
Share

Would it be possible to make an image to illustrate, edit the question to include the image. $$anonymous$$y understanding now is that you want to sweep a raycast infront at different angles, e.g :

alt text

isthiswhatyoumean2.png (12.0 kB)
avatar image eric_c · Dec 12, 2012 at 10:50 AM 0
Share

Yes sir, your illustration describes exactly what I mean.

avatar image AlucardJay · Dec 12, 2012 at 04:14 PM 0
Share

I have edited my answer, hopefully I have understood correctly, please let me know =]

avatar image eric_c · Dec 13, 2012 at 02:36 AM 0
Share

Thanks for the great answer! Although I might need to study and modify the script a little to suit my needs. Thanks again!

avatar image
2

Answer by JimPD · Dec 22, 2017 at 12:08 PM

Original Converted to C#

 public float radius = 5.0f;
     public int segments  = 12;
     public float curveAmount = 360.0f;
     private float calcAngle;
     private List<Vector3> nodes;
 
     public void Start()
     {
         nodes = new List<Vector3>();
     }
 
     private void Update()
     {
         if (Input.GetMouseButtonDown(0))
         {
             CalculatePoints();
             DrawLines();    // just for testing    
             CheckForHits();
         }
     }
 
     private void CalculatePoints()
     {
         nodes.Clear();
         calcAngle = 0;
 
         // Calculate Arc on Y-Z    
         for (int i = 0;  i < segments + 1; i++ )
      {
             float posY = Mathf.Cos(calcAngle * Mathf.Deg2Rad) * radius;
             float posZ = Mathf.Sin(calcAngle * Mathf.Deg2Rad) * radius;
             nodes.Add(transform.position + (transform.up * posY) + (transform.forward * posZ));
             calcAngle += curveAmount / (float)segments;
         }
     }
 
     private void CheckForHits()
     {
         RaycastHit hit;
         for (int i = 0; i < nodes.Count - 1; i++ )
         {
             if (Physics.Linecast(nodes[i], nodes[i + 1], out hit))
             {
                 Debug.Log("Hit " + hit.collider.gameObject.name);
             }
         }
     }
 
     private void DrawLines()
     {
         for (int i = 0; i < nodes.Count - 1; i++)
      {
             Debug.DrawLine(nodes[i], nodes[i + 1], Color.red, 1.5f);
         }
     }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ludomitch198 · Jun 05, 2020 at 10:13 AM

C# implementation for edited answer:

     public void RaycastSweep() 
      {
         float distance = 40.0f;
         float theAngle = 25.0f;
         float segments = 10.0f;
         Vector3 startPos = cam.transform.position; // umm, start position !
         Vector3 targetPos = Vector3.zero; // variable for calculated end position
          
         int startAngle = Convert.ToInt32(-theAngle * 0.5f); // half the angle to the Left of the forward
         int finishAngle = Convert.ToInt32(theAngle * 0.5f); // half the angle to the Right of the forward
          
          // the gap between each ray (increment)
         int inc = Convert.ToInt32(theAngle / segments);
         RaycastHit hit;
 
          // step through and find each target point
          for (int i = startAngle; i < finishAngle; i += inc ) // Angle from forward
          {
              targetPos = (Quaternion.Euler( 0, i, 0 ) * transform.forward).normalized * distance;    
              
              // linecast between points
              if ( Physics.Linecast( startPos, targetPos, out hit ) )
              {
                  Debug.Log( "Hit " + hit.collider.gameObject.name );
 
              }    
              
              // to show ray just for testing
              Debug.DrawLine( startPos, targetPos, Color.green ); 
          }        
      }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to raycast using a vector3 and a rotation? 1 Answer

How to shoot raycast with slight random direction? 1 Answer

How to add slight angle/rotation variation to transform.forward? 5 Answers

Raycast in the direction of looking plus an angle offset 0 Answers

Relative rotation offset? 2 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges