Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How would I find out if a player is looking at an object?

I've looked at WorldToScreenPoint and WorldToViewportPoint but I don't really think it is that effective considering my game still needs 3rd person. I don't really see raycasting as an option as to effectively consider the player's full viewing angle, we'd need a lot of rays. I don't need a method to be 100% accurate in actually being seen, but enough so that I don't have to look directly at the object.

5 comments

0

plr:look(object)

0

WorldToViewportPoint should do the job, even with third person, it returns a vector and a bool which is true if the vector is within the bounds of the viewport

0

So you mean "A character is facing towards an object", not "a player is looking at an object", because those are two different things.

0

Updated my response with your revised specifications

0

wow i wanna cry, big necrobump.

1 answer

I wrote an answer on it here

As you said, you want WorldToScreenPoint or whatever, but you also want to use GetPartsObscuringTarget.

Edit

What you actually want is "Character facing towards part", not "Player looking at part"

You can do this with vectors:

player = game:GetService("Players").LocalPlayer
character = player.Character or player.CharacterAdded:wait()
torso = character:WaitForChild("Humanoid").RootPart
target = workspace:WaitForChild("LookyLou")
vectors = {}


function dotProduct(a, b)
	return a.x * b.x + a.y * b.y + a.z * b.z
end


function getAngle(a, b)
	return math.acos(dotProduct(a, b) / (a.magnitude * b.magnitude))
end


function drawVector(position, angle, magnitude, name)
	if vectors[name] then
		vectors[name]:Destroy()
	end
	
	local p = Instance.new("Part")
	p.Anchored = true
	p.Size = Vector3.new(0.1, 0.1, magnitude)
	p.CFrame = CFrame.new(position + angle * magnitude / 2, position + angle)
	p.CanCollide = false
	p.Parent = workspace
	
	vectors[name] = p
end


game:GetService("RunService").RenderStepped:Connect(function()
	local torsoAngle = torso.CFrame.lookVector
	local targetVector = torso.Position - target.Position
	local flatTorsoAngle = Vector3.new(torsoAngle.x, 0, torsoAngle.z)
	local flatTargetVector = Vector3.new(targetVector.x, 0, targetVector.z)
	drawVector(torso.Position - Vector3.new(0, 2.5, 0), flatTorsoAngle, flatTargetVector.magnitude, "torso")
	drawVector(target.Position, flatTargetVector.unit, flatTargetVector.magnitude, "target")
	
	local angle = math.deg(getAngle(-flatTorsoAngle, flatTargetVector))
	if angle > 40 then
		target.BrickColor = BrickColor.new("Bright red")
	else
		target.BrickColor = BrickColor.new("Bright green")
	end
end)

Put a brick in the workspace called "LookyLou" -- it will go red when you're within 40 degrees of facing it.

1 comment

0

I dont want WorldToScreenPoint. If a player is in 3rd person, they can just rotate their camera to the part while facing away. I think raycasting actually might be the option here.

This discussion is preserved as it was. New answers, comments, and votes are closed.