function ControlModule.SelectTouchModule(a)if not UserInputService.TouchEnabled then return nil,false end local Z=nil local T=Players.LocalPlayer.DevTouchMovementMode if T==Enum.DevTouchMovementMode.UserChoice then Z=movementEnumToModuleMap[UserGameSettings.TouchMovementMode]elseif T==Enum.DevTouchMovementMode.Scriptable then return nil,true else Z=movementEnumToModuleMap[T]end return Z,true end local function a(a,Z)local T=Workspace.CurrentCamera if not T then return Z end if a:GetState()==Enum.HumanoidStateType.Swimming then return T.CFrame:VectorToWorldSpace(Z)end local D,U local L,h,g,V,z,G,u,N,q,y,k,E=T.CFrame:GetComponents()if q<1 and q>-1 then D=E U=G else D=V U=-z*math.sign(q)end local C=math.sqrt(D*D+U*U)return Vector3.new((D*Z.x+U*Z.z)/C,0,(D*Z.z-U*Z.x)/C)end function ControlModule.OnRenderStepped(T,Z)if T.activeController and(T.activeController.enabled and T.humanoid)then T.activeController:OnRenderStepped(Z)local D=T.activeController:GetMoveVector()local U=T.activeController:IsMoveVectorCameraRelative()local L=T:GetClickToMoveController()if T.activeController~=L then if D.magnitude>0 then L:CleanupPath()else L:OnRenderStepped(Z)D=L:GetMoveVector()U=L:IsMoveVectorCameraRelative()end end local h=false if T.vehicleController then D,h=T.vehicleController:Update(D,U,T.activeControlModule==Gamepad)end if FFlagUserFixMovementCameraStraightDown then if U then D=a(T.humanoid,D)end T.moveFunction(Players.LocalPlayer,D,false)else T.moveFunction(Players.LocalPlayer,D,U)end T.humanoid.Jump=T.activeController:GetIsJumping()or T.touchJumpController and T.touchJumpController:GetIsJumping()end end function ControlModule.OnHumanoidSeated(T,a,Z)if a then if Z and Z:IsA("\086\101\104\105\099\108\101\083\101\097\116")then if not T.vehicleController then T.vehicleController=T.vehicleController.new(CONTROL_ACTION_PRIORITY)end T.vehicleController:Enable(true,Z)end else if T.vehicleController then T.vehicleController:Enable(false,Z)end end end function ControlModule.OnCharacterAdded(Z,a)Z.humanoid=a:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")while not Z.humanoid do a.ChildAdded:wait()Z.humanoid=a:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")end if Z.touchGui then Z.touchGui.Enabled=true end if Z.humanoidSeatedConn then Z.humanoidSeatedConn:Disconnect()Z.humanoidSeatedConn=nil end Z.humanoidSeatedConn=Z.humanoid.Seated:Connect(function(a,T)Z:OnHumanoidSeated(a,T)end)end function ControlModule.OnCharacterRemoving(Z,a)Z.humanoid=nil if Z.touchGui then Z.touchGui.Enabled=false end end

function ControlModule:SelectTouchModule()
	if not UserInputService.TouchEnabled then
		return nil, false
	end
	local touchModule = nil
	local DevMovementMode = Players.LocalPlayer.DevTouchMovementMode
	if DevMovementMode == Enum.DevTouchMovementMode.UserChoice then
		touchModule = movementEnumToModuleMap[UserGameSettings.TouchMovementMode]
	elseif DevMovementMode == Enum.DevTouchMovementMode.Scriptable then
		return nil, true
	else
		touchModule = movementEnumToModuleMap[DevMovementMode]
	end
	return touchModule, true
end

