local c=require(script.Parent:WaitForChild("\066\097\115\101\067\104\097\114\097\099\116\101\114\067\111\110\116\114\111\108\108\101\114"))local f=setmetatable({},c)f.__index=f function f.new()local V=setmetatable(c.new(),f)V.isFollowStick=false V.thumbstickFrame=nil V.moveTouchObject=nil V.onTouchMovedConn=nil V.onTouchEndedConn=nil V.screenPos=nil V.stickImage=nil V.thumbstickSize=nil return V end function f.Enable(V,c,f)if c==nil then return false end c=c and true or false if V.enabled==c then return true end V.moveVector=ZERO_VECTOR3 V.isJumping=false if c then if not V.thumbstickFrame then V:Create(f)end V.thumbstickFrame.Visible=true else V.thumbstickFrame.Visible=false V:OnInputEnded()end V.enabled=c end function f.OnInputEnded(c)c.thumbstickFrame.Position=c.screenPos c.stickImage.Position=UDim2.new(0,c.thumbstickFrame.Size.X.Offset/2-c.thumbstickSize/4,0,c.thumbstickFrame.Size.Y.Offset/2-c.thumbstickSize/4)c.moveVector=ZERO_VECTOR3 c.isJumping=false c.thumbstickFrame.Position=c.screenPos c.moveTouchObject=nil end function f.Create(f,c)if f.thumbstickFrame then f.thumbstickFrame:Destroy()f.thumbstickFrame=nil if f.onTouchMovedConn then f.onTouchMovedConn:Disconnect()f.onTouchMovedConn=nil end if f.onTouchEndedConn then f.onTouchEndedConn:Disconnect()f.onTouchEndedConn=nil end end local V=math.min(c.AbsoluteSize.x,c.AbsoluteSize.y)local Y=V<=500 f.thumbstickSize=Y and 70 or 120 f.screenPos=Y and UDim2.new(0,f.thumbstickSize/2-10,1,-f.thumbstickSize-20)or UDim2.new(0,f.thumbstickSize/2,1,-f.thumbstickSize*1.75)f.thumbstickFrame=Instance.new("\070\114\097\109\101")f.thumbstickFrame.Name="\084\104\117\109\098\115\116\105\099\107\070\114\097\109\101"f.thumbstickFrame.Active=true f.thumbstickFrame.Visible=false f.thumbstickFrame.Size=UDim2.new(0,f.thumbstickSize,0,f.thumbstickSize)f.thumbstickFrame.Position=f.screenPos f.thumbstickFrame.BackgroundTransparency=1 local W=Instance.new("\073\109\097\103\101\076\097\098\101\108")W.Name="\079\117\116\101\114\073\109\097\103\101"W.Image=TOUCH_CONTROL_SHEET W.ImageRectOffset=Vector2.new()W.ImageRectSize=Vector2.new(220,220)W.BackgroundTransparency=1 W.Size=UDim2.new(0,f.thumbstickSize,0,f.thumbstickSize)W.Position=UDim2.new(0,0,0,0)W.Parent=f.thumbstickFrame f.stickImage=Instance.new("\073\109\097\103\101\076\097\098\101\108")f.stickImage.Name="\083\116\105\099\107\073\109\097\103\101"f.stickImage.Image=TOUCH_CONTROL_SHEET f.stickImage.ImageRectOffset=Vector2.new(220,0)f.stickImage.ImageRectSize=Vector2.new(111,111)f.stickImage.BackgroundTransparency=1 f.stickImage.Size=UDim2.new(0,f.thumbstickSize/2,0,f.thumbstickSize/2)f.stickImage.Position=UDim2.new(0,f.thumbstickSize/2-f.thumbstickSize/4,0,f.thumbstickSize/2-f.thumbstickSize/4)f.stickImage.ZIndex=2 f.stickImage.Parent=f.thumbstickFrame local y=nil local M=.05 local function v(c)local V=c/(f.thumbstickSize/2)local Y=V.magnitude if Y<M then V=Vector3.new()else V=V.unit*((Y-M)/(1-M))V=Vector3.new(V.x,0,V.y)end f.moveVector=V end local function G(c)local V=Vector2.new(c.x-y.x,c.y-y.y)local Y=V.magnitude local W=f.thumbstickFrame.AbsoluteSize.x/2 if f.isFollowStick and Y>W then local Y=V.unit*W f.thumbstickFrame.Position=UDim2.new(0,(c.x-f.thumbstickFrame.AbsoluteSize.x/2)-Y.x,0,(c.y-f.thumbstickFrame.AbsoluteSize.y/2)-Y.y)else Y=math.min(Y,W)V=V.unit*Y end f.stickImage.Position=UDim2.new(0,V.x+f.stickImage.AbsoluteSize.x/2,0,V.y+f.stickImage.AbsoluteSize.y/2)end f.thumbstickFrame.InputBegan:Connect(function(c)if f.moveTouchObject or c.UserInputType~=Enum.UserInputType.Touch or c.UserInputState~=Enum.UserInputState.Begin then return end f.moveTouchObject=c f.thumbstickFrame.Position=UDim2.new(0,c.Position.x-f.thumbstickFrame.Size.X.Offset/2,0,c.Position.y-f.thumbstickFrame.Size.Y.Offset/2)y=Vector2.new(f.thumbstickFrame.AbsolutePosition.x+f.thumbstickFrame.AbsoluteSize.x/2,f.thumbstickFrame.AbsolutePosition.y+f.thumbstickFrame.AbsoluteSize.y/2)local V=Vector2.new(c.Position.x-y.x,c.Position.y-y.y)end)f.onTouchMovedConn=UserInputService.TouchMoved:Connect(function(c,V)if c==f.moveTouchObject then y=Vector2.new(f.thumbstickFrame.AbsolutePosition.x+f.thumbstickFrame.AbsoluteSize.x/2,f.thumbstickFrame.AbsolutePosition.y+f.thumbstickFrame.AbsoluteSize.y/2)local V=Vector2.new(c.Position.x-y.x,c.Position.y-y.y)v(V)G(c.Position)end end)f.onTouchEndedConn=UserInputService.TouchEnded:Connect(function(c,V)if c==f.moveTouchObject then f:OnInputEnded()end end)GuiService.MenuOpened:Connect(function()if f.moveTouchObject then f:OnInputEnded()end end)f.thumbstickFrame.Parent=c end return f
--
local BaseCharacterController = require(script.Parent:WaitForChild("BaseCharacterController"))
local TouchThumbstick = setmetatable({}, BaseCharacterController)
TouchThumbstick.__index = TouchThumbstick
function TouchThumbstick.new()
	local self = setmetatable(BaseCharacterController.new(), TouchThumbstick)
	
	self.isFollowStick = false
	
	self.thumbstickFrame = nil
	self.moveTouchObject = nil
	self.onTouchMovedConn = nil
	self.onTouchEndedConn = nil
	self.screenPos = nil
	self.stickImage = nil
	self.thumbstickSize = nil -- Float
	
	return self
