Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question A moving object twitching and stops rotation when it collides with another object

Discussion in 'Scripting' started by Kujji, Mar 26, 2023.

  1. Kujji

    Kujji

    Joined:
    Oct 20, 2021
    Posts:
    109
    I make a game runner in which the character runs if the mouse is pressed, otherwise it stops, if you led the mouse left to right he turns left to right, if not character goes back to the position "looking forward", when the character collides with the wall, character starts to twitch and does not return to the original rotation "looking forward".

    On the wall is BoxCollider with trigger off, on the character is Rigidbody and CapsuleCollider with trigger off.

    Video of problem:


    Character movement script:

    Code (CSharp):
    1. using UnityEngine;
    2. public class StickmanMover : MonoBehaviour
    3. {
    4.     [SerializeField] private float _speedMoving;
    5.     [SerializeField] private float _minRotation;
    6.     [SerializeField] private float _maxRotatioan;
    7.     [SerializeField] private float _maxSpeedMoving;
    8.     [SerializeField] private float _speedRotationSide;
    9.     [SerializeField] private float _speedRotationBack;
    10.     private Rigidbody _rigidbody;
    11.     private void Start()
    12.     {
    13.         _rigidbody = GetComponent<Rigidbody>();
    14.     }
    15.     private void Update()
    16.     {
    17.         if (Input.GetKey(KeyCode.Mouse0))
    18.         {
    19.             if (_rigidbody.velocity.magnitude < _maxSpeedMoving)
    20.             {
    21.                 _rigidbody.AddForce(transform.forward * _speedMoving * Time.deltaTime);
    22.             }
    23.             transform.eulerAngles = new Vector3(0, transform.eulerAngles.y + Input.GetAxis("Mouse X") * _speedRotationSide, 0);
    24.             LimitRotation();
    25.         }
    26.         if (!Input.GetKey(KeyCode.Mouse0))
    27.         {
    28.             SetDefaultRotation();
    29.         }
    30.     }
    31.     private void LimitRotation()
    32.     {
    33.         Vector3 stickmanRotation = transform.rotation.eulerAngles;
    34.         stickmanRotation.y = (stickmanRotation.y > 180) ? stickmanRotation.y - 360 : stickmanRotation.y;
    35.         stickmanRotation.y = Mathf.Clamp(stickmanRotation.y, _minRotation, _maxRotatioan);
    36.         transform.rotation = Quaternion.Euler(stickmanRotation);
    37.     }
    38.     private void SetDefaultRotation()
    39.     {
    40.         Quaternion rotation = Quaternion.LookRotation(Vector3.forward);
    41.         transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * _speedRotationBack);
    42.     }
    43. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    You are bypassing physics when you do this:

    With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

    Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

    https://forum.unity.com/threads/col...-unity-physic-rigidbody.1216875/#post-7763061

    https://forum.unity.com/threads/oncollisionenter2d-not-being-called.1266563/#post-8044121
     
  3. Kujji

    Kujji

    Joined:
    Oct 20, 2021
    Posts:
    109
    I edited this, now object doesn't twitch, but still has problems with rotation like in the video

    Edited code:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class StickmanMover : MonoBehaviour
    4. {
    5.     [SerializeField] private float _speedMoving;
    6.     [SerializeField] private float _minRotation;
    7.     [SerializeField] private float _maxRotatioan;
    8.     [SerializeField] private float _maxSpeedMoving;
    9.     [SerializeField] private float _speedRotationSide;
    10.     [SerializeField] private float _speedRotationBack;
    11.  
    12.     private Rigidbody _rigidbody;
    13.  
    14.     public bool isRotatebleRight = true;
    15.     public bool isRotatebleLeft = true;
    16.  
    17.     private void Start()
    18.     {
    19.         _rigidbody = GetComponent<Rigidbody>();
    20.         Debug.Log(_rigidbody.rotation);
    21.     }
    22.  
    23.     private void Update()
    24.     {
    25.         if (Input.GetKey(KeyCode.Mouse0))
    26.         {
    27.             if (_rigidbody.velocity.magnitude < _maxSpeedMoving)
    28.             {
    29.                 _rigidbody.AddForce(transform.forward * _speedMoving * Time.deltaTime);
    30.             }
    31.  
    32.             float rotationY = Input.GetAxis("Mouse X") * _speedRotationSide;
    33.             _rigidbody.rotation *= Quaternion.Euler(0f, rotationY, 0f);
    34.  
    35.             LimitRotation();
    36.         }
    37.         else
    38.         {
    39.             SetDefaultRotation();
    40.         }
    41.     }
    42.  
    43.     private void LimitRotation()
    44.     {
    45.         Vector3 stickmanRotation = _rigidbody.rotation.eulerAngles;
    46.  
    47.         stickmanRotation.y = (stickmanRotation.y > 180) ? stickmanRotation.y - 360 : stickmanRotation.y;
    48.  
    49.         stickmanRotation.y = Mathf.Clamp(stickmanRotation.y, _minRotation, _maxRotatioan);
    50.  
    51.         _rigidbody.rotation = Quaternion.Euler(stickmanRotation);
    52.     }
    53.  
    54.     private void SetDefaultRotation()
    55.     {
    56.         Quaternion rotation = Quaternion.Euler(0, 0, 0);
    57.         _rigidbody.rotation = Quaternion.Lerp(_rigidbody.rotation, rotation, Time.deltaTime * _speedRotationBack);
    58.     }
    59. }