Kujji
March 26, 2023, 3:07pm
1
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:
using UnityEngine;
public class StickmanMover : MonoBehaviour
{
[SerializeField] private float _speedMoving;
[SerializeField] private float _minRotation;
[SerializeField] private float _maxRotatioan;
[SerializeField] private float _maxSpeedMoving;
[SerializeField] private float _speedRotationSide;
[SerializeField] private float _speedRotationBack;
private Rigidbody _rigidbody;
private void Start()
{
_rigidbody = GetComponent<Rigidbody>();
}
private void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
if (_rigidbody.velocity.magnitude < _maxSpeedMoving)
{
_rigidbody.AddForce(transform.forward * _speedMoving * Time.deltaTime);
}
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y + Input.GetAxis("Mouse X") * _speedRotationSide, 0);
LimitRotation();
}
if (!Input.GetKey(KeyCode.Mouse0))
{
SetDefaultRotation();
}
}
private void LimitRotation()
{
Vector3 stickmanRotation = transform.rotation.eulerAngles;
stickmanRotation.y = (stickmanRotation.y > 180) ? stickmanRotation.y - 360 : stickmanRotation.y;
stickmanRotation.y = Mathf.Clamp(stickmanRotation.y, _minRotation, _maxRotatioan);
transform.rotation = Quaternion.Euler(stickmanRotation);
}
private void SetDefaultRotation()
{
Quaternion rotation = Quaternion.LookRotation(Vector3.forward);
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * _speedRotationBack);
}
}
You are bypassing physics when you do this:
Kujji:
transform.rotation = Qua
Kujji:
transform.eulerAngles =
Kujji:
transform.rotation =
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://discussions.unity.com/t/866410/5
https://discussions.unity.com/t/878046/8
Kujji
March 26, 2023, 4:40pm
3
Kurt-Dekker:
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://discussions.unity.com/t/866410/5
https://discussions.unity.com/t/878046/8
I edited this, now object doesn’t twitch, but still has problems with rotation like in the video
Edited code:
using UnityEngine;
public class StickmanMover : MonoBehaviour
{
[SerializeField] private float _speedMoving;
[SerializeField] private float _minRotation;
[SerializeField] private float _maxRotatioan;
[SerializeField] private float _maxSpeedMoving;
[SerializeField] private float _speedRotationSide;
[SerializeField] private float _speedRotationBack;
private Rigidbody _rigidbody;
public bool isRotatebleRight = true;
public bool isRotatebleLeft = true;
private void Start()
{
_rigidbody = GetComponent<Rigidbody>();
Debug.Log(_rigidbody.rotation);
}
private void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
if (_rigidbody.velocity.magnitude < _maxSpeedMoving)
{
_rigidbody.AddForce(transform.forward * _speedMoving * Time.deltaTime);
}
float rotationY = Input.GetAxis("Mouse X") * _speedRotationSide;
_rigidbody.rotation *= Quaternion.Euler(0f, rotationY, 0f);
LimitRotation();
}
else
{
SetDefaultRotation();
}
}
private void LimitRotation()
{
Vector3 stickmanRotation = _rigidbody.rotation.eulerAngles;
stickmanRotation.y = (stickmanRotation.y > 180) ? stickmanRotation.y - 360 : stickmanRotation.y;
stickmanRotation.y = Mathf.Clamp(stickmanRotation.y, _minRotation, _maxRotatioan);
_rigidbody.rotation = Quaternion.Euler(stickmanRotation);
}
private void SetDefaultRotation()
{
Quaternion rotation = Quaternion.Euler(0, 0, 0);
_rigidbody.rotation = Quaternion.Lerp(_rigidbody.rotation, rotation, Time.deltaTime * _speedRotationBack);
}
}