Convert 1 Raycast Into 4 Parallel Raycasts Given 2 Positions and Radius To Simulate Projectile Width

I need to create a total of four raycasts given two Vector3 positions, starting from Position1 and ending at Position2.

I can easily create a raycast to emulate a projectile hit (given two positions) but I need to account for the Radius of the projectile. I figure a quick and simple solution would be to do four raycasts parallel but offset to the original raycast (offset by the radius of the projectile). (making a box is fine I don’t need a perfect circle)

Here is a visualization of the ray given two positions (top image) and the four rays I need (bottom image):

Again, the only known variables here are Position1, Position2, and Radius of Projectile.

For example:

local Pos1 =, 7.63, 0.62)
local Pos2 =, 7.63, 0.62)
local Radius = 1.2

What I need is to convert those pair of positions into four pairs of positions given the Radius.

Oh you can just use CFrame.lookAt() to generate the CFrame.

local Pos1 =, 7.63, 0.62)
local Pos2 =, 7.63, 0.62)
local Radius = 1.2
local lookAtCF = CFrame.lookAt(Pos1,Pos2)

local upPosition = Pos1 +lookAtCF.UpVector*Radius
local rightPosition = Pos1 +lookAtCF.RightVector*Radius
local downPosition = Pos1 - lookAtCF.UpVector*Radius
local leftPosition = Pos1 - lookAtCF.RightVector*Radius

And here is how CFrame.lookAt() works via the example code they gave on the API which was meant to subsitute,pos2) but then removed for some reason to promote CFrame.lookAt() I guess. Just if you were curious to how the CFrame.lookAt() is generated.

Native lua implementation of CFrame.lookAt
--This is the same as CFrame.lookAt
local function customLookAt(position,lookAt,upVector)
	upVector = upVector or,1,0)
	local direction = lookAt-position
	local rightVector = direction:Cross(upVector)
	local newUpVector = rightVector:Cross(direction)
	return CFrame.fromMatrix(position,rightVector,newUpVector)

If you want to place the rays in a circular approach instead you can use the obtained CFrame.lookAt.UpVector as the new y axis and CFrame.lookAt.RightVector as the x axis.

Oh nice, I’m pretty new to Roblox and didn’t know about CFrame.lookAt.

I’ll test that out now and let you know how that goes.

If they found the answer mark it as the solution.

1 Like

Yup, that did the trick (Thanks), whipped up a sample real fast to verify:

local function VisualizeRayGivenTwoPositions(pos1, pos2, color)
	local rayVector = pos2 - pos1
	local ray =, rayVector)
	local part ="Part");
	part.Material = Enum.Material.Neon;
	part.Size =, .1, ray.Direction.magnitude);
	part.CFrame = + ray.Direction/2, ray.Origin + ray.Direction);
	part.Anchored = true;
	part.CanCollide = false;
	part.BrickColor = color
	part.Transparency = 0.5
	part.Parent = game.Workspace;

local Pos1 =, 7.63, 0.62)
local Pos2 =, 7.63, 0.62)
local Radius = 1.2
local lookAtCF = CFrame.lookAt(Pos1,Pos2)

VisualizeRayGivenTwoPositions(Pos1, Pos2,, 255, 255))

for _, vectr in pairs({lookAtCF.UpVector, lookAtCF.RightVector, -lookAtCF.UpVector, -lookAtCF.RightVector}) do
	local newpos1 = Pos1 + vectr * Radius
	local newpos2 = Pos2 + vectr * Radius
	VisualizeRayGivenTwoPositions(newpos1, newpos2,, 255, 0))

This gave me:

1 Like