Raycast script not working

I know this sounds like a “here’s my script, please fix it” post but I really need help because I am not sure what is wrong. The value isn’t changing and there are no errors.

CODE:

local Player = game.Players.LocalPlayer
local Character = Player.Character
local IsSafeValue = script:WaitForChild("IsSafe",9000)
local SafeZone = workspace:WaitForChild("SafeZoneArea",9000)

function MakeRay()
	local ray = Ray.new(
	    Character.HumanoidRootPart.CFrame.p,                           -- origin
	    ( Character.HumanoidRootPart.CFrame.p - (Character.HumanoidRootPart.CFrame * CFrame.new(0,1,0)).p).unit * 500
	) 
	local ignore = Character
	 
	local hit, position, normal = workspace:FindPartOnRay(ray, ignore)
	if hit then
		return hit
	else
		return nil
	end
end

while true do
	wait()
	local HitPart = MakeRay()
	if HitPart then
		IsSafeValue.Value = HitPart:IsDescendantOf(SafeZone)
	end
end

Explain what your code is trying to accomplish step by step. Even if you believe it is self evident, it isn’t to everyone else.

1 Like

It is a region that raycasts upwards and detects if a player is in that particular region, changing a bool if it is. But right now, the value isn’t changing at all

Wouldn’t it be better to use Region3 because you are checking if a player is within a certain zone?

https://pastebin.com/x4r7F4mA

On the client, this will raycast up from the player’s HumanoidRootPart with a length of 500 studs and change the value of the IsSafe BoolValue object to true if the part detected is a child of SafeZone, false if not.

I assumed that you also wanted the value to be false if a part was not detected by the raycast at all.

Yeah but its a projectile game so if I use region3 they will collide

A region created via Region3 isn’t a part, so nothing will collide.

2 Likes

Oh ok, do you know how to use it

The script isn’t working

A Region3 is basically a defined bounding box between two points. After you created your bounding box through using the Region3 class, you can use some awesome methods, just like raycasts. One of these methods is FindPartsInRegion3, which returns up to 100 players that exist within the region. Much like raycasts, you can also find the parts with an ignore list or white list. You can find the wiki page here. :slight_smile:

1 Like

I am using this in a server script but it does not work

function GetPlayersInPart(Part)
	
		local Point1 = Vector3.new(40.529, -20.558, 61.449)
local Point2 = Vector3.new(-147.815, 57.37, 260.209)
local region = Region3.new(Point1,Point2)

    local partsInRegion = workspace:FindPartsInRegion3(region,nil,math.huge)
    local Players = {}
    for _,Part in pairs(partsInRegion) do
        local player = game.Players:GetPlayerFromCharacter(Part.Parent)
        if player then
	print("Player in zone")
            player.PlayerGui.ProvinceIndicator.Activate:FireClient(player, script.Parent.PlaceName.Value)
        end
    end
    return Players
end

GetPlayersInPart(script.Parent)

This should hopefully help you out. I also commented the code to help you understand each section of the code. In order to constantly check if the player is within a Region3, you’ll have to check the parts in the Region3 with a while loop or any other timed loop).

local debugPart = true -- to show the region

local point1 = Vector3.new(0, 0, 0) -- first position
local point2 = Vector3.new(10, 10, 10) -- second position
local region = Region3.new(point1, point2) -- creating the Region3, which we only need to do it once

if debugPart then -- if the debugPart is set to true
	
	-- part creation 
	local part = Instance.new("Part")
	part.Anchored = true
	part.CanCollide = false
	part.Size = region.Size
	part.CFrame = region.CFrame
	part.Parent = workspace
end
	
function getPlayersInPart()
    local partsInRegion = workspace:FindPartsInRegion3(region, nil, math.huge) -- getting the parts in the Region3
    local players = {} -- create a table for the players
	for _,part in pairs(partsInRegion) do -- loop through all of the parts
		if part.Name == "HumanoidRootPart" then -- if the part is the player's HumanoidRootPart (change if needed)
	  		local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent) -- get the player from that part
			if player then -- checking if the player exists
				if not players[player] then -- checking if the player isn't already in the table
					table.insert(players, player) -- inserting the player into the table
				end
			end
		end
	end
    return players -- return the table
end

while wait() do -- main while loop to check the parts
	local players = getPlayersInPart() -- the actual player table
end

Not going to get too into it here since it’s not what the thread is about, but since you brought up issues with parts potentially blocking projectiles it’s not safe to have that little control over your game.

Look into CollectionService, it has a lot of helpful methods you could use to tag parts so you can make your projectile system ignore them using CollectionService’s GetTagged method.

I already fixed it thanks! Turns out my parts were unknowingly rotated so the position stuff was wrong

Just for future reference, it would be best if the ray looked like this:

local ray = Ray.new(Character.HumanoidRootPart.Position,Vector3.new(0,1,0)*500) 

The second argument tells the ray to shoot in the direction up for 500 studs from the first argument’s position.

If you want the ray to shoot directly forward in relation to the cframe, it should look like this:

local HRP = Character.HumanoidRootPart -- got lazy
local ray = Ray.new(HRP.Position,HRP.CFrame.lookVector*500)

http://wiki.roblox.com/index.php?title=CFrame#lookVector

2 Likes

I was told not to use raycasting for such things but thanks anyway!

I wouldn’t run that function in a loop that waits <0.5 seconds before running again, personally. Lag will set in and that’s not cool.