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; }
}
Answer by Paul_Hughes · Nov 24, 2021 at 12:53 AM
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.
Your answer
Follow this Question
Related Questions
MoveTowards is curving for no reason 0 Answers
having CharacterController movement in fixedupdate causes jerky movement on camera 0 Answers
How to make character look at movement direction? 1 Answer
First person movement with character controller does not detect ground properly 0 Answers
High speed sliding (ski/sled) from curved slopes in a 2d game. 0 Answers