My problem is simple for most people i would think,but for some reason it has me stumped. One of those “Duh” questions that you hate asking.
If I have a ball that is aimed at an angle at a wall, and I want to change its direction how would I calculate that. I know I can do it with a rigidbody but sometimes that behavior is wrong. Plus I want to be able to “fake” it and not have any velocity change. If it hit at a 45 degree angel it would come off at a 45 degree angle. I know how it works in my head, I just can’t make the code for it. In case I have done a bad explanation I have a crappy drawing to illustrate what I am talking about.
If you could, maybe explain it so I could fake it with and without a rigidbody? I still don’t know which one I want to use.
It’s usually more straightforward to solve this sort of problem using vector math rather than by working with angles directly. In this case what you’re looking for is ‘vector reflection’ (your favorite search engine will tell you the rest).
As for using a rigid body, I’m not sure, but you might double check the physics materials being used and make sure they’re frictionless or close to it.
I used Vincenti’s suggestion and it actually does the calculation above without me having to code it. This works if it is head on, but if a object goes forward and hits an obstacle at a 45 degree angle, it should bounce off at a 45 degree angle, and neither is making it do that. I will keep looking. Thank you to both of you.
Edit: after playing with it some, I just realized that my code is making it go in the direction of the wall normal and i have no idea why.
This makes sense in my head, though I haven’t had a chance to try it:
var angle : float = Vector3.Angle( rocket.velocity, contact.normal ); // get angle of contact
var radians : float = 3.1415 * angle / 180.0; // convert to radians
// Rotate [i]away[/i] from rocket.velocity by that many radians
var newVelocity : Vector3 = Vector3.RotateTowards( contact.normal, rocket.velocity, -radians, 0.0 );
There really shouldn’t be any need to use angles for this.
@The OP: Regarding this line:
var curDir = rocketPrefab.transform.TransformDirection(Vector3.forward);
First of all, transform.TransformDirection(Vector3.forward) is the same as transform.forward, so you don’t need the TransformDirection() in there. Also, keep in mind that the object’s forward vector isn’t necessarily the same as its direction of motion (you may know a priori that it is in this case, but just be aware that it’s not necessarily the case in general).
Also, what’s ‘rocketPrefab’, and why are you modifying it here? Are you sure you’re applying the changes to the right object?
So, I finally figured it out. I figured I would post the results for anyone having the same problems. Thanks to both of you for pointing me in the right direction.
if(collision.gameObject.tag == "BounceWall")
{
var contact : ContactPoint = collision.contacts[0];
var newDir : Vector3 = Vector3.zero;
var curDir = rocketPrefab.TransformDirection(Vector3.forward);
newDir = Vector3.Reflect(curDir, contact.normal);
rocketPrefab.rotation = Quaternion.FromToRotation(Vector3.forward, newDir);
}