Need help with brezier curve and raycast

Im trying to make a frieza death ball which makes the player teleport up and shoot the ball that it has created down

local UIS = game:GetService("UserInputService")
local Rp = game:GetService("ReplicatedStorage")
local BallEvent = Rp:WaitForChild("Ball")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local speed = 50
local damage = 15
local Meshes = script.Meshes


function lerp(a, b, c) 
	return a + (b - a) * c
end

function quadBezier(t, p0, p1, p2)
	--/ bezier takes t (time) p0 (1st point) (p1 = middle point) (p2 = Last point)
	local l1 = lerp(p0 ,p1, t)
	--/ lerps first point to the 2nd point
	local l2 = lerp(p1, p2, t)
	--/ lerps 2nd point to the 3rd point
	local quad = lerp(l1, l2, t)
	--/ then puts both of those 2 lerps inside the quad and makes the quad curve

	return quad
end

BallEvent.OnServerEvent:Connect(function(Player,active)
	if active == false then
		local Character = Player.Character
		local Humanoid = Character.Humanoid
		local HumanoidRP = Character:WaitForChild("HumanoidRootPart")
		
		HumanoidRP.CFrame = HumanoidRP.CFrame + Vector3.new(0,8,0)
		HumanoidRP.Anchored = true
		
		
		Humanoid.WalkSpeed = 0  --16
		Humanoid.JumpPower = 0  --50
		
		wait(1)
		
		local Folder = Instance.new("Folder", workspace)
		Folder.Name = Player.Name.." Ball"
		
		----------------------------------------------------------- Ball
		
		local Ball = Meshes:WaitForChild("Main"):Clone()
		Ball.CFrame = Character:WaitForChild("RightHand").CFrame
		Ball.Size = Vector3.new(1,1,1)
		Ball.Anchored = true
		Ball.Parent = Folder
		
		local Effect1 = Meshes:WaitForChild("Effect1"):Clone()
		Effect1.CFrame = Ball.CFrame
		Effect1.Size = Vector3.new(1,1,1)
		Effect1.Anchored = true
		Effect1.Parent = Folder
		
		local Effect2 = Meshes:WaitForChild("Effect2"):Clone()
		Effect2.CFrame = Ball.CFrame
		Effect2.Size = Vector3.new(1,1,1)
		Effect2.Anchored = true
		Effect2.Parent = Folder
		
		local info = TweenInfo.new(
			4.5,                       ---/ Length
			Enum.EasingStyle.Linear,   ---/ easing style
			Enum.EasingDirection.Out, ---/ Easing direction
			0,                       ---/ Times repeated
			false,                   ---/ Reverse (Do you want it to go back or no?)
			0                        ---/ Delay
		)

		local Goals = 
			{
				Size = Vector3.new(9.6, 9.6, 9.6);
			} 
		local BallTween = TweenService:Create(Ball, info, Goals)
		
		BallTween:Play()
		
		----------------------------------------------------------- Effect 1
		
		local info2 = TweenInfo.new(
			4.5,                       ---/ Length
			Enum.EasingStyle.Linear,   ---/ easing style
			Enum.EasingDirection.Out, ---/ Easing direction
			0,                       ---/ Times repeated
			false,                   ---/ Reverse (Do you want it to go back or no?)
			0                        ---/ Delay
		)

		local Goals2 = 
			{
				Size = Vector3.new(10, 10, 10);
			} 
		local BallTween2 = TweenService:Create(Effect1, info2, Goals2)

		BallTween2:Play()

		
		-----------------------------------------------------------              Effect 2
		
		
		local info1 = TweenInfo.new(
			4.5,                       ---/ Length
			Enum.EasingStyle.Linear,   ---/ easing style
			Enum.EasingDirection.Out, ---/ Easing direction
			0,                       ---/ Times repeated
			false,                   ---/ Reverse (Do you want it to go back or no?)
			0                        ---/ Delay
		)

		local Goals1 = 
			{
				Size = Vector3.new(10.5, 10.5, 10.5);
			} 
		local BallTween3 = TweenService:Create(Effect2, info1, Goals1)
		

		BallTween3:Play()
		
		local outWeld = Instance.new("ManualWeld")
		outWeld.Part0 = Ball
		outWeld.Part1 = Effect1
		outWeld.C0 = Ball.CFrame:Inverse() * Effect1.CFrame
		outWeld.Parent = Ball

		local outWeld2 = Instance.new("ManualWeld")
		outWeld2.Part0 = Effect1
		outWeld2.Part1 = Effect2
		outWeld2.C0 = Effect1.CFrame:Inverse() * Effect1.CFrame
		outWeld2.Parent = Effect1

		local outWeld3 = Instance.new("ManualWeld")
		outWeld3.Part0 = Ball
		outWeld3.Part1 = Ball
		outWeld3.C0 = Ball.CFrame:Inverse() * Effect1.CFrame
		outWeld3.Parent = Effect2

		
	end
end)


