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
0
Question by warren- · Jan 28, 2016 at 10:52 PM · rigidbodyrigidbody-collisionreflect

Reflect a Rigidbody in Javascript

I first started out with a regular OnCollisionEnter reflection, and this worked well, but after reading about coroutines, I got to wondering if it would be faster by doing my own Raycast and reflecting manually.

First I wanted to show my original reflection code, which uses OnCollisionEnter, keep in mind, the collision function is based on FixedUpdate. The collision data isn't updated until the next update.

     function Start() {
      for (var i = 0;i < 360; i++) {
 
      //Create Object.
       var newObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
 
       //Enable a Objects' Collider.
       newObj.GetComponent.<Rigidbody>().GetComponent.<Collider>().enabled = true;
 
       //Rotate 90 degrees on Y axis.
       newObj.GetComponent.<Rigidbody>().transform.rotation = Quaternion.Euler(0,90,0);
 
       //Add a degree for each X axis.
       newObj.GetComponent.<Rigidbody>().transform.rotation.eulerAngles += Vector3(i,0,0);
 
       //Add velocity.
       newObj.GetComponent.<Rigidbody>().AddRelativeForce(Vector3(0,objSpeed,0));
      }
     }
 
 
     function OnCollisionEnter(collision: Collision) {
 
 //Change velocity based on reflection.
       gameObject.GetComponent.<Rigidbody>().velocity = Vector3.Reflect(gameObject.GetComponent.<Rigidbody>().velocity, collision.contacts[0].normal);        
 
 //Visualize Helper variable.  
     var reflection = Vector3.Reflect (gameObject.GetComponent.<Rigidbody>().transform.position, collision.contacts[0].normal);
                  
   //Visualize.                 
     Debug.DrawRay(gameObject.GetComponent.<Rigidbody>().transform.position, collision.contacts[0].normal, Color.green, 1);
     Debug.DrawRay(collision.contacts[0].point, gameObject.GetComponent.<Rigidbody>().velocity, Color.red, 1);
     Debug.DrawRay(collision.contacts[0].point, reflection,Color.blue,1);
     
      }

We start out creating 360 objects, then we add a force to each, relative to their own rotation. In my setup, I rotated the Y axis 90 degrees, and then in the for-loop, rotated the X-axis 1 - 360 degrees. (This was done for my own camera layout, rotate accordingly.)

Giving each object a velocity of 10, based on its relative direction.

Create an object for it to collide with, and it should reflect it. Also, you will want to add this to its own layer, and disable collisions for that layer in Project Settings -> layers.

That reflection code works....




However, i wanted to create a "coroutine" for reflecting, which uses Raycast to do the collision detection, so heres how I did it:

(Note: You may want to add this to a new script and attach it, to the one you have above.)

 function Start() { 
 
  //This is a bitwise operation, used to listen to colliders on layer 9.
  var layermask = 1 << 9;
 
  //coroutine loop.
  while (true) {
 
    //Initialize Raycasting object.
    var hit: RaycastHit;
 
    //Get this scripts rigidbody position.
    var ray =  gameObject.GetComponent.<Rigidbody>().transform.position;
 
    //Plot a line using rigidbody(ray) and multiply by the Up position, since we used rotated by the 
    // Y-axis in our previous script, the floating point math is to make the lines smaller.
    Debug.DrawLine(ray + (transform.up *.03), ray + (transform.up * .2), Color.red);
             if (Physics.Raycast(ray + (transform.up *.03), ray + (transform.up *.2), hit, 20, layermask)) {
 
    //Get Objects current rotation.
    var myRotation = gameObject.GetComponent.<Rigidbody>().rotation;
 
    //Get Objects current velocity.
    var myVelocity = gameObject.GetComponent.<Rigidbody>().velocity;
 
    //Get Objects new Reflection vector, based on Objects velocity, where hit.normal is the Raycast line colliding with a rigidbody.
    var myReflect = Vector3.Reflect(myVelocity, hit.normal);
 
   //Get Objects new Rotation using Velocity and Reflection vector.
    var newRotation = Quaternion.FromToRotation(myVelocity, myReflect);
 
      //Visualize.
      Debug.DrawLine(ray, hit.point, Color.red);
      Debug.DrawRay(hit.point, myReflect, Color.green);
 
      //Change Objects velocity to the new Reflection vector.
      gameObject.GetComponent.<Rigidbody>().velocity = myReflect;        
 
      //Change Objects rotation angle to the new rotation.
      gameObject.GetComponent.<Rigidbody>().transform.rotation = newRotation * myRotation;
     }
 
   //Coroutine statement.
   yield;
  }
 
 }


This code also works, and its inside a coroutine.

However, I ended up not using the coroutine at all, because if you ever change the time scale, (which i am), the coroutine code will fail to work (as expected). This is because the collider updates the Collider data each frame, and everything is synchronized to work together.



While the coroutine is independantly based on the Time settings, so the velocity of the objects would keep the objects in motion, while our Raycast script would not be processed in time to detect the collision.

There were some ways around this, by modifying the script Update refresh rate in Settings -> Time or by increasing the Raycast length.

In the end I decided there wasn't any speed or accuracy advantages I was getting with coroutines that I wasn't getting with a plain and simple OnCollisionEnter.

I realize this isn't a Question, but perhaps it will help someone out there banging their head against the wall with Reflection scripts.

Comment
Add comment · Show 2
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 brunocoimbra · Jan 28, 2016 at 11:11 PM 0
Share

If you are using Rigidbody anyway, the only reason to detect collision with raycasts rather than OnCollisionEnter / OnTriggerEnter is if you need to detect things far away from the object or at a specific point.

In that case, using Coroutine will be a really bad idea, as coroutines will be called inumerous times per second, while the OnCollisionEnter /OnTriggerEnter will only be called when needed.

avatar image warren- brunocoimbra · Jan 29, 2016 at 05:07 AM 0
Share

yeah, in hindsight i wished I'd never used the coroutine to begin with, as I wasted a lot of time doing the same thing with a lot less code, with no obvious benefit.

That's why I really wanted to post this, to show that it can be done, but that you're not going to be gaining anything from it. I could have even made this coroutine to work like the other with enough tinkering, but its just not practical.

I was curious why I never seen any questions about raycasting in a coroutine... now i know why.

0 Replies

· Add your reply
  • Sort: 

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

37 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 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

Making a Gameobject expand! 1 Answer

Reflect a rigid body without rotating it 1 Answer

Rigidbody not colliding with walls 1 Answer

moving an object from point to point using force 1 Answer

Trouble with rigidbody collisions while attached to Joint 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