How to set a beam's curve position depending on the player position

Hello everyone, so i’m trying to create a beam effect that sets the curves depending of the player position.

This is what i mean:

How would i handle this? This is my current script:

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()

local maxDistance = 18

local function CreateCurvedBeam(startPos, endPos, color)
	workspace.ClientStuff:ClearAllChildren()

	local sphere = Instance.new("Part")
	sphere.Shape = Enum.PartType.Ball
	sphere.Color = color
	sphere.Position = endPos
	sphere.Size = Vector3.new(0.5, 0.5, 0.5)
	sphere.Anchored = true
	sphere.CanCollide = false
	sphere.Parent = workspace.ClientStuff

	local midpoint = (startPos + endPos) / 2
	local distance = (endPos - startPos).Magnitude

	local curveHeight = math.sin(distance / maxDistance * math.pi) * 5
	midpoint = midpoint + Vector3.new(0, curveHeight, 0)

	local sphereAttachment = Instance.new("Attachment")
	sphereAttachment.Position = Vector3.new(0, 0, 0)
	sphereAttachment.Parent = sphere

	local playerTorsoAttachment = Instance.new("Attachment")
	playerTorsoAttachment.Position = Vector3.new(0, 0, 0)
	playerTorsoAttachment.Parent = Player.Character.HumanoidRootPart

	local beam = Instance.new("Beam")
	beam.Attachment0 = playerTorsoAttachment
	beam.Attachment1 = sphereAttachment
	beam.Parent = workspace.ClientStuff
	beam.Color = ColorSequence.new(color)
	beam.Width0 = 0.6
	beam.Width1 = 0.6
	beam.FaceCamera = true
	beam.Enabled = true
	beam.LightEmission = 1

	beam.CurveSize0 = midpoint.Y
	beam.CurveSize1 = -midpoint.Y
	beam.Width0 = .6
	beam.Width1 = .6
end

Mouse.Button1Down:Connect(function()
	local playerPosition = Player.Character.HumanoidRootPart.Position
	local mousePosition = Mouse.Hit.Position
	local direction = (mousePosition - playerPosition).unit * maxDistance

	local ray = Ray.new(playerPosition, direction)
	local Params = RaycastParams.new()
	Params.FilterType = Enum.RaycastFilterType.Exclude
	Params.FilterDescendantsInstances = {Player.Character}
	local raycastResult = workspace:Raycast(playerPosition, direction, Params)

	if raycastResult then
		local distance = (raycastResult.Position - playerPosition).Magnitude

		if distance <= maxDistance then
			CreateCurvedBeam(playerPosition, raycastResult.Position, Color3.fromRGB(255, 0, 0))
		else
			print("Click is too far away")
		end
	else
		print("Ray did not hit anything")
	end
end)

Any help would be appreciated.

Sorry seems like the video isnt available, heres the one that works

External Media

Hi! I came up with a little idea. Here’s a photo:

Basically, you get the magnitude of the difference between the attachment position and the player position:

local mag = (Attachment1.WorldPosition - HumanoidRootPart.Position).Magnitude

Next, you get the lookVector of the HumanoidRootPart:

local lookVector = HumanoidRootPart.CFrame.LookVector

finally, the curve position relative to the player position is:

local curvePos = lookVector * mag/number

Edit: You can also achieve a similar effect by editing the CurveSize0 of the beam to 5-15, without the need of a curve position.

Edit2: you gotta get the Lookvector of the camera, not the root, sorry.

1 Like

Okay thank you, i will try this

Thank you so much! This works perfectly.

External Media

Glad to hear. If you want some elevation as well, you can switch HumanoidRootPart.CFrame.LookVector with Camera.CFrame.LookVector.

If you want the curve to be stronger or weaker, you can divide the mag by some number.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.