Help: Rotation speed between Mouse and Tablet vary widely.

I’m developing an application have requires the user to rotate an object by dragging the mouse OR tablet.

I’m using a Walcom Tablet for developement.

However I’m having trouble with the rotation speed of the 2 devices - the rotation speed using the tablet is always way too fast compared to the mouse input. If I’ll to adjust the tablet speed to a comfortable level, the mouse will be way too slow.

Could this be because of the differences in resolution between different input devices? How do I solve this?

function Update () {

	if (Input.GetMouseButton(0)){
			
			var y = Input.GetAxis("Mouse X") * Time.deltaTime * speed;
			transform.Rotate(0, -y, 0);
	
			var x = Input.GetAxis("Mouse Y") * Time.deltaTime * speed;
			transform.Rotate(x, 0, 0,Space.World);

	}
	
}

Create some kind of settings screen that will ask the user what device he’s using, or create a sensitivity setting slider… So the user can have it behave as he wants it to.
Check out the input settings in your project… See if you can make the two behave closer if you tweak the sesitivity setting of the mouse input.

You can try using Input.GetAxisRaw() to bypass the smoothing unity does. Maybe without the smoothing the values are more alike.

Also - You can maybe try using Input.mousePosition to calculate the delta yourself… If you absolutely insist on it.

I was just thinking about this problem over the weekend…

Some applications have a setting for Use Relative Mouse or Use Pen Mouse- for both editor and runtime

does Unity have an equivalent?

(getting tired of picking up the mouse, making room to use it every time I need to test the scene)

I’ve tried Input.GetAxisRaw()and it didn’t work.

Adjusting input sensitivity in Project Input doesn’t work too, as my script uses Mouse X Mouse Y for both mouse and tablet as there isn’t a Tablet option.

Many applications out there already makes the process transparent to the user whether he’s using a mouse or tablet, which I think should be the way to go.

Most people ( besides gamers ) uses mouse and tablet interchangably. So I thought there should be a way to address this conveniently, without writing a script to capture mouse position calculate delta, though I understand that’s my fallback plan.

Well, if you set sensitivity as close to 0 as possible (or as close to 1 as possibe… not sure) and increase your own sensitivity in your code to adjust for it - you might get more similar values… This is just a guess, and I don’t have a tablet near me right now to test it out…
I just think there’s a difference between the sampling rate of the mouse and tablet, and the sensitivity just increases that difference (Since the data is multiplied by that number).

Then just calculate your own deltas. It’s not that hard or complicated, you know… If you need some help i’ll be glad to assist.

And by the way - 3D applications still need the user to choose what input device he’s using - and they adjust their sensitivity settings based on it. Not only the handling of absolute position on screen Vs. relative position. I know lightwave does for a fact.

And if you think strongly that Unity needs to address the tablet as an input device in the editor and in the input class - add it to the wish list. If you’re right, there should be many others that feel the same way as you that will join your call and Unity tech will probably address the issue in their future updates…

For now, if you think it’s that important - write a class to handle it and add it to the wiki so others can benefit from your work :slight_smile:

mouse input + tablet in a single code = very bad scenario.

Mice move over the surface continously (sending movement to the system), while tablets teleport by a fraction of the screen space, they don’t move (sending position data at their sampling rate to the system).
Should you ever raise the pen and click somewhere else, you are basically asking for spinning headache.

To handle tablets usefully its normally better to implement an alternative code path just for them and request the user to choose the corresponding layout (keyboard, kb + mouse, kb + pen)

I’m not sure if a simple solution like sensitivity will do it in this case actually, as 1000 pixel within a few hundred microseconds, independent of the sensivity, will throw the cam appart.

What I would do in tablet case is a “drag vector” based approach.
The screen coords at which the pen hits the surface is used as 0,0 point and until it is lifted, all mouse based input is done in relation to the vector from the current position to that drag position.
once the pen is raised again, the position is “fixed” at the last valid drag based position and the whole procedure repeats.
That way you avoid the click - click rotation spinning as well as a totally useless rotation due to micro-sensivity

I understand where your coming from. I’m a Lightwave user too, and was completely OK with the tablet/mouse switch until I started switching to Softimage XSI where the switching of mouse and Tablet is transparent to the user. This is IMO how I feel programs should be written.

Will really appreciate some help here.

This is what I have so far. It works exactly the same regardless whether mouse or tablet is used.
I only managed to get the rotation around the Y-Axis working. For X-Axis, I need the rotation to be in world space. i.e. always tilting towards/away from the camera.

	if (Input.GetMouseButton(0)){ // Mouse is dragging
	
			// Enter only once on mouse click to register mouse click position  current rotation
				if ( Input.GetMouseButtonDown(0)) {  
				
					clickFirst.x=Input.mousePosition.x;
					clickFirst.y=Input.mousePosition.y;
					rotFirst.y=transform.eulerAngles.y;
					rotFirst.x=transform.eulerAngles.x;

				}
			
			// Adds to current rotation 
			navX=rotFirst.x-((Input.mousePosition.y-clickFirst.y)/5);
			navY=rotFirst.y-((Input.mousePosition.x-clickFirst.x)/5);
		
			transform.rotation=Quaternion.Euler(0,navY,0);
			
			// transform.rotation=Quaternion.Euler(navX,navY,0);
			// Doesn't work because X-axis rotation needs to be in World Space
			
	}

I managed to do this previously ( mouse/tablet not sync version )using

var y = Input.GetAxis("Mouse X") * Time.deltaTime * speed;
			transform.Rotate(0, -y, 0);
			
		
			var x = Input.GetAxis("Mouse Y") * Time.deltaTime * speed;
			transform.Rotate(x, 0, 0,Space.World);

But I can’t do the same for transform.Rotation

Any help appreciated.

You had me stumped with this for a while here… After a year and a half I thought I had quaternions figured out by now…

Try this :slight_smile:

var clickFirst: Vector2;
var rotFirst: Vector2;
var qPreviousRotation: Quaternion;

function Update()
{
	if (Input.GetMouseButton(0))
	{ // Mouse is dragging
	    // Enter only once on mouse click to register mouse click position  current rotation
        if ( Input.GetMouseButtonDown(0)) 
		{ 
            clickFirst.x=Input.mousePosition.x;
            clickFirst.y=Input.mousePosition.y;
            rotFirst.y=transform.eulerAngles.y;
            rotFirst.x=transform.eulerAngles.x;
			
			qPreviousRotation = transform.rotation;
        }

	    navY = (Input.mousePosition.x - clickFirst.x) / 5;
		navX = (Input.mousePosition.y - clickFirst.y) / 5;

		var v3RelativeRight: Vector3 = Camera.main.transform.TransformDirection (Vector3.right);
		var v3RelativeUp: Vector3 = transform.TransformDirection (Vector3.up);
		
		var qNavX: Quaternion = Quaternion.AngleAxis (navX, v3RelativeRight);
		var qNavY: Quaternion = Quaternion.AngleAxis (navY, v3RelativeUp);
		

        var qDiffXRotation: Quaternion = Quaternion.identity * qNavX;
		transform.rotation = qDiffXRotation * qPreviousRotation * Quaternion.Euler(0,-navY,0);
	}		
}

Wow! I didn’t think it can be done this way.
The last few lines make all the difference.

I must admit that I got to look up the scripting manual for some functions new to me like TransformDirection Quaternion AngleAxis.

Thanks for showing me the way…and your time. :smile:

( I think you meant to comment off v3RelativeUp qNavY ( Y-axis ) as they are not used, since only X-axis is the tricky one.)