Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by CiberX15 · Aug 31, 2014 at 04:54 AM · 2dreflection

How do I get reflection vector from a 2D collision

Ok I am trying to do what I thought would be a simple bouncing bullet. Bullet hits wall, bounces off like a laser. I have now been at this for six hours. I was found this: http://answers.unity3d.com/questions/350431/vector3reflect-wrong-direction.html and tried to reverse engineer the code but it is not working correctly for me.

Their Code (adapted for Physics2D):

 function drawLaser(startPoint:Vector3,n:int)  
 {
     var hit : RaycastHit2D ;
     var rayDir:Vector3 = Spawner.transform.up;
  
     for(var i = 0; i < n; i++)
     {   
         hit = Physics2D.Raycast (startPoint, rayDir, 1000);  
         if (hit.collider != null) 
         {
             Debug.DrawLine (startPoint, hit.point, Color.red, 0.1, false);
              rayDir = Vector3.Reflect( (hit.point - startPoint).normalized, hit.normal  ) ;
             startPoint = hit.point;
         }
     }
 }


Now the thing that has me really confused is the above code works perfectly fires the little laser and bounces off the walls. But when I try to use the same calculation on my projectile, it derps of whatever which way it feels like. Code for my projectile here:

 function OnCollisionEnter2D(coll: Collision2D)
 {    
     if(coll.collider.GetComponent(Health) != null)
     {
         coll.collider.GetComponent(Health).Hurt(Dammage);
     }
     
     if(PingCount <= 0)
     {
         Destroy(gameObject);
     }
     else
     {
         var dir = Vector3.Reflect( (coll.contacts[0].point - transform.position).normalized, coll.contacts[0].normal);
 
 
 
         
         var angle : float = Mathf.Atan2(-dir.x,dir.y) * Mathf.Rad2Deg;
         var targetRot = Quaternion.AngleAxis(angle, Vector3.forward);
         transform.rotation = targetRot;
     }
     PingCount -= 1;
 }


I would really appreciate it if someone could explain what I am doing wrong. Thanks in advance : )

PS: All of this is using physics2d

Comment
Add comment · Show 3
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 CiberX15 · Aug 31, 2014 at 11:36 AM 0
Share

Oh, also in case you are wondering, the reason I am using a Vector3.Reflect when everything else is in 2D is because Vector2.Reflect does not exist. Similarly that little knot of code at the bottom is for pointing the object to face in the direction a vector is pointing without flipping my 2D object sideways making it invisible.

avatar image Scribe · Aug 31, 2014 at 11:41 AM 0
Share
 static Vector2 Reflect(Vector2 inDirection, Vector2 inNormal) {
     return  2.0f * Vector2.Dot (inDirection, inNormal) * inNormal - inDirection; 
 }

That is not actually 'my code', it comes from one of @robertbu's comments here. but it is the logical code equivalent of the maths needed!

avatar image CiberX15 · Aug 31, 2014 at 07:01 PM 0
Share

That still did not work for me for some reason. It looked like it was doing the same thing as the previous script.

1 Reply

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

Answer by CiberX15 · Aug 31, 2014 at 07:05 PM

I don't know if this is the best solution but the following is how I got it to work for my purposes. Basically, I could not figure out how to get the reflection vector from the collision. However I had a perfectly working example of how to do it with simple lines and ray casts. So I cheated. The projectile now casts a ray in front of it and when the ray hits something it does the calculation figures out the reflection vector and then rotates to face that vector.

The Code:

 function PingOff()
 {    
     var hit: RaycastHit2D = Physics2D.Raycast (transform.position, transform.up, 0.5, hitMask);  
     if (hit.collider != null) 
     {
         //Calculate ping
         var rayDir : Vector3 = Vector3.Reflect( (hit.point - transform.position).normalized, hit.normal  ) ;
 
         
         if(hit.collider.GetComponent(Health) != null)
         {
             hit.collider.GetComponent(Health).Hurt(Dammage);
         }
         
         if(PingCount <= 0)
         {
             Destroy(gameObject);
         }
         else
         {
             //Ping off
             var dir : Vector3 = rayDir;
 
             var angle : float = Mathf.Atan2(-dir.x,dir.y) * Mathf.Rad2Deg;
             var targetRot = Quaternion.AngleAxis(angle, Vector3.forward);
             transform.rotation = targetRot;
         }
         PingCount -= 1;
         Dammage = Dammage * 2;
     }
 }
Comment
Add comment · Show 3 · 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 kingkonglee · Sep 10, 2014 at 02:33 AM 0
Share

@CiberX15 Hi there, I would like to ask a question as well, didnt want to start another thread. I'm working on 2D game, which when I shoot bullet it will reflect and the bullet will disappear after a couple bounces. How would I do that? Thank you.

avatar image kylewill713 · Dec 07, 2019 at 08:52 PM 0
Share

So this solution worked except when my ray wasn't hitting the object, since my collider could be wider than the ray. Like a glancing blow. To Fix this I did the following

  1. cast a ray from the center first

  2. if that raycast missed cast a ray from the bottom of the collider

  3. if that raycast missed cast a ray from the top of the collider

      public static Vector2 getReflectVelocity(Transform bulletTransform, Vector2 velocity, Collider2D col, Collider2D bulletCollider)
         {
             Vector3 direction = velocity.normalized;
             Vector3 rayOrigin = bulletTransform.position - (direction * 1f);
     
             //Try hitting from the center of the projectile
             RaycastHit2D hit = Physics2D.Raycast(rayOrigin,  direction, 2, 1 << col.gameObject.layer);
             
             //We missed - Try hitting on bottom of projectile
             if(!hit) 
             {
                 Bounds bounds = bulletCollider.bounds;
                 rayOrigin = new Vector3(bounds.center.x, bounds.$$anonymous$$.y) - (direction * 1f);
                 hit = Physics2D.Raycast(rayOrigin,  direction, 2, 1 << col.gameObject.layer);
             }
     
             //We missed - Try hitting on top of projectile..
             if(!hit) 
             {
                 Bounds bounds = bulletCollider.bounds;
                 rayOrigin = new Vector3(bounds.center.x, bounds.max.y) - (direction * 1f);
                 hit = Physics2D.Raycast(rayOrigin,  direction, 2, 1 << col.gameObject.layer);
             }
     
             if(hit) return Vector2.Reflect(velocity, hit.normal);
             //Welp we tried....
             else return -velocity;
         }
    
    
    
    
avatar image CiberX15 kylewill713 · Dec 15, 2019 at 01:02 AM 0
Share

In that case you might want to use Physics2D.CircleCast(). It acts like a raycast but you can give it a radius. This would save you from having to make multiple checks, and also guard against the edge case where your projectile should be bouncing off something that fits between the raycasts.

https://docs.unity3d.com/ScriptReference/Physics2D.CircleCast.html

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

24 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 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 do i make something reflect in 2D? 1 Answer

Assets/Scripts/PlayerController.cs(32,49): error CS0126: An object of a type convertible to `float' is required for the return statement 1 Answer

2D - more lights 2 Answers

How to Create Still Water Reflections [2D] C# 0 Answers

2D Dynamic Reflections ReadPixel Issue 0 Answers


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