end
function TouchThumbstick:Enable(enable, uiParentFrame)
	if enable == nil then return false end			-- If nil, return false (invalid argument)
	enable = enable and true or false				-- Force anything non-nil to boolean before comparison
	if self.enabled == enable then return true end	-- If no state change, return true indicating already in requested state
	
	self.moveVector = ZERO_VECTOR3
	self.isJumping = false
	
	if enable then
		-- Enable
		if not self.thumbstickFrame then
			self:Create(uiParentFrame)
		end
		self.thumbstickFrame.Visible = true
	else 
		-- Disable
		self.thumbstickFrame.Visible = false
		self:OnInputEnded()
	end
	self.enabled = enable
end
function TouchThumbstick:OnInputEnded()
	self.thumbstickFrame.Position = self.screenPos
	self.stickImage.Position = UDim2.new(0, self.thumbstickFrame.Size.X.Offset/2 - self.thumbstickSize/4, 0, self.thumbstickFrame.Size.Y.Offset/2 - self.thumbstickSize/4)
	
	self.moveVector = ZERO_VECTOR3
	self.isJumping = false
	self.thumbstickFrame.Position = self.screenPos
	self.moveTouchObject = nil
end
function TouchThumbstick:Create(parentFrame)
	
	if self.thumbstickFrame then
		self.thumbstickFrame:Destroy()
		self.thumbstickFrame = nil
		if self.onTouchMovedConn then
			self.onTouchMovedConn:Disconnect()
			self.onTouchMovedConn = nil
		end
		if self.onTouchEndedConn then
			self.onTouchEndedConn:Disconnect()
			self.onTouchEndedConn = nil
		end
	end
	
	local minAxis = math.min(parentFrame.AbsoluteSize.x, parentFrame.AbsoluteSize.y)
	local isSmallScreen = minAxis <= 500
	self.thumbstickSize = isSmallScreen and 70 or 120
	self.screenPos = isSmallScreen and UDim2.new(0, (self.thumbstickSize/2) - 10, 1, -self.thumbstickSize - 20) or
		UDim2.new(0, self.thumbstickSize/2, 1, -self.thumbstickSize * 1.75)
		
	self.thumbstickFrame = Instance.new("Frame")
	self.thumbstickFrame.Name = "ThumbstickFrame"
	self.thumbstickFrame.Active = true
	self.thumbstickFrame.Visible = false
	self.thumbstickFrame.Size = UDim2.new(0, self.thumbstickSize, 0, self.thumbstickSize)
	self.thumbstickFrame.Position = self.screenPos
	self.thumbstickFrame.BackgroundTransparency = 1
	
	local outerImage = Instance.new("ImageLabel")
	outerImage.Name = "OuterImage"
	outerImage.Image = TOUCH_CONTROL_SHEET
	outerImage.ImageRectOffset = Vector2.new()
	outerImage.ImageRectSize = Vector2.new(220, 220)
	outerImage.BackgroundTransparency = 1
	outerImage.Size = UDim2.new(0, self.thumbstickSize, 0, self.thumbstickSize)
	outerImage.Position = UDim2.new(0, 0, 0, 0)
	outerImage.Parent = self.thumbstickFrame
	
	self.stickImage = Instance.new("ImageLabel")
	self.stickImage.Name = "StickImage"
	self.stickImage.Image = TOUCH_CONTROL_SHEET
	self.stickImage.ImageRectOffset = Vector2.new(220, 0)
	self.stickImage.ImageRectSize = Vector2.new(111, 111)
	self.stickImage.BackgroundTransparency = 1
	self.stickImage.Size = UDim2.new(0, self.thumbstickSize/2, 0, self.thumbstickSize/2)
	self.stickImage.Position = UDim2.new(0, self.thumbstickSize/2 - self.thumbstickSize/4, 0, self.thumbstickSize/2 - self.thumbstickSize/4)
	self.stickImage.ZIndex = 2
	self.stickImage.Parent = self.thumbstickFrame
	
	local centerPosition = nil
	local deadZone = 0.05
	
	local function DoMove(direction)
		
		local currentMoveVector = direction / (self.thumbstickSize/2)
		
		-- Scaled Radial Dead Zone
		local inputAxisMagnitude = currentMoveVector.magnitude
		if inputAxisMagnitude < deadZone then
			currentMoveVector = Vector3.new()
		else
			currentMoveVector = currentMoveVector.unit * ((inputAxisMagnitude - deadZone) / (1 - deadZone))
			-- NOTE: Making currentMoveVector a unit vector will cause the player to instantly go max speed
			-- must check for zero length vector is using unit
			currentMoveVector = Vector3.new(currentMoveVector.x, 0, currentMoveVector.y)
		end
		
		self.moveVector = currentMoveVector
	end
	
	local function MoveStick(pos)
		local relativePosition = Vector2.new(pos.x - centerPosition.x, pos.y - centerPosition.y)
		local length = relativePosition.magnitude
		local maxLength = self.thumbstickFrame.AbsoluteSize.x/2
		if self.isFollowStick and length > maxLength then
			local offset = relativePosition.unit * maxLength
			self.thumbstickFrame.Position = UDim2.new(
				0, pos.x - self.thumbstickFrame.AbsoluteSize.x/2 - offset.x,
				0, pos.y - self.thumbstickFrame.AbsoluteSize.y/2 - offset.y)
		else
			length = math.min(length, maxLength)
			relativePosition = relativePosition.unit * length
		end
		self.stickImage.Position = UDim2.new(0, relativePosition.x + self.stickImage.AbsoluteSize.x/2, 0, relativePosition.y + self.stickImage.AbsoluteSize.y/2)
	end
	
	-- input connections
	self.thumbstickFrame.InputBegan:Connect(function(inputObject)
		--A touch that starts elsewhere on the screen will be sent to a frame's InputBegan event
		--if it moves over the frame. So we check that this is actually a new touch (inputObject.UserInputState ~= Enum.UserInputState.Begin)
		if self.moveTouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch
			or inputObject.UserInputState ~= Enum.UserInputState.Begin then
			return
		end
		
		self.moveTouchObject = inputObject
		self.thumbstickFrame.Position = UDim2.new(0, inputObject.Position.x - self.thumbstickFrame.Size.X.Offset/2, 0, inputObject.Position.y - self.thumbstickFrame.Size.Y.Offset/2)
		centerPosition = Vector2.new(self.thumbstickFrame.AbsolutePosition.x + self.thumbstickFrame.AbsoluteSize.x/2,
			self.thumbstickFrame.AbsolutePosition.y + self.thumbstickFrame.AbsoluteSize.y/2)
		local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y)
	end)
	
	self.onTouchMovedConn = UserInputService.TouchMoved:Connect(function(inputObject, isProcessed)
		if inputObject == self.moveTouchObject then
			centerPosition = Vector2.new(self.thumbstickFrame.AbsolutePosition.x + self.thumbstickFrame.AbsoluteSize.x/2,
				self.thumbstickFrame.AbsolutePosition.y + self.thumbstickFrame.AbsoluteSize.y/2)
			local direction = Vector2.new(inputObject.Position.x - centerPosition.x, inputObject.Position.y - centerPosition.y)
			DoMove(direction)
			MoveStick(inputObject.Position)
		end
	end)
	
	self.onTouchEndedConn = UserInputService.TouchEnded:Connect(function(inputObject, isProcessed)
		if inputObject == self.moveTouchObject then
			self:OnInputEnded()
		end
	end)
	
	GuiService.MenuOpened:Connect(function()
		if self.moveTouchObject then
			self:OnInputEnded()
		end
	end)	
	
	self.thumbstickFrame.Parent = parentFrame
end
return TouchThumbstick
