Is there way to curve Raycast?

Hi! Is tere any way to make a curved raycasts?
I need it for shooting ballistics.
Rigidbody bullets are not suitable, when speed is very fast - rigidobies could come through object without detecting.

So is there any ways to make it?
Thank you!

You can make your bullet report whether something is between its current position and previous position.

public class BulletCollision : MonoBehaviour
{
    private Vector3 previous;
    public event Action<GameObject> RaiseCollision;
     void Start()
    {
          this.previous = this.transform.position;
    }
    void Update()
    {
          RaycastHit hit
          if(Physics.Linecast(this.previous, this.transform.position, out hit)){
                  if(RaiseCollision != null) { RaiseCollision(hit.collider.gameObject); }
          }
          this.previous = this.transform.position;
    }
}

At this point, your projectile does not need collider anymore.

Have you considered combining raycast with rigidbody?
Each fixed update check raycast toward next position, if it hits, then you’ll detect your object even when rigidbody has high velocity.

I know this is kind of reviving a dead thread, but I was playing around with this and got something somewhat similar. It’s by no means perfect, and could definitely use some improvement, but it does work and isn’t that performance intensive. The iterations represents the scale of the curvature, as well as the scale of the ray. The Ray should have the same position as the startPos parameter and the Ray’s direction is used to move the raycasts. You can tag things with a “Permeable” tag to get the raycast to pass through them (it only works once as I only included one secondary for loop, you can include more if you want to add more penetration). Like I said, it’s not perfect but it could definitely be a start. Hope this helps! :smiley:

void curvedRaycast(int iterations, Vector3 startPos, Ray ray, int velocity)
    {
        RaycastHit hit;
        Vector3 pos = startPos;
        var slicedGravity = Physics.gravity.y / iterations / velocity;
        Ray ray2 = new Ray(ray.origin, ray.direction);
        print(slicedGravity);
        for (int i = 0; i < iterations; i++)
            {
                if (Physics.Raycast(pos, ray2.direction * velocity, out hit, velocity))
                {
                    Debug.DrawRay(pos, ray2.direction * hit.distance, Color.green);
                if (hit.transform.tag == "Permeable")
                {
                    Debug.DrawRay(pos, ray2.direction * velocity, Color.green);
                    pos += ray2.direction * velocity;
                    ray2 = new Ray(ray2.origin, ray2.direction + new Vector3(0, slicedGravity, 0));
                    for (int x = 0; x < iterations; x++)
                    {
                        if (Physics.Raycast(pos, ray2.direction * velocity, out hit, velocity))
                        {
                            Debug.DrawRay(pos, ray2.direction * hit.distance, Color.yellow);
                            return;
                        }
                        Debug.DrawRay(pos, ray2.direction * velocity, Color.magenta);
                        pos += ray2.direction * velocity;
                        ray2 = new Ray(ray2.origin, ray2.direction + new Vector3(0, slicedGravity, 0));
                    }
                }
                else
                {
                    return;
                }
            }
                Debug.DrawRay(pos, ray2.direction * velocity, Color.cyan);
                pos += ray2.direction * velocity;
                ray2 = new Ray(ray2.origin, ray2.direction + new Vector3(0, slicedGravity, 0));
        }
        Debug.DrawRay(startPos, pos, Color.red);
        /*for (int i = 0; i < iterations; i++)
        {
            Debug.DrawRay(pos, ray2.direction * velocity, Color.red);
            pos += ray2.direction * velocity;
            ray2 = new Ray(ray2.origin, ray2.direction + new Vector3(0, slicedGravity, 0));
        }*/
    }

This is the experimental version I was working on to try and reduce the number of parameters. Only issue with this one is that the rays don’t connect, despite the math and logging suggesting they should. If anyone figures out why and can fix it feel free to let me know!

EDIT: I updated and redid this script, it works 100% percent now!

Vector3[] GravCast(Vector3 startPos, Vector3 direction, int killAfter, int velocity, bool reflect)
	{
		RaycastHit hit;
		Vector3[] vectors = new Vector3[killAfter];
		Ray ray = new Ray(startPos, direction);
		for (int i = 0; i < killAfter; i++)
		{
            if(Physics.Raycast(ray,out hit,1f))
			{
                if (reflect)
				{
					print(hit.normal);
					/*for (int e = 0; e < killAfter; e++)
					{
                        if (Physics.Raycast(ray, out hit, 1f))
						{
							return vectors;
						}
						ray = new Ray(ray.origin + ray.direction, ray.direction + (Physics.gravity / killAfter / velocity));
					}*/
				}
				return vectors;
			}
			Debug.DrawRay(ray.origin, ray.direction, Color.blue);
			ray = new Ray(ray.origin + ray.direction, ray.direction + (Physics.gravity / killAfter / velocity));
			vectors *= ray.origin;*
  •  }*
    
  •  return vectors;*
    
  • }*
    }