Raycasting problems

Context: im trying to make a horror game, im using some free models and scripts to see how i could do so, im trying to make an eye that makes the player loose health while looking at it, but im new to raycasting

  1. What do you want to achieve? Keep it simple and clear!
    Make a script that detects when the eye is visible in the player’s screen, and a raycast that detects if there is anything in front blocking the view

  2. What is the issue? Include screenshots / videos if possible!
    The raycast seems to detect the wall behind it while looking at it in the front, and while looking at it behind a wall, it doesnt the detect the wall

Video: 2023-12-14 22-46-40

The Script:

--Local script
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")

local EyeParent = Workspace:WaitForChild("Eye"):WaitForChild("Eye")
local eye = EyeParent:WaitForChild("NewEye")
local OriginalEyePos = eye.Position --34.228, 7, -5.5

local MaxDistance = 100
--Just some animations for the eye, please ignore
local TS = game:GetService("TweenService")
local TInfo = TweenInfo.new(
	0.1, --The Tween will take 4 seconds.
	Enum.EasingStyle.Linear, --The tween will use the "Sine" EasingStyle.
	Enum.EasingDirection.In, --The tween will use the "In" EasingDirection.
	0, --The tween will repeat 5 times, so it will perform 6 times in total.
	false, --The tween reverses.
	0 --The tween will delay for 1 second before repeating.
)
local TInfo2 = TweenInfo.new(
	1, --The Tween will take 4 seconds.
	Enum.EasingStyle.Quad, --The tween will use the "Sine" EasingStyle.
	Enum.EasingDirection.In, --The tween will use the "In" EasingDirection.
	0, --The tween will repeat 5 times, so it will perform 6 times in total.
	false, --The tween reverses.
	0 --The tween will delay for 1 second before repeating.
)
local TweenGoals = {
	Size = Vector3.new(0.7,0.7,0.7);
	Color = Color3.fromRGB(33, 10, 10)
}
local TweenGoals2 = {
	Size = Vector3.new(1,1,1);
	Color = Color3.fromRGB(0, 0, 0)
}
local EyeVisible = TS:Create(eye,TInfo,TweenGoals)
local EyeNotVisible = TS:Create(eye,TInfo2,TweenGoals2)
-- ^animations for the eye

IsVisibleToggle = false


local part1 = EyeParent:WaitForChild("Part1")
local part2 = EyeParent:WaitForChild("Part2")
local random = Random.new()

function EyeMove()
	while IsVisibleToggle do
		wait()
		local PosX = random:NextNumber(part1.Position.X,part2.Position.X)
		local PosZ = random:NextNumber(part1.Position.Z,part2.Position.Z)
		
		local NewEyePos = Vector3.new(PosX,
			eye.Position.Y,
			PosZ)
		--print(NewEyePos,PosX,PosZ)
		eye.Position = NewEyePos
		--print("Loop")
	end
end

function EyeToPosStart()
	wait()
	eye.Position = OriginalEyePos
	--print("OriginalPos")
end

--Using ropes to see the raycast, for now
local Rope = workspace:WaitForChild("RayTesting")
local Att0 = workspace:WaitForChild("Att0Parent"):WaitForChild("Attachment")
local Att1 = workspace:WaitForChild("Att1Parent"):WaitForChild("Attachment")

local TempEvent = game.ReplicatedStorage:WaitForChild("TempEvent")

local RayStart = EyeParent.Parent:WaitForChild("RayStart") --Where the ray goes to, to check if there is anything in between

RunService.RenderStepped:Connect(function()
	local camera = workspace.CurrentCamera
	local Vector, inViewport = camera:WorldToViewportPoint(eye.Position)
	--print(Vector)
	local ray = camera:ViewportPointToRay(Vector.X, Vector.Y, 0)
	--print(ray.Origin,RayStart.Position)
	--print(ray)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = {EyeParent,
		game.Players.LocalPlayer.Character,eye,EyeParent.Parent,
		RayStart,Att1.Parent,Att0.Parent}
	
	local raycastResult = workspace:Raycast(ray.Origin, RayStart.Position , raycastParams)
	--ray.Direction * 1000
	local onScreen = inViewport and Vector.Z > 0
	print(ray.Origin,RayStart.Position,raycastResult)
	--local onScreen = inViewport and Vector.Z <= MaxDistance
	TempEvent:FireServer(ray.Origin,RayStart.Position,raycastResult.Distance)
	
	--Att0.Parent.Position = ray.Origin
	--Att1.Parent.Position = ray.Direction * 1000
	--Rope.Length = raycastResult.Distance
	
	local isVisible = onScreen and not raycastResult
	
	if isVisible then
		if IsVisibleToggle == false then
			EyeVisible:Play()
			IsVisibleToggle = true
			--EyeMove()
		end
		--print("facing a part")
		
	else
		if IsVisibleToggle == true then
			EyeNotVisible:Play()
			IsVisibleToggle = false
			--EyeToPosStart()
		end
		
	end
	print(raycastResult.Instance)
	--print(raycastResult.Normal)
	--print(raycastResult.Distance)
end)

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I tried searching about raycasts but didnt find anything about it that could possibly help me, i just want to know how raycasts work and what is going on with my raycast

