Character slides down hill when stopped or moves slow when going up hills

Hey all, I’m not really sure if this should be here in Scripting or in Physics, and I’ll explain later.
I’m using a character controller script by Renaissance Coders on YouTube, but I have an issue where if the character is on a slope, they slide down. If needed, I’ll post my script when I get home.
If I set the rigidbody on the character to not use gravity, and instead force the player down to the ground via script, then they no long slide down slopes. However, they now move much faster going down hill and much slower going up hill, compared to level terrain.

Neither of these is really acceptable, and I’m not sure if the fix is in the Physics side, or if it’s something I’ll need to program in via scripting, or a combination of both. Any help would be appreciated.
Just to note, my character is currently a simple sphere with the character controller and rigid body components.

That sounds like the script is code to react with the rigid body physics, I wouldn’t be to fimilear with this format but try debug the code to find physics involved, and if not it could just be the rigid odd itself. Disabling use gravity will cause the player to glide away but you can try ground him via script.

Like I said, though, if I disable use gravity, then the gliding stop, but slopes have greater affect on speed than I’d like

Here’s the script I’m using for my Character Controller

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System;

public class CharacterController : NetworkBehaviour
{

    public float inputDelay = 0.1f;
    public float forwardVel = 12;
    public float rotateVel = 100;
    public float fallVel = -9.81f; //Gravity replacement. Without it, the character falls very slowly
    public float sprintMod;
    bool canMove;
    public bool inDialogue;
    public bool statusEffected;
    int MaxStamina;
    public float CurStamina;
    Vector3 properVel;
    CharacterInfo charInfo;
    public bool sprinting = false;
    public float stopSprint = 0;
    Image stamBar;
    public bool canSprint = true;
   

    Quaternion targetRotation;
    Rigidbody rBody;
    float forwardInput, turnInput;

    public Quaternion TargetRotation
    {
        get { return targetRotation; }
    }

    void Start()
    {
        stamBar = GameObject.Find("StaminaBar").GetComponent<Image>();
        charInfo = FindObjectOfType<CharacterInfo>();
        properVel = new Vector3(0, fallVel, 0);
        targetRotation = transform.rotation;
        if (GetComponent<Rigidbody>())
            rBody = GetComponent<Rigidbody>();

        forwardInput = turnInput = 0;
    }

    void GetInput()
    {
        if (canMove == true)
        {
            forwardInput = Input.GetAxis("Vertical");
            turnInput = Input.GetAxis("Horizontal");
        }
        else
        {
            turnInput = Input.GetAxis("Horizontal");
            forwardInput = 0;
        }
    }

    void Update()
    {
        if (isLocalPlayer)
        {
            if(inDialogue)
            {
                canMove = false;
            }
            else if(!inDialogue && !statusEffected)
            {
                canMove = true;
            }
            GetInput();
            Turn();
            if (charInfo != null)
            {
                MaxStamina = charInfo.stamina;
            }

            if (sprinting == false && (Time.time - stopSprint) >= 1)
            {
                CurStamina = Mathf.Round((CurStamina + ((1 + (charInfo.stats[0] / 2)) / 60f)) * 100) / 100;
            }
            if (sprinting && (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)))
            {
                sprinting = false;
                stopSprint = Time.time;
            }
            stamBar.fillAmount = CurStamina / MaxStamina;
            if (CurStamina > MaxStamina)
            {
                CurStamina = MaxStamina;
            }
            if (CurStamina <= 0)
            {
                canSprint = false;
                CurStamina = 0;
            }
            if (canSprint == false && stamBar.fillAmount > 0.1)
            {
                canSprint = true;
            }
        }
    }
    void FixedUpdate()
    {
        Run();
    }

    void Run()
    {
        if (isLocalPlayer)
        {
            if (Mathf.Abs(forwardInput) > inputDelay)
            {
                if (canSprint && Input.GetKey(KeyCode.LeftShift) && CurStamina >= 0.02)
                {
                    sprintMod = 0.50f;
                    CurStamina = CurStamina - (Mathf.Round((5 / 60f) * 100) / 100f);
                    sprinting = true;
                }
                else
                {
                    sprintMod = 0;
                    if (Input.GetKeyUp(KeyCode.LeftShift) && canSprint)
                    {
                        stopSprint = Time.time;
                    }
                    sprinting = false;
                }
                rBody.velocity = properVel + (transform.forward * (forwardInput) * (forwardVel * (1 + sprintMod)));
            }
            else
            {
                rBody.velocity = properVel;
            }
        }
    }

    void Turn()
    {
        targetRotation *= Quaternion.AngleAxis(rotateVel * turnInput * Time.deltaTime, Vector3.up);
        transform.rotation = targetRotation;
    }
}

Therigidbody variable line 29, could possibly be your problem.

What do you mean? That’s just declaring a variable, and gets set in line 44, after checking if there is a rigidbody (which there is)

Anyone have a suggestion?

I’m still needing help on this.

Any ideas on how I could fix this?

The character controller that comes with the standard unity assets goes over this in great detail. I started with that script and then modified it to suit my needs.

It does? I guess I’ll take a look at it and learn something. Thanks

We must be looking at different standard assets, because I saw nothing about anything regarding slopes.

EDIT: I did see something in the RigidbodyFirstPersonController, but there were 0 details about it, such as what it does, why it does it, or when it is applied. Not exactly detailed

Does your character rely on physics in any way besides gravity? If not just toggle Is Kinematic in your characters rigid body.

Since I’m moving the character by changing it’s velocity, this unfortunately isn’t an option. A work-around was to unfreeze or freeze rigidbody constraints when my controller script checks if the player is pressing a movement key or not.
I don’t think it’s the best work-around, but… for now.

Add a material to the capsule collider attached to your rigidbody. That fixed it for me.

1 Like

I used the Max Friction and it worked for me! Thanks for the heads up!