I have a specific problem that I am trying to figure out. I currently am creating a viewmodel system for my tools. And I can’t figure out how to see if they are in first person or not.
I have tried a few examples like detecting if their cameramode is LockFirstPerson or detecting their first person body transparency.
Here is my script:
--Services
local RunService = game:GetService("RunService")
local ReplicatedFirst = game.ReplicatedFirst
local VIEW_M = ReplicatedFirst.Sword
--Player Junk
local player = game.Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local CurrentCamera = workspace.CurrentCamera
local Tool = script.Parent
Tool.Equipped:Connect(function()
if player.CameraMinZoomDistance <= 0.5 then
local VIEW_M_CLONE = VIEW_M:Clone()
local RUNNING = RunService.RenderStepped:Connect(function() -- Create a function that I can easily disconnect
if VIEW_M_CLONE then -- If the viewmodel is actually there, do stuff
print("VIEW_M_CLONE CHECK COMPLETE")
VIEW_M_CLONE.Parent = workspace
VIEW_M_CLONE:SetPrimaryPartCFrame(CurrentCamera.CFrame * CFrame.new(0,0,0))
end
end)
end
end)
Have you tried using the distance between the player’s head and the camera position? i.e. if the distance is less than a certain threshold like <1 you can assume the player is zoomed in?
Since you already have a reference to the character and the camera you could use something like:
if (character.Head.Position - CurrentCamera.CFrame.Position).Magnitude < 1 then
Unfortunately, when I tried this out it turns out that the camera doesn’t actually focus on your character’s head but on a point roughly around your head that is anchored to the HumanoidRootPart and it is difficult to figure out the exact position that the camera is supposed to point to, meaning there could be cases where it may think you’re zoomed in when you’re really not.
(Edit: forget all this, as @tlr22 pointed out there is a property of Camera called Focus that I was not aware of at the time I wrote this reply.)
local camera = workspace.CurrentCamera
local distance = (camera.CFrame.p - camera.Focus.p).magnitude
local isFirstPerson = distance <= 0.75
I grabbed the code from here Camera.FirstPersonTransition
I changed the value to 0.75 instead of 0.5 because it would sometimes be false when in first person
You would have to loop in order to detect it. Probably every frame. Something like this.
local camera = game.Workspace.CurrentCamera
local isFirstPerson = (camera.CFrame.p - camera.Focus.p).magnitude < 0.75
local function onFirstPersonChanged(val)
print(val)
end
local detector = function()
local distance = (camera.CFrame.p - camera.Focus.p).magnitude
if distance < 0.75 ~= isFirstPerson then
isFirstPerson = distance < 0.75
onFirstPersonChanged(isFirstPerson)
end
end
game:GetService("RunService"):BindToRenderStep('firstPersonDetector',Enum.RenderPriority.Camera.Value + 1, detector)
Now the onFirstPersonChanged function will fire when first person is entered or exited setting the parameter to true if it’s in first person.
Ahh. Your script isn’t looking for changes, but rather just if it is in that perspective. My bad. The larger code was to detect changes. Since you only need to know it at time of check you can simply do this.
--Services
local RunService = game:GetService("RunService")
local ReplicatedFirst = game.ReplicatedFirst
local VIEW_M = ReplicatedFirst.Sword
--Player Junk
local player = game.Players.LocalPlayer
local character = player.CharacterAdded:Wait()
local CurrentCamera = workspace.CurrentCamera
local Tool = script.Parent
Tool.Equipped:Connect(function()
local camera = workspace.CurrentCamera
local distance = (camera.CFrame.p - camera.Focus.p).magnitude
local isFirstPerson = distance <= 0.75 --Now this is equal to true if the character is in first person. I'm not entirely certain where you want to check? The next line?
if isFirstPerson then --This might not be what you want..
local VIEW_M_CLONE = VIEW_M:Clone()
local RUNNING = RunService.RenderStepped:Connect(function() -- Create a function that I can easily disconnect
if VIEW_M_CLONE then -- If the viewmodel is actually there, do stuff
print("VIEW_M_CLONE CHECK COMPLETE")
VIEW_M_CLONE.Parent = workspace
VIEW_M_CLONE:SetPrimaryPartCFrame(CurrentCamera.CFrame * CFrame.new(0,0,0))
end
end)
end
end)
I am not entirely certain where you wanted to check if someone is in first person so I just took a guess. I might have put it in the wrong spot. Keep in mind with what I did it is only checking this once as soon as you equip the tool. You’ll have to loop that check to keep it updated constantly.
How exactly do you want behavior to differ between a state where the character is in first person and a state where the character is not in first person?