Okay, so I was reading some posts on devforum on how body movers are deprecated, and i’m wondering, should I use them or not? If not, what would be a good replacement for moving a character, rotating a character, or even setting a character in a certain CFrame? Any help would be appreciated!
Body movers are not deprecated, they are only legacy. Roblox has introduced constraints, and those are recommended instead.
I had a similar question a few months back, check out There's no indication that legacy BodyMovers are deprecated
I use constraints over bodymovers 90% of the time, they’re usually easier to use, and work better
Basic pet follow system example
apologies for the not very detailed examples, but it gets the point across
BodyPosition> has to be setup and requires a loop
AlignPosition > setup once and done, no loops
BodyPosition [Legacy Body Mover]
local bodyPosition = pet.BodyPosition while true do bodyPosition.Position = characterPrimary.CFrame * CFrame.new(0, 3, -3) wait() end
local alignPosition = pet.AlignPosition local basePetAttachment = pet.BaseAttachment -- align position attachment0 local petOffsetAttachment = characterPrimary.PetOffsetAttachment -- align position attachment1 petOffsetAttachment.Position = Vector3.new(0, 3, -3) -- relative to character primary, it's not WorldPosition
AI movement example
Here’s some code from a basic AI system I’m working on, I had a goal attachment parented to a dummy part, and I can use that as the attachment1 for my constaints (align position and orientation)
local Players = game:GetService("Players") local OFFSET = 5 local npc = script.Parent local humanoidRootPart = npc.HumanoidRootPart humanoidRootPart:SetNetworkOwner(nil) -- if this isn't done, network swapping will cause a bit of jittering local originPosition = humanoidRootPart.Position local animations = npc.Animations local walkAnimation = animations.WalkAnimation local idleAnimation = animations.IdleAnimation -- because attachments require a part parent local attachmentHolderPart = Instance.new("Part") attachmentHolderPart.CanCollide = false attachmentHolderPart.Anchored = true attachmentHolderPart.Transparency = 1 attachmentHolderPart.Size = Vector3.new(0, 0, 0) attachmentHolderPart.Position = Vector3.new(99999, 99999, 99999) attachmentHolderPart.Parent = workspace local baseAttachment = Instance.new("Attachment", humanoidRootPart) local goalAttachment = Instance.new("Attachment", attachmentHolderPart) local NPCPosition = Instance.new("AlignPosition") NPCPosition.ApplyAtCenterOfMass = true NPCPosition.MaxForce = 1000000 NPCPosition.MaxVelocity = 16 NPCPosition.Responsiveness = 35 NPCPosition.Attachment0 = baseAttachment NPCPosition.Attachment1 = goalAttachment NPCPosition.Parent = humanoidRootPart local NPCOrientation = Instance.new("AlignOrientation") NPCOrientation.MaxTorque = 20000 NPCOrientation.Responsiveness = 15 NPCOrientation.Attachment0 = baseAttachment NPCOrientation.Attachment1 = goalAttachment NPCOrientation.Parent = humanoidRootPart local currentlyWalking = false local currentTarget = npc.Target -- anims local function enterWalk() currentlyWalking = true idleAnimation.Value = false walkAnimation.Value = true end local function enterIdle() currentlyWalking = false walkAnimation.Value = false idleAnimation.Value = true end -- moving local function moveTo(goalPosition) goalAttachment.WorldPosition = goalPosition end local function lookAt(goalPosition) goalAttachment.WorldCFrame = CFrame.new(goalAttachment.WorldPosition, goalPosition) end -- position helpers local function setVectorY(vector, y) return Vector3.new(vector.X, y, vector.Z) end local function follow(target) if not target then return end local targetPart = target:IsA("Model") and target.PrimaryPart or target local lastPosition = setVectorY(humanoidRootPart.Position, 3) local function update() local currentPosition = setVectorY(humanoidRootPart.Position, 3) local targetPosition = setVectorY(targetPart.Position, 3) local direction = (currentPosition - targetPosition).Unit local goalPosition = targetPosition + direction * OFFSET moveTo(goalPosition) lookAt(targetPosition) local mag = (lastPosition - currentPosition).Magnitude if not currentlyWalking and mag > .1 then enterWalk() elseif currentlyWalking and mag <= .1 then enterIdle() end lastPosition = currentPosition end while currentTarget.Value == target do update() wait() end end moveTo(originPosition) currentTarget.Changed:Connect(follow)
I’d say use constraints over bodymovers when you can, but there are some cases where I prefer to use bodymovers, they tend to have Vector3 forces like which is useful when you want to exert more force on a particular axis, and this isn’t usually possible with constraints AFAIK (correct me if I’m wrong, I’d love to be able to do this with AlignPos/AlignOrientation)