- Home /
StackOverflowExeption problem
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.
Answer by Hellium · Mar 16, 2018 at 10:21 PM
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);
}
Similarly (or additionally), a limit can be enforced using shot distance if desired, although it would be a bit more computationally expensive to process.
public void Shoot(Vector2 start, Vector2 dir, int maxReflectionCount = 10, float remainingDistance = 100.0f)
{
RaycastHit2D hit = Physics2D.Raycast(start, dir, remainingDistance, mask);
if (hit.collider.tag == "$$anonymous$$irror")
{
direction = Vector2.Reflect(dir, hit.normal);
float distance = (hit.point - start).magnitude;
Shoot(hit.point, direction, maxReflectionCount - 1, remainingDistance - distance);
}
}
Answer by Bunny83 · Mar 16, 2018 at 10:48 PM
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;
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612154737im_/https://answers.unity.com/themes/thub/images/avi.jpg)