BallEvent.OnServerEvent:Connect(function(Player,active,mousepos)
	if active == true then
		wait(4)

		local Character = Player.Character
		local Humanoid = Character.Humanoid
		local Humrp = Character:WaitForChild("HumanoidRootPart")
		local Players = game.Players.LocalPlayer
		
		Humanoid.WalkSpeed = 0  --16
		Humanoid.JumpPower = 0  --50

		local Folder = workspace:FindFirstChild(Player.Name.." Ball")
		
		local Ball = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Main")
		Ball.CFrame = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Main").CFrame
		Ball.Size = Vector3.new(1,1,1)
		Ball.Parent = Folder
		
		
		local Effect1 = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Effect1")
		Effect1.CFrame = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Effect1").CFrame
		Effect1.Size = Vector3.new(1,1,1)
		Effect1.Parent = Folder
		
		local Effect2 = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Effect2")
		Effect2.CFrame = workspace:FindFirstChild(Player.Name.." Ball"):FindFirstChild("Effect2").CFrame
		Effect2.Size = Vector3.new(1,1,1)
		Effect2.Parent = Folder
		
		Ball.Anchored = false
		Effect1.Anchored = false
		Effect2.Anchored = false
		
		
		
		Ball.CFrame = CFrame.lookAt(Ball.Position,mousepos) -- replace ball with ur variable for the beam
		
		local BodyVel = Instance.new("BodyVelocity",Ball)
		BodyVel.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
		BodyVel.Velocity = Ball.CFrame.LookVector * speed
		BodyVel.Parent = Ball
		



		local PointA = Humrp
		local PointB = Instance.new("Part")
		PointB.Name = "B"
		PointB.Anchored = true
		PointB.Transparency = 1
		PointB.Position = (Character.PrimaryPart.Position + Player.Character.PrimaryPart.CFrame.LookVector * 15) - Vector3.new(0,-3,0)
		PointB.Parent = Character
		local PointC = Instance.new("Part")
		PointC.Name = "C"
		PointC.Anchored = true
		PointC.Position = (Character.PrimaryPart.Position + Player.Character.PrimaryPart.CFrame.LookVector * 45) - Vector3.new(0,11,0)
		PointC.Transparency = 1
		PointC.Parent = Character


		while true do
			task.wait(1)
			for i=0, 1, .1 do
				Ball.CFrame = CFrame.new(quadBezier(i, PointA.Position,PointB.Position,PointC.Position))
				
				
				local rayparams = RaycastParams.new()
				rayparams.FilterDescendantsInstances = {Character}

				local ray = workspace:Raycast(Humrp.Position, quadBezier(), rayparams)
				if ray then
					
					Ball.Position = ray.Position
					game.TweenService:Create(Ball, TweenInfo.new(2), {CFrame = ray.Position}):Play()
					game.TweenService:Create(Effect1, TweenInfo.new(2), {CFrame = ray.Position}):Play()
					game.TweenService:Create(Effect2, TweenInfo.new(2), {CFrame = ray.Position}):Play()


				else --/ if ray didnt hit anything

				end
				--/ raycast are (startposition, direction * distance, rayparams)
			end
		end	
	end
end)





		
		
		
		
	



What’s the issue? You’re only giving us the goal of the script.

ServerScriptService.Script:13: attempt to perform arithmetic (sub) on nil

1 Like

b doesn’t exist. Check the lines where you call quadBezier.

Ball.CFrame = CFrame.new(quadBezier(i, PointA.Position,PointB.Position,PointC.Position))
this line right? cant seem to find whats wrong w it

I don’t understand why you are using that equation instead of the more formal equation. Use this instead.

function quadBezier(t, p0, p1, p2)
	return (1 - t)^2 * p0 + 2 * (1 - t) * t * p1 + t^2 * p2
end

" t " is a value of 0 - 1 which you can think of a percentage of completion for the bezier curve.
p0, p1, and p2 are Vector3 values for creating the path/curve (See Here). The function will return a Vector3 value. Here is an example of me using it to move a part created by 3 other parts.


I know you probably already knew this but I will just write it for anybody who came to this post with a similar issue and doesn’t understand.

1 Like

oh alright its just that i learned bezier curve and im pretty new to it also

	while true do
		task.wait(1)
		for i=0, 1, .1 do
			Ball.CFrame = CFrame.new(quadBezier(i, PointA.Position,PointB.Position,PointC.Position))
			
			
			local rayparams = RaycastParams.new()
			rayparams.FilterDescendantsInstances = {Character}

			local ray = workspace:Raycast(Humrp.Position, quadBezier(), rayparams)
			if ray then
				
				Ball.Position = ray.Position
				game.TweenService:Create(Ball, TweenInfo.new(2), {CFrame = ray.Position}):Play()
				game.TweenService:Create(Effect1, TweenInfo.new(2), {CFrame = ray.Position}):Play()
				game.TweenService:Create(Effect2, TweenInfo.new(2), {CFrame = ray.Position}):Play()


			else --/ if ray didnt hit anything

			end
			--/ raycast are (startposition, direction * distance, rayparams)
		end
	end	
end

end)

is that right?

local ray = workspace:Raycast(Humrp.Position, quadBezier(), rayparams)

No parameters were given to quadBezier() this could be the problem.

You set the ball’s CFrame correctly. Let me know if it works how you intend for it to work. Also, in your variable ‘ray’ you have not put in the parameters for that quadBezier( ) function. However, you do not need to do this. Replace the quadBezier( ) in your variable ‘ray’ with the ball’s CFrame. (msix29 already pointed this out)

it says this now
Unable to cast CoordinateFrame to Vector3

Instead of a vector3 value put a cframe value. also send your code