- Home /
Unity3d find angle/direction of a Ray / Raycasthit
Hello,
I'm trying to make a Billiard game and I wanna calculate the direction on which the Cue Ball(white ball) will be moving after it hits another ball.
As you can see I wanna calculate the angle/direction in which the RAY hits the ball and the angle/direction on which the raycast will change its direction into. I need the angle to display as a Vector3 variable so I can use it on the linerenderer(3).
I already calculated the direction that the ball that gets hit will go.
If you could help me on this that would be great!
Current code:
RaycastHit hitz;
if (Physics.SphereCast(transform.position, 0.8f, location - transform.position, out hitz, Mathf.Infinity, lmm2))
{
lineRenderer2 = hitz.collider.GetComponentInChildren<LineRenderer>();
lineRenderer2.SetVertexCount(2);
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(0, hitz.point);
if (!Input.GetKey(KeyCode.Mouse0))
{
Vector3 start = hitz.point;
Vector3 end = start + (-hitz.normal * 4);
if (lineRenderer2)
{
if (!Input.GetKey(KeyCode.Mouse0))
lineRenderer2.SetPosition(1, end);
}
if(lineRenderer3)
{
anglelel = Vector3.Angle(hitz.normal, hitz.point);
Vector3 cross = Vector3.Cross(hitz.normal, hitz.point);
if(cross.y > 0)
{
tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward;
}
if (cross.y < 0)
{
anglelel = -anglelel;
tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward;
}
Vector3 start2 = hitz.point;
Vector3 end2 = start2 + ((tzt) * 5f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
}
}
Thank you for your time.
Edit:
This part of the code has been changed to this one, currently makign some progress but still, it's not good enough. Before
if(lineRenderer3)
{
Vector3 start2 = hitz.point;
//THIS IS WHERE I'M CURRENTLY STUCK AT
Vector3 end2 = start2 + (hitz.point * 0.7f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
After
if(lineRenderer3)
{
anglelel = Vector3.Angle(hitz.normal, hitz.point);
Vector3 cross = Vector3.Cross(hitz.normal, hitz.point);
if(cross.y > 0)
{
tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward;
}
if (cross.y < 0)
{
anglelel = -anglelel;
tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward;
}
Vector3 start2 = hitz.point;
Vector3 end2 = start2 + ((tzt) * 5f);
lineRenderer3.SetPosition(0, hitz.point);
lineRenderer3.SetPosition(1, end2);
}
Answer by Bunny83 · Aug 22, 2016 at 05:09 PM
Well, the rules are pretty simple. The ball you hit moves along the hit normal and the ball that hits moves along the tangent of the hit point.
Wikipedia ellastic collision has this animated gif which should explain everything:
So what you have to do is:
get the normal vector of your collision
calculate the tangent (in 2d simply rotate the normal 90°)
Project the original velocity vector onto both normalized directions (normal, tangent)
Apply the resulting vector as new velocity vectors for each ball.
This of course assumes that the two balls have the same mass.
This is how you calculate it manually. Keep in mind that the physics system might give you a different result due to some inaccuracies and rotations involved in the collision. Also keep in mind when you calculate it manually that it's possible to get a chain reaction of new collisions when more than 2 balls are involved. This might be difficult to simulate with a limited frame rate / certain step size.
For example a "split" of two balls with a third will result the wrong direction of the cueball if you process one collision at a time.
In the 3d case you would need to calculate the correct tangent. This can be done by using "Vector3.ProjectOnPlane" and projecting the direction vector between the two balls onto the plane with the hit normal as normal. You might want to take some extra care when the direction is in line with the hit normal. In this case it's a central collision, so the cue ball stops and the other moves in a straight line
If you also need the reflection off a wall it's basically the same as with two balls, just that the impulse that would drive the other ball (which is now the wall) is simply reflected back onto cue ball) So you simply apply both velocities to the ball but reverse the vector that goes "into the wall"
Hey, that did the trick. Thank you very much for your help!
Your answer
Follow this Question
Related Questions
Get Direction from 2 Vectors - and Apply to Transform 0 Answers
Transform angle to grid position 2 Answers
Why does gravity's vector3 act so weird? 1 Answer
how to find direction between two points 2 Answers
Angle to Direction 1 Answer