Rigidbody interpolation causes laggy movement

I created a 2D CharacterController and have some issues with using normal movement together with Rigidbody2D jumps (addForce).
I use a camera script which is moving the camera to the character. Until I read that I should activate Rigidbody2D.interpolation the jumps were a bit laggy. Now the jumps alone are ok but together with the normal movement it’s even laggier and the jumps are smaller.
Do I need to interpolate the normal movement too? If yes which interpolation (I found Slerp and Lerp) and how?

I created a small script from my script for this thread. The whole script is here.

Thanks :slight_smile:

using UnityEngine;
using System.Collections;

public class TestController : MonoBehaviour {

	public bool jumpKey = false;
	private bool moveRightKey = false;
	private bool moveLeftKey = false;
	public bool holdMoveRightKey = false;
	public bool holdMoveLeftKey = false;
	
	private bool activeJump = false;
	private bool activeDoubleJump = false;

	//speed of actions
	public float moveRightSpeed = 10f;
	public float moveLeftSpeed = 10f;
	public float jumpSpeed = 300f;
	public float doubleJumpSpeed = 250f;

	//speed variables will be stored in them at Start()
	private Vector2 jumpForce;
	private Vector2 doubleJumpForce;

	public Transform characterTransform;
	public Rigidbody2D characterRigidbody;
	public BoxCollider2D boxCollider;
	private Vector3 colliderCenter;
	
	private RaycastHit2D raycast;

	//check if the player is *holding* the jump button
	private bool oldJump = false;

	void Start (){
		//store speed variables in vectors
		jumpForce = new Vector2(0, jumpSpeed);
		doubleJumpForce = new Vector2(0, doubleJumpSpeed);

		//store center of collider in Vector3 for Raycast
		colliderCenter = new Vector3(0, boxCollider.center.y /2 + 0.6f, 0);
	}
	
	void Update(){

		//manage the input with the InputManager of Unity
		PlayerInput();
		
		//function for x movement
		PerformMovement();
	}
	
	void FixedUpdate () {

		//function for jumps and double jumps
		PerformJump();
	}

	//manage the input with the InputManager of Unity
	void PlayerInput(){

		//jump
		if(Mathf.Abs(Input.GetAxisRaw("Jump")) > 0){
			jumpKey = true;
		}
		else{
			jumpKey = false;
		}
		
		//move right
		if(Mathf.Abs(Input.GetAxisRaw("MoveRight")) > 0){
			moveRightKey = true;
		}
		else{
			moveRightKey = false;
		}
		
		//move left
		if(Mathf.Abs(Input.GetAxisRaw("MoveLeft")) > 0){
			moveLeftKey = true;
		}
		else{
			moveLeftKey = false;
		}
	}

	//function for x movement
	void PerformMovement(){

		//move right
		if(moveRightKey || holdMoveRightKey){
			characterTransform.Translate(moveRightSpeed * Time.deltaTime, 0, 0);
		}

		//move left
		if(moveLeftKey || holdMoveLeftKey){
			characterTransform.Translate(-moveLeftSpeed * Time.deltaTime, 0, 0);
		}
	}

	//function for jumps and double jumps
	void PerformJump(){

		//jump key not pushed
		if(!jumpKey){
			oldJump = false;
		}
		
		if(IsGrounded()){

			//double jump over
			activeDoubleJump = false;
			if(doubleJumpForce.y != doubleJumpSpeed) doubleJumpForce = new Vector2(0, doubleJumpSpeed);

			//jump by holding jump key  after every jump key push
			else if(jumpKey  !activeJump){
				characterRigidbody.AddForce(jumpForce);
				jumpKey = false;
				activeJump = true;
				oldJump = true;
			}
			else if(activeJump){
				activeJump= false;
			}
		}

		//double jump
		if(!activeDoubleJump  (!oldJump  jumpKey)){

			if(characterRigidbody.velocity.y < 0){
				characterRigidbody.velocity = new Vector2(characterRigidbody.velocity.x, 0);
			}
	
			characterRigidbody.AddForce(doubleJumpForce);
			jumpKey = false;
			activeDoubleJump = true;
			oldJump = true;
		}
	}

	//use a raycast to check if the character is grounded
	RaycastHit2D IsGrounded(){

		raycast = Physics2D.Raycast(characterTransform.position + colliderCenter - new Vector3(boxCollider.size.x /2, 0, 0), -Vector2.up, boxCollider.size.y / 2);
		if(!raycast){
			raycast = Physics2D.Raycast(characterTransform.position + colliderCenter + new Vector3(boxCollider.size.x /2, 0, 0), -Vector2.up, boxCollider.size.y / 2);
		}
		return raycast;
	}
}

Translate will move the transform and with the rigidbody doesn’t go that well togheter, that will cause the jittering you have. Use forces on movement too or change the velocity. Also you can simplify the key detection a lot by using one single axis and checking its value, Eg::

float h = Input.GetAxis ("Horizontal");
rigidbody2D.velocity = new Vector2(h * movementSpeed, 0);

Thanks for the answer. :slight_smile:
I thought about using force or velocity but I want clean movement (no negative acceleration). Of course I could set the velocity to 0 if the axis is 0 but wouldn’t that destroy every force from outside?
I just found forcemodes for the rigidbody which sounded interesting but then I realized that they only exist for the 3D rigidbody.
I don’t remember why I used different axes. Thanks, I will change that.

I found Addforce extensions to use forcemodes with the 2D rigidbody but it probably doesn’t matter how I add the force because the velocity is still there which will decrease over a time and not instantly.
Is there a way to reset the velocity of the movement without ignoring or modifying forces from outside (for example a explosion which whould catapult you somewhere)?
If not is there a way to use translation together with rigidbody forces + interpolation without the jittering?