Sweeper hits player in opposite direction

When a player touches the sweeper, the sweeper will fling them in the direction it is facing. The issue is that when the player jumps over the sweeper once, the back of the sweeper will hit them and fling the player in the opposite direction.

Here is my code:

local tweenService = game:GetService("TweenService")

local teleportParts = workspace.TeleportParts:GetChildren()
local sweeper = workspace.Sweeper

local playersAlive = {}
local debounce = false

sweeper.Touched:Connect(function(hit)
	if debounce then return end
	debounce = true
	
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	
	if player then
		local character = player.Character
		
		for i, v in pairs(playersAlive) do
			if v == player then
				table.remove(playersAlive, i)
				print(player.Name.." has died")
			end
		end
		
		if #playersAlive == 1 then
			game.ReplicatedStorage.ChangeStatus:FireAllClients(playersAlive[1].." has won")
			playersAlive[1].leaderstats.Wins.Value += 1
		end
		
		for index,joint in pairs(character:GetDescendants()) do
			if joint:IsA("Motor6D") then
				local socket = Instance.new("BallSocketConstraint")
				local a1 = Instance.new("Attachment")
				local a2 = Instance.new("Attachment")
				a1.Parent = joint.Part0
				a2.Parent = joint.Part1
				socket.Parent = joint.Parent
				socket.Attachment0 = a1
				socket.Attachment1 = a2
				a1.CFrame = joint.C0
				a2.CFrame = joint.C1
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true
				joint:Destroy()
			end
		end
		
		game.ReplicatedStorage.Sounds.Hit:Play()
		
		local bodyVelocity = Instance.new("BodyVelocity", character.HumanoidRootPart)
		bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		bodyVelocity.Velocity = sweeper.CFrame.LookVector * 100 + Vector3.new(0, 100, 0) -- Bug
		wait(0.1)
		bodyVelocity:Destroy()
		
		wait(3)
		character.Humanoid.Health = 0
		debounce = false
	end
end)

while true do
	playersAlive = {}
	
	for i, player in pairs(game.Players:GetPlayers()) do
		local character = player.Character
		local teleportPart = teleportParts[i]
		
		character.HumanoidRootPart.CFrame = teleportPart.CFrame
		table.insert(playersAlive, player)
	end
	
	print(playersAlive)
	
	tweenService:Create(sweeper, TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 10), {Orientation = Vector3.new(sweeper.Orientation.X, sweeper.Orientation.Y + 360, sweeper.Orientation.Z)}):Play()
	wait(100)
end
1 Like

maybe change it to negative? like -100?

Try change this line to this

bodyVelocity.Velocity = -(sweeper.CFrame.LookVector * 100 + Vector3.new(0, 100, 0))

That didn’t work. I need to identify what face of the sweeper hits the player before flinging them with that information. I don’t know how to do this, though.

I’ve modified your script according to your terms. I’ve also added a few notes on the lines which you have to modify yourself for any inaccuracies.

Sweeper Script
local tweenService = game:GetService("TweenService")

local teleportParts = workspace.TeleportParts:GetChildren()
local sweeper = workspace.Sweeper

local playersAlive = {}
local debounce = false

sweeper.Touched:Connect(function(hit)
	if debounce then return end
	debounce = true

	local player = game.Players:GetPlayerFromCharacter(hit.Parent)

	if player then
		local character = player.Character

		for i, v in pairs(playersAlive) do
			if v == player then
				table.remove(playersAlive, i)
				print(player.Name.." has died")
			end
		end

		if #playersAlive == 1 then
			game.ReplicatedStorage.ChangeStatus:FireAllClients(playersAlive[1].." has won")
			playersAlive[1].leaderstats.Wins.Value += 1
		end

		for index,joint in pairs(character:GetDescendants()) do
			if joint:IsA("Motor6D") then
				local socket = Instance.new("BallSocketConstraint")
				local a1 = Instance.new("Attachment")
				local a2 = Instance.new("Attachment")
				a1.Parent = joint.Part0
				a2.Parent = joint.Part1
				socket.Parent = joint.Parent
				socket.Attachment0 = a1
				socket.Attachment1 = a2
				a1.CFrame = joint.C0
				a2.CFrame = joint.C1
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true
				joint:Destroy()
			end
		end

		game.ReplicatedStorage.Sounds.Hit:Play()
		
		local rootPosition = character.HumanoidRootPart.Position
		local sweeperCFrame = sweeper.CFrame
		local lookVector = sweeperCFrame.LookVector
		local closestSide = nil
		
		local sideVectors = {sweeperCFrame.RightVector * ((sweeper.Size.Z-5)/2)} -- Change to UpVector if it's the wrong direction. You will also need to find out the longest axis
		sideVectors[2] = -sideVectors[1]
		
		for i, direction in pairs(sideVectors) do
			local edgePosition = sweeperCFrame + (direction)
			local edgeDistance = (edgePosition - rootPosition).Magnitude
			if edgeDistance <= 20 then
				closestSide = edgePosition
				break
			end
		end
		
		if closestSide then
			lookVector = CFrame.new(closestSide, rootPosition).LookVector
		end
			
		local bodyVelocity = Instance.new("BodyVelocity", character.HumanoidRootPart)
		bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		bodyVelocity.Velocity = lookVector * 100 + Vector3.new(0, 100, 0) -- Bug
		wait(0.1)
		bodyVelocity:Destroy()

		wait(3)
		character.Humanoid.Health = 0
		debounce = false
	end
end)

while true do
	playersAlive = {}

	for i, player in pairs(game.Players:GetPlayers()) do
		local character = player.Character
		local teleportPart = teleportParts[i]

		character.HumanoidRootPart.CFrame = teleportPart.CFrame
		table.insert(playersAlive, player)
	end

	print(playersAlive)

	tweenService:Create(sweeper, TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 10), {Orientation = Vector3.new(sweeper.Orientation.X, sweeper.Orientation.Y + 360, sweeper.Orientation.Z)}):Play()
	wait(100)
end

Here’s what it does (ordered list):

  • Finding out the position of the spinner’s edges by using it’s other directional vectors i.e RightVector, UpVector.
  • Finding half of the spinner’s length and multiplying it by the designated direction (- or + vector), which is also based on the closest edge to the player, to get an offset position.
  • Apply the offset position to the spinner’s position to get the position where it’s edge is.
  • Make a new CFrame with the applied position and use the player’s position as it’s lookAt vector.
  • Use that CFrame’s LookVector to later apply force to the player’s velocity in that direction (which should be the direction the sweeper is moving).
  • If there is trouble finding the closest edge, the player’s velocity will alternate to your original input instead, though I highly doubt it would fail.