I'm trying to create a game that involved shooting a laser at objects and having that laser reflect off objects, but the laser seems to go through objects sometimes. I've noticed that the second raycast will end at the origin of the scene instead of reflecting off the object, even if that means going through the object.
Here is a picture of what I mean:
Sometimes it will reflect off the object, but still go through the origin.
This is my code for reflecting so far:
if(hit.collider.gameObject.tag == "Reflect"){
hit2 = Physics2D.Raycast(hit.point, -hit.point); //The problem is probably here
Debug.DrawLine(hit.point, hit2.point);
lineRenderer.SetPosition(2, hit2.point);
}
I've tried using the Vector2.Reflect method, but it does the same thing. I've tried using the hit.normal, but that doesn't work either. I've also tried using a ray and setting the direction to be the opposite of the ray's direction, but that didn't work.
I'm not sure I understand what you are trying to do with "hit2". As I understand it you want your laser to reflect on the object like this:
Basicly, you need to get the hit.point and use the hit.normal to get the direction of the beam reflection. This is done with by passing them into Vector2.Reflect().
To get the points for the line renderer you assign them the hit.point and loop through for the amount of times you want your laser to reflect. I've built it for you here, but I recommend you spend some time understanding what it does before you use it. Make sure the Line Renderer is a child object of the object that holds the script:
[SerializeField] private LineRenderer lineRenderer;
[SerializeField] private float laserMaxLength = 2f;
[SerializeField] private int laserMaxHits = 5;
private void Start()
{
//This is to stop a raycast from inside a collider from hitting said collider
//(risk of happening with the "reflected" raycasts):
Physics2D.queriesStartInColliders = false;
}
void Update()
{
RaycastHit2D[] hits = new RaycastHit2D[laserMaxHits];
Vector3[] linePoints = new Vector3[hits.Length + 1];
float laserLength = laserMaxLength;
Vector2 laserDirection = transform.right;
hits[0] = Physics2D.Raycast(transform.position, laserDirection, laserLength);
linePoints[0] = Vector2.zero;
for (int i = 0; i < hits.Length; i++)
{
if (hits[i])
{
if (hits[i].collider.gameObject.tag == "Reflect")
{
//Part of the max length of the laser is used:
laserLength -= hits[i].distance;
//Get the reflect direction from the hit normal:
laserDirection = Vector2.Reflect(laserDirection, hits[i].normal);
//Assign a point on the linerenderer where the ray hit:
linePoints[i + 1] = transform.InverseTransformPoint(hits[i].point);
//New raycast for evey bounce, except for the last hit
//possible (to avoid running out of array):
if (i != hits.Length-1)
{
hits[i + 1] = Physics2D.Raycast(hits[i].point, laserDirection , laserLength);
}
Debug.DrawRay(hits[i].point, laserDirection, Color.blue);
} else
{
//Hit a collider that is non non-reflective
linePoints[i + 1] = transform.InverseTransformPoint(hits[i].point);
//Make sure the lineRenderer has enough points to draw the entire laser:
lineRenderer.positionCount = i + 2;
break;
}
} else
{
//End of laser did not hit anything
linePoints[i + 1] = (Vector2)linePoints[i] + laserDirection * laserLength;
//Make sure the lineRenderer has enough points to draw the entire laser:
lineRenderer.positionCount = i + 2;
break;
}
}
//Assign the found point to the line renderer:
lineRenderer.SetPositions(linePoints);
}
Good luck, pew pew!