How would i make a script so if you look at a part you take damage?

Hello i want to make a part so if you look at it the player who is looking at it takes damage,
Inspired by eyes in doors.

3 Likes

Not sure, but you could use the Dot product for this Vector3 Dot Product: Calculating NPC Field of View (Roblox Studio) - YouTube

1 Like

An easier way would be to take a proximity prompt set it to custom to remove the background and check when it becomes visible to the player.

2 Likes

You wanna make it with mouse looking on object?

He clearly says he wants the player to take damage when the player looks at the part.

I don’t understand, what you mean in “look”.

1 Like

Look meaning the player has the part directly in its fieldofview.

I’m guessing by “eyes in doors” you’re referring to this enemy in the roblox game DOORS?

I’ve not played that game, so when you say “look at”, do you mean

  • “the eye is anywhere on the player’s screen”, or
  • “the eye part is within an imaginary cone in front of the player’s physical character, not necessarily their camera”?

U can use Raycasts to send a signal. and if the plr is looking in the direction of the part. Damage the plr

You would use WorldToScreenPoint() function for this, it returns 2 things, if the part visible on player screen on second variable returned value and the other one kinda forgot you might aswell look on the devhub

1 Like

That could work, But best guess is to check with WorldToScreenPoint() if it even exists on the players screen. And send signals with Raycasting if the plr is directly looking to the part. Otherwise it could be inaccurate.

1 Like
local Camera = workspace.CurrentCamera

function isPartVisible(part:BasePart)
    local Position, Visible = Camera:WorldToScreenPoint(part.Position)

    return Visible -- Visible is a boolean value that will tell whether the Vector3 is visible on screen or not
end

while task.wait() do
    if isPartVisible() then
        hum:TakeDamage(10)
    end
end
1 Like

in look i meant if its in the players field of view

What do you mean with the hum i know it is refering to humanoid tho

I use raycasting. It’s a server script inside StarterCharacterScripts

local character = script.Parent
local head = character:WaitForChild("Head")

local keepcasting = true
local db = true --cooldown so it won't take more damage than it should be at once

local function takedamage()
	if db == true then db = false
		print("MONSTER")
		character.Humanoid:TakeDamage(10)
		task.wait(1)
		db = true
	end
end

coroutine.resume(coroutine.create(function()
	repeat
		local rayOrigin = head.Position
		local rayDirection = head.CFrame.LookVector * 25 -- CFrame.LookVector is the front direction, *25 is how far to look or cast the ray, you can change the number
		local raycastResult = workspace:Raycast(rayOrigin, rayDirection)
				
		if raycastResult then
			if raycastResult.Instance.Name == "MONSTER" then
				takedamage()
			end
		else
			
		end

		task.wait()
	until keepcasting == false
end))

raycastResult.Instance is the basepart’s name, not the model.
You can change that line to if raycastResult.Instance.Parent.Name == "MONSTER" then so it can get the name of the model the part’s in.

I guess I will give you the full script then

-- Local Script (StarterPlayer.StarterPlayerScripts)
local plr = game:GetService("Players").LocalPlayer
local Camera = workspace.CurrentCamera
local event = game:GetService("ReplicatedStorage").DamageEvent

function partIsVisible(part:BasePart)
    local Position, Visible = Camera:WorldToScreenPoint(part.Position)

    return Visible -- Visible is a boolean value that will tell whether the Vector3 is visible on screen or not
end

while task.wait() do
    local char = plr.Character

    if char and partIsVisible() then
        local hum = char:FindFirstChild("Humanoid")
        if hum then 
            event:FireServer()
        end
    end
end

-- ServerScript (ServerStorage)
local event = game:GetService("ReplicatedStorage").DamageEvent

event.OnServerEvent:Connect(function(p)
    if p.Character and p.Character:FindFirstChild("Humanoid") then
        p.Character:FindFirstChild("Humanoid"):TakeDamage(10)
    end
end)

Edit : Put this in a LocalScript (game.StarterPlayer.StarterPlayerScripts)

Wouldn’t this cause performances issue as the codes fires the server multiple times?

Edited: Yeah this is only the way to dmg player when something in screen, plus script can’t retrieve player from server side

In order to do this you will need to use Dot product, which returns a value between -1 and 1 (you can set a value between those two numbers to get the FOV of the eye)

You will need to use a local script to get the players camera:

local Player = game:GetService("Players").LocalPlayer
local Eye = workspace:WaitForChild("Eye")
local Camera = workspace.CurrentCamera

local function DetectModelLook(Character, Damage)
	local UnitDir = (Camera.CFrame.LookVector - Eye.PrimaryPart.Position).Unit
	local DotProduct = UnitDir:Dot(Camera.CFrame.LookVector)
	
	if DotProduct >= 0.75 then -- the eye has a fov of around 40
		-- camera is looking at the eye
		RemoteEvent:FireServer() -- send an event to the server to damage the character.
	else
		-- what ever you want to put here, or just remove the else
		print("Player is facing away from the eye")
	end
end

DetectModelLook(Player.Character, 3) -- loop this function in order to continuously check

4 Likes

where do i exactly put the script?

LocalPlayer Should be a clear giveaway where to put it.
StarterCharacter.

1 Like