Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by
marfit 104
6 years ago

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.

0
plr:look(object) greatneil80 2647 — 6y
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 GoldAngelInDisguise 297 — 6y
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. fredfishy 833 — 6y
0
Updated my response with your revised specifications fredfishy 833 — 6y
0
wow i wanna cry, big necrobump. greatneil80 2647 — 4y

1 answer

Log in to vote
0
Answered by
fredfishy 833 Moderation Voter
6 years ago
Edited 6 years ago

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.

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. marfit 104 — 6y
Ad

Answer this question