So i have a function that sends out a raycast from a point to a direction. This ray will check if it hits an object with the tag “mirror” and be reflected by calling the shoot function again and that works, but it causes a stack overflow.
public void Shoot(Vector2 start, Vector2 dir)
{
RaycastHit2D hit = Physics2D.Raycast(start, dir, 100f, mask);
if (hit.collider.tag == "Mirror")
{
direction = Vector2.Reflect(dir, hit.normal);
Shoot(hit.point, direction);
}
float dist = Vector3.Distance(start, hit.point);
Debug.DrawRay(start, dir * dist, Color.red, 2f);
}
So now I’m wondering if there is a better way to go about this than calling the function inside of itself, or if there is another way to not cause a stack overflow.
public void Shoot(Vector2 start, Vector2 dir, int maxReflectionCount = 10)
{
if( maxReflectionCount <= 0 )
{
Debug.LogError(“Too many reflections” ) ;
return ;
}
RaycastHit2D hit = Physics2D.Raycast(start, dir, 100f, mask);
if (hit.collider.tag == "Mirror")
{
direction = Vector2.Reflect(dir, hit.normal);
Shoot(hit.point, direction, maxReflectionCount - 1);
}
float dist = Vector3.Distance(start, hit.point);
Debug.DrawRay(start, dir * dist, Color.red, 2f);
}
Any recursive process can be carried out iteratively and the other way round. Certain things can be easier implemented recursively but generally a recursive process is usually slower due to the call stack overhead.
To reach a stack overflow you really need a lot recursive calls. Any recursive process requires a well defined exit condition. However in your case it would be easier to do your ray bouncing interatively since you don’t really need to preserve the state of the previous calls.
const int maxBounces = 1000;
public void Shoot(Vector2 start, Vector2 dir)
{
for(int i = 0; i < maxBounces; i++)
{
RaycastHit2D hit = Physics2D.Raycast(start, dir, 100f, mask);
Debug.DrawRay(start, dir * hit.distance, Color.red, 2f);
// if we didn't hit anything or if the thing we hit is not a mirror, exit
if (hit.collider == null || hit.collider.tag != "Mirror")
return;
// we have hit a mirror
dir = Vector2.Reflect(dir, hit.normal);
start = hit.point;
}
}