I'm Having Trouble With Vector3.Reflect.. Please Help?


I think I’m doing something wrong with Vector3.Reflect and I think it has something to do with the normals, but I’m not quite sure how to fix it. Here is the scenario, while my player object moves, it is being controlled by Vector2.Lerp, I record the last position and second to last position of the player while it Lerps, so when it collides with another object, Vector3.Reflect is passed the second to last position as the vector to reflect, the current position as the inNormal (reflector) and the reflected vector that results from the function is used as the target destination in my Lerp function. The problem is that the reflected vector is popping up in strange spots (always on the left). I’m thinking that it must be that my normals are messed up, I also think that I may have to change my update function to fixed update. Because I’m pretty sure that collisions are processed every physics time step and since I change the tag of the player object to recognize the collision over multiple scripts in oncollisionenter and reference it in update of another script where I implement the reaction as a result of the collision, I think there may be some delay, but I’m not familiar with this stuff.

Hopefully somebody can tell me where I mucked up.

Here is my code:

The collision script attached to the player object:

public class CraneCollisions : MonoBehaviour

	void OnCollisionEnter(Collision other)
		gameObject.tag = "Hit";

The Gameplay script:

private float speed = 3f;
Vector2 cranePos = crane.transform.position;
Vector2 targetLocation;
Vector3 lastPos;
Vector3 secondToLastPos;

void Update()
	if( crane.tag == "Hit" )
		targetLocation = Vector3.Reflect( secondToLastPos, crane.transform.right );
		crane.transform.position = Vector2.Lerp( cranePos, targetLocation, Time.deltaTime * speed );

		if( targetLocation == crane.transform.position );

    		crane.tag = "Player";


	if( crane.transform.position != lastPos )
		secondToLastPos = new Vector3( lastPos.x, lastPos.y, 0 );
		lastPos = new Vector3( crane.transform.position.x, crane.transform.position.y, 0 ) ;

***Please note that I didn’t include any other part of the script than the subjects that I want to touch on because it is very long. Thanks

Any help would be much appreciated.

Your ‘inDirection’ is calculated wrong. It should be (lastPos - secondToLastPos). You are calculating a vector using a position, which means the vector will be from the world origin. You want the vector to be relative to object moving. As for the normal, ‘crane.transform.right’ does not look right, but might work if you have special knowledge of the geometry. What you are looking for is a vector perpendicular to the surface of the object you are bouncing off of at the point of the hit…in this case the player object. Typically you would get the normal from the contact points of the collision pass into OnCollisionEnter(). Typically you would have the the OnCollisionEnter() in the same moving object you would want to reflect. Sometimes you can get the normal from a Raycast(). The RaycastHit that is set during the call contains the normal of the surface at the point hit. For the special case of a collision between two spheres, you can get the normal by subtracting one position from another.

Note what you get back from Vector3.Reflect() will be a vector, not a ray. You will still need to calculate the position:

targetLocation = Vector3.Reflect(/* whatever parameters you use */);
targetLocation = lastPos + targetLocation * distance;