1
\$\begingroup\$

I am making a speed meter of car. Its pretty simple when ever speed increases or decreases the meter pin moves accordingly. I have done the movement part of pin but I am unable to get a smooth movement.

    public Image meterPin;

    const float maxPinAngle = -116f;
    const float minPinAngle = 16f;

    float meterMinSpeed = 10f;
    float meterMaxSpeed = 210f;


    void Update()
    {
        changeMeterSpeed();
    }
    void changeMeterSpeed()
    {
        meterMinSpeed = userSpeed;
        meterMinSpeed = Mathf.Clamp(meterMinSpeed, 0f, meterMaxSpeed);

        meterPin.transform.eulerAngles = new Vector3(0, 0, getTransformRotation());
    }

    float getTransformRotation()
    {
        float totalAngle = minPinAngle - maxPinAngle;

        float speedNormalized = meterMinSpeed / meterMaxSpeed;

        return minPinAngle - speedNormalized * totalAngle;
    }

The userSpeed value is calculated in another function in this script. The only issue is that the movement is not smooth. Any ideas if I can fix the smoothness issue in this script.

EDIT:

Here is a gif to explain whats happening. enter image description here

Thanks

\$\endgroup\$
2
  • \$\begingroup\$ why not multiplying getTransformRotation() to Time.deltaTime? \$\endgroup\$ – Saad Anees Jul 11 '19 at 13:09
  • \$\begingroup\$ that does not work I tried \$\endgroup\$ – thirteen4054 Jul 11 '19 at 13:10
2
\$\begingroup\$

You change the arrow rotation immediately when speed changes. To make the transition smooth, you have to store the arrow current state and change it slowly towards the target state.

// arrow shows a car's speed. These are bounds for what it can display
const float meterMinSpeed =  10f;
const float meterMaxSpeed = 210f;

const float minPinAngle =   16f; // rotation for  10 units of speed, degrees
const float maxPinAngle = -116f; //          for 210

// arrow's current rotation in degrees (z component of euler angles)
float currentArrowEulerZ;

void Update() {
    // find relative arrow position between min and max, it will be from 0 to 1
    float targetState = Mathf.InverseLerp (meterMinSpeed, meterMaxSpeed, userSpeed);
    // no need to clamp, it's already in Lerp

    // find arrow rotation which it will try to reach
    float targetEulerZ = Mathf.Lerp (minPinAngle, maxPinAngle, targetState);

    // move the arrow towards target, but only 20% this frame
    // so it will move smoothly, first fast then slower
    currentArrowEulerZ = Mathf.Lerp (currentArrowEulerZ, targetEulerZ, 0.2f);
    // change that number to make arrow faster or slower

    // actually change rotation
    arrowTransform.eulerAngles = new Vector3 (0, 0, currentArrowEulerZ);
}
\$\endgroup\$
4
  • \$\begingroup\$ can you please explain your code, I am sorry I am confused. What are these: minEulerZ, maxEulerZ, targetSpeed \$\endgroup\$ – thirteen4054 Jul 11 '19 at 12:51
  • \$\begingroup\$ @thirteen3054 sorry, I gave wrong names to variables. Edited. \$\endgroup\$ – trollingchar Jul 11 '19 at 13:00
  • \$\begingroup\$ thanks man it worked. Can I add a speed to the meter rotation? \$\endgroup\$ – thirteen4054 Jul 11 '19 at 13:16
  • 1
    \$\begingroup\$ @thirteen3054 I used Lerp(a, b, 0.2f), you can replace 0.2f with speed, from 0 (no movement) to 1 (instant teleportation). Also you can use MoveTowards but IMHO Lerp is better here. \$\endgroup\$ – trollingchar Jul 11 '19 at 13:24
0
\$\begingroup\$

I understand that no smooth movement = some times it moves slower and some times it moves faster.

It is a case of Update vs FixedUpdate. Unity has both. In Update you need to get the delta time since last frame. In FixedUpdate you can forget about that.

https://unity3d.com/es/learn/tutorials/topics/scripting/update-and-fixedupdate

The answer is then: use FixedUpdate or calculate your transformation including Time.deltaTime.

My personal preference: FixedUpdate.

\$\endgroup\$
1
  • \$\begingroup\$ no it does not moves slower or faster its just moves very very fast every time. I have attached a gif. \$\endgroup\$ – thirteen4054 Jul 11 '19 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.