I resolved the question on how to draw a line, so here is the result:
So, now I want to create a line that shows the possible bounce off the wall (and the other ball).
Some suggested I use the Reflect method but it did not work, here is how I implemented it, script is attached to the white que ball:
//
Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit2;
//
if (Physics.Raycast(ray2, out hit2, 100.0f)){
//position of white wall
Vector3 startPos = transform.position;
//cliked position, translated to the table plane
Vector3 clickPos2 = new Vector3(hit2.point.x, hit2.point.y, transform.position.z);
//get direction from ball to clicked position
Vector3 direction = Direction (clickPos2 - startPos);
//so I simply should do I reflect, it gives me a bit odd results
Vector3 reflectDir = Vector3.Reflect(direction, hit2.normal);
//finally im drawing the line
lineRenderer.SetPosition(0, startPos);
Vector3 forward = transform.TransformDirection(direction) * 100;
lineRenderer.SetPosition(1, forward);
//reflection?
lineRenderer.SetPosition(2, hit2.point);
lineRenderer.SetPosition(3, reflectDir);
The inDirection is the direction you are currently moving and the normal is the normal of the surface you want to reflect against. This will (or should) give you the reflected direction.
You’re taking a raycast from the CAMERA towards the table… you’re basically getting the normal where you click on the table. This is going to be adjacent to the surface of the table. If you reflect a vector parallel to the table with a vector adjacent to the table, you’ll get NO reflection… by definition of the reflection formula:
v2 = v1 - 2(v1 dot n) * n
Note the v1 dot n, if two vectors are adjacent to one another, their dot product is 0. You get:
v1 - 2 * 0 * n
v1 - 0
v1
You end up with the same result.
You’re using the wrong normal. What I think you are meaning to do is raycast from the camera to get a point to describe in which direction the cue ball should go (you want to shoot TOWARDS the point clicked). This is what this line is doing right?
//get direction from ball to clicked position
Vector3 direction = Direction (clickPos2 - startPos);
Ok, so once you have that… you need to calculate ANOTHER raycast from the cueball position in that direction, and see what THAT hits. That’s the normal you’re going to reflect over.
you just created an array at the position ‘direction’. That doesn’t make sense.
The constructor for Ray is:
Ray(Vector3 position, Vector3 direction)
So… if ‘this’ is the cue ball you would say:
Vector3 direction = (
Ray ray3 = new Ray(this.transform.position, direction);
And now that’s a ray from the position of ‘this’ (the cue ball) in the direction of ‘direction’. Which is from the cue ball to the point clicked on the table!
How I’d write it completely is:
Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit2;
if(Physics.Raycast(ray2, out hit2))
{
var cueBallPos = this.transform.position;
var dir = (hit.point - cueBallPos);
dir.z = 0f; //flatten on table plane
Ray ray3 = new Ray(cueBallPos, dir);
RaycastHit hit3;
if(Physics.Raycast(ray3, out hit3))
{
Debug.Log("Hit the wall!");
Debug.Log("Wall Collider: " + hit3.collider.name);
Debug.Log("Wall Normal: " + hit3.normal.ToString());
}
}
Thanks for answer, it is definitely the right direction. Here is how I wrote it and Im still having a problem with the correct reflection, check the ending lines:
Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit2;
//
if (Physics.Raycast(ray2, out hit2, 100.0f)){
//
Vector3 startPos = transform.position;
Vector3 clickPos2 = new Vector3(hit2.point.x, hit2.point.y, transform.position.z);
Vector3 direction = Direction (clickPos2 - startPos);
if(rb.velocity.x == 0.0f && rb.velocity.y == 0.0f){
gameObject.transform.rotation = startTrans;
lineRenderer.SetPosition(0, startPos);
Vector3 forward = transform.TransformDirection(direction) * 100;
lineRenderer.SetPosition(1, forward);
//lineRenderer.SetPosition(2, hit2.point);
//lineRenderer.SetPosition(3, reflectDir);
lineRenderer.enabled = true;
}
Vector3 cueBallPos = this.transform.position;
var dir = (hit2.point - cueBallPos);
dir.z = 0f; //flatten on table plane
Ray ray3 = new Ray(cueBallPos, dir);
RaycastHit hit3;
if(Physics.Raycast(ray3, out hit3)){
//
Vector3 reflectDir = Vector3.Reflect(dir, hit3.normal);
//
lineRenderer.SetPosition(2, hit3.point);
//
lineRenderer.SetPosition(3, dir);
}
}
I notice you often mix up direction vectors and position vectors.
A vector representing direction use in place of a posiiton will give you a point from <0,0,0> that is direction units away from <0,0,0>. That’s what a ‘point’ is… it’s telling you how far away from the origin you are.