I have this simple script, that detects if a part is 20 studs or less above a player’s head. It doesn’t work - it does not detect when a part is over the player’s head.
while true do
for _,p in pairs(game.Players:GetPlayers()) do
local char = p.Character or p.CharacterAdded:Wait()
local MyRayCast = Ray.new(char.Head.CFrame.p, char.Head.CFrame.UpVector)
local part = workspace:FindPartOnRay(MyRayCast)
local hit, position = game.Workspace:FindPartOnRayWithIgnoreList(MyRayCast,{char})
if hit then
print('ray hit a part!')
else
print('no part found')
end
end
task.wait(1)
end
local Players = game:GetService("Players")
task.spawn(function()
while true and task.wait(1) do
for i,v in pairs(Players:GetChildren()) do
if (v.Character) and (v.Character:FindFirstChild("Head")) then
local Char = v.Character
local Result = workspace:Raycast(Char.Head.Position, (Char.Head.Position+Vector3.new(0, 20, 0)))
if (Result) and (Result.Instance) then
print("Found part for "..v.Name)
else
print("No part found for "..v.Name)
end
end
end
end
end)
you can check if the properties of the part that the raycast hit match the acid parts, for example you can name the acid parts AcidPart and in the script check if Result.Instance.Name == "AcidPart"
The way this acid rain is supposed to work, is it is supposed to detect if a player is inside a building or not, by having a raycast go about 20 studs above their head to see if there is a building roof above them, aka, they are inside a building.
If they are not inside a building, every second, they are supposed to lose 15 or so health.
The issue that is being seen, is the script you provided now seems to be detecting parts that are WAY out of the 20 stud range of the character’s head that was mentioned in the previous post, as seen in this video that includes output.
if your detecting if it’s within a certain distance then raycasting is pointless just get the distance between the acid part and the player’s HumanoidRootPart like so:
while true do
for _,p in pairs(game.Players:GetPlayers()) do
local char = p.Character or p.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart")
local dist = (hrp.Position - acidPart.Position).Magnitude -- might need to switch these around
-- I typed this in dev forum so the local's have a weird layout thing
if dist <= minimumDistance then
print('hit a part!')
else
print('no part found')
end
end
task.wait(1)
end
No, the acid parts are not supposed to do anything but be a visual effect. The acid parts themselves have their CanTouch, CanCollide, and CanQuery properties set to false, so the rays will have no interaction with them.
The way players are damaged, is if they are not inside a building during the acid rain event, which is determined by the ray shooting out of the top of their heads and seeing if it hits a part, and if it does, see if that part is 20 or less studs away.
I think this script is going by the front of their heads, and not the top of their heads.
task.wait(.5)
local players = game:GetService("Players")
local run = game:GetService("RunService")
local checkingOffset = CFrame.new(0, 80, 0)
local checkingDistance = 100
local function checkRay(rayInstance, toFind)
for i,v in pairs(toFind:GetDescendants()) do
if v == rayInstance or i == rayInstance then
return true
end
end
return false
end
run.RenderStepped:Connect(function(dt)
for _, plr in pairs(players:GetPlayers()) do
local char = plr.Character or plr.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart")
local acidCFrame = hrp.CFrame * checkingOffset
local acidRaycast = workspace:Raycast(acidCFrame.p, (hrp.Position - acidCFrame.p))
if acidRaycast and checkRay(acidRaycast.Instance, char) then
print("got player")
-- send data to server
else
print("player is hiding")
end
end
end)
also I just now realized after I made this that doing the for loop on the players was pointless for this since my version is local lol.
This also wouldn’t work because now your stopping the ray from hitting the players, so instead of erroring because it’s hitting the accessories it’s because it can’t hit the player at all.
The checking distance (which does not get used in your code) and checking offset variables seem to be way off for the 20 stud distance I am looking for. Will this also spawn the ray cast in the up direction?
local Player_Character = --The player's character here
local Player_Head = --The player's head here
local Ray_Params = RaycastParams.new()
Ray_Params.FilterType = Enum.RaycastFilterType.Exclude
Ray_Params.FilterDescendantsInstances = {Player_Character}
local Upwards_Limit = 9e9
local RayResult = workspace:Raycast(Player_Head.Position, Vector3.new(0, Upwards_Limit, 0), Ray_Params)
if RayResult then
--code here
end
(If the limit value is negative it raycasts downwards, if its positive it raycasts upwards)
Lol, I’m dull I didn’t even realize I referenced checkingDistance. You don’t need checking distance, let me explain, when doing (hrp.Position - acidCFrame.p) it’s not only getting the direction but also the distance between them so when I set the direction of the raycast to (hrp.Position - acidCFrame.p), it is just setting the distance to however long the distance between the two positions are. However if you want I think you can just do this in the direction part of the raycast (hrp.Position - acidCFrame.p) * checkingDistance.
And to answer your question yes this pushes the ray up to whatever you set the checkingOffset to, including on the x and z axis not just the y.
Certainly, although I wouldn’t recommend it personally, the delay between the players real position and where the server thinks the player is can be quite big depending on the players ping, sometimes even different enough that the raycast wont hit, which is why I would recommend doing it on the client and if it hits send the player that it hit to the server with a RemoteEvent. Here’s an example of how this would look:
– CLIENT –
-- game > StarterPlayer > StarterCharacterScripts --
task.wait(.5)
local hitEvent = game.ReplicatedStorage.hitEvent
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local run = game:GetService("RunService")
local checkingOffset = CFrame.new(0, 80, 0)
local checkingDistance = 100
local function checkRay(rayInstance, toFind)
for i,v in pairs(toFind:GetDescendants()) do
if v == rayInstance or i == rayInstance then
return true
end
end
return false
end
run.RenderStepped:Connect(function(dt)
local acidCFrame = humanoidRootPart.CFrame * checkingOffset
local acidRaycast = workspace:Raycast(acidCFrame.p, (humanoidRootPart.Position - acidCFrame.p))
if acidRaycast and checkRay(acidRaycast.Instance, character) then
print("got player")
hitEvent:FireServer()
else
print("player is hiding")
end
end)
– SERVER –
-- game > ServerScriptService --
local hitEvent = game.ReplicatedStorage.hitEvent
local function onHit(player:Player)
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
humanoid:TakeDamage(10)
end
hitEvent.OnServerEvent:Connect(onHit)