Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a problem smoothly motion - I see jerking when I am using physics and AddForce.

It's not a question related to Update or Time.deltaTime - I created simple scene with few lines and sphere. When player clicked ">" button, I apply force to sphere, but motion is jerky and is not smoothly (please see web version below).

Project: fixed ortho camera, sphere with disable gravity, few cubs and bouncy as default material.

To fixed this problem, I tried to use some solutions from posts, related with jerking motion in Unity:

  • http:// answers.unity3d.com/questions/10907/smoothing-rigidbody-movement-over-a-bumpy-track.html
  • answers.unity3d.com/questions/228095/why-is-the-motion-jerky-in-a-simple-2d-game.html
  • answers.unity3d.com/questions/275016/updatefixedupdate-motion-stutter-not-another-novic.html

Things, that I tried:

  1. Interpolate for sphere rigibody - slightly better, but jerky is still here.
  2. Change Vsync(Dont Sync, Every Blank, Every Second Blacnk) and Quality (Fastest-Fantastic) - nothing
  3. Use different object for collission (just rigibody and collision object) and display object(mesh renderer). This InterpolateToTarget.cs script in source folder - nothing.
  4. In previous other game (with gravity, other default material, etc.) I used motion forward without AddForce, but I faced with jerky motion, too. I tried all solutions, that I find (FixedUpdate/Update with deltaTime, Coroutine, Transform.Translate, Interpolation, Lerp, LateUpdate...) and I saw that only one combination (small AddForce/Interpolation and Simply Quality setttings (VSync is turn off)) give me acceptable smoothly motion. But in this game I need AddForce with larger value and this solution is not work in this case.

Web version: https://dl.dropbox.com/u/15321992/2DjerkyMotion.rar

Sources: https://dl.dropbox.com/u/15321992/2DjerkyMotion.rar

Android apk: dl.dropbox.com/u/15321992/2dJerkyMotion.apk

Code that I am using for motion: public class TestMovingScript : MonoBehaviour {

private Rect restartBtnRect = new Rect(20, 20, 120, 60);
private Rect rightMoveBtnRect = new Rect(Screen.width - 100, Screen.height - 100, 100, 100);
private GameObject _player;
private Vector3 _movingVector = new Vector3(1, 0, 0);


// Use this for initialization
void Start () {
    _player = GameObject.FindGameObjectWithTag("Player");
    _player.rigidbody.AddForce(_movingVector * 20);
}

// Update is called once per frame
void Update () {

}

private void OnGUI()
{
    if (GUI.RepeatButton(restartBtnRect, "Restart"))
    {
        Application.LoadLevel(0);
    }
    if (GUI.RepeatButton(rightMoveBtnRect, ">"))
    {
        {
            _player.rigidbody.AddForce(_movingVector * 20);
        }
    }
}

}

I suppose in web version this jerking is not as noticeable, but on Android it is a horrible. Also, try to play in web version few minutes and you will see it. I don't believe, that Unity3d does not allow to build smoothly Android game, so maybe I missing something in physics/player setting.

I will be grateful for any suggestions and ideas.

Thanks, Dmitry.

share|improve this question

closed as off-topic by Anko, Byte56 Mar 3 at 20:32

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Anko, Byte56
If this question can be reworded to fit the rules in the help center, please edit the question.

    
You are meant to addForce in FixedUpdate, adding it in OnGUI is probably your issue. Try moving in to a function called void FixedUpdate(). –  T. Kiley Jan 30 at 13:34

1 Answer 1

As stated in docs :

If you add or subtract to a value every frame chances are you should multiply with Time.deltaTime. When you multiply with Time.deltaTime you essentially express: I want to move this object 10 meters per second instead of 10 meters per frame.

Try doing this :

public class TestMovingScript : MonoBehaviour {

private Rect restartBtnRect = new Rect(20, 20, 120, 60);
private Rect rightMoveBtnRect = new Rect(Screen.width - 100, Screen.height - 100, 100, 100);
private GameObject _player;
private Vector3 _movingVector = new Vector3(1, 0, 0);
private Vector3 _appliedForce = Vector3.zero;


// Use this for initialization
void Start () {
    _player = GameObject.FindGameObjectWithTag("Player");
    _appliedForce = _movingVector * 2000 //Notice that here i multiply your value by
                                         // 100 (approximately what you need to
                                         // compensate deltaTime (around 0.01xxxx)
    _player.rigidbody.AddForce(_appliedForce *Time.DeltaTime);
}

// Update is called once per frame
void Update () {

}

private void OnGUI()
{
    if (GUI.RepeatButton(restartBtnRect, "Restart"))
    {
        Application.LoadLevel(0);
    }
    if (GUI.RepeatButton(rightMoveBtnRect, ">"))
    {
        {
            _player.rigidbody.AddForce(_appliedForce *Time.DeltaTime);
        }
    }
}
}

Why multiplying by DeltaTime might fix the issue?? : Because AddForce() ADD a force to the sum of forces applied to your rigidbody, and then each force applied will diminish with time (except if you have no gravity and even ther i'm not sure) and if used in Update() it will add every frame the amount of force you want but frames are NEVER evenly timespaced so sum of forces will have different value each time you apply a new force so even if you add every time the same force, because you do not add it at the same interval of time it will stutter.

What delta time does is that it will multiply your force by the timespan between the previous frame and this one so the final value will compensate this timegap between the two frames

It is worth noticing that in this particular case you might try :

_appliedForce *Time.fixedDeltaTime

As Fixed Delta Time is the timespan between two physics calculated states

Docs here :

share|improve this answer
    
except if you have no gravity and even ther i'm not sure It will still slow down if it has damping (dampening?) set. I only just started learning Unity but this was said in the small video tutorials Unity provides :) –  Flater Jan 30 at 12:46

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