Players can stop an object with AlignPosition

I want to make a moving cart, similiar to Payload from Team Fortress 2, in which a team has to stand near a cart which causes it to start moving and the opposite team has to stop them from doing so. For this I decided to use AlignPosition and AlignOrientation

However…

Players can easily stop the cart from moving by standing infront of it. What I want is the cart to be able to push the players

I’ve considered doing TweenService or LinearVelocity but I don’t know if these are good alternatives to AlignPosition. Same with making the part non-collidable but I honestly want players to be able to stand on it and just go with it.

	self.AlignPosition = Instance.new("AlignPosition", self.CartCore)
	
	self.AlignPosition.MaxForce = math.huge
	self.AlignPosition.Responsiveness = 200
	self.AlignPosition.MaxVelocity = module.CartSpeed
	self.AlignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
	self.AlignPosition.Attachment0 = self.Attachment

I don’t know if I maybe set up AlignPosition incorrectly but I think I did?

This is super weird bug and help is really appreciated!!!

Something you could use under TweenService is SmoothDamp - it’s like a regular tween but handled every frame rather than as a pre-set animation that cannot be altered once it has started playing. It simulates how much the tween changes in a certain time frame (being the deltaTime between two frames).

Though, tweening a part’s position means players that stand on top of it will not be moved, as the part does not have a velocity attached to it, meaning they will slide off the part when it moves under them. I’ve got a solution for this, you need to track the part’s position and compare the position from the last frame to the current frame, then set the part’s velocity manually to the difference between the two.

My code sample (run server-side):

local part: Part = --Put part reference here
local rsConnection: RBXScriptConnection
function StartRecordingVelocity()
	if not rsConnection then
		local last_cf = part.CFrame
		rsConnection = game:GetService("RunService").PreSimulation:Connect(function(dT)
			local difference = part.Position-last_cf.Position
			local rx,ry,rz = last_cf:ToObjectSpace(part.CFrame):ToOrientation()
			
			if part:GetAttribute("ApplyAngularVelocity") then
				part.AssemblyAngularVelocity = Vector3.new(rx,ry,rz)/dT
			end
			part.AssemblyLinearVelocity = difference/dT
			last_cf = part.CFrame
		end)
	end
end
function StopRecordingVelocity()
	if rsConnection then
		rsConnection:Disconnect()
		rsConnection = nil
	end
end

1 Like

TYSM!!! I’ll look into this, though is it okay if this is run in Heartbeat rather than PreSimulation?!

Yes! You can run it in any RunService context. PreSimulation is before physics simulation calculations for that frame, PostSimulation is after - Heartbeat is the same as PostSimulation but with a different name. Heartbeat is the older name for PostSimulation but it’s functionally the same ^^

1 Like

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