- Home /
Vector3.Reflect problems
When I use vector3.reflect some times the ball will start rolling along the surface that it collided with. I think it is only when the angle is real low.
my reflection code
void OnCollisionEnter(Collision collider) { foreach (ContactPoint contact in collider.contacts) {
ballVelocity = Vector3.Reflect(ballVelocity, contact.normal);
}
}
my movement code
if ( setting.GetComponent<settings>().stage == stages.game && setting.GetComponent<settings>().ballpaused == false) { if (Physics.Linecast( setting.GetComponent<settings>().vect1, setting.GetComponent<settings>().vect4, mask.value)) {
ballVelocity = Vector3.Reflect(ballVelocity,Vector3.right);
}
if (Physics.Linecast( setting.GetComponent<settings>().vect1, setting.GetComponent<settings>().vect2, mask.value))
{
ballVelocity = Vector3.Reflect(ballVelocity, Vector3.down);
}
if (Physics.Linecast( setting.GetComponent<settings>().vect2, setting.GetComponent<settings>().vect3, mask.value))
{
ballVelocity = Vector3.Reflect(ballVelocity, Vector3.left);
}
if (Physics.Linecast( setting.GetComponent<settings>().vect4, setting.GetComponent<settings>().vect3, mask.value))
{
Destroy(gameObject);
}
ballVelocity.z = 0;
Vector3 vect = transform.position += ballVelocity * (ballSpeed + setting.GetComponent<settings>().difficulty) * Time.deltaTime ;
vect.z = 0;
if (vect.y < setting.GetComponent<settings>().vect4.y)
{
Destroy(gameObject);
}
transform.position = vect;
transform.position.Normalize();
Answer by twinnightmare · Jul 08, 2010 at 03:32 AM
With other method still had some problems so cooked up another method that used manual direction calculation.
My Directions
directions[0] =Vector3.up;
directions[1] =Vector3.down;
directions[2] =Vector3.Lerp(Vector3.up,Vector3.left, 0.25f);//
directions[3] =Vector3.Lerp(Vector3.up,Vector3.left, 0.5f);
directions[4] = Vector3.Lerp(Vector3.up,Vector3.left, 0.75f);
directions[5] = Vector3.Lerp(Vector3.left,Vector3.down,0.25f);
directions[6] = Vector3.Lerp(Vector3.left,Vector3.down,0.5f);
directions[7] =Vector3.Lerp(Vector3.left,Vector3.down,0.75f);
directions[8] =-Vector3.Lerp(Vector3.up,Vector3.left, 0.25f);
directions[9] =-Vector3.Lerp(Vector3.up,Vector3.left, 0.5f);
directions[10] = -Vector3.Lerp(Vector3.up,Vector3.left, 0.75f);
directions[11] = -Vector3.Lerp(Vector3.left,Vector3.down,0.25f);
directions[12] = -Vector3.Lerp(Vector3.left,Vector3.down,0.5f);
directions[13] =-Vector3.Lerp(Vector3.left,Vector3.down,0.75f);
I omitted the left and right directions b/c didn't need them in my game.
Changed
Vector3 vect = transform.position += ballVelocity * (ballSpeed + setting.GetComponent<settings>().difficulty) * Time.deltaTime ;
TO: if(transform.gameObject.rigidbody != null) {
transform.gameObject.rigidbody.velocity = ballVelocity * (ballSpeed + setting.GetComponent<settings>().difficulty) ;
}
uses the physics engine to do the movement like others suggested, but have to make sure to set velocity back to zero to stop the object when it doesn't need to move.
and my direction recalculating function
private Vector3 bounce(Vector3 Direction, Vector3 normal) {
if (normal == Vector3.up)
{
if (Direction == directions[1])
{
Direction = directions[0];
}
else if (Direction == directions[8])
{
Direction = directions[13];
}
else if (Direction == directions[9])
{
Direction = directions[12];
}
else if (Direction == directions[10])
{
Direction = directions[11];
}
else if (Direction == directions[7])
{
Direction = directions[2];
}
else if (Direction == directions[6])
{
Direction = directions[3];
}
else if (Direction == directions[5])
{
Direction = directions[4];
}
}
else if (normal == Vector3.down)
{
if (Direction == directions[0])
{
Direction = directions[1];
}
else if (Direction == directions[13])
{
Direction = directions[8];
}
else if (Direction == directions[12])
{
Direction = directions[9];
}
else if (Direction == directions[11])
{
Direction = directions[10];
}
else if (Direction == directions[2])
{
Direction = directions[7];
}
else if (Direction == directions[3])
{
Direction = directions[6];
}
else if (Direction == directions[4])
{
Direction = directions[5];
}
}
else if (normal == Vector3.left)
{
if (Direction == directions[13])
{
Direction = directions[2];
}
else if (Direction == directions[12])
{
Direction = directions[3];
}
else if (Direction == directions[11])
{
Direction = directions[4];
}
else if (Direction == directions[10])
{
Direction = directions[5];
}
else if (Direction == directions[9])
{
Direction = directions[6];
}
else if (Direction == directions[8])
{
Direction = directions[7];
}
}
else if (normal == Vector3.right)
{
if (Direction == directions[2])
{
Direction = directions[13];
}
else if (Direction == directions[3])
{
Direction = directions[12];
}
else if (Direction == directions[4])
{
Direction = directions[11];
}
else if (Direction == directions[5])
{
Direction = directions[10];
}
else if (Direction == directions[6])
{
Direction = directions[9];
}
else if (Direction == directions[7])
{
Direction = directions[8];
}
}
else
{
Direction = -Direction;
error = normal;
}
return Direction;
}
Answer by Tetrad · Jun 24, 2010 at 04:59 AM
Shot in the dark: Could you be hitting multiple contact points at once and not doing the correct reflect calculation?
Is your movement code in FixedUpdate? Does your object have a rigid body on it? Is your object penetrating the collision and getting stuck?
Yes the movement does happen during the FixedUpdate. Yes it does have a RigidBody attached.
Not the same kind of question, but I wrote an answer here for somebody doing something similar with movement that you might want to look into. http://answers.unity3d.com/questions/13402/getting-maze-walls-using-3d-meshes-to-work/13418#13418
Forgot to mention also using linecasting to detect the collision for the camera boundary.
The multiple contact point wouldn't be the problem b/c it uses linecasting on the walls. I think it is more then likely a low angle with the wall. I am just not sure how to make the $$anonymous$$imum angle be higher when i reflect the ball. If that makes any since
Only suggestion I have is to put some debug lines in your world so you can see what your velocity is, normals are, etc. to make sure things are doing what you think they're doing. http://unity3d.com/support/documentation/ScriptReference/Debug.DrawLine.html
Answer by Wolfram · Aug 16, 2010 at 03:32 PM
"... some times the ball will start rolling along the surface that it collided with. I think it is only when the angle is real low."
Actually, this effect can be controlled by an editor setting, Edit->ProjectSettings->Physics->BounceThreshold. The default is 2, which is very large. Use something small, adapt to your needs (not too small, because (taken from the docs): "Bounce Threshold Two colliding objects with a relative velocity below this value will not bounce. This value also reduces jitter so it is not recommended to set it to a very low value."
But I admit it is very hard to make the connection that a parameter like this could be the problem - took me a while to get it when I first had the problem you described :-/