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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
2
Question by Simon Crowe · May 02, 2011 at 07:58 PM · rotationjavascriptcollision

Rotation and collision vectors: How can I make an object turn away from the object it has collided with based on the collision vector?

UPDATE 5:

I now have a working solution but I will share some of the problems I encountered:

  • The collision normals from Collision.contacts.normals aren't suited to the Vector3.Reflect function. By default, they are facing the wrong way to be used in vector reflection. I solved this by flipping them (multiplying the vector by -1).
  • The collision normals aren't automatically normalized, code has to be added to do this.
  • Your object has to have its forward direction facing -z in order for transform.LookAt to work(At least, I couldn't find a way of changing which vector it took as the forward vector).


Code:

 function OnCollisionEnter (collision : Collision){
     if (collision.gameObject.tag == "Obstacle"){
 
         var contact : Vector3;
         for (i=0;i<collision.contacts.length;i++){
         print ("Collision point" + "i" + ": "+collision.contacts[i].normal);
         contact += collision.contacts[i].normal;
         }
 //The above for statement adds all the collision points for the given 
 //collision together, to be normalized later.
 
         var facingRot : Quaternion = transform.rotation;
         var facingVector : Vector3 = facingRot * Vector3(0,0,1);
 //The current rotation of the object is stored and changed into the facing vector 
 // of the object, in this case +z.
 
         var collisionNormal = (Vector3.Normalize(contact))*-1;
 //An average of all collision normals is normalised. It is also reversed so it is 
 //facing the right way for the Vector3.Reflect function. 
 
         newVector = Vector3.Reflect (facingVector,collisionNormal);
 //An alternative to using the Vector3.Reflect function:
 //newVector = facingVector - (2 * Mathf.Abs(Vector3.Dot(facingVector,collisionNormal)) * collisionNormal);
 
         transform.LookAt(transform.position+newVector);
 //The transform.Lookat function will rotate the object so its +z direction faces a vector. 
 //(This gave me trouble as my object faced +x at rotation 0, to begin with)
     }
 }


My original Question in full:

I would like to know how I can derive a rotation from a collision vector or collision point using js.

I am writing a behaviour script for an object. My object meanders around aimlessly, sometimes it collides with obstacles. At present, when it collides with an obstacle, it smoothly turns 180 degrees, regardless of the angle at which it collides with the other collider or the direction that the other collider's normals are facing.

Bellow is a sketch of what I want to achieve here. The grey-brown rectilinear biped represents my object. My object has a box collider so the point(s) of collision would be different to the one I have circled in red. (note: I'm only using the y axis for rotation so the two dimensional representation below isn't a simplification) A diagram I put together to illustrate my goals My diagram can be found here if it doesn't load

I think it's also worth noting what I don't want to do:

My object is not effected by the physics engine, and I do not want it to be. It has a rigidbody collider with all axes of position and rotation frozen. All movement and rotation are input directly, not via forces. I suppose you could view my object as a robust robot which completely absorbs the impact of the collision and works out which way to turn based on the way the collider they have hit is facing.

--Many thanks.

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 Jean-Fabre · May 02, 2011 at 08:04 PM 0
Share

I might be misreading, but what's missing in your question is how you intend to define the target or the right number of degrees. Do you want the object to bounce off, smoothly tangent the collision points, etc etc. $$anonymous$$aybe a simple sketch would help.

avatar image Joshua · May 17, 2011 at 11:45 AM 0
Share

As opposed to using transform.LookAt (which rotates the local z axis to your reflected direction) I would use transform.RotateAround. As angle calculate the Vector3.Angle between your inco$$anonymous$$g and your reflected angle, as axis take a vector orthogonal to your normal vector.

1 Reply

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

Answer by Antony-Blackett · May 02, 2011 at 09:06 PM

I think what you're after is some vector maths. A simple solution that does not take into account friction or bounciness is this.

This is the mathematical formula for what you want to do:

Vnew = V - (2 |V.N| N)

where: V = incoming vector

N = normal to surface

|V.N| = the absolute dot product of V and N

In JS here's the code:

newVelocity : Vector3 = rigidbody.velocity - 2 * Mathf.Abs(Vector3.Dot(rigidbody.velocity, contact.normal)) * contact.normal;

To set your object facing this velocity do this.

transform.LookAt(transform.position + newVelocity);

Hope this helps.

Comment
Add comment · Show 7 · 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 Simon Crowe · May 03, 2011 at 10:00 AM 0
Share

I'm very new to coding and I can't work out how to do what you've suggested in js. Are you suggesting that I regularly record the direction my object is facing (local+x) in the variable directionBeforeInpact and add the vectors from the collision to it? Would I be able to record the direction my object is facing as a vector?

I'm not sure how this maths would work or how I would derive a rotation from the value of the newFacingDirection variable...

avatar image Antony-Blackett · May 03, 2011 at 09:06 PM 0
Share

Sorry I got the maths wrong...

I'll rewrite my answer and also explain how to code it as well. I want you to understand the maths behind the answer as well as it'll help you with similar future problems.

avatar image Simon Crowe · May 05, 2011 at 10:46 PM 0
Share

Thanks, your help is greatly appreciated. I have some idea of what the formula you have supplied is supposed to do, but I'm afraid I haven't been able to get it to work yet.

If you have the time, I'd like you to have a look at what how I've implemented your suggestion. Perhaps you can tell what I'm doing wrong. I've pasted the code I'm using at the time of my typing this into the question.

avatar image Antony-Blackett · May 06, 2011 at 04:45 AM 0
Share

Looks to me like there's a missing - somewhere. I assumed Vector3.Dot(facingVector,contact.normal) would come out negative. I may have been wrong. try this ins$$anonymous$$d.

newVector = facingVector - (2 $$anonymous$$athf.Abs(Vector3.Dot(facingVector,contact.normal)) contact.normal);

avatar image Antony-Blackett · May 06, 2011 at 04:53 AM 0
Share

Lol, I'm a retard. Vector3.Dot(facingVector,contact.normal) is negative but it gets multiplied by a possible negative value in the normal so it flips the result. The line I wrote in the comment above should fix that.

Show more comments

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

No one has followed this question yet.

Related Questions

How to make two objects mimic each other? 1 Answer

Scripting question about rotating on collision 0 Answers

Player rotating after wall collision 1 Answer

Rotation changes direction for no reason? 0 Answers

Questions about rotation. 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