How would you see if a player is facing a model?

I recommend you use my example, the one on the developer hub is a little old.

It raycasts from the center of your camera to wherever the world point is.

In a local script correct? (30 chars)

yes

local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera

local function is_point_visible(world_point)
    local vector, on_screen = camera:WorldToViewportPoint(world_point)
    
    if on_screen then
        local origin = camera.CFrame.Position
        local raycast_result = Workspace:Raycast(origin, world_point - origin)
        local hit = raycast_result and raycast_result.Instance
        if hit.Name == "Chair"
            print("Looking at chair!")
            return false
        end
    else
        print("Not looking at chair")
        return false
    end
    return true
end

EDIT: Never mind it doesn’t work, nothing prints

If I’m understanding correctly, you want to check if the model is within a certain field of view of the character? I believe you could use Vector3:Dot() to get a range between 1 and -1.

Okeanskiy made a good video on it; https://www.youtube.com/watch?v=BUwAcW_18Ws

Not exactly what I’m looking for, I want it so that if a player is facing the chair, it prints something, if it is not facing the chair, also print something

So basically a ray that starts at the players head and goes forward:

You could create a Ray, at the Head position, looking at the Head.CFrame.LookVector * 500. Then, if it hits a part, check if part.Parent:IsA(Model) and print the name of the model?

You could also use CollectionService and create a tag with a model name, and then group all the parts of that model to simply detect if part is tagged and see if the tag is from a model.

local player = game.Players.LocalPlayer
local origin = player.Head

local raycast_result = workspace:Raycast(origin, Head.CFrame.LookVector*500)
local hit = raycast_result and raycast_result.Instance
if hit.Name == "Chair" then
       print("Chair")
else
      prinr("No Chair")
end

Like this?

Not exactly.

local player = game.Players.LocalPlayer
local Character = player.CharacterAdded:Wait()
local origin = Character.Head

local Raycast = Ray.new(origin, Head.CFrame.LookVector*500)
local hit, position = FindPartOnRayWithIgnoreList(Raycast, Character:GetDescendants())

if (hit and hit.Parent and hit.Parent:IsA("Model") then
    print(hit.Parent.Name)
else
    print("No model found")
end

If I wanted all player to have a ray through their head would I do this?

-- serverscript
game.Players.PlayerAdded:Connect(function(plr) 
local character = plr.CharacterAdded:Wait()
local origin = Character.Head

local Raycast = Ray.new(origin, Head.CFrame.LookVector*500)
local hit, position = FindPartOnRayWithIgnoreList(Raycast, Character:GetDescendants())

if (hit and hit.Parent and hit.Parent:IsA("Model") then
    print(hit.Parent.Name)
else
    print("No model found")
end
end)
1 Like

error: 09:30:04.357 - ServerScriptService.Script:8: Expected ‘)’ (to close ‘(’ at column 4), got ‘then’

That script will fire a Ray when a player joins, but It will only fire once. The best thing you can do is using RunService.RenderStepped into a LocalScript at the Character

game:GetService("RunService").RenderStepped:Connect(function()
    --// Put the code here
end)

Instead of this right? (30 chars)

error: 09:34:37.579 - Players.Kamlkaze_Kid.Backpack.LocalScript:8: Expected ‘)’ (to close ‘(’ at column 4), got ‘then’

1 Like

even when I did that error showed up, how do I fix that?

Do this in a local script:

(UNTESTED CODE)

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local Range = 500

game:GetService("RunService").RenderStepped:Connect(function()

local ray = Ray.new(Character.Head.Position, Character.Head.CFrame.LookVector * Range)
local hit = workspace:FindPartOnRay(ray)

if hit then

local model = hit.Parent or hit.Parent.Parent

if model and model:IsA("Model") then
print(model.Name)
  end

 end
end)
1 Like

Actually, has it is a LocalScript, you could directly put it into StarterCharacterScripts and use script.Parent, being sure that it will always find the character without creating infinite yields.

1 Like

Using the dot product would also be a good way to do this, if you’d like to see this method I could also write some code for it.

There is a very good tutorial in youtube about Dot Product made by @okeanskiy

Check it out here https://www.youtube.com/watch?v=BUwAcW_18Ws

This is an example of using the dot product to calculate if the player is looking at a specific object:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local Range = 500

--initializing functions--

local vector3 = Vector3.new 
local dot = vector3().Dot
----------------------

local ModelName = "Chair" 

local Chair = workspace[ModelName]

game:GetService("RunService").RenderStepped:Connect(function()
	
	local ChairLookVector = Chair.PrimaryPart.CFrame.LookVector
	local Unit = (Character.HumanoidRootPart.Position - Chair.PrimaryPart.Position).Unit
	
	local dotProduct = dot(ChairLookVector, Unit)

	if dotProduct >= (0.9) or dotProduct <= (-0.9) then
		print("Looking at chair")
	end

end)