How can I make bodyposition "take control" of player movement?

Currently, i’m trying to make a morph that allows you to play as a flying character. The character flies, and i’m trying to use BodyPosition to be it’s main source of movement. While it does work, it works incredibly janky, and the morph moves in a very annoying way and sometimes goes mach 5.

	local BodyPosition = MuffinCharacter:FindFirstChildWhichIsA("BodyPosition", true)
	BodyPosition.Position = MuffinCharacter:FindFirstChild("HumanoidRootPart").Position
	
	local HumanoidRootPart = MuffinCharacter:FindFirstChild("HumanoidRootPart")
	local Humanoid = MuffinCharacter:FindFirstChildWhichIsA("Humanoid")
	
	local Distance = BodyPosition:GetAttribute("Distance")
	local MaxHeight = BodyPosition:GetAttribute("MaxHeight")
	local FlightSpeed = BodyPosition:GetAttribute("FlightSpeed")
	
	local function Levitate()
		if Humanoid.Health > 0 then
			local GroundDirection = Vector3.new(0,-1000,0)
			local Params = RaycastParams.new()
			Params.FilterType = Enum.RaycastFilterType.Exclude
			Params.FilterDescendantsInstances = {MuffinCharacter}
			local result = workspace:Raycast(HumanoidRootPart.Position, GroundDirection, Params)
			if result then
				if result.Instance then

					local Difference = math.abs(result.Position.Y - HumanoidRootPart.Position.Y)
					-- print(Difference)
					if Difference < Distance then
						--	print("Rising")
						BodyPosition.Position = BodyPosition.Position+Vector3.new(0,3,0)
					elseif Difference > MaxHeight then
						--	print("Falling")
						BodyPosition.Position = BodyPosition.Position-Vector3.new(0,5,0)
					end

				end
			end
		end
	end
	
	local function Accelerate(dir)
		if MuffinCharacter:FindFirstChildWhichIsA("Humanoid").Health > 0 then
			local angle = math.atan2(dir.X, -dir.Z)
			local quarterTurn = math.pi / 2
			angle = -math.round(angle / quarterTurn) * quarterTurn

			local newX = -math.sin(angle)
			local newZ = -math.cos(angle)
			if math.abs(newX) <= 1e-10 then newX = 0 end
			if math.abs(newZ) <= 1e-10 then newZ = 0 end

			BodyPosition.Position = BodyPosition.Position + Vector3.new(newX, 0, newZ) * FlightSpeed
		end
	end
	
	Humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
		Accelerate(Humanoid.MoveDirection)
	end)

I tried using the MovePosition property of humanoid to determine where the bodyposition should go, but that makes it incredibly janky still. (Also because you can’t detect running while held in one place by BodyPosition)

Any feedback helps. Thanks.

1 Like