local function calculateRawMoveVector(humanoid, cameraRelativeMoveVector)
	local camera = Workspace.CurrentCamera
	if not camera then
		return cameraRelativeMoveVector
	end

	if humanoid:GetState() == Enum.HumanoidStateType.Swimming then
		return camera.CFrame:VectorToWorldSpace(cameraRelativeMoveVector)
	end

	local c, s
	local _, _, _, R00, R01, R02, _, _, R12, _, _, R22 = camera.CFrame:GetComponents()
	if R12 < 1 and R12 > -1 then
		-- X and Z components from back vector.
		c = R22
		s = R02
	else
		-- In this case the camera is looking straight up or straight down.
		-- Use X components from right and up vectors.
		c = R00
		s = -R01*math.sign(R12)
	end
	local norm = math.sqrt(c*c + s*s)
	return Vector3.new(
		(c*cameraRelativeMoveVector.x + s*cameraRelativeMoveVector.z)/norm,
		0,
		(c*cameraRelativeMoveVector.z - s*cameraRelativeMoveVector.x)/norm
	)
end

function ControlModule:OnRenderStepped(dt)
	if self.activeController and self.activeController.enabled and self.humanoid then
		-- Give the controller a chance to adjust its state
		self.activeController:OnRenderStepped(dt)

		-- Now retrieve info from the controller
		local moveVector = self.activeController:GetMoveVector()
		local cameraRelative = self.activeController:IsMoveVectorCameraRelative()

		local clickToMoveController = self:GetClickToMoveController()
		if self.activeController ~= clickToMoveController then
			if moveVector.magnitude > 0 then
				-- Clean up any developer started MoveTo path
				clickToMoveController:CleanupPath()
			else
				-- Get move vector for developer started MoveTo
				clickToMoveController:OnRenderStepped(dt)
				moveVector = clickToMoveController:GetMoveVector()
				cameraRelative = clickToMoveController:IsMoveVectorCameraRelative()
			end
		end

		-- Are we driving a vehicle ?
		local vehicleConsumedInput = false
		if self.vehicleController then
			moveVector, vehicleConsumedInput = self.vehicleController:Update(moveVector, cameraRelative, self.activeControlModule==Gamepad)
		end

		-- If not, move the player
		-- Verification of vehicleConsumedInput is commented out to preserve legacy behavior, in case some game relies on Humanoid.MoveDirection still being set while in a VehicleSeat
		--if not vehicleConsumedInput then
			if FFlagUserFixMovementCameraStraightDown then
				if cameraRelative then
					moveVector = calculateRawMoveVector(self.humanoid, moveVector)
				end
				self.moveFunction(Players.LocalPlayer, moveVector, false)
			else
				self.moveFunction(Players.LocalPlayer, moveVector, cameraRelative)
			end
		--end

		-- And make them jump if needed
		self.humanoid.Jump = self.activeController:GetIsJumping() or (self.touchJumpController and self.touchJumpController:GetIsJumping())
	end
end

function ControlModule:OnHumanoidSeated(active, currentSeatPart)
	if active then
		if currentSeatPart and currentSeatPart:IsA("VehicleSeat") then
			if not self.vehicleController then
				self.vehicleController = self.vehicleController.new(CONTROL_ACTION_PRIORITY)
			end
			self.vehicleController:Enable(true, currentSeatPart)
		end
	else
		if self.vehicleController then
			self.vehicleController:Enable(false, currentSeatPart)
		end
	end
end

function ControlModule:OnCharacterAdded(char)
	self.humanoid = char:FindFirstChildOfClass("Humanoid")
	while not self.humanoid do
		char.ChildAdded:wait()
		self.humanoid = char:FindFirstChildOfClass("Humanoid")
	end

	if self.touchGui then
		self.touchGui.Enabled = true
	end

	if self.humanoidSeatedConn then
		self.humanoidSeatedConn:Disconnect()
		self.humanoidSeatedConn = nil
	end
	self.humanoidSeatedConn = self.humanoid.Seated:Connect(function(active, currentSeatPart) self:OnHumanoidSeated(active, currentSeatPart) end)
end

function ControlModule:OnCharacterRemoving(char)
	self.humanoid = nil

	if self.touchGui then
		self.touchGui.Enabled = false
	end
end
