UserInputService.TouchRotate issue

Hi,

I’ve run into an issue with TouchRotate where if I start one rotation with 2 fingers, keep one of the fingers on the screen, and then rotate again, it causes the rotation to sorta jump if that makes sense?

I don’t know how to describe it so I haven’t been able to find any solutions, here’s a video. Gray squares are where my fingers are:

Script:

    userInputService.TouchRotate:Connect(function(touchPositions, rotation, velocity, state, gameProcessedEvent)
		if #touchPositions < 2 then -- argument from userInputService.TouchRotate
			cameraRotationAtBeginningOfTouchRotate = nil
			return
		end
		if #touchPoints < 2 then -- also manually keeping track of the amount of fingers on the screen which is the touchPoints table, as a fallback
			cameraRotationAtBeginningOfTouchRotate = nil
			return
		end
		canPanCamera = false -- disable panning
		if not cameraRotationAtBeginningOfTouchRotate then -- if it's nil, this is the start of a rotation
			cameraRotationAtBeginningOfTouchRotate = cameraRotation -- save the current camera rotation as the rotation to apply the offset
		end
		cameraRotation = cameraRotationAtBeginningOfTouchRotate * CFrame.Angles(0,rotation,0) -- the offset
	end)

It looks like the code sample on the dev hub gets it right from minimal testing.

local cameraRotation = Vector2.new(0, math.rad(-60))

-- ...

local function UpdateCamera()
	SetCameraMode() -- doesn't do anything with cameraRotate

	local cameraRotationCFrame = CFrame.Angles(0, cameraRotation.X, 0) 
		* CFrame.Angles(cameraRotation.Y, 0, 0)

	camera.CFrame = cameraRotationCFrame 
		+ cameraPosition 
		+ cameraRotationCFrame * Vector3.new(0, 0, cameraZoom)

	camera.Focus = camera.CFrame - Vector3.new(0, camera.CFrame.p.Y, 0)
end

-- ...

local lastTouchRotation = nil

-- gets connected to UserInputService.TouchRotate
local function TouchRotate(_touchPositions, rotation, _velocity, state)
	if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
		local difference = rotation - lastTouchRotation

		local rotationDelta = -difference
			* math.rad(cameraTouchRotateSpeed * cameraRotateSpeed)

		cameraRotation += Vector2.new(rotationDelta, 0)

		UpdateCamera()

	end
	lastTouchRotation = rotation
end

Here is the entire code sample.

I honestly can’t really tell what’s different.

1 Like

Something must have been wrong with how I was handling it, works now.

Main differences are that I’m using the difference between the last, and I’m not discarding anything at the beginning of the function if conditions aren’t met.

	userInputService.TouchRotate:Connect(function(touchPositions, rotation, velocity, state, gameProcessedEvent)
		if state == Enum.UserInputState.Change or state == Enum.UserInputState.End then
			local difference = rotation - lastTouchRotation
			cameraRotation *= CFrame.Angles(0,-difference,0)
		end
		lastTouchRotation = rotation
	end)

Thanks for the help!

1 Like