- Home /
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) 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.
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.
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.
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.
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...
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.
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.
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);
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.
Your answer
Follow this Question
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