- Home /
Using delta to find mouse movement
I am trying to get the relative movement of the cursor. Currently, this script works but only when you click and drag. I want it to activate when the mouse has been moved. Also, it activates twice for some reason, even though it's only set to one object.
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
void OnGUI() {
if (Event.current.delta.x > 0 || Event.current.delta.y > 0)
Debug.Log(Event.current.delta);
}
}
Answer by CodeMasterMike · Jan 24, 2013 at 08:48 AM
Looks like the current event only reacts when the button is pressed. Because Mouse move events are never sent in the games.
But you can do something like this instead:
private Vector2 oldMouePosition = Vector2.zero;
void OnGUI()
{
Vector2 currentMousePosition = Event.current.mousePosition;
float xMovement = Mathf.Abs(oldMouePosition.x - currentMousePosition.x);
float yMovement = Mathf.Abs(oldMouePosition.y - currentMousePosition.y);
oldMouePosition = currentMousePosition;
if(xMovement != 0.0f || yMovement != 0.0f)
{
Debug.Log(xMovement + ", " + yMovement);
}
}
So you take the current mouse position and you calculate the difference between the last time you updated the mouse position. I use Abs to always get a positive float. If you want to know if the mouse goes to the left or to the right (positive or a negative float) just can just ignore the Abs function.
And if the xMovement or the yMovement is not 0, that means that the mouse pointer has moved since the last GUI update.
If you want to avoid having a strange variable at the very first GUI update (since the old mouse positio is 0, 0 and the mouse position is whatever it is), you might want to set a little "check" to avoid that issue.
For instance, set the oldMousePosition to a value that will never appear:
private Vector2 oldMouePosition = new Vector2(-999.99f, -999.99f);
And then in the GUI function, make a small check to see if the oldMousePosition vector has this specific value:
void OnGUI()
{
if(oldMouePosition.x == -999.99f && oldMouePosition.y == -999.99f)
{
oldMouePosition = Event.current.mousePosition;
}
// Rest of the function here...
}
And if it does have this value, then set the vector to the current mouse position.
I hope this example helps you.
Good luck!
This was a good write up, thanks for that. Worked like a charm. The only issue I had was how CPU intensive it is; and because of that I'm probably going to have to scrap the idea. $$anonymous$$y idea was to use this to move a gui mouse relatively to the hardware mouse, so I could do things such as freeze the mouse in place. But as I said, this seems to be pretty CPU intensive.
OnGUI is not triggered only once per frame. It can actually happen many times per frame especially if you click and drag your mouse in the game window or you hold down a key.
if (Event.current.type != EventType.Repaint) return;
Adding that line in the beginning of the OnGUI method will limit the number of times your code is executed to about one or two times per frame according to my tests.
If you want to be absolutely sure that the code inside OnGUI() is only executed once per frame, I think you'll have to manage that yourself using a variable (myGUI_FrameCount, for example).
In the OnGUI method do this in the following order:
If myGUI_FrameCount is below Time.frameCount then execute your code.
Set myGUI_FrameCount to Time.frameCount.
Use this inside OnGUI() to test if it's working correctly:
Debug.Log ("OnGUI executed. Frame: " + Time.frameCount);
If it ever outputs the same frame more than once then something is wrong with your code.
(I am aware that this question was asked in 2013)
Your answer

Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Overlapping GUI Button priority 3 Answers
Fix Gimbal Lock Mouse Look? 0 Answers