How to get blood puddle to match terrain orientation

CODE

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Blacklist
	local t = {script.Parent, script.Parent.Parent}
	params.FilterDescendantsInstances = t
	local ray = workspace:Raycast(script.Parent.Position, Vector3.new(0,-1,0), params)
	if ray then
		if ray.Instance.Anchored == true and ray.Instance.CanCollide == true then
			local s = game.ReplicatedStorage.BloodPuddle:Clone()
			s.Parent = script.Parent.Parent
			s.Color = script.Parent.Color
			s.Position = ray.Position
			script.Parent:Destroy()
		end
	end
```end)

Instead of setting the position of “s” to the ray, you would have to set the cframe of “s” and make it face the ray normal. A normal is just a vector3 that represents a direction. A ray normal would be the direction that the hit part side is facing. You can do:

s:PivotTo(CFrame.new(ray.position, ray.position + ray.Normal))
1 Like

Do i remove s.Position line and replace with the one you posted?

Yeah. ___________________________

image
this now happens with the blood

Resolved that issue but. I still have the issue on slopes and such.

image

You can use the ray’s Normal direction to make the blood puddle face the position that should be orientated to the slope

bloodPuddle.CFrame = CFrame.lookAt(ray.Position, ray.Position + ray.Normal)

You may have to add a slight bit of rotation if the blood puddle’s front face isn’t its top

Why is there 2 ray.position? I’m confused

I removed one and it works the same. My issue still happen

The first ray.Position is to set the origin position of the cframe (basically the bloodpuddle’s position), the latter one is to set the location it is looking at (ray.Position + ray.Normal returns a position that is located in the direction of the slope and is relative to ray.Position (which is why we’re summing it, otherwise it returns a normal that isn’t relative to any actual physical position))

May I see the updated code? From experience making blood systems, this should’ve done it.

image
this what happen

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Blacklist
	local t = {script.Parent, script.Parent.Parent}
	params.FilterDescendantsInstances = t
	local ray = workspace:Raycast(script.Parent.Position, Vector3.new(0,-1,0), params)

	if ray then
		if ray.Instance.Anchored == true and ray.Instance.CanCollide == true then
			local s = game.ReplicatedStorage.BloodPuddle:Clone()
			s.Parent = script.Parent.Parent
			s.Color = script.Parent.Color
			s.CFrame = CFrame.lookAt(ray.Position, ray.Position + ray.Normal)


			script.Parent:Destroy()
		end
	end
end)

Try multiplying this by CFrames such as CFrame.Angles(math.pi/2, 0, 0), CFrame.Angles(0, math.pi/2, 0), or CFrame.Angles(0, 0, math.pi/2).
Check if any of those work (try each one individually)

Yay! It worked thank you for your help

image

1 Like

Wait I am sorry for asking but how would blood go on wall?

Are you having issues with the blood not being placed correctly on walls? Or do you want to make blood go on walls?

I want to make blood go on walls

This part is what you should change, you should set the second argument (the Vector3 one) to something such as Vector3.new(math.random(-1, 1), math.random(-1, 1), math.random(-1, 1)), which will cast a ray going in random directions, and will usually hit the wall or floor.

It may sometimes not produce any blood though as it might not hit anything at all, so in that case you could make it do another ray that’s the same as the original script’s if it doesnt find anything

Thank you it now works on walls