local t={}local i=require(script.Parent.Parent:WaitForChild("\067\111\110\102\105\103\117\114\097\116\105\111\110"))local o=i.MoveControllerCreator.MAGNITUDE_THRESHOLD local x={None=Enum.KeyCode.Thumbstick1;[Enum.VRTouchpad.Left]=Enum.KeyCode.Thumbstick1,[Enum.VRTouchpad.Right]=Enum.KeyCode.Thumbstick2}local P=game:GetService("\086\082\083\101\114\118\105\099\101")local Y=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local U=game:GetService("\082\117\110\083\101\114\118\105\099\101")local l,Z,r=math.sin,math.cos,math.atan2 local n local G,A=0,0 local I,R,y,F=0,0,0,0 local C=0 local Q=false U.RenderStepped:Connect(function(t)if n and y>0 then local i=C+F local o=(n.Humanoid.WalkSpeed*t)*y local x,P=l(i)*o,-Z(i)*o G,A=G+x,A+P n:SetCharacterXZOffset(G,A)end end)function t.CreateMoveController(U,t,i)n=i local l={}local Z=i.CharacterModel if t then P:SetTouchpadMode(t,Enum.VRTouchpadMode.Touch)else t="\078\111\110\101"end local j=x[t]local T,b=Enum.VRTouchpad.Left,Enum.VRTouchpad.Right local V,a=Enum.UserCFrame.LeftHand,Enum.UserCFrame.RightHand local function L()if t=="\078\111\110\101"then if j==x[T]then return not P:GetUserCFrameEnabled(V)else return not P:GetUserCFrameEnabled(a)end else return P:GetUserCFrameEnabled(t==T and V or a)end end local J=0 function l.UpdateController(i,t)J=r(t.lookVector.X,-t.lookVector.Z)end local function v()if Q==false then Q=true i:SetYPlaneLockWorldOffset(true)end end local function w()I,R=0,0 y=0 if(G~=0 or A~=0)and Q then Q=false i:SetYPlaneLockWorldOffset(false)local t=i:GetWorldOffset()i:SetCharacterXZOffset(0,0)i:SetWorldXZOffset(G+t.X,A+t.Z)G,A=0,0 end end local O=Y.InputEnded:Connect(function(t)local i=t.KeyCode if i==j and L()then w()end end)local z=Y.InputChanged:Connect(function(t)if t.KeyCode==j and L()then local i,x=t.Position.X,t.Position.Y local P=(i^2+x^2)^.5 local Y=r(i,x)F=Y C=J if P>o then v()I,R=i,x y=P else w()end end end)function l.Disconnect(t)O:Disconnect()z:Disconnect()end return l end return t



local MoveControllerCreator = {}



local Configuration = require(script.Parent.Parent:WaitForChild("Configuration"))
local MAGNITUDE_THRESHOLD = Configuration.MoveControllerCreator.MAGNITUDE_THRESHOLD

local TouchpadThumbstickToInput = {
	["None"] = Enum.KeyCode.Thumbstick1,
	[Enum.VRTouchpad.Left] = Enum.KeyCode.Thumbstick1,
	[Enum.VRTouchpad.Right] = Enum.KeyCode.Thumbstick2,
}

local VRService = game:GetService("VRService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local sin,cos,atan2 = math.sin,math.cos,math.atan2



local GlobalCharacterClass
local CurCharX,CurCharZ = 0,0
local ControllerX,ControllerY,ControllerMag,ControllerAngle = 0,0,0,0
local CurrentControllerLookAngle = 0
local CameraYLocked = false
RunService.RenderStepped:Connect(function(DeltaTime)
	if GlobalCharacterClass and ControllerMag > 0 then
		local FinalAngle = CurrentControllerLookAngle + ControllerAngle
		local TotalWalkspeed = GlobalCharacterClass.Humanoid.WalkSpeed * DeltaTime * ControllerMag
		local MoveX,MoveZ = sin(FinalAngle) * TotalWalkspeed,-cos(FinalAngle) * TotalWalkspeed
		
		CurCharX,CurCharZ = CurCharX + MoveX,CurCharZ + MoveZ
		GlobalCharacterClass:SetCharacterXZOffset(CurCharX,CurCharZ)
	end
end)
	
function MoveControllerCreator:CreateMoveController(VRTouchpad,CharacterClass)
	GlobalCharacterClass = CharacterClass
	local MoveControllerClass = {}
	local CharacterModel = CharacterClass.CharacterModel
	
	if VRTouchpad then
		VRService:SetTouchpadMode(VRTouchpad,Enum.VRTouchpadMode.Touch)
	else
		VRTouchpad = "None"
	end
	local ThumbstickInput = TouchpadThumbstickToInput[VRTouchpad]
	
	local Left,Right = Enum.VRTouchpad.Left,Enum.VRTouchpad.Right
	local LeftHand,RightHand = Enum.UserCFrame.LeftHand,Enum.UserCFrame.RightHand
	local function ValidInput()
		if VRTouchpad == "None" then
			if ThumbstickInput == TouchpadThumbstickToInput[Left] then
				return not VRService:GetUserCFrameEnabled(LeftHand)
			else
				return not VRService:GetUserCFrameEnabled(RightHand)
			end
		else
			return VRService:GetUserCFrameEnabled((VRTouchpad == Left and LeftHand or RightHand))
		end
	end
	
	local ControllerLookAngle = 0
	function MoveControllerClass:UpdateController(ControllerCF)
		ControllerLookAngle = atan2(ControllerCF.lookVector.X,-ControllerCF.lookVector.Z)
	end
	
	local function StartInput()
		if CameraYLocked == false then
			CameraYLocked = true
			CharacterClass:SetYPlaneLockWorldOffset(true)
		end
	end
	
	local function EndInput()
		ControllerX,ControllerY = 0,0
		ControllerMag = 0
		if (CurCharX ~= 0 or CurCharZ ~= 0) and CameraYLocked then
			CameraYLocked = false
			CharacterClass:SetYPlaneLockWorldOffset(false)
			local CurOffset = CharacterClass:GetWorldOffset()
			CharacterClass:SetCharacterXZOffset(0,0)
			CharacterClass:SetWorldXZOffset(CurCharX + CurOffset.X,CurCharZ + CurOffset.Z)
			CurCharX,CurCharZ = 0,0
		end
	end
	
	local UserInputEvent1 = UserInputService.InputEnded:Connect(function(Input)
		local KeyCode = Input.KeyCode
		if KeyCode == ThumbstickInput and ValidInput() then
			EndInput()
		end
	end)
	
	local UserInputEvent2 = UserInputService.InputChanged:Connect(function(Input)
		if Input.KeyCode == ThumbstickInput and ValidInput() then
			local X,Y = Input.Position.X,Input.Position.Y
			local Magnitude = ((X ^ 2) + (Y ^ 2)) ^ 0.5
			local Angle = atan2(X,Y)
			
			ControllerAngle = Angle
			CurrentControllerLookAngle = ControllerLookAngle
			if Magnitude > MAGNITUDE_THRESHOLD then
				StartInput()
				ControllerX,ControllerY = X,Y
				ControllerMag = Magnitude
			else
				EndInput()
			end
		end
	end)
	
	function MoveControllerClass:Disconnect()
		UserInputEvent1:Disconnect()
		UserInputEvent2:Disconnect()
	end
	
	return MoveControllerClass
end

return MoveControllerCreator
