How should I go about doing this?

So I have a uhh, blood script… I hope it’s okay… eh combat warriors is still up
Whenever a drop touches something, it creates a cframe.lookat towards what it touched, and makes a raycast far away from the drops look vector, and then back down. (just incase for big parts) But I came across one issue, the cframe.lookat. The baseplate is very huge, so if it touches and looks at the baseplate, it would look something like this.


Yellow is raycast, grey is the cframe.lookat

Since the drop is slightly above the baseplate, and it looks at the baseplate, it leaves a huge gap between where the drop is, and where the ray cast is looking at.

How do I fix it? Actually, is there another method other than making a cframe.lookat the touched part?

2 Likes

Instead of making it look at the instance the raycast hit, make it look at the position the raycast hit. RayCast.Position instead of RayCast.Instance.Position

1 Like

Well no, you see it casts the raycast with the position. That’s how I get the raycast. By that point I don’t have a ray cast yet.

it doesn’t use raycasts to get the instance, it uses .Touched.

1 Like

No, I mean, you do set the lookAt with the instance that the raycast hits, correct?

No, with what the drop hit.

awewaeae

Oh, alright, I see now. Raycast down from the blood spill’s center and look at the position it hits there. (make sure to blacklist the blood spill from being a target)

But… What if it’s on a wall?
How do I detect if I should move the origin up,down,left,or right?

That is a bit of a difficult question to answer, but I think something like this should work:

local hit = --touched part
local blood = --the blood spill

local direction = (blood.Position - hit.Position).Unit
local t = {X = direction.X, Y = direction.Y, Z = direction.Z}
table.sort(t, function(a, b)
    return math.abs(a) > math.abs(b)
end)

t[2] = 0
t[3] = 0

direction = Vector3.new(t.X, t.Y, t.Z)

It may be a bit complicated, or I may have overcomplicated this, but it should work.

Are these in radians? And I tried to put it in but all of the parts that landed of the ground disappeared…

local ray = workspace:Raycast(water.Position-direction.Unit*100,direction.Unit * 200)

remove this, you just need the origin there.

Alot of them are still missing.

Well, I did realize that I overcomplicated it, so it should look like this:

local hit = --touched part
local blood = --the blood spill

local direction = (blood.Position - hit.Position).Unit
local t = {X = direction.X, Y = direction.Y, Z = direction.Z}

for i,v in pairs(t) do
    if i == "Y" then
        if v > -1 and v < 1 then
            t[i] = 0
        end
    end
        
    if v > 0 then
        t[i] = 1
    elseif v < 0 then
        t[i] = -1
    end
end

direction = Vector3.new(t.X, t.Y, t.Z)

Now again, I’m not sure if this will work too well, I’m not too well versed in blood spills or things like that (I normally use raycasts to begin with and am not too good at figuring out where to raycast if I don’t)

Well it works fine, in one direction. If I shoot the dummy in the front, it seems to work fine, but if I shoot it in the back, nothing appears.

that’s quite weird, could I see the code or at least the part that includes my code and rotates/moves the blood spill?

Alright, I tested this on my own, it took quite a while, but here’s the solution I got:

local hit = workspace.Baseplate
local blood = workspace.Blood

local rpm = RaycastParams.new()
rpm.FilterType = Enum.RaycastFilterType.Blacklist
rpm.FilterDescendantsInstances = {blood}

local raycasts = {}

for i = -1, 1, 2 do
	workspace:Raycast(blood.Position,Vector3.new(i, i, i), rpm)
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(i, i, i)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(0, i, i)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(i, 0, i)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(i, i, 0)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(0, 0, i)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(i, 0, 0)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(0, i, 0)*5, rpm))
end

local closest
local closestmag = math.huge

for i,v in pairs(raycasts) do
	if v then
		if closestmag > (blood.Position-v.Position).Magnitude then
			closest = v
			closestmag = (blood.Position-v.Position).Magnitude
		end
	end
end

if closest then
	blood.CFrame = CFrame.lookAt(blood.Position, closest.Position)	
end

Basically, I took every combination of raycasts I could get (around 14 total), and I compared all of them to each other to figure out which one was closest to the part and used that.

It works almost perfectly, just some of them are rotated. You can see in the output that it all says baseplate, which is what the blood hit.

You don’t need to print the “hit” variable at all you can remove it. I was just using it as a test. Also, if it being rotated diagonally annoys you, you can simply remove the ones with multiple directions like this:

local blood = workspace.Blood

local rpm = RaycastParams.new()
rpm.FilterType = Enum.RaycastFilterType.Blacklist
rpm.FilterDescendantsInstances = {blood}

local raycasts = {}

for i = -1, 1, 2 do
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(0, 0, i)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(i, 0, 0)*5, rpm))
	table.insert(raycasts, workspace:Raycast(blood.Position,Vector3.new(0, i, 0)*5, rpm))
end

local closest
local closestmag = math.huge

for i,v in pairs(raycasts) do
	if v then
		if closestmag > (blood.Position-v.Position).Magnitude then
			closest = v
			closestmag = (blood.Position-v.Position).Magnitude
		end
	end
end

if closest then
	blood.CFrame = CFrame.lookAt(blood.Position, closest.Position)	
end