Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 E_Sarkis · Apr 06, 2017 at 07:26 PM · 2draycastlinerendererreflectionraycasthit2d

Inconsistent Reflection/Ricochet of 2D Lines at Specific Angles via Raycasting and 2D Colliders

Hello!

I am currently implementing a rotating beam weapon for a 2D game which reflects/ricochets from its original point of contact with a 2D collider and continues until hitting another 2d collider.

Using the initial 2D raycast hit to begin another raycast with its direction obtained via reflection I have only had success when the direction of the initial raycast hits colliders at specific angles.

I've hit a roadblock finding an explanation for this behaviour, and would appreciate any insight into what is causing it and how it can be fixed.

My code is below, and here is a video of the problem in action.

 public class Laser : MonoBehaviour
 {
 
     public Transform laserHit; // point where laser initially hits
     public Transform laserRicochetHit; // point where laser ricochet hits
 
     private LineRenderer lr;
 
 
     void Awake ()
     {
         lr = GetComponent<LineRenderer>();
         lr.enabled = true;
         lr.useWorldSpace = true; // world origin instead of the parent object origin
         lr.numPositions = 3; // 0 - origin, 1 - initial wall hit, 2 - ricochet hit
     }
 
 
     void Update()
     {
         RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.parent.up);
         laserHit.position = hit.point;
 
         // create a ricochet line via raycasting
         Vector2 ricoDir = Vector2.Reflect(transform.parent.up, hit.normal); // direction for ricochet raycast
         RaycastHit2D ricochetHit = Physics2D.Raycast(hit.point, ricoDir);
         laserRicochetHit.position = ricochetHit.point;
 
         // set line positions
         lr.SetPosition(0, transform.position); // origin
         lr.SetPosition(1, laserHit.position); // initial wall hit
         lr.SetPosition(2, laserRicochetHit.position); // ricochet hit
 
         // draw debug lines
         Debug.DrawLine(transform.position, hit.point);
         Debug.DrawLine(hit.point, ricochetHit.point);
     }
 }

I am new to Unity and C#, and would appreciate any and all comments. Thanks!

Comment
Add comment · Show 4
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 FortisVenaliter · Apr 06, 2017 at 11:03 PM 0
Share

That code looks good, especially for a beginner.

Can you post a screenshot of the scene view? What is the raycast shooting at? Are there colliders on the edges of the screen?

avatar image E_Sarkis FortisVenaliter · Apr 07, 2017 at 03:24 PM 0
Share

Sure thing @FortisVenaliter!

alt text

The "Walls" of the screen are 4 intersecting cubes with 2d box Collider components.

avatar image FortisVenaliter E_Sarkis · Apr 07, 2017 at 03:53 PM 0
Share

Image link is broken. 403 forbidden.

Show more comments

2 Replies

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

Answer by FortisVenaliter · Apr 07, 2017 at 04:29 PM

From the documentation for raycast:

Additionally, this will also detect Collider(s) at the start of the ray. In this case the ray is starting inside the Collider and doesn't intersect the Collider surface. This means that the collision normal cannot be calculated in which case the collision normal returned is set to the inverse of the ray vector being tested. This can easily be detected because such results are always at a RaycastHit2D fraction of zero.

So, what you probably need to do, is get the initial ray start point out of your starting collider. Try disabling the collider on the cube to confirm this is the problem.

Comment
Add comment · Show 4 · 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 E_Sarkis · Apr 07, 2017 at 04:59 PM 0
Share

No problems with the initial raycast exiting the cube which emitting the beam. This does explain the issue though. It appears the initial hit position is landing within the wall's collider when approaching from most directions. Therefore, my ricochet raycasts are unable to obtain the correct normal and go nowhere.

Thanks for this, I'll read the documentation more closely next time.

With this information I have a leg up on finding a solution, but would be welcome to anyone else's solutions of course! I'll post my own provided I'm able to come up with one myself.

avatar image FortisVenaliter E_Sarkis · Apr 07, 2017 at 05:15 PM 1
Share

You should just be able to offset the ricochet position by a small fraction of the collision surface normal. That should push it far enough to not collide.

avatar image E_Sarkis FortisVenaliter · Apr 07, 2017 at 08:29 PM 0
Share

Yep! The adding hit.normal to one line was enough to fix the behavior:

 RaycastHit2D ricochetHit = Physics2D.Raycast(hit.point + hit.normal, ricoDir);

Thanks for all your help @FortisVenaliter

Here's the complete implemented fix in case anyone else is facing the same issue in the future.

 public class Laser : $$anonymous$$onoBehaviour
 {
 
     public Transform laserHit; // point where laser is hits
     public Transform laserRicochetHit; // point where laser ricochet 
 
     private LineRenderer lr;
 
     void Awake ()
     {
         lr = GetComponent<LineRenderer>();
         lr.enabled = true;
         lr.useWorldSpace = true; // world origin ins$$anonymous$$d of the parent object origin
         lr.numPositions = 3; // 0 - origin, 1 - initial wall hit, 2 - ricochet hit
     }
 
     void Update()
     {
         RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.parent.up);
         laserHit.position = hit.point;
 
         // create a ricochet line via raycasting
         Vector2 ricoDir = Vector2.Reflect(transform.parent.up, hit.normal); // direction for ricochet raycast
 
         RaycastHit2D ricochetHit = Physics2D.Raycast(hit.point + hit.normal, ricoDir);
         laserRicochetHit.position = ricochetHit.point;
 
         // set line positions
         lr.SetPosition(0, transform.position); // origin
         lr.SetPosition(1, laserHit.position); // initial wall hit
         lr.SetPosition(2, laserRicochetHit.position); // ricochet hit
 
         // draw debug lines
         Debug.DrawLine(transform.position, hit.point);
         Debug.DrawLine(hit.point, ricochetHit.point);
     }
 }
Show more comments
avatar image
0

Answer by imaginationrabbit · Jun 01, 2019 at 01:26 AM

The answer above is really useful but more specifically to solve this you need to modify the hit normal you are giving to the Reflect- all I did was create a new variable for the hitnormal I gave the Reflect by adding the hitnormal + hitpoint- now it works as it should.

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.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

2D Collider larger than specified 0 Answers

Top down shooter: Laser Sight 1 Answer

RaycastHit2D to hit an enemy when player rotates. (Using keyboard input only) 2 Answers

2D Raycast not working 1 Answer

LineRenderer (Laser Beam) is not following the ray it's going on the wrong direction when reflecting 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges