# Calculating Shortest distance to target with ricochets

Hi,
I have objects that will only move in a straight line and will ricochet off of any surface that they hit.

I’m trying to calculate the angle at which to launch the object, taking ricochet’s into account, that will result in the shortest path taken to reach a target.

I’m using the following line of code to apply force to the object

``````Vector3 GetLaunchDir()
{
Vector3 bestDir = new Vector3(0,0,0); // this is used to store the best direction to launch this rigidbody
collider.enabled = false; // I turn off the collider on this object so it isn't caught by my sphere casting

for(float deg = 0; deg < 360; deg += 1)	// I'm checking every euler angle between 0 and 360
{
Vector3 dir = (Quaternion.Euler(0,deg,0) * Vector3.forward).normalized;	// this sets the starting angle to be checked this loop
Vector3 start = transform.position;	// start out at enemy's current position
Vector3 launchDir = dir;  //store the starting angle for this check, not to be changed

float distance = -Mathf.Infinity; // store the shortest distance found

float travelDist = 1000; // this is the maximum distance that will be checked

for(float dist = 0; dist < travelDist; dist += 0) // for each angle, calculate ricochets so long as the distance 'traveled' by the check hasn't exceeded travelDist, i have travelDist decrement within the loop rather than dist increment
{
RaycastHit tempHit;	// store raycast hit from spherecast this loop
if(Physics.SphereCast(start,objRad,dir, out tempHit, travelDist))	// get the next object this enemy will hit if traveling in direction dir from position start
{
travelDist -= Vector3.Distance(start, tempHit.point); //decrement travelDist by the distance of this check

if(tempHit.transform.gameObject == target.gameObject)	//if the hit object is the target, see if this is the best direction so far
{
if(travelDist > distance) //if travelDist is greater than distance, then this is currently the shortest path
{
bestDir = launchDir;// set bestDir to the initial launchDir
distance = travelDist;//set distance to travelDist as this is the new best to beast
}

travelDist = 0;
}
else // if this hit an object other than the target
{
start = tempHit.point;	// set start to the currently hit position so the next check starts from there
dir = Vector3.Reflect(dir,tempHit.normal).normalized;	// reflect dir off of the normal of raycast hit
}
}
else // if the spherecast didn't hit anything, set travelDist to 0 to cancel this angle's check
{
travelDist = 0;
}
}

}
collider.enabled = true; //after all checks, set this object's collider back on
return bestDir; //return the bestDir found to be used for the force
}
``````

This is giving me unexpected and unwanted behavior, launching the object in odd directions. What am I doing wrong?
I am searching for a solution and have yet to find one.

Well, the conceptual way you do this is:

a) You have a start position A, and a destination position B.

b) You have an infinite line W.

c) You calculate the position, C on the line W, which gives the shortest path from A to B via C.

d) Reflect the position B about the line W. (So B to B’ intersects W at right angles.)

e) Compute C which is where A->B’ crosses W.

How do you calculate W’s position or C’s position on W?

Also, I need to allow any number of ricochets. Will this allow for that?

I got the functionality I was looking for.
I ended up splitting the function in two and, rather than using a for loop to check if the direction was good, I had the spherecast function return a bool if it hits the player, and if it hits something else, I have it return another iteration of the spherecast function. In this way, it continues spherecasting with a new starting position and direction until it doesn’t hit anything or it hits the player.