--Set SoftwareAnchor tag on parts --Use :SetAttribute("Anchored", true/false) to anchor without changing the part's network status --Part MUST have NetworkOwner set to this player's client or the part will just teleport back to where it should be when Anchored == false again --Only works on parts atm (~model support is an exercise for the reader!) local CollectionService = game.CollectionService local RunService = game:GetService("RunService") local records = {} --Setup function, called when stuff comes/goes from the datamodel function Setup(instance) if (not instance:IsA("BasePart")) then print(instance, "not a basepart.") return end if (game.Workspace:IsAncestorOf(instance) == false) then --Dont care about stuff in storage or guis etc return end if (records[instance]) then --already got a record return end --Create the record local record = {} record.instance = instance local function PropertyChanged() record.anchored = instance:GetAttribute("Anchored") if (record.anchored == nil) then instance:SetAttribute("Anchored", false) record.anchored = false end if (record.anchored == true) then record.storedCFrame = instance.CFrame end end --handle property change via event PropertyChanged() record.attribSignal = instance:GetAttributeChangedSignal("Anchored"):Connect(function(a,b) PropertyChanged() end) records[instance] = record end --Setup CollectionService:GetInstanceAddedSignal("SoftwareAnchor"):Connect(function(instance) Setup(instance) end) for key,instance in CollectionService:GetTagged("SoftwareAnchor") do Setup(instance) end --Cleanup CollectionService:GetInstanceRemovedSignal("SoftwareAnchor"):Connect(function(instance) local record = records[instance] if (record) then record.attribSignal:Disconnect() end records[instance] = nil end) RunService.PostSimulation:Connect(function() for key,record in records do if (record.anchored == true) then record.instance.CFrame = record.storedCFrame record.instance.AssemblyLinearVelocity = Vector3.zero record.instance.AssemblyAngularVelocity = Vector3.zero end end end)