How to offset an attachment?

Problem

Hello, I have this script which I am trying to set the players camera to their head so that they are able to see their arms and it looks cooler for my first person mode

What I am trying to do is set the camera to the players head then move it forward a small bit.

Here is my code:

local camera = game.Workspace.CurrentCamera
local plr = game.Players.LocalPlayer
local char = plr.Character
local head = char:FindFirstChild("Head")
local HRP = char:FindFirstChild("HumanoidRootPart")

-- create an attachment to attach the camera to
local attachment = Instance.new("Attachment")
attachment.Name = "CameraAttachment"
attachment.Position = Vector3.new(0, 1000, -1000) -- move the attachment forward and upward
attachment.Parent = head

-- set the camera subject to the attachment
camera.CameraSubject = attachment


task.wait(1)

as you can see by the line of code

attachment.Position = Vector3.new(0, 1000, -1000) -- move the attachment forward and upward

I set the offset to the Y to 1000 and the Z to -1000 however it doesnt actually offset and and instead looks like this

As you can see the camera still follows the player but it doesnt go on the offset.

CameraSubject seems to only support BasePart and Humanoid objects. You could instead use Humanoid.CameraOffset to offset the player’s camera.

1 Like

The entire point of me doing this is not to move the camera but so I can have the body parts visible like the arms for my first person mode. I want to set the cameraSubject to the head and also offset the camera.

Hey! Try this out:

local player = game.Players.LocalPlayer
local char = player.Character
local RunService = game:GetService("RunService")

char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)

for i, v in pairs(char:GetChildren()) do
    if v:IsA("BasePart") and v.Name ~= "Head" then

        v:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
            v.LocalTransparencyModifier = v.Transparency
        end)

        v.LocalTransparencyModifier = v.Transparency

    end
end

RunService.RenderStepped:Connect(function(step)
    local ray = Ray.new(char.Head.Position, ((char.Head.CFrame + char.Head.CFrame.LookVector * 2) - char.Head.Position).Position.Unit)
    local ignoreList = char:GetChildren()

    local hit, pos = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

    if hit then
        char.Humanoid.CameraOffset = Vector3.new(0, 0, -(char.Head.Position - pos).magnitude)
    else
        char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)
    end
end)
2 Likes
  1. one of my arms is invisible
  2. it lags behind
1 Like

Use BindToRenderStep and set the priority to Enum.RenderPriority.Camera.Value - 1. This should prevent the camera from lagging behind.

this works but why is the hand invisible?

here is my character:

as you can see the hand is gone but the other hand is there

script:

local player = game.Players.LocalPlayer
local char = player.Character
local camera = workspace.CurrentCamera
local RunService = game:GetService("RunService")

char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)

for i, v in pairs(char:GetChildren()) do
	if v:IsA("BasePart") and v.Name ~= "Head" then
		v:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
			v.LocalTransparencyModifier = v.Transparency
		end)
		v.LocalTransparencyModifier = v.Transparency
	end
end

RunService:BindToRenderStep("CameraOffsetUpdate", Enum.RenderPriority.Camera.Value - 1, function()
	local ray = Ray.new(char.Head.Position, ((char.Head.CFrame + char.Head.CFrame.LookVector * 2) - char.Head.Position).Position.Unit)
	local ignoreList = char:GetChildren()
	local hit, pos = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
	if hit then
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -(char.Head.Position - pos).magnitude)
	else
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)
	end
end)

You might need to change the CameraType to Attach for the CameraSubject to work properly.

The only thing I can think of is that the right hand’s transparency isn’t set to 0, it doesn’t exist or the for loop executes too soon. I’d try setting v.LocalTransparencyModifier to 0, or going into Studio to check the transparency of the right hand.

It also might be because you need a ChildAdded connection in addition to the GetChildren for loop.

1 Like

I ended up fixing it by doing instead of checking if its a basepart I simply did a pcall.

here is the working script:

task.wait(3)

local player = game.Players.LocalPlayer
local char = player.Character
local camera = workspace.CurrentCamera
local RunService = game:GetService("RunService")

char.Humanoid.CameraOffset = Vector3.new(0, -0.6, -1.1)

for i, v in pairs(char:GetChildren()) do
	pcall(function()
		if v.Name ~= "Head" then
			v:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
				v.LocalTransparencyModifier = v.Transparency
			end)
			v.LocalTransparencyModifier = v.Transparency

		end
	end)	
end


RunService:BindToRenderStep("CameraOffsetUpdate", Enum.RenderPriority.Camera.Value - 1, function()
	local ray = Ray.new(char.Head.Position, ((char.Head.CFrame + char.Head.CFrame.LookVector * 2) - char.Head.Position).Position.Unit)
	local ignoreList = char:GetChildren()
	local hit, pos = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
	if hit then
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -(char.Head.Position - pos).magnitude)
	else
		char.Humanoid.CameraOffset = Vector3.new(0, 0, -1)
	end
end)

That’s not because of the pcall, that’s because you waited 3 seconds before running the script. By that time, all the character’s descendants would’ve loaded. Personally, I’d recommend you go with @BendsSpace’s solution (use the for loop and use ChildAdded or DescendantAdded), but whatever works best for you.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.