Slight issue with blood system

So, I’ve made a blood system for my game. When the player is damaged it will shoot a few blood drops at the point of impact. These blood drops are simply spheres with a vectorforce, but here comes the issue. When they touch a surface they are supposed to shoot a raycast onto said surface so it can spawn a bloodsplat part, but, they are not consistently accurate on where they spawn it.

An example of the issue may also be observed in my YouTube devlog if you pause the video and go frame by frame when the blooddrops hit the ground. ( said issue is extremely prominent at 0:26 - 0:40)

Here is the designated function responsible for handling said bloodrops and bloodsplats.

 function goremodule.BloodDrop(bullethole, character, amount)
	for i = 1, amount, 1 do
		local blooddropclone = blooddrop:Clone()
		blooddropclone.Parent = workspace
		blooddropclone.CFrame = bullethole.CFrame
		blooddropclone.VectorForce.Force = Vector3.new(math.random(-4, 4) / 6, math.random(2, 3) / 3, math.random(4, 6) / 10 * -1)
		blooddropclone.Anchored = false
		debris:AddItem(blooddropclone.VectorForce, 0.05)
		debris:AddItem(blooddropclone, 5)
		blooddropclone.Touched:Connect(function(op)
			if op.Parent then
				if op.Name ~= "Tracer" and op.Name ~= "Flesh" and op.Parent ~= character and op.Parent ~= "Holster" and op.Name ~= "BloodDrop" and op.Name ~= "Hitbox" and op.Name ~= "Handle" and not op:FindFirstChild("blood") then
					
					local params = RaycastParams.new()
					params.FilterType = Enum.RaycastFilterType.Exclude
					params.FilterDescendantsInstances = {blooddropclone, character}
					
					local og = blooddropclone.Position
					local dir = (op.Position - blooddropclone.Position).Unit
					local mag = (op.Position - blooddropclone.Position).Magnitude
					
					local raycast = workspace:Raycast(og, dir * mag, params)
						
					if blooddropclone.Anchored == false then
						local sounds = game.ReplicatedStorage.GoreAssets.Sounds.BloodSplat:GetChildren()
						local soundclone = sounds[math.random(1, #sounds)]:Clone()
						soundclone.Parent = blooddropclone
						soundclone:Play()
						debris:AddItem(soundclone, 0.5)
					end
					
					if raycast and not raycast.Instance.Parent:FindFirstChild("Humanoid") and raycast.Instance.Name ~= "ViewBullet" and raycast.Instance.Name ~= "ViewMag" and raycast.Instance.Name ~= "Handle" and raycast.Instance.Name ~= "Holster" and raycast.Instance.Name ~= "Hitbox" then			
						local blood = raycast.Instance:FindFirstChild("blood")
						if blood then									
							local bloodtween = tweenservice:Create(raycast.Instance, tweeninfo1, {Size = raycast.Instance.Size + Vector3.new(0.2, 0.2, 0)})
							bloodtween:Play()
							bloodtween.Completed:Connect(function()
								bloodtween:Destroy()
							end)
						else
							local bloodsplat = bloodsplats[math.random(1, #bloodsplats)]
							local bloodsplatclone = bloodsplat:Clone()
							bloodsplatclone.Parent = raycast.Instance
							bloodsplatclone.Position = raycast.Position
							blooddropclone.CollisionGroup = "Default"
							local radsize = math.random(1, 2)
							bloodsplatclone.Size = Vector3.new(radsize, radsize, 0.001)
							
							local randomAngle = math.random() * 2 * math.pi
							local randomRotation = CFrame.Angles(0, 0, randomAngle)
							
							local attach = Instance.new("Attachment", bloodsplatclone)
							
							bloodsplatclone.CFrame = CFrame.new(bloodsplatclone.Position, bloodsplatclone.Position + raycast.Normal) * randomRotation
							bloodsplatclone.BloodWeld.Part1 = raycast.Instance	
							local smallpuff = game.ReplicatedStorage.GoreAssets.Blood.BloodSplashParticles.Splats:Clone()
							smallpuff.Parent = attach
							smallpuff:Emit(math.random(32, 67))
							debris:AddItem(smallpuff, 5)
							if op.Anchored == true then
								bloodsplatclone.BloodWeld:Destroy()
								bloodsplatclone.Anchored = true
							end
							task.wait(55)
							debris:AddItem(bloodsplatclone, 5)
							local decal = bloodsplatclone:FindFirstChild("Decal")
							if decal then
								local tween = tweenservice:Create(bloodsplatclone.Decal, TweenInfo.new(2), {Transparency = 1})
								tween:Play()
								tween.Completed:Connect(function()
									tween:Destroy()
								end)
							end
						end	
					end
					blooddropclone.Anchored = true
					blooddropclone.CanCollide = false
					blooddropclone.CanQuery = false
					blooddropclone.Transparency = 1
				end
			end
		end)
	end
end

Anybody’s assistance is greatly appreciated.

The .Touched event is very inaccurate at times, and issues like this aren’t uncommon when relying on Roblox physics. Basically what I’m getting at is, you’re not doing anything wrong, it’s just how Roblox is.

I’ve personally experienced this issue when using higher velocities on parts, so maybe toning down the velocity can help? There’s really not much you can do to my knowledge, unless using something like :GetTouchingParts() in a loop fixes it.

I recommend researching to see what others have done to get around similar issues involving .Touched inaccuracies.

1 Like

Thanks, I will look into this. Hopefully I’ll be able to find a reliable method to fix this issue. Cheers.

Fastcast. I love Fastcast.

That is all i have to say, I just love Fastcast.

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