Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Simple mouse wheel rotate?

Discussion in 'Scripting' started by mrtiff, Dec 1, 2013.

  1. mrtiff

    mrtiff

    Joined:
    Dec 1, 2013
    Posts:
    4
    Hi

    I'm just starting out scripting and I'm trying to make various objects rotate using the mouse scroll wheel. I've been using the following script to attach to objects but it the scrolling is slow and jerky.

    var speed = 30;

    function Update () {

    if (Input.GetAxis("Mouse ScrollWheel") > 0)
    transform.Rotate(Vector3.up * speed * Time.deltaTime);

    if (Input.GetAxis("Mouse ScrollWheel") < 0)
    transform.Rotate(-Vector3.up * speed * Time.deltaTime);

    }

    I'd like to know how to make the objects spin smoother and speed up the faster you scroll the wheel and gradually slow as you stop scrolling instead of stopping straight away.

    Thanks for any help Mark.
     
  2. OrbitusII

    OrbitusII

    Joined:
    Jul 4, 2011
    Posts:
    175
    You can simply multiply the rotation by the input you get from the scrollwheel.

    Like so:
    Code (csharp):
    1. transform.Rotate(Vector3.up * speed * Input.GetAxis("Mouse ScrollWheel") * Time.deltaTIme);
    2. //there's also no need for the if() statements here:
    3. //if there's no input from the scrollwheel, there will be no rotation.
    To get the rotation to smooth out you can use Mathf.Lerp(from, to, rate)
     
    SonEvil likes this.
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,853
    Well, scroll wheel input is supposed to be slow and jerky — a good mouse wheel should have a tangible click on each position in its rotation. In between clicks, its input is zero.

    That said, maybe what you want is to increase the speed (in a certain direction) with the mouse wheel. To do that, you'll need to add a property to your script. My JavaScript is a bit rusty, but it should look something like this:

    Code (csharp):
    1.   var curSpin = 0;
    2.  
    Then in your Update method, you'd want something like this:

    Code (csharp):
    1.  // update the current spin with the mouse wheel
    2.   curSpin += Input.GetAxis("Mouse ScrollWheel") * speed * Time.deltaTime;
    3.  
    4.   // ...but let it decay back towards zero, as if we have some friction
    5.   var friction = curSpeed * 0.1 * Time.deltaTime;
    6.   curSpin -= friction;
    7.   if (curSpin > -0.1  curSpin < 0.1) curSpin = 0;
    8.  
    9.   // finally, do the actual rotation
    10.   transform.Rotate(Vector3.up * curSpin * Time.deltaTime);
    11.  
    Play with the constants until you get the effect you're looking for.

    HTH,
    - Joe
     
  4. mrtiff

    mrtiff

    Joined:
    Dec 1, 2013
    Posts:
    4
    Orbitus, I couldnt get your piece of code to work ?
     
  5. mrtiff

    mrtiff

    Joined:
    Dec 1, 2013
    Posts:
    4
    Hi Joe,

    I've just tried your code as well and nothing appears to rotate ? I've attached the code to a sphere to test it. speed and curSpeed variables both gave errors so I defined them but wasnt sure what values to give them. Sorry, very new to coding.

    Code (csharp):
    1.  
    2. var curSpin = 0;
    3. var speed = 30;
    4. var curSpeed = 30;
    5.  
    6.     function Update () {
    7.      
    8.      // update the current spin with the mouse wheel
    9.       curSpin += Input.GetAxis("Mouse ScrollWheel") * speed * Time.deltaTime;
    10.      
    11.       // ...but let it decay back towards zero, as if we have some friction
    12.       var friction = curSpeed * 0.1 * Time.deltaTime;
    13.       curSpin -= friction;
    14.       if (curSpin > -0.1  curSpin < 0.1) curSpin = 0;
    15.      
    16.       // finally, do the actual rotation
    17.       transform.Rotate(Vector3.up * curSpin * Time.deltaTime);
    18.      
    19.     }
    20.  

    Thanks Mark,
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,853
    OK, I had some errors in that script, which I'd just typed out of my head. This time I actually went and tried it, and found that even when the errors were corrected, it wasn't very satisfactory.

    It took quite a bit of fiddling, and some digging into exactly what Unity reports for Mouse ScrollWheel (it appears to give a value of about 0.01 and change per click, and does no smoothing). But I came up with this, which I think might work for you.

    Code (csharp):
    1. #pragma strict
    2.     var targetAngle = 0;
    3.     var degreesPerClick = 2;
    4.     var secsPerClick = 0.3;
    5.    
    6.     private var curAngle = 0f;
    7.     private var startAngle=0f;
    8.     private var startTime=0f;
    9.      
    10.     function Update () {
    11.         var clicks = Mathf.Round(Input.GetAxis("Mouse ScrollWheel") * 100);
    12.         if (clicks != 0) {
    13.             targetAngle += clicks * degreesPerClick;
    14.             startAngle = curAngle;
    15.             startTime = Time.time;
    16.         }
    17.        
    18.         var t = (Time.time - startTime) / secsPerClick;
    19.         if (t <= 1) {
    20.             curAngle = Mathf.Lerp(startAngle, targetAngle, t);
    21.             // finally, do the actual rotation
    22.             transform.eulerAngles.y = curAngle;
    23.         }
    24.            
    25.  
    26.     }
    Basically the scroll wheel just updates the target, and whenever we update it, we start a new lerp (linear interpolation) from wherever we are to the new target over the next so-many seconds (0.3 seems like a good amount of time).

    Please give it a try, and let us know how it goes!
    - Joe
     
    uzmanonder likes this.
  7. mrtiff

    mrtiff

    Joined:
    Dec 1, 2013
    Posts:
    4
    Fantastic work Joe! Works really well. Is there a way to make it not stop dead/suddenly? Kind of like a spinning wheel once power has been taken away from it ?

    Many thanks Mark.
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,853
    Try increasing the secsPerClick property. That controls how long the script takes to reach the target orientation. Of course it's a linear interpolation, so the stopping (whenever it is) will be abrupt.

    To fix that, you'd have to switch from Lerp to some sort of easing function... maybe Mathf.SmoothDamp would do the trick, but I haven't tried it.