Twitching when colliding with a wall

Hello everyone. When my object is pressed and moves along it, then there is such a twitch, as on a gif. Can you tell me how to fix it?8582851--1150087--3.gif

8582851--1150093--upload_2022-11-13_21-37-55.png

Вот мой код движения:

using UnityEngine;
using UnityEngine.InputSystem;

[RequireComponent(typeof(Rigidbody))]
public class MovementRigidbody : MonoBehaviour
{
    [SerializeField] private float _moveSpeed;
    [SerializeField] private float _rotationSpeed;

    private Vector3 _targetDirection;
    private float _inputAngle;
    private float _rotationSmoothVelocity;
    private float _lockAngleValue = 0.0f;
    private Rigidbody _rigidbody;

    private void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
        Move(); 
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        CreateTargetDirection(context.ReadValue<Vector2>());
    }

    private void Move()
    {
        if (_targetDirection.magnitude > 0.01f)
        {
            _rigidbody.velocity = _targetDirection * _moveSpeed;
            Rotate();
        }      
    }

    private void CreateTargetDirection(Vector2 inputDirection)
    {
        _targetDirection = new Vector3(inputDirection.x, 0.0f, inputDirection.y).normalized; 
    }

    private void Rotate()
    {
        _inputAngle = Mathf.Atan2(_targetDirection.x, _targetDirection.z) * Mathf.Rad2Deg;
        float targetAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y,
                _inputAngle, ref _rotationSmoothVelocity, _rotationSpeed);
 
        _rigidbody.MoveRotation(Quaternion.Euler(_lockAngleValue, targetAngle, _lockAngleValue));
    }
}

AFAIK in 3D when using MovePosition or MoveRotation on a Dynamic body-type, it simply sets the pose instantly which can cause an overlap (as above) that the solver will then try to solve. In 3D it’s really meant to be used with Kinematic bodies.

This isn’t the case in 2D where it works by moving the body via its velocity so it correctly contacts.

For 3D, you’d need to manipulate the angular velocity to rotate it.

NOTE: I’m not in the 3D physics team.

1 Like

Don’t modify rigidbody.velocity directly nor call rigidbody.MoveRotation. Doing any of these overrides the results of the internal physics calculations, so the next step the physics engine has to “resolve” the new situation somehow - hence that “twitch”.

Instead, use rigidbody.AddForce and rigidbody.AddTorque only (or their variants). These methods allow not only to apply forces, but also instant changes in velocity (check out the ForceMode parameter). For example, for imposing a velocity to the rigidbody you can do this:

rigidbody.AddForce(targetVelocity - rigidbody.velocity, ForceMode.VelocityChange)

This will set the rigidbody velocity to targetVelocity while the physics engine also resolves collisions and friction properly. Same for angular velocity with AddTorque.

1 Like

Tnx)