1
\$\begingroup\$

I am working with the latest version of Unity (2019.3.4f1) at the time of writing.

I have some terrain, some blocks as obstacles and a player character with some mouse driven motion controls. You click the mouse on the terrain and the player character turns and walks in the direction of where you clicked until they reach their destination, so far so good.

I have recently added a rigidbody component and a box collider on the player character in order to get the character to 'bump' into walls and not simply walk through them like a ghost. This aspect is working, unfortunately the character keeps sliding on the ground. Since the terrain is at a bit of a slope the character just slides forever away as if they were standing on oil. I've been trying different solutions to get the character to stop doing this when they are not moving but nothing seems to work.

These are the things that I have tried thus far:

Increasing the Mass of the Rigidbody - No effect, actually I think the character is sliding even faster.

Increasing the Drag - This was working but the moment I added an X and Z constraint on Freeze Rotation it just stopped working and I need those constraints because I don't want the character to fall over.

Adding a Physic Material to the Box Collider - This doesn't seem to be doing anything. the physic material I created has friction values around 300 and the character is still sliding away on oil.

These are the settings for the rigidbody and the box collider currently on the character.

enter image description here

This is the Physic Material that I added to the player character's box collider.

enter image description here

This is the code that I am using to move the character.

void FixedUpdate()
{        
    switch (currentState)
    {
        case State.Idle:
            break;
        case State.Moving:
        case State.Sneaking:
            MoveTowardsTarget();
            break;
    }

    transform.position = new Vector3(transform.position.x, grid.GetHeightAtCoord(transform.position), transform.position.z);
}

private void MoveTowardsTarget()
{
    if (currentState == State.Moving) _currentCrouch = 0.0f;
    else if (currentState == State.Sneaking) _currentCrouch = 1.0f;

    Vector3 position = transform.position;
    _currentPosition = position;
    _currentPosition = new Vector3(_currentPosition.x, grid.GetHeightAtCoord(position), _currentPosition.z);

    float distanceToDestination = Vector3.Distance(_currentPosition, currentDestination);
    float targetSpeed;

    if (distanceToDestination > _strollDistance && distanceToDestination < _hustleDistance) targetSpeed = _strollSpeed;
    else if (distanceToDestination > _hustleDistance) targetSpeed = isRunModeOn ? _runSpeed : _hustleSpeed;
    else
    {
        targetSpeed = 0;
        currentState = State.Idle;
    }

    if(targetSpeed > 0) TurnTowardsTarget(distanceToDestination);

    _currentSpeed = Mathf.Lerp(_currentSpeed, targetSpeed, Time.deltaTime * _accelleration);
    transform.Translate(Vector3.forward * (Time.deltaTime * _currentSpeed));
}

private void TurnTowardsTarget(float distanceToDestination)
{
    float currentRotation = transform.eulerAngles.y;

    Vector3 normalizedAngle = (transform.position - currentDestination).normalized;
    float angle = -(Mathf.Atan2(normalizedAngle.z, normalizedAngle.x) * Mathf.Rad2Deg + 180);

    Vector3 targetAngle = new Vector3(0.0f, angle + 90, 0.0f);
    Vector3 currentAngle = transform.eulerAngles;

    currentAngle = new Vector3(
        Mathf.LerpAngle(currentAngle.x, targetAngle.x, Time.deltaTime * _turnSpeed),
        Mathf.LerpAngle(currentAngle.y, targetAngle.y, Time.deltaTime * _turnSpeed),
        Mathf.LerpAngle(currentAngle.z, targetAngle.z, Time.deltaTime * _turnSpeed));

    _currentRotation = CameraOrbitManager.ClampAngle(currentRotation - currentAngle.y, -360, 360);

    transform.eulerAngles = currentAngle;
}

Can someone please tell me what I am missing? Why does the player character keep sliding away?

\$\endgroup\$
  • \$\begingroup\$ Don't forget to show us the code you're using to move your player character. \$\endgroup\$ – DMGregory Mar 11 '20 at 11:57
  • \$\begingroup\$ Ok I added the movement code. \$\endgroup\$ – William Calleja Mar 11 '20 at 12:01
  • \$\begingroup\$ Ah, there's your problem. You don't want to move an object with a Rigidbody by using its Transform. You should be using Rigidbody.MovePosition, AddForce, or setting velocities to let the physics system manage its motion. Doing this, you can also apply stationkeeping to keep it at one place when idle. \$\endgroup\$ – DMGregory Mar 11 '20 at 12:03
  • \$\begingroup\$ I never used MovePosition, does it take a Vector3 as an input? How would I translate my current movement method to the rigid body? \$\endgroup\$ – William Calleja Mar 11 '20 at 12:07
  • \$\begingroup\$ William, when wondering about what parameters a function accepts, you can enter into Google e.g. Unity MovePosition. It will then lead you to the documentation, like this one, where it shows you have to pass Vector3, and it also often provides example code. Good luck! \$\endgroup\$ – Philipp Lenssen Mar 12 '20 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.