I have a start and end, i need to place an adjustable amount of rays on the line from start to end. But I can't figure out how to correctle place them. I almost finished, but rays is not placed at the end.
Green (2, 0, 2) for start and Red (2, 0, -2) for end with distance between 4
This is my result with 2 rays, the center ray need to be at the end (red ray), and next rays add should be at the center of start and end rays
What happens if i adding third ray, the end ray position isn't in use
And 5 rays. The first and the last rays need to be at the start and the end. Other 3 rays should to be between
This is my code:
public class VehicleAroundCast : MonoBehaviour
{
[SerializeField] private int sideRaysAmount;
[SerializeField] private Vector3 offset;
private void Update()
{
Vector3 startRayPos = transform.position + Vector3.left * offset.x + Vector3.forward * offset.z;
Vector3 endRayPos = transform.position + Vector3.left * offset.x + Vector3.back * offset.z;
float dist = Vector3.Distance(startRayPos, endRayPos);
Debug.DrawRay(startRayPos, Vector3.down, Color.green);
Debug.DrawRay(endRayPos, Vector3.down, Color.red);
for (int i = 0; i < sideRaysAmount; i++)
{
float step = dist / sideRaysAmount * i;
Vector3 position = (transform.position + Vector3.left * offset.x + Vector3.forward * offset.z) + Vector3.back * step;
Debug.DrawRay(position, Vector3.down);
}
}
}
Following up from the clarification through the comment I'd do a couple of things a bit different. I'll just edit your code so that it should work as you'd need it to and explain it in code comments.
public class VehicleAroundCast : MonoBehaviour
{
[SerializeField] [Min(0)] private int intermediateRayCount;
// I renamed this field so the name is more descriptive, intermediate meaning between start and end
// to make sure that no number below 0 can be assigned I added the [Min(0)] attribute, a number
// below 0 would break the logic and wouldn't make sense
[SerializeField] private Vector3 offset;
private void Update ()
{
// we don't want to clog up our Update() method with tons of lines of code
// this serves better maintainability as well
CastRays();
}
private void CastRays ()
{
Vector3 startRayPos = transform.position + Vector3.left * offset.x + Vector3.forward * offset.z;
Vector3 endRayPos = transform.position + Vector3.left * offset.x + Vector3.back * offset.z;
// if we don't have any intermediate rays we can save on the calculation that is necessary when we
// have intermediates, we just cast the the two rays and end the method by returning
if (intermediateRayCount == 0)
{
Debug.DrawRay(startRayPos, Vector3.down, Color.green);
Debug.DrawRay(endRayPos, Vector3.down, Color.red);
return;
}
// instead of using Vector3.Distance() we'll calculate the directional vector manually this way
// we can get not only the distance (directional vectors magnitude) but the direction to move
// along to space the rays as well
// subtarting the start position from the end position gives us the directional vector
Vector3 direction = endRayPos - startRayPos;
// a directional vectors magnitude gives the distance from start to end
float distance = direction.magnitude;
// after the distance has been established we normalize the direction so that it's length is 1
direction.Normalize();
// we have at least two rays (start and end) so our total is the rays between start and end plus two
int totalRayCount = intermediateRayCount + 2;
// the space between the individual rays, we have to subtract one from the totalRayCount in order to
// place the the last ray at the end position (yes this could be optimized but I want to write out
// the logic fully so that it's clear what happens)
float spacing = distance / (totalRayCount - 1);
for (int i = 0; i < totalRayCount; i++)
{
// we can simply get the ray position by adding the direction multiplied by the spacing multiplied
// by the number of iterations we've gone through to the start position
// since the direction is normalized we can multiply it by the distance between rays to give it
// the length between two rays, if we then multiply it by the number of rays the current ray is,
// we get the distance as well as direction the current ray has to be placed away from the start
// position
Vector3 rayPosition = startRayPos + direction * spacing * i;
// i added some color so you can see start and end
if (i == 0)
Debug.DrawRay(startRayPos, Vector3.down, Color.green);
else if (i == totalRayCount - 1)
Debug.DrawRay(endRayPos, Vector3.down, Color.red);
else
Debug.DrawRay(rayPosition, Vector3.down, Color.white);
}
}
}