Rotate plane based on touch limit speed of movement

For context: I just started with unity. I have followed two courses (2d and 3d) and I have a background in programming. I’m making something simple for the experience of finishing something. It’s a plane that has a sphere on it. You tilt the plane and try to let the sphere not fall. It’s really silly but it’s a start.

So I have a simple plane (with a rigidbody) and a sphere (also with a rigidbody). I’ve rotated my main camera (on the x axis) so it looks straight down, onto my plane.

What I want to do is use touch input (mobile/tablet) to tilt the plane (from the perspective of the camera) from left to right and top to bottom, limited to a space of -20, 20 on x and z (so it doesn’t go full circle).

This works. Attach the following script to a plane with a camera tilted over it and tilt the plane like you mean it.

using UnityEngine;
using Quaternion = UnityEngine.Quaternion;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;

public class PlaneControl : MonoBehaviour
    // x axis (up down)
    public float maxTiltVertical = 20f;

    // z axis (left right)
    public float maxTiltHorizontal = 20f;

    private Camera _camera;

    private Vector3 _lastPosition =;

    private void Start()
        _camera = Camera.main;

    protected void Update()
        if (Input.touchCount == 0)
            _lastPosition =;


        Touch touch = Input.GetTouch(0);
        Vector2 pos = touch.position;
        Vector3 touchPosition = new Vector3(pos.x, pos.y, _camera.nearClipPlane);

        // First touch, we don't want to actually calculate anything yet because we haven't moved.
        if (touch.phase == TouchPhase.Began)
            _lastPosition = touchPosition;


        Vector3 delta = touchPosition - _lastPosition;

        transform.Rotate(transform.forward, -Vector3.Dot(delta, _camera.transform.right), Space.World);
        transform.Rotate(transform.right, -Vector3.Dot(delta, _camera.transform.forward), Space.World);

        Vector3 angles = transform.localEulerAngles;

        float x = ClampRotation(angles.x, maxTiltVertical);
        float z = ClampRotation(angles.z, maxTiltHorizontal);

        transform.localRotation = Quaternion.Euler(x, 0, z);

        _lastPosition = touchPosition;

    private float ClampRotation(float value, float range)
        float normalized = (value > 180) ? value - 360 : value;

        return Mathf.Clamp(normalized, -range, range);

Now for my question(s).

  1. What I want to do is make the movement a little slower. Right now when I touch the screen and move from side to side a bit it flies around and it’s really hard to move the plane with precision (you have to move your finger really slowly). Is there a way to take the delta and just… Slow it down? Fake that the movement is less than it actually is? With a value between 0 and 1 for example?
  2. When I move my plane to quickly the sphere passes through it and falls forever. I get that this is because the physics miss a frame (or a couple) but I don’t know how to solve it. Should I make my plane a box for a greater volume (and thus more frames to match in)?
  3. Any other feedback on my code (best practises, stuff I’m doing wrong or could do better) is also greatly appreciated as I really want to get better at this.

Update: For clarity I’ve made a short video that shows the thing in action:

Youtube video

Am I allowed to bump my thread on this forum?