Bezier curve projectiles behaving strangely

I am currently just testing bezier curves and shooting arcing projectiles at a target and I have just realised that if the target is moving, or if the distance between the character and target is too long, the projectiles go straight downwards.

The intended behaviour is that the projectile spreads out from the player before homing in towards the target.

I had initially believed that the issue was caused by the raycast for hit detection being too short, however I then realised that it was still occurring, and had always been a problem if the target was moving.

d6859238b325188510e78cfe3d42de72

local module = {}

local RepStore = game:GetService("ReplicatedStorage")

module.soulbomb = function(chr, p2, amnt)
	local hum = chr:WaitForChild("Humanoid")
	local root = chr:WaitForChild("HumanoidRootPart")

	local step = 1.5

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

	local instPart = RepStore["thePill"]:Clone()
	instPart.CFrame = root.CFrame
	instPart.CanCollide = false
	instPart.Anchored = false
	instPart.Parent = workspace["Projectiles"]

	local sound = Instance.new("Sound")
	sound.Volume = 0.5 / amnt
	sound.SoundId = "rbxassetid://336771379"
	sound.Parent = instPart
	sound.TimePosition = 0.2
	sound.PlaybackSpeed = math.random(95, 128) / 100
	sound:Play()

	local p0 = instPart.Position

	--print((p0 - target).Magnitude)

	local p1 = p0 + Vector3.new(math.random(-30, 30), math.random(10, 30), math.random(-30, 30))

	local coro = coroutine.create(function()
		for t = 0, 1, step / 100 do
			--print(t)

			local cf = CFrame.lookAt(quadBez(t, p0, p1, p2), quadBez(t + step / 100, p0, p1, p2)) * CFrame.Angles(0, math.rad(90), 0)
			instPart.CFrame = cf
			
			game:GetService("RunService").Heartbeat:Wait()
		end
	end)

	coroutine.resume(coro)

	local loop
	loop = game:GetService("RunService").Heartbeat:Connect(function(dt)

		local org = instPart.Position
		local dir = instPart.CFrame.RightVector * 3
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Blacklist
		params.FilterDescendantsInstances = {chr, workspace["Projectiles"]}

		local result = workspace:Raycast(org, dir, params)
		if result then
			loop:Disconnect()
			instPart.Transparency = 1
			game:GetService("Debris"):AddItem(instPart, 0.3)

			local explosion = Instance.new("Part")
			explosion.Material = Enum.Material.Neon
			explosion.Shape = Enum.PartType.Ball
			explosion.Transparency = 0.7
			explosion.Color = Color3.fromRGB(105, 199, 218)
			explosion.Size = Vector3.new(1,1,1)
			explosion.CFrame = instPart.CFrame
			explosion.CanCollide = false
			explosion.Anchored = true
			explosion.Parent = workspace["Projectiles"]

			local expSound = Instance.new("Sound")
			expSound.TimePosition = 0.1
			expSound.Volume = 0.5 / amnt
			expSound.RollOffMode = Enum.RollOffMode.InverseTapered
			expSound.RollOffMinDistance = 25
			expSound.RollOffMaxDistance = 200
			expSound.SoundId = "rbxassetid://315775189"
			expSound.Parent = explosion
			expSound:Play()

			game:GetService("TweenService"):Create(explosion, TweenInfo.new(2, Enum.EasingStyle.Circular, Enum.EasingDirection.Out), {Size = Vector3.new(10, 10, 10)}):Play()
			task.delay(0.4, function()

				local tween = game:GetService("TweenService"):Create(explosion, TweenInfo.new(1.5), {Transparency = 1})
				tween:Play()

				local con
				con = tween.Completed:Connect(function()
					con:Disconnect()
					explosion:Destroy()
				end)

			end)

		end
	end)
end

return module

1 Like

Only thing I can think of is an edge case with CFrame.lookAt. Try putting a check in there to make sure the difference between the two results of quadBez are never zero or nan?

check if the orbs are on the humanoid rootpart position if not then recontinue the anims (tween i think)

They simply fall due to gravity. You are making instPart.Anchored = false when it should be true.
Also once the projectile ends its trajectory, it should be destroyed. That should solve the problem.

2 Likes

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