Head movement without the tool?

Hello,
I was wondering what i could do to make this movement script work for my head constantly when my player doesnt have anything equiped just to add to camera movement…?
this is how it looks when i got the script working when i equip a tool:

server side:

i eventually want to add constraints so it looks more realistic and attached to the neck but i dont even know how to make it work without using the tool haha!
here is a video

External Media

the end product should hopefully work with the first person camera setup i have going just people can see where im looking on the server (which is my goal)

this is how it functions when im running it with the camera script i got going on just no head movement when the tool is equiped :frowning:

External Media

please id enjoy any help id get and thank you for your time!

1 Like

would i have to recreate the script and run it through server script service without the tool function aspects of it?

thinking on this now is it possible to make it work in this way here let me post the script i totally forgot im terribly sorry!

local Tool = script.Parent
local Handle = Tool:WaitForChild("Handle")
local Light = Handle:WaitForChild("Light")
local Remote = Tool:WaitForChild("Remote")

local Motor
local MotorPart0
local MotorPart1

function getPlayer()
	return game:GetService("Players"):GetPlayerFromCharacter(Tool.Parent)
end

function setPointDirection(position)
	local char = Tool.Parent
	if not char then return end

	if not Motor then
		Motor = Instance.new("Motor6D")
		Motor.Part0 = char.Torso
		Motor.Part1 = char.Head
		Motor.C0 = CFrame.new(0, 1.5, 0) -- Adjust according to the character's head position
		Motor.Parent = Motor.Part0
	end

	local jointPosition = Motor.Part0.CFrame:toWorldSpace(CFrame.new(0, 1.5, 0)) -- Adjust according to the character's head position
	local cframe = CFrame.new(jointPosition.p, position)
	Motor.C0 = Motor.Part0.CFrame:toObjectSpace(cframe)
end

function toggleLight()
	Light.Enabled = not Light.Enabled
end

function onRemote(player, func, ...)
	if player ~= getPlayer() then return end

	if func == "UpdateDirection" then
		setPointDirection(...)
	elseif func == "ToggleLight" then
		toggleLight()
	end
end

function onUnequipped()
	if Motor then
		Motor:Destroy()
		Motor = nil
	end
end

Remote.OnServerEvent:connect(onRemote)
Tool.Unequipped:connect(onUnequipped)

ive made changes so its more server sided and not binded to the tool but the script runs completeley broken ;/

server side part:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Create RemoteEvent for updating target position
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = "UpdateCursorPosition"
remoteEvent.Parent = ReplicatedStorage

-- Table to store target positions
local targetPositions = {}

-- Function to set the head's point direction
local function setPointDirection(character, position)
	if not character then return end

	local head = character:FindFirstChild("Head")
	local torso = character:FindFirstChild("Torso") or character:FindFirstChild("UpperTorso")
	if not head or not torso then return end

	local neck = torso:FindFirstChild("Neck")
	if not neck then
		neck = Instance.new("Motor6D")
		neck.Name = "Neck"
		neck.Part0 = torso
		neck.Part1 = head
		neck.C0 = CFrame.new(0, 1.5, 0) -- Adjust according to the character's head position
		neck.Parent = torso
	end

	local direction = (position - neck.Part0.Position).unit
	local lookAt = CFrame.lookAt(neck.Part0.Position, neck.Part0.Position + direction)
	neck.C0 = neck.Part0.CFrame:toObjectSpace(lookAt) * CFrame.Angles(0, math.pi, 0)
end

-- Update head directions for all players
local function updateHeadDirections()
	for player, position in pairs(targetPositions) do
		local character = player.Character
		if character then
			setPointDirection(character, position)
		end
	end
end

-- Listen for cursor position updates from clients
remoteEvent.OnServerEvent:Connect(function(player, newPosition)
	targetPositions[player] = newPosition
end)

-- Continuously update head directions
RunService.Stepped:Connect(updateHeadDirections)

local side:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")

local remoteEvent = ReplicatedStorage:WaitForChild("UpdateCursorPosition")
local player = Players.LocalPlayer

-- Function to update the target position
local function setTargetPosition(newPosition)
	remoteEvent:FireServer(newPosition)
end

-- Capture mouse movement and send to server
UserInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement then
		local mousePosition = input.Position
		local camera = workspace.CurrentCamera
		local ray = camera:ScreenPointToRay(mousePosition.X, mousePosition.Y)
		local targetPosition = ray.Origin + ray.Direction * 10
		setTargetPosition(targetPosition)
	end
end)

broken spawn in:

Using the Torso.Neck motor is fine for this as the default C0 and C1 values are set to make the motors look natural when an offset is used
(basically roblox already made the motors look natural in their default rigs)

local char = --char
local neck = char.Torso.Neck
local nc0, nc1 = neck.C0, neck.C1
--set offset like this
neck.C0 = nc0 * offset
neck.C1 = nc1 * offset

you should be fine