Rotating Welds C0

Hello, I want to make neck that turns backward when walking. I tried to rotate entire part but it rotated at center not at attachment position.

My question is how to rotate welds?


Attachments are position in which weld should rotate backwards.

I’m not asking for entire script but how to rotate weld at certain position.

I would replace the welds with motor6ds in a chain attached to the head, and just edit the default walk animation to make the heads move back

Good idea, but you can add more segments to this neck, and it would be hard to animate every single segment.

You could probably do some kinda system like this:

--settings
local base_mod = 0.1 --this is how much the heads will curl based on movement
local sine_mod = 0.2 --this is how much the heads will "bounce" as it moves
local sine_speed = 10 --this is how often the heads will "bounce" as it moves
local lerp_mod = 0.2 --this is how fast the heads will reach their goal position, like time on a tween

while true do
    for i, head in next, neckSegments do
        local weld = head.Weld
        local angle = -humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
        weld.C0 = weld.C0:Lerp(CFrame.Angles(angle, 0, 0), lerp_mod)
    end
    wait() --you can replace this with runservice.Heartbeat:Wait() or smthn if you want
end

(This system is assuming youre using C1 to offset the heads, if you use C0 you might have to remove the negative on the “local angle = -humanoid.Mo…” line and switch the next line from “weld.C0” to “weld.C1”)

1 Like

I am using C0 and C1 to position the segments. When I did what You sent me, all the segments go into each other without gaps and sometimes they go into the torso. When I’m walking segment1 rotates in other direction than segmnet2. I will show you my script, maybe You can fix something or maybe You will show me how to make it easier. Sorry for confusing but I’m Lua beginner so I don’t know a lot of things.

There is also script that set transparency of head to 0 and creates fake head because I can’t move character head.

local Weld1 = Instance.new("Weld") --Creates first neck segment to make it easier.
Weld1.Name = "WeldX"
Weld1.Parent = script.NeckSegment
Weld1.Part1 = Torso
Weld1.Part0 = script.NeckSegment
Weld1.C1 = TorsoAttachment.CFrame --TorsoAttachment is attachment at top of UpperTorso.
Weld1.C0 = script.NeckSegment.Down.CFrame -- "Down" Attachment is attachment at bottom of neck segment. And "Up" is attachment at top of neck segment.

local FirstNeckSegment = script.NeckSegment:Clone()
FirstNeckSegment.Name = "Segment1"
FirstNeckSegment.Parent = Segments
FirstNeckSegment.CanCollide = true
FirstNeckSegment.Massless = true
FirstNeckSegment.Color = Head.Color

function CreateSegment() -- "Segments" is folder that contains all segments. S is number of segments.
	S = S + 1
	local OldNeckSegment = Segments:FindFirstChild("Segment"..S-1)
	local NewNeckSegment = script.NeckSegment:Clone()
	NewNeckSegment.Parent = Segments
	NewNeckSegment.Name = "Segment"..S
	NewNeckSegment.Color = Head.Color
	NewNeckSegment.CanCollide = true
	NewNeckSegment.Massless = true
	NewNeckSegment.CFrame = OldNeckSegment.CFrame + Vector3.new(0,OldNeckSegment.Size.Y,0)
	
	NewWeld = Instance.new("Weld") -- Creates weld and sets its position above the previous one.
	NewWeld.Parent = NewNeckSegment
	NewWeld.Name = "WeldX"
	NewWeld.Part1 = OldNeckSegment
	NewWeld.Part0 = NewNeckSegment
	NewWeld.C1 = OldNeckSegment.Up.CFrame
	NewWeld.C0 = NewNeckSegment.Down.CFrame
end

NeckCount.Changed:Connect(function() -- When "NeckCount" value changes it destroys all segments and make new.
	S = 1
	for i, v in pairs(Segments:GetChildren()) do
		if v.Name ~= "Segment1" then
			v:Destroy()
		end
	end
	for i = 1, NeckCount.Value, 1 do
		wait(0.1)
		CreateSegment()
	end
end)

NeckCount.Value = 0
NeckCount.Value = 1

--settings
local base_mod = 0.1 --this is how much the heads will curl based on movement
local sine_mod = 0.2 --this is how much the heads will "bounce" as it moves
local sine_speed = 10 --this is how often the heads will "bounce" as it moves
local lerp_mod = 0.2 --this is how fast the heads will reach their goal position, like time on a tween

while true do
	for i, head in next, Segments:GetDescendants() do
		if head.Name == "WeldX" then
			local weld = head
			local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
			weld.C0 = weld.C0:Lerp(CFrame.Angles(angle, 0, 0), lerp_mod)
		end
	end
	wait() --you can replace this with runservice.Heartbeat:Wait() or smthn if you want
end

I would personally do the create segment script a bit more like this:

function CreateSegment() -- "Segments" is folder that contains all segments. S is number of segments.
	S = S + 1
	local OldNeckSegment = Segments:FindFirstChild("Segment"..S-1)
	local NewNeckSegment = script.NeckSegment:Clone()
	NewNeckSegment.Name = "Segment"..S
	NewNeckSegment.Color = Head.Color
	NewNeckSegment.CanCollide = true
	NewNeckSegment.Massless = true
	
	NewWeld = Instance.new("Weld") -- Creates weld and sets its position above the previous one.
	NewWeld.Name = "WeldX"
	NewWeld.Part1 = OldNeckSegment
	NewWeld.Part0 = NewNeckSegment
	NewWeld.C1 = CFrame.new(0,1,0)

    NewWeld.Parent = NewNeckSegment --performance benefit of parenting after setting properties
    NewNeckSegment.Parent = Segments
end

That should work with the exact script I have in the post above (hopefully)

Okay, Thank You for help. It works now. My last question is how to decrease the segments curl? If there is a lot of segments (for example 25 or more) it curls too much. I tried to divide the base_mod and sine_mod by segment count but it stopped to curl.

With settings of:

local base_mod = 0.6/#neckSegments
local sine_mod = 1.2/#neckSegments

It seems to scale up pretty evenly

1 Like

Sorry for replying again, but I saw that lerping is very laggy.
When the number of segments exceeds 100, the script’s activity is already ~3% and it starts to lag. When I deleted 2 lines of script:

local angle = -Humanoid.MoveDirection.Magnitude * (base_mod + sine_mod * math.abs(math.sin(tick() * sine_speed)) )
v.C0 = v.C0:Lerp(CFrame.Angles(angle, 0, 0), lerp_mod)

The script activity was same, but it stopped lagging with larger numbers of segments. Is there any way to reduce the lags? I tried to stop the loop when player is not moving, but it started to lag again when I started to walk. I also tried while true do loop and heartbeat loop but it was lagging too.