Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Thursday, June 8, for a Q&A with Unity's Content Pipeline group here on the forum, and on the Unity Discord, and discuss topics around Content Build, Import Workflows, Asset Database, and Addressables!
    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:
    80
    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:
    33,693
    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:
    80
    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. }