Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How would I make a brick spawn at the ground when a player dies?

Asked by 4 years ago
local player = game.Players.LocalPlayer

wait(1)
player.Character.Humanoid.Died:Connect(function()
    local part = Instance.new("Part", workspace)
    part.Position = Vector3.new(player.Character.HumanoidRootPart.Position.X, 0, player.Character.HumanoidRootPart.Position.Z)
end)

It works, however, standing on taller or lower grounds will make this script not work. I am trying to make a blood script. How would I make the brick always be visible and put on the ground, no matter where you are?

2 answers

Log in to vote
1
Answered by
gskw 1046 Moderation Voter
4 years ago

At the moment, your script is spawning the part at a Y position of 0, which is not necessarily where the ground is. In some cases, the ground may be higher or lower than that, as you surely have noticed. This means that we need some way of figuring out where the ground is at certain point given the X and Z coordinates.

Thankfully, Roblox provides us with just what we need: raycasting. For our purposes, you can think of rays as "half" of a line: they extend infinitely in a certain direction, while in the other direction they have a specific ending point. For technical reasons, Roblox raycasts don't allow rays to extend infinitely, but instead we must set a cap. Anyways, in this case we want to perform a raycast using the HumanoidRootPart's position as a starting point, and the ray's direction should be along the Y axis. In code, this looks like so:

local startPos = player.Character.HumanoidRootPart.Position
local direction = Vector3.new(0, -1, 0).unit -- Our constant direction vector is already in unit form
-- This is often not the case, and that's why I'm explicitly converting it here
local magnitude = 500 -- Look 500 studs below the character for a floor. You probably want to adjust this for your needs

local ray = Ray.new(startPos, direction * magnitude)
-- The arguments we pass to FindPartOnRay mean the following:
-- Ignore everything in player.Character, terrain cells aren't cubes, ignore water
local foundPart, endPos = workspace:FindPartOnRay(ray, player.Character, false, true)

if foundPart == nil then
    print("Player isn't above a floor!")
else
    local part = Instance.new("Part", workspace)
    part.Position = endPos
end

FindPartOnRay actually returns two more values: the normal vector of the surface that the ray hit (this can be used for calculating the angle between the ray and the surface) and the material of the thing that was hit. Those aren't useful for our purposes.

Ad
Log in to vote
0
Answered by
Thetacah 712 Moderation Voter
4 years ago
Edited 4 years ago

Set the position of the part equal to the HumanoidRootParts position - 3 studs in the Y axis since the humanoidrootpart is 3 studs in the air.

local player = game.Players.LocalPlayer

wait(1)
player.Character.Humanoid.Died:Connect(function()
    local part = Instance.new("Part", workspace)
    part.Position = player.Character.HumanoidRootPart.Position - Vector3.new(0,3,0)

end)

*NOTE: Since this is being done from the Client, other players won't be able to see the blood.

You could do it in a Server-Side script in ServerScriptService by doing the following:

game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        local hum = character:WaitForChild("Humanoid")
        hum.Died:Connect(function()
            local part = Instance.new("Part", workspace)
            part.Position = character.HumanoidRootPart.Position - Vector3.new(0,2,0)
        end)
    end)
end)

0
Good catch on the client-server separation! I forgot to take it into consideration in my answer. gskw 1046 — 4y

Answer this question