Search Unity

Movement with transform.Translate() jitters

Discussion in 'General Graphics' started by helveticau, Aug 13, 2019.

  1. helveticau

    helveticau

    Joined:
    Jan 28, 2019
    Posts:
    2
    Hello. As the title says, objects jitter when I move them with transform.Translate() or by changing transform.position.

    For example,
    Code (CSharp):
    1.  
    2. private void Update()
    3. {
    4.     transform.Translate(Vector3.right * speed * Time.deltaTime);
    5. }
    If I attach a script like this to an object, the object jitters several times per second.

    Well, I had the same problem with moving physical objects. I fixed it by changing Time -> fixedTimestep to 0.01666 (i.e. 1/60, which is my monitor's update rate). Now physics-based movement works just fine, so I wonder what's wrong with movement in Update().

    I asked my friend to test the game and he said it jitters on both 60Hz and 75Hz.

    I know about Lerp, SmoothDamp, MoveTowards etc. But the movement should be kinda smooth without Lerp, shouldn't it? I mean, I multiply the speed by Time.deltaTime.

    I used other engines, where multiplying by dt works just fine, so I'm a little bit confused. Please, tell me what I misunderstand and how to fix the problem. Does it work like this for everyone or just for me?
     
  2. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    Do you change the position from any other place? like from the physics engine for example
     
  3. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    No, I don't. I literally have only one script in my test project (plus one for the camera).
     
    Last edited: Aug 15, 2019
  4. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    My code:

    PlayerController.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(Rigidbody2D))]
    6. [RequireComponent(typeof(Collider2D))]
    7. public class PlayerController : MonoBehaviour
    8. {
    9.     public float minGroundNormalY = .65f;
    10.  
    11.     [SerializeField] private float m_speed;
    12.  
    13.     private RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
    14.     private List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
    15.     private ContactFilter2D contactFilter;
    16.     private Vector2 targetVelocity;
    17.     private Vector2 groundNormal;
    18.  
    19.     private Rigidbody2D m_rb2d;
    20.     private BoxCollider2D m_col2d;
    21.  
    22.     private Vector2 velocity;
    23.     private bool grounded;
    24.  
    25.     private const float shellRadius = 0.01f;
    26.  
    27.     void Awake()
    28.     {
    29.         m_rb2d = GetComponent<Rigidbody2D>();
    30.         m_col2d = GetComponent<BoxCollider2D>();
    31.  
    32.         contactFilter.useTriggers = false;
    33.         contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
    34.         contactFilter.useLayerMask = true;
    35.  
    36.         targetVelocity = Vector2.right * m_speed;
    37.     }
    38.  
    39.     private void FixedUpdate()
    40.     {
    41.         velocity += m_rb2d.gravityScale * Physics2D.gravity * Time.deltaTime;
    42.         velocity.x = targetVelocity.x;
    43.  
    44.         Vector2 deltaPosition = velocity * Time.deltaTime;
    45.         Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
    46.         Vector2 move = moveAlongGround * deltaPosition.x;
    47.  
    48.         Movement(move, false);
    49.  
    50.         move = Vector2.up * deltaPosition.y;
    51.  
    52.         Movement(move, true);
    53.     }
    54.  
    55.     void Movement(Vector2 move, bool yMovement)
    56.     {
    57.         float distance = move.magnitude;
    58.  
    59.         int count = m_rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
    60.         hitBufferList.Clear();
    61.         for (int i = 0; i < count; i++)
    62.         {
    63.             hitBufferList.Add(hitBuffer[i]);
    64.         }
    65.  
    66.         for (int i = 0; i < hitBufferList.Count; i++)
    67.         {
    68.             Vector2 currentNormal = hitBufferList[i].normal;
    69.             if (currentNormal.y > minGroundNormalY)
    70.             {
    71.                 grounded = true;
    72.                 if (yMovement)
    73.                 {
    74.                     groundNormal = currentNormal;
    75.                     currentNormal.x = 0;
    76.                 }
    77.             }
    78.  
    79.             float projection = Vector2.Dot(velocity, currentNormal);
    80.             if (projection < 0)
    81.             {
    82.                 velocity = velocity - projection * currentNormal;
    83.             }
    84.  
    85.             float modifiedDistance = hitBufferList[i].distance - shellRadius;
    86.             distance = modifiedDistance < distance ? modifiedDistance : distance;
    87.         }
    88.  
    89.  
    90.         m_rb2d.position = m_rb2d.position + move.normalized * distance;
    91.     }
    92. }
    93.  
    CameraFollowTarget.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraFollowTarget : MonoBehaviour
    6. {
    7.     [SerializeField]
    8.     private float speed;
    9.  
    10.     [SerializeField]
    11.     private float XOffset;
    12.  
    13.     [SerializeField]
    14.     private Transform target;
    15.  
    16.     [SerializeField]
    17.     private bool paused = false;
    18.  
    19.     void OnValidate()
    20.     {
    21.         if (!target)
    22.             target = GameObject.FindGameObjectWithTag("Player").transform;
    23.  
    24.         transform.position = new Vector3(target.position.x - XOffset, transform.position.y, transform.position.z);
    25.     }
    26.  
    27.     void Update()
    28.     {
    29.         if (!paused)
    30.         {
    31.             var targetPos = Vector3.MoveTowards(transform.position, target.transform.position - Vector3.right * XOffset, speed * Time.deltaTime);
    32.             transform.position = new Vector3(targetPos.x, transform.position.y, transform.position.z);
    33.         }
    34.     }
    35.  
    36.     public Transform Target
    37.     {
    38.         get => target;
    39.         set
    40.         {
    41.             target = value;
    42.         }
    43.     }
    44. }
    45.  
     
  5. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    It shouldn't behave weirdly.
    This can happen if you have a rigidbody that drives your transform, or anything else. But if you don't, not sure what is the reason.
     
  6. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    I do have a rigidbody, but it's kinematic
     
  7. sharkapps

    sharkapps

    Joined:
    Apr 4, 2016
    Posts:
    145
  8. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    Delta time should be irrelevant to the movement since it is factored in.


    Try this, put your script on a new game object with only a transform component. If it behaves normal, then it's not your script that is the issue.
     
  9. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    It behaves exactly the same. I even tried to create a new script with only
    Code (CSharp):
    1. void Update() => transform.position += Vector2.right * 10 * Time.deltaTime;
    Same effect. I also tried different unity versions
     
  10. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    I just tried this 2018.3.0f2 and it works just fine, no jittering of any kind.

    Code:
    Code (CSharp):
    1. void Update()
    2.     {
    3.         this.transform.position += this.transform.forward * Time.deltaTime;
    4.     }
    Also tried it with a multiplicator of 10, smooth.
     
  11. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    Can you try 2019* ? Also, how about this (add Rigidbody2D first):
    Code (CSharp):
    1. void FixedUpdate() => rb.velocity = Vector2.right * 10 * Time.deltaTime;
     
  12. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    I'm not sure if there is a difference between unity versions, but if deltaTime in fixed update isn't constant then you will have jittering. You have a varying(assuming) deltaTime each frame, and your velocity jumps abruptly to different values each frame, hence the jittering.

    There is also very little sense to update the velocity to the same value every fixedupdate. You could just set it in start and be done with it.
     
    Last edited: Aug 18, 2019
  13. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    "MonoBehaviour.FixedUpdate uses fixedDeltaTime instead of deltaTime." @ docs

    Can you try to set velocity in Start() and then say if it jitters for you? Also, what's your monitor's refresh rate?
     
  14. mydeadvictoria

    mydeadvictoria

    Joined:
    Aug 15, 2019
    Posts:
    10
    Look at this. Is it jittering? I can't decide.
    Code (CSharp):
    1. void Update()
    2. {
    3.     transform.position += Vector3.right * 10 * Time.deltaTime;
    4. }
    5. // Unity 2018.4.6f1
    60 fps gif:
     
  15. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    Yes, but this can be caused by many things, including the tool that records that gif.

    The code is fine.
     
  16. SaadTheGlad

    SaadTheGlad

    Joined:
    Sep 9, 2020
    Posts:
    2
    I'm having major jittering in my game too, but I also have an rb on it so I have no idea
     
  17. Hormhoom

    Hormhoom

    Joined:
    Mar 26, 2021
    Posts:
    1
    Don't know if this is relevant but when I'm changing the transform directly I get jitters unless I go to project settings and enable 'Auto Sync Transforms' for the 2D physics
     
  18. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    201
    You shouldn't be changing the transform directly if its driven by the physics engine(aka has a rigidbody on it that is simulated)
     
  19. nathanqueija

    nathanqueija

    Joined:
    Apr 18, 2013
    Posts:
    19
    Did you try to change the position of the Camera using LateUpdate instead of Update? Doing this way you ensure that if the Player is moving using Update the Camera will change its position after the Update function was called for the current loop.
     
  20. sadpanders

    sadpanders

    Joined:
    Jan 22, 2023
    Posts:
    12
    i mean my personal problem seemed to be ram usage making it stutter. seems to be fine in build and editor when i shut down my 100500 tabs on chrome. idk but no jitters anymore. using 16gb of crap ram