Unity CharacterController.Move and Slopes. Sliding down steep slopes and stop bouncing down non steep slopes.

Essentially what I’d like is to

(1). Have my controller slide down slopes say slopeX > 45

(2). Stop my controller from bouncing when moving down a non steep slope say slopeX < 45

(the current hypothesis and starting point is

if(objectHitAngle > player.slopeLimit)

{

isSliding = true;

//from here do what? and where?

//You will see a quick not so great solution starter Vector3.OrthoNormalize(ref groundObjectNormal, ref movement);

}

I have reviewed several tutorials on character controllers and I have managed to make a decent one. What is being a HUGE pain is slopes and all of the solutions I have found are infinitely confusing for me. Many of them seem great but I just cannot understand them. I will provide my code and all the comments I have made to manage it and understand it.

Really quick to summarize, all movement is based on input axis. The character has a constant force applied so it stays grounded. When falling and !isGrounded, the falling speed multiplies or increases. When isGrounded, the falling force resets to a constant value to ensure I may jump. Additive force will cause too much force where you may not even jump. (Reason for reset)

void Awake()
    {
        player = GetComponent<CharacterController>();
        anim = transform.Find("Character").GetComponent<Animator>();
	}

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void Update ()
    {
        playerControl();
        updateMovementAnimation();
        fightTransition();
	}

    void playerControl()
    {
        //Assigning values to a float based on Input
        moveFB = Input.GetAxis("Vertical") * speed;
        moveLR = Input.GetAxis("Horizontal") * speed;

        //Sprint
        if(Input.GetButton("Fire3"))
        {
            isSprinting = true;
            moveFB = moveFB * sprintMultiplier;
            moveLR = moveLR * sprintMultiplier;
            anim.SetBool("isSprinting", true);
        }

        else
        {
            isSprinting = false;
            anim.SetBool("isSprinting", false);
        }

        //place values in a vector 3 called movement
        Vector3 movement = new Vector3(moveLR, verticalVelocity, moveFB);

        //Add forward physics to transform, commented out for now to minimize other errors
        //transform.Translate(moveLR * Time.deltaTime, 0, moveFB * Time.deltaTime);

        //Keeps the movement overall speed at a 1:1 ratio. So double key press won't multiply speed
        if (player.isGrounded) //if theres no check, the player will continue falling at same speed
        {
            //clamps values to avoid any movement is doubled if traveling in two+ directions
            if (isSprinting) { movement = Vector3.ClampMagnitude(movement, speed * sprintMultiplier); }
            else { movement = Vector3.ClampMagnitude(movement, speed); }
        }

        //Debug.Log(movement); THIS OUtPUTS PROPERLY RIGHT HERE

        if (isSliding)
        {
            //made small progress, doesnt quite work yet
            Vector3.OrthoNormalize(ref groundObjectNormal, ref movement);
        }

        //movement is frame independent
        movement *= Time.deltaTime;

        //When rotated by mouse, it rotates local but moves forward on world, so here you align the rotation to world By using movement = transform.rotation * movement; or below local to global
        movement = transform.TransformDirection(movement);

        //Move is called and requires a Vector 3. Assign Vector 3 to move and make it frame independent
        player.Move(movement);

        if (player.isGrounded)
        {
            anim.SetBool("isGrounded", true);
            if (Input.GetButtonDown("Jump") )
            {
                isJumping = true;
                verticalVelocity += jumpDistance;
                anim.SetBool("Jump", true);
            }
        }

        //------------------------------------------****MOUSE****-------------------------------------------------//
        mouseRotX = Input.GetAxis("Mouse X") * mouseSensitivityX;
        mouseRotY -= Input.GetAxis("Mouse Y") * mouseSensitivityY;

        mouseRotY = Mathf.Clamp(mouseRotY, -mouseYCap, mouseYCap);

        //rotate the player LR by mouse movement;
        transform.Rotate(0, mouseRotX, 0);

        //rotates the camera up and down, if you mix with x, the entire player is rotated 360, no buno
        playerCam.transform.localRotation = Quaternion.Euler(mouseRotY, 0, 0); //switch mouseRotY to negative for invert
    }

    //**JUMP PHYSICS & isGrounded
    private void FixedUpdate()//runs every other frame instead of every frame
    {
        //player is constantly falling, on one its a constant speed, on the other its additive speed
        if (player.isGrounded)
        {
            if (isJumping)
            {
                //this was not allowing jump and overwriting
                isJumping = false;
                return;
            }

            else
            {
                //Constamt Same Fall Force
                //reset gravity so the collision detection works. If set vertVelocity to 0 unity ignores collision detection
                anim.SetBool("Jump", false);
                verticalVelocity = Physics.gravity.y * Time.deltaTime; //Gravity pulls you down faster and faster based on how much time has gone by. BUILT IN!
            }
        }

        else
        {
            //add fall force over time
            anim.SetBool("isGrounded", false);
            verticalVelocity += Physics.gravity.y * Time.deltaTime;
        }

        if(objectHitAngle > player.slopeLimit)
        {
            isSliding = true;
        }
        else { isSliding = false; }

    }

1 Answer

1

I’m finding the sliding down slopes difficult, been through tutorials for weeks on here and on YT, none of them quite gel with the starter assets ThirdPersonController using the new input system, so for example m_moveDir.x I think it is _input.move.x and so far either my character hovers above ground or does a skiing action lol or nothing at all, very frustrating moving into my 3rd week and I really need the player to slide down a slope that’s steeper than the slopelimit. The player just stands on a slope and they can just jump back up defeating the purpose of the game falling down from a great height and losing a life. I really hope there is a solution for the starter assets soon and they have the remote5 working with the new input system also, been well over 2 years and nothing only a few have their own solutions for the remote 5 to work but I prefer the official. I can get the normal pointing down the slope but can not get the character controller to slide in that direction, I need more physics and math practice it seems lol but time is not on my side. Anyway as usual thanks guys much appreciated if anyone has a starter assets TPCntrlr soln.