Okay so i managed to fix it, instead of making a direction variable i was using a position, this is the final code:

local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")

local EyeParent = Workspace:WaitForChild("Eye"):WaitForChild("Eye")
local eye = EyeParent:WaitForChild("NewEye")
local OriginalEyePos = eye.Position --34.228, 7, -5.5

local MaxDistance = 100

local TS = game:GetService("TweenService")
local TInfo = TweenInfo.new(
	0.1, --The Tween will take 4 seconds.
	Enum.EasingStyle.Linear, --The tween will use the "Sine" EasingStyle.
	Enum.EasingDirection.In, --The tween will use the "In" EasingDirection.
	0, --The tween will repeat 5 times, so it will perform 6 times in total.
	false, --The tween reverses.
	0 --The tween will delay for 1 second before repeating.
)
local TInfo2 = TweenInfo.new(
	1, --The Tween will take 4 seconds.
	Enum.EasingStyle.Quad, --The tween will use the "Sine" EasingStyle.
	Enum.EasingDirection.In, --The tween will use the "In" EasingDirection.
	0, --The tween will repeat 5 times, so it will perform 6 times in total.
	false, --The tween reverses.
	0 --The tween will delay for 1 second before repeating.
)
local TweenGoals = {
	Size = Vector3.new(0.7,0.7,0.7);
	Color = Color3.fromRGB(33, 10, 10)
}
local TweenGoals2 = {
	Size = Vector3.new(1,1,1);
	Color = Color3.fromRGB(0, 0, 0)
}
local EyeVisible = TS:Create(eye,TInfo,TweenGoals)
local EyeNotVisible = TS:Create(eye,TInfo2,TweenGoals2)

IsVisibleToggle = false




local part1 = EyeParent:WaitForChild("Part1")
local part2 = EyeParent:WaitForChild("Part2")
local random = Random.new()

function EyeMove()
	while IsVisibleToggle do
		wait()
		local PosX = random:NextNumber(part1.Position.X,part2.Position.X)
		local PosZ = random:NextNumber(part1.Position.Z,part2.Position.Z)

		local NewEyePos = Vector3.new(PosX,
			eye.Position.Y,
			PosZ)
		--print(NewEyePos,PosX,PosZ)
		eye.Position = NewEyePos
		--print("Loop")
	end
end

function EyeToPosStart()
	wait()
	eye.Position = OriginalEyePos
	--print("OriginalPos")
end


local Rope = workspace:WaitForChild("RayTesting")
local Att0 = workspace:WaitForChild("Att0Parent"):WaitForChild("Attachment")
local Att1 = workspace:WaitForChild("Att1Parent"):WaitForChild("Attachment")



local TempEvent = game.ReplicatedStorage:WaitForChild("TempEvent")

local RayStart = EyeParent.Parent:WaitForChild("RayStart")

RunService.RenderStepped:Connect(function()
	local camera = workspace.CurrentCamera
	local Vector, inViewport = camera:WorldToViewportPoint(eye.Position)
	--print(Vector)
	--local ray = camera:ViewportPointToRay(Vector.X, Vector.Y, 0)
	--print(ray.Origin,RayStart.Position)
	--print(ray)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = {EyeParent,
		game.Players.LocalPlayer.Character,eye,EyeParent.Parent,
		RayStart,Att1.Parent,Att0.Parent}
	
	local direction = game.Players.LocalPlayer.Character.Head.Position - RayStart.Position
	local raycastResult = workspace:Raycast(RayStart.Position,direction, raycastParams)
	--ray.Direction * 1000
	local onScreen = inViewport and Vector.Z > 0
	--print(game.Players.LocalPlayer.Character.Head.Position,RayStart.Position,raycastResult)
	--local onScreen = inViewport and Vector.Z <= MaxDistance
	TempEvent:FireServer(game.Players.LocalPlayer.Character.Head.Position,RayStart.Position)

	--Att0.Parent.Position = ray.Origin
	--Att1.Parent.Position = ray.Direction * 1000
	--Rope.Length = raycastResult.Distance

	local isVisible = onScreen and not raycastResult
	print(isVisible,onScreen,not raycastResult)
	if isVisible then
		if IsVisibleToggle == false then
			EyeVisible:Play()
			IsVisibleToggle = true
			--EyeMove()
		end
		--print("facing a part")

	else
		if IsVisibleToggle == true then
			EyeNotVisible:Play()
			IsVisibleToggle = false
			--EyeToPosStart()
		end

	end
	if raycastResult ~= nil then
		print(raycastResult.Instance)
	end
	--print(raycastResult.Normal)
	--print(raycastResult.Distance)
end)

Now it works just fine, and detects the wall, i hope this helps others with the same problem later

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.