How to make a model of a character move only when not looked at?

I’m trying to make a statue-like character that is completely anchored when any player can see it, and when it is not looked at, is unanchored and free to move (movement controlled by another script). I have tried researching WorldToViewPoint and I have not gotten anything to work consistently. I tried even using the AI for some help (regrettably), and not even it could find a solution. Here is my script, put inside the model of the statue that works on the server:

local model = script.Parent
local camera = game.Workspace.CurrentCamera
local runService = game:GetService("RunService")

local function isPartVisible(part)
    local partPos, onScreen = camera:WorldToViewportPoint(part.Position)
    return onScreen
end

local function updateAnchoring()
    local isVisible = false

    for _, part in model:GetDescendants() do
        if part:IsA("BasePart") then
            if isPartVisible(part) then
                isVisible = true
                if not part.Anchored then
                    part.Anchored = true
                    print(part.Name .. " is visible and anchored.")
                end
            else
                if part.Anchored then
                    part.Anchored = false
                    print(part.Name .. " is not visible and unanchored.")
                end
            end
        end
    end

    if isVisible then
        print("Statue is on screen.")
    else
        print("Statue is off screen.")
    end
end

runService.Stepped:Connect(updateAnchoring)

If you have any solutions I would greatly appreciate it!

The main issue I’m having is that the script doesn’t ever anchor the model, and never recognizes it as on-screen (always prints “Statue is off screen”). It works perfectly in Run mode, but when I actually play it, it stops working.

place this LocalScript inside the model of the statue:

local runService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local statueModel = script.Parent

local function isPartVisible(part)
    local partPos, onScreen = camera:WorldToViewportPoint(part.Position)
    return onScreen and partPos.Z > 0
end

local function updateAnchoring()
    local isVisible = false

    for _, part in statueModel:GetDescendants() do
        if part:IsA("BasePart") then
            if isPartVisible(part) then
                isVisible = true
                part.Anchored = true
                print(part.Name .. " is visible and anchored.")
            else
                part.Anchored = false
                print(part.Name .. " is not visible and unanchored.")
            end
        end
    end

    remoteEvent:FireServer(isVisible)

    if isVisible then
        print("Statue is on screen.")
    else
        print("Statue is off screen.")
    end
end

runService.RenderStepped:Connect(updateAnchoring)

Anchor it

local statueModel = script.Parent
local remoteEvent = Instance.new("RemoteEvent", statueModel)

local function toggleAnchoring(isVisible)
    for _, part in statueModel:GetDescendants() do
        if part:IsA("BasePart") then
            part.Anchored = isVisible
        end
    end
end

remoteEvent.OnServerEvent:Connect(function(player, isVisible)
    toggleAnchoring(isVisible)
end)

Link the scripts:

local function updateAnchoring()
    local isVisible = false

    for _, part in statueModel:GetDescendants() do
        if part:IsA("BasePart") then
            if isPartVisible(part) then
                isVisible = true
                part.Anchored = true
                print(part.Name .. " is visible and anchored.")
            else
                part.Anchored = false
                print(part.Name .. " is not visible and unanchored.")
            end
        end
    end

    -- Fire the RemoteEvent to notify the server about visibility
    remoteEvent:FireServer(isVisible)

    if isVisible then
        print("Statue is on screen.")
    else
        print("Statue is off screen.")
    end
end