Help making blood stick to walls

  1. What do you want to achieve? Keep it simple and clear!
    I want to make a gore system, nothing too complex, nothing over the top.

  2. What is the issue? Include screenshots / videos if possible!
    The script works pretty well, the only issue I’m having is making the blood stick to walls.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Yes I did in fact, the only article I found was this: Help with Making Blood Stick to Walls - #5 by baseparts

I did try one of the suggestions but it didnt work for me :frowning:

local cleanuptime = 60 -- time when its gonna cleanup

	local function raycast(origin, direction, ignorelist) -- we move raycasting to a function so the final function doesnt get long
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = ignorelist
		local result = workspace:Raycast(origin, direction, params)
		print(result.Instance)
		return result
	end

	-- final function
	local function splatter(c)
		local ray = raycast(c.HumanoidRootPart.Position, Vector3.new(math.random(-3,3),-1,math.random(-3,3))*2, {c, workspace.blood:GetChildren()})

		if ray then -- we check if there is a ray
			if ray.Instance then -- we check if hit something
				-- it hit something!
				for i = 1,math.random(1,2) do -- 1 splatter is kind of boring why not add more!
					local splatter = RS.bloodAssets.BloodSplatter:Clone() -- clone the splatter from serverstorage
					splatter.CFrame = CFrame.new(ray.Position, ray.Normal)
					splatter.Orientation = Vector3.new(0,math.random(10,90),0) -- random orientation
					splatter.Parent = workspace.blood -- now we parent it to the workspace
					splatter.Size = Vector3.new(0, 0.001, 0)
					
					game:GetService("TweenService"):Create(splatter.Decal, TweenInfo.new(0.3, Enum.EasingStyle.Sine), {Transparency = math.random(0, 0.5);}):Play()
					game:GetService("TweenService"):Create(splatter, TweenInfo.new(0.3, Enum.EasingStyle.Sine), {Size = Vector3.new(math.random(1,5),0.001,math.random(1,5));}):Play()
					game:GetService("Debris"):AddItem(splatter, cleanuptime)
				end
			end
		end
	end
	
	splatter(char)

Any help is appreciated!

1 Like

You’re setting the orientation of the blood after the CFrame, which means you it isn’t aligned with the surface anymore. You need to apply that random spin onto the CFrame created from the raycast contact point so that it’s both rotated randomly and parallel with the surface.

Comment out the Orientation line to see if it’s parallel to the wall.

change this to:

splatter.CFrame = CFrame.new(ray.Position, ray.Normal) * CFrame.Angles(0,0, math.random(0,360))

to be honest I never knew the orientation thing was there, I kinda just put it there and completely forgot about it


I commented out the Orientation part and I still didnt get what I wanted

I also tried this but it only gave the part a random spin, didnt stick to the wall

Is the blood anchored? Is it possible you could show a video of what it looks like right now?

yes the blood is anchored, is that an issue?

Why does the size of the blood use zero for two of its dimensions? What is the structure of the model you’re using for blood?

I set it to zero, and then apply a random size in the tween to make it look like a different blood asset

I didn’t notice the CFrame wasn’t constructed properly until now. Try this:

splatter.CFrame = CFrame.new(ray.Position) * CFrame.fromAxisAngle(ray.Normal, math.rad(math.random(0, 360)))

If it wasn’t already obvious, don’t include the Orientation line at all. Just remove it.


still didnt work
just to clarify, I dont actually want a random rotation, I took some parts of another script made by someone else, and I didn’t see that it applied the random rotation until I made this topic, I tried to remove the math.random, and it didnt error, it just made the blood face the wrong way all the time.