I’m working on my first Unity project right now (a bit of a self prescribed crash-course) and I’ve run into a slight issue.
I’m trying deflect one object off of another one (via collision). For now, the deflection should be at a perfectly mirrored angle. No problem! I think to myself, I see this super handy contact.normal
property; seems pretty straight forward (I’m working in a 2D plane, so it really should be have been smooth sailing from there).
A few frustratingly failed attempts, and several thousand drawRay
commands later, I realize that the normal is NOT a normal to the face of impact, but is a normal OF the impact (ie, mirrors the angle of impact).
This is actually useful information, but to be useful, I need a face-normal to reflect the angle of impact over.
The moving object is using this.rigidbody.velocity =
so I can’t rely on built in physics; I’m also being a total stickler for how this bounce looks, so I’d really love to maintain full control over it.
Relevant code below:
function OnCollisionEnter(collision : Collision)
{
var contactCount : int = 0;
var normalAve : Vector3 = Vector3(0,0,0);
var velocityAve : Vector3 = Vector3.zero;
for (var contact : ContactPoint in collision.contacts)
{
contactCount++;
normalAve += contact.normal;
velocityAve += collision.relativeVelocity;
Debug.DrawRay(contact.point, contact.normal, Color.green, 2, false);
}
normalAve /= contactCount;
velocityAve /= contactCount;
var damage = Vector3.Dot(normalAve, velocityAve) * collision.rigidbody.mass;
life -= damage;
if(life <= 0)
{
// Stackoverflow people can ignore this, bounces
// don't happen when you're dead
this.rigidbody.useGravity = this.GetComponent(ship_small_physics).stage.GetComponent(stage_params).grav_on_hit;
this.GetComponent(ship_small_physics).impact();
}else{
// Stackoverflow people! Right here!
Debug.Log("survived! with " + life + " life");
this.GetComponent(ship_small_physics).small_impact(normalAve, velocityAve);
}
}
Then, in .small_impact
function small_impact(n : Vector3, v : Vector3)
{
var h_angle : Vector3 = Vector3(n.x, 0, n.z);
Debug.DrawRay(this.transform.position, n, Color.blue, 2, false);
Debug.DrawRay(this.transform.position, h_angle, Color.red, 2, false);
}
Just to clarify: The game IS in some sorts of 3D, but for various reasons in this case I only care about the collision normals in the x-z
plane (another reason why the plane old physics engine won’t do). That’s why I make a new vector h_angle
that’s essentially the projection of the collision-normal onto the x-z
plane.
It’s entirely possible that I’m just not understanding everything.