How to raycast from Camera [HELP]

Hello,
I am trying to make an RPG style game where the camera is above the player. Similar to this:
https://gyazo.com/62fb3bb1bb4645066ae673f6ff1b5786

I’ve got everything about it done. Whenever you go into a building, the roof of the building and goes half-transparent and the overall system works well. But, I want the transparency thing to be fully automatic because what I am doing right now is coding each building so that the roof goes transparent when the player is inside. This is very inefficient because I am going to have a lot of buildings and having to code for each building seems a bit pointless so I came up with an idea that I can make this work. I thought that I could raycast from the center of the camera and make everything on it’s way transparent although I will need some guidance.

My questions are?

  • Is this method even good? If not what should I do?
  • How would I raycast from the center of the screen (camera) towards the player so I can make everything on its way transparent
2 Likes

Thanks,
I’ll check them out but how would I raycast towards the player?

Edit: Would I do someething like player.Torso.Position?

raycasting

to get the direction from camera to player

local camera = game.Workspace.CurrentCamera
local direction = (somecharacter.Head.Position - camera.CFrame.Position).Unit * 100 --this will raycast for 100 studs

I guess you could do torso, but I think head would be easier. If you do Torso, you need to account for R6 and R15 characters (if you allow both).

3 Likes

Woops, I deleted the solution. Let me know if you need it again.

1 Like

You should put it back anyways. That way if someone else has the same issue, they know the solution and don’t have to ask again.

I can’t express how many times I ran into a roadblock and found my solution in a question someone else already asked.

2 Likes

Hey, it would be nice if you could put back the solution haha.

1 Like

Ummm, I had this link

and I had this link for a useful function with no raycasting needed

3 Likes

So I made this:

local camera = game.Workspace.CurrentCamera
local direction = (game:GetService("Players").LocalPlayer.Character.Head.Position - camera.CFrame.Position).Unit * 100

game:GetService("RunService").RenderStepped:Connect(function()
	local ray = Ray.new(
		camera.CFrame,
		direction
	)
	local ignore = game.Players.LocalPlayer.Character 
	local hit, position = workspace:FindPartOnRay(ray, ignore)
	
	if hit and hit:IsA("BasePart") then
		hit.Transparency = 0.8
	end	
end)

2 problems:

  • For some odd reason I get this error: Head is not a valid member of Model
  • How would I make a part go back to its original transparency after the player has walked out of the building ect.
1 Like
  • Maybe the head has not loaded in yet. Try using WaitForChild.
  • when you define your ray, do camera.CFrame.Position
  • keep in mind that this method of raycasting is depreciated
  • You can put transparent parts in a table and then make those parts visible in the next frame
1 Like

I kind of did it. It works alright with buildings that dont have too many parts (ofcourse I can create a filter and everything). Imma just post the script here. Is there anything you reckon I can improve it with? (And thank you so much for the help:

wait()
local camera = game.Workspace.CurrentCamera
local direction = (game:GetService("Players").LocalPlayer.character.Head.Position - camera.CFrame.Position).Unit * 100
local Parts = {}

game:GetService("RunService").RenderStepped:Connect(function()
	local ray = Ray.new(
		camera.CFrame.Position,
		direction
	)
	local ignore = game.Players.LocalPlayer.Character 
	local hit, position = workspace:FindPartOnRay(ray, ignore)
	
	if hit and hit:IsA("BasePart") then
		table.insert(Parts, 1, hit)
		hit.Transparency = 0.8
	end	
	
	for i,v in pairs(Parts) do
		if hit ~= v then
			v.Transparency = 0
			table.remove(Parts, i)
		end
	end
end)

Oh and is there a way I can make the raycast more thick so that it makes everything in its way transparent rather than a thin line or will I have to cast more than 1 line?

Another Edit: The ray doesnt seem to be casting straight to the player. Not sure.

Another Edit (lol): https://gyazo.com/cfd54d40334a1a3e597b68c5b4a7d8cd
Works perfectly dont worry about my other edit

  • I would recommend using WaitForChild() instead of using a wait()
  • If there are multiple parts in the way, only one part will be made transpareny - multiple raycasts are needed if multiple parts are in the way
  • this is easier Camera | Documentation - Roblox Creator Hub
  • for a “thicker” raycast, multiple raycasts may be needed (or maybe the above link will help)
1 Like

Sorry to be a pain. I did all your methods that you suggested (except the last one since I am a bit unsure of how to do so) but here is what I came up with:

local camera = game.Workspace.CurrentCamera
local direction = (game:GetService("Players").LocalPlayer.character:WaitForChild("Head").Position - camera.CFrame.Position).Unit * 100
local ignoreList = {game:GetService("Players").LocalPlayer.Character.Head}
local Parts = {}


game:GetService("RunService").RenderStepped:Connect(function()
	local hit = workspace.CurrentCamera:GetPartsObscuringTarget(direction, ignoreList)
	
	if hit and hit:IsA("BasePart") and hit.Name == "EngineCompatible" then
		table.insert(Parts, 1, hit)
		hit.Transparency = 0.8
	end	
	
	for i,v in pairs(Parts) do
		if hit ~= v then
			v.Transparency = 0
			table.remove(Parts, i)
		end
	end
end)

But I get the following error:
Unable to cast to Array

GetPartsObscuringTarget returns an array of parts, not just 1. Also, it does not take a direction, it takes an array of Vector3’s (positions).

Hey I cant figure out how to do this:

local camera = game.Workspace.CurrentCamera
local direction = (game:GetService("Players").LocalPlayer.Character:WaitForChild("Head").Position - camera.CFrame.Position).Unit * 100
local Parts = {}
local ignore = {game:GetService("Players").LocalPlayer.Character.Head}

print("decalred all vars and tables")

game:GetService("RunService").RenderStepped:Connect(function()
	local castpoints = {game:GetService("Players").LocalPlayer.Character.Head}
	local hit = camera:GetPartsObscuringTarget(castpoints, ignore)
	for i,v in pairs(hit) do
		if v:IsA("BasePart") and v.Name == "EC" then
			table.insert(Parts, 1, v)
			v.Transparency = 0.8
		end
	end
	
	for i,v in pairs(Parts) do
		if hit.v ~= v then
			v.Transparency = 0
			table.remove(Parts, i)
		end
	end
end)

There are no errors. It just doesn’t work. Pls help.

game.Workspace:WaitForChild(game.Players.LocalPlayer.Name) --humanoid may not be loaded in yet

local camera = game.Workspace.CurrentCamera
--local direction = don't need this, but if you did, it needs to be calculated every frame
local Parts = {}
local ignore = {game:GetService("Players").LocalPlayer.Character} --ignore the whole character, not just the head

print("decalred all vars and tables")

game:GetService("RunService").RenderStepped:Connect(function()
	local castpoints = {game:GetService("Players").LocalPlayer.Character.Head.Position} --don't do just Head, do Head.Position (Vector3 needed)
	local hit = camera:GetPartsObscuringTarget(castpoints, ignore)
	local freshparts = {}
	for i,v in pairs(hit) do
		if v:IsA("BasePart") and v.Name == "EC" then
			table.insert(Parts, 1, v) --1 not needed, but ok
			v.Transparency = 0.8
			freshparts[v] = true
		end
	end
	 
	--as soon as you made the parts transparent, you immediately made them visible again in the code you had
	
	for i,v in pairs(Parts) do
		if not freshparts[v] then 
			v.Transparency = 0
			table.remove(Parts, i)
		end
	end
end)
5 Likes