Blood Splatter System not working

So, I revamped my blood system, and I’m having issues where when a player takes a certain amount of damage blood spills, but now the blood isn’t spilling when the player takes a certain amount of damage. Can anyone help?

I’ve already tried to make it where whenever the humanoids health changes, blood occurs when you take damage but that didn’t work either.

here is the script:

local Module = {}

local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")

local BloodAssets = ReplicatedStorage["BloodAssets"]
local BloodDecals = BloodAssets["Decals"]
local BloodSounds = BloodAssets["Sounds"]
local BloodParticles = BloodAssets["Particles"]
local BloodPrints = BloodAssets["BloodPrints"]

local Ignore = {workspace.Debris, workspace.LiveContainer}

local SMALL_SIZES = {Vector3.new(1, 0.062, 1), Vector3.new(1.5, 0.062, 1.5), Vector3.new(0.75, 0.062, 0.75)}
local BIG_SIZES = {Vector3.new(3, 0.062, 3), Vector3.new(4.152, 0.062, 4.152), Vector3.new(5.257, 0.062, 5.257)}
local WALL_ORIENTATIONS = {Vector3.new(0, 90, -90), Vector3.new(-45, 90, -90), Vector3.new(-90, 0, 0), Vector3.new(-45, -90, 90), Vector3.new(0, -90, 90), Vector3.new(45, -90, 90), Vector3.new(90, 180, 0), Vector3.new(45, 90, -90)}
local WEDGE_ORIENTATIONS = {Vector3.new(-0, -90, 172.875), Vector3.new(-5.032, -134.778, 174.949), Vector3.new(-7.125, 180, -180), Vector3.new(-5.032, 134.778, -174.949), Vector3.new(0, 90, -172.875), Vector3.new(5.032, 45.222, -174.949)}

local function GetRayPoints(Object, SizeY)
	local RayPoints, Length = {}, 0
	local c = Object:GetChildren()

	for _, RayPoint in ipairs(c) do
		if RayPoint:IsA("Attachment") and RayPoint.Name == "RayPoint" then
			Length = Length + 1
			RayPoint.Position = Vector3.new(RayPoint.Position.X, -SizeY, RayPoint.Position.Z)
			RayPoints[Length] = RayPoint
		end
	end
	return RayPoints, Length
end

local function BloodEffects(Splat, IsPuddle)
	coroutine.wrap(function()
		local SFX = {BloodSounds.Splat1, BloodSounds.Splat2, BloodSounds.Splat3}
		local RNG = math.random(1,3)
		local Sound = SFX[RNG]:Clone()
		Sound.Parent = Splat
		Sound:Play()
		task.wait(1)
		Sound:Stop()
	end)()

	coroutine.wrap(function()
		local RNG = math.random(1,3)
		local TWEENINFO = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
		local GOALS
		if IsPuddle then
			GOALS = {Size = BIG_SIZES[RNG]}
		else
			GOALS = {Size = SMALL_SIZES[RNG]}
		end

		local SizeTween = TweenService:Create(Splat, TWEENINFO, GOALS)
		SizeTween:Play()
	end)()

	coroutine.wrap(function()
		local RNG = math.random(1, #BloodDecals:GetChildren())
		Splat.Decal.Texture = BloodDecals[RNG].Decal.Texture
	end)()

	coroutine.wrap(function()
		task.wait(Random.new():NextNumber(3, 7))
		local TWEENINFO = TweenInfo.new(2, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut, 0, false, 0)
		local GOALS = {Transparency = 1}
		local TransparencyTween = TweenService:Create(Splat.Decal, TWEENINFO, GOALS)
		TransparencyTween:Play()
		TransparencyTween.Completed:Wait()
		Splat:Destroy()
	end)()
end

function Module.Bleed(Drop, TargetPart, BleedTime, BloodDropRate, IsPuddle)
	local Counter = 0
	local RandomVelocity = Vector3.new(math.random(-15,15),math.random(-15,15),math.random(-15,15))
	
	while Counter < BleedTime do 	
		
		local CreatedTick = tick()
		local CurrentTick = tick()
		local Drop = Drop:Clone()
		Drop.CanCollide = false
		Drop.CanQuery = false
		
		local Velocity = Drop.BodyVelocity

		Drop.Parent = workspace.Debris
		Drop.Position = TargetPart.Position

		Velocity.MaxForce = Vector3.new(50000, 50000, 50000)
		Velocity.P = Vector3.new(100000)
		Velocity.Velocity =  Vector3.new(math.random(-15, 15), math.random(-6,-5), math.random(-15, 15))

		task.wait()
		Velocity.Velocity = Vector3.new(0,0,0)
		Velocity.MaxForce = Vector3.new(0,0,0)
		Velocity.P = Vector3.new(0,0,0)
		Counter += 1 
		
		coroutine.wrap(function()
			task.wait(.45)
			if Drop then
				Drop:Destroy()
			end
		end)()
		
		local RaycastData = RaycastParams.new()
		RaycastData.FilterType = Enum.RaycastFilterType.Blacklist
		RaycastData.FilterDescendantsInstances = Ignore
		RaycastData.IgnoreWater = true	

		local RayPoints, Length = GetRayPoints(Drop, BIG_SIZES[2])
		local PosData = {}

		local HasHit = false
		
		coroutine.resume(coroutine.create(function()
			while Drop and Drop.Parent and not HasHit do
				for i = 1, Length do
					local RayPoint = RayPoints[i]
					local NewPos = RayPoint.WorldPosition
					local OldPos = PosData[RayPoint]

					if not OldPos then
						OldPos = NewPos
						PosData[RayPoint] = NewPos
					end

					local RaycastResults = workspace:Raycast(NewPos, (NewPos - OldPos), RaycastData)

					if not RaycastResults or HasHit then PosData[RayPoint] = NewPos continue end

					local RayHit = RaycastResults.Instance
					local RayNormal = RaycastResults.Normal

					if not RayHit.CanCollide or HasHit then PosData[RayPoint] = NewPos continue end
					
					HasHit = true
					
					coroutine.wrap(function()
						Drop:Destroy()
					end)()
					
					local Blood = BloodPrints.Puddle:Clone()	
					if Blood then
						Blood.Anchored = true
						Blood.CanCollide = false
						Blood.CanTouch = false
						Blood.Position = RaycastResults.Position
						Blood.CFrame = CFrame.new(Blood.Position, Blood.Position + RayNormal) * CFrame.Angles(math.rad(90),0,0)
						if RayHit.CollisionGroup == "Floor" then
							if not RayHit:IsA("WedgePart") then
								Blood.Orientation += Vector3.new(0, Random.new():NextNumber(-180, 180), 0)
							else
								Blood.Orientation = WEDGE_ORIENTATIONS[math.random(1, #WEDGE_ORIENTATIONS)]
							end
						elseif RayHit.CollisionGroup == "Wall" then
							Blood.Name = "BloodPrint"
							Blood.Orientation = WALL_ORIENTATIONS[math.random(1, #WALL_ORIENTATIONS)]
						end
						Blood.Decal.ZIndex = Counter
						Blood.Parent = workspace.Debris

						BloodEffects(Blood, IsPuddle)
					end

				end
				RunService.Heartbeat:Wait()
			end
			
		end))
		
		if BloodDropRate == 0 then
			RunService.Heartbeat:Wait()
		else
			task.wait(BloodDropRate)
		end
		
	end
	
end

return Module
1 Like

Probably not what is going to help you, but try using the RaycastData parameters to Enum.RayCastFilterType.Exclude, hope it helps.

2 Likes

I’m about to try that out, thank you!

Tell me if it helped :smiley: Oh and you could try using task.spawn instead of all of those coroutines, but it’s kind of the same, maybe a bit more optimized! @dd_y09

It didn’t help, but I appreciate you trying. :+1:

Thanks, hope you will find the solution soon!

1 Like