Good day,
I have encountered an issue with my script for movement down a slope using a character controller where the controller bounces as it moves downwards. Although I have found a few forums posts related to this issue and some alternative fixes such as increasing y velocity based on how steep the terrain angle is, I have been unable to find the fix I am looking for which is adjusting the velocity vector to match the normal of the terrain so that the player travels in the direction of the slope. If anyone has any insight on where I am going wrong, it would be much appreciated.
I am following this tutorial:
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
DESCRIPTION:
CLASSES:
DATABASES:
VARIABLES:
METHODS:
COROUTINES:
*/
namespace EasyControls
{
public class MovementTemplate : MonoBehaviour
{
//
[HideInInspector]
public CharacterController controller;
// Variable for movement speed
private float speed = 5;
// Variable for gravity constant
private float gravityConstant = -9.81f;
//
private float ySpeed;
//
private float defaultStepOffset;
//
private float slopeLimit;
// Bool for grounded state
private bool isGrounded;
// Move forward ControlObject reference for linking value on ControlBuffer to movement speed
public ControlObject moveForward;
// Move backward ControlObject reference for linking value on ControlBuffer to movement speed
public ControlObject moveBackward;
// Move left ControlObject reference for linking value on ControlBuffer to movement speed
public ControlObject moveLeft;
// Move right ControlObject reference for linking value on ControlBuffer to movement speed
public ControlObject moveRight;
// Move jump ControlObject reference for linking value on ControlBuffer to movement speed
public ControlObject moveJump;
public void Start()
{
controller = this.GetComponent<CharacterController>();
defaultStepOffset = controller.stepOffset;
slopeLimit = controller.slopeLimit;
}
// System method
public void Update()
{
PlayerMovement();
}
// Last Updated:
public void PlayerMovement()
{
float _horizontalInput = (-ControlBuffer.assignedControls.controls[moveLeft.data.Id].Value + ControlBuffer.assignedControls.controls[moveRight.data.Id].Value);
float _verticalInput = (ControlBuffer.assignedControls.controls[moveForward.data.Id].Value + -ControlBuffer.assignedControls.controls[moveBackward.data.Id].Value);
Vector3 _movementDirection = new Vector3(_horizontalInput, 0, _verticalInput).normalized;
float _magnitude = Mathf.Clamp01(_movementDirection.magnitude) * speed;
ySpeed += gravityConstant * Time.deltaTime;
if (controller.isGrounded)
{
controller.stepOffset = defaultStepOffset;
ySpeed = -0.5f;
}
else
{
controller.stepOffset = 0;
}
Vector3 _moveVelocity = _movementDirection * _magnitude;
_moveVelocity = AdjustVelocityToSlope(_moveVelocity);
_moveVelocity.y += ySpeed;
controller.Move(transform.TransformDirection(_moveVelocity * Time.deltaTime));
}
public void JumpPlayer()
{
Debug.Log("Jump");
}
private Vector3 AdjustVelocityToSlope(Vector3 _velocity)
{
var ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out RaycastHit hit, 1.5f))
{
var slopeRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
var adjustedVelocity = slopeRotation * _velocity;
var slope = Vector3.Cross(hit.normal, Vector3.Cross(hit.normal, Vector3.up));
if (adjustedVelocity.y < 0)
{
return adjustedVelocity;
}
}
return _velocity;
}
}
// Last Updated: DD/MM/YYYY - Author Name
}
// Last Updated: DD/MM/YYYY - Author Name