How could I fix this issue with the code?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

  2. What is the issue? The parts are spawning mid air as they attach to players and other npc’s but as those two things move, the part is left floating

  3. What solutions have you tried so far? Tried rewriting it and trying to detect if the praent of the part doesn’t have a humanoidrootpart as a child

THE SCRIPT IS STORED IN SERVERSCRIPTSERVICE

local bloodsplats = {"116830967","116830967","116830967","116830967" }

local human = script.Parent:WaitForChild("Humanoid")

human.HealthChanged:Connect(function()
	local headcf = script.Parent.Head.CFrame
	for i = 1,5 do
		local a = Instance.new("Part",nil)
		a.Size = Vector3.new(math.random(1,3.5),math.random(1,3.5),0.05)
		a.Transparency = 0
		a.CanCollide = false
		a.Anchored = true
		a.Color = Color3.new(1, 0, 0)
		local decal = Instance.new("Decal",a)
		decal.Texture = "rbxassetid://0"
		
		local dir = Vector3.new(math.random(-50,50),math.random(-50,50),math.random(-50,50)).Unit * 20
		local ray = Ray.new(headcf.Position,dir)
		local part,pos,normal = workspace:FindPartOnRay(ray,script.Parent,false,true)
		if part ~= nil then
			a.CFrame = CFrame.new(pos,pos + normal)
			a.Parent = workspace
		end
		
		game:GetService("Debris"):AddItem(a,10)
	end
end)

EXAMPLE
Screenshot 2024-03-30 002527

Instead of using a ray like this, you can use workspace:raycast with specific raycastParams so that it only lands on parts you want it to.

human.HealthChanged:Connect(function()
	local headcf = script.Parent.Head.CFrame
	for i = 1,5 do
		local a = Instance.new("Part",nil)
		a.Size = Vector3.new(math.random(1,3.5),math.random(1,3.5),0.05)
		a.Transparency = 0
		a.CanCollide = false
		a.Anchored = true
		a.Color = Color3.new(1, 0, 0)
		local decal = Instance.new("Decal",a)
		decal.Texture = "rbxassetid://0"
		
		local dir = vector3.new(math.random(-50,50),math.random(-50,50),math.random(-50,50)).Unit* 20
		local raycast = workspace:Raycast(script.Parent.Head.Position, dir, --[[use raycast params here]])
		if raycast then
			a.Position = raycast.Position
			a.Parent = workspace
		end
		
		game:GetService("Debris"):AddItem(a,10)
	end
end)

Also, make sure to set raycastParams before at the top of your script.
Example:

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist --Or blacklist depending on what you want to filter.
params.FilterDescendantsInstances = {--[[this is what you want to filter]]}