i followed a tutorial showing how to fix slopes on your game, i saw that the tutorial used projectonplane
to it’s vector3 would be perpendicular to the slope. but i keep getting small bumps
dik0de
this was the tutorial by the way
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerMovement : MonoBehaviour
{
// jump button UI event
public JumpButtonEvent jumpBtn;
// player game object components
public AudioSource ballBounceSFX;
public Rigidbody playerRb;
public Collider playerCollider;
// camera
public Transform gameCamera;
// movement properties
public Vector3 playerVector;
public float movementSpeed;
public float jumpSpeed;
public float jumpForce = 50f;
public bool isJumping = false;
public bool isMoving = false;
public FixedJoystick joystickMove;
public float x;
public float y;
public float z;
public float gravity = 2f;
//overlap sphere colliders
public float sphereRadiusNew;
public Collider[] overlapSphereColliders;
// raycast
public bool isGrounded = false;
RaycastHit hitInfo;
RaycastHit slopeHit;
Vector3 raycastDirection;
public LayerMask raycastLayers;
public float sphereRadius = 0.1f;
public float castDistance = 0.01f;
public float slopeCastDistance = 1f;
public float slopeSpeed = 1f;
Vector3 slopeMoveDirection;
Vector3[] surfaceNormal;
private void Awake()
{
raycastDirection = Vector3.down;
}
// Start is called before the first frame update
void Start()
{
}
public void MovementAndJump()
{
Quaternion cameraRot = Quaternion.Euler(0, gameCamera.eulerAngles.y, 0); // convers camera quaternion to euler, to be able to rotate the camera in euler angles (rotation axis from inspector)
x = joystickMove.Horizontal;
z = joystickMove.Vertical;
playerVector = cameraRot * new Vector3(x, 0, z) * movementSpeed; // the playervector input will have the x and z values. y is added later
if(IsGrounded() == true && isMoving == true)
{
playerRb.drag = 15f;
}
if (isMoving == false && IsGrounded() == true)
{
playerRb.velocity = Vector3.zero;
playerRb.drag = 0f;
}
if(OnSlope() == true)
{
playerRb.drag = 0f;
}
if (isJumping == false && jumpBtn.jumpBtnClicked == true && IsGrounded() == true)
{
Vector3 jumpVector = new Vector3(0, jumpForce, 0);
playerRb.AddForce(jumpVector, ForceMode.Impulse);
isJumping = true;
}
if(isJumping == true)
{
playerRb.drag = 0f;
}
if (isJumping == true && IsGrounded() == false)
{
playerVector.y = playerVector.y - gravity; // if player is mid-air (jumping) the vertical movement will be subtracted to the gravity, making the gravity pushing the player to the ground
}
if(isJumping == true && isMoving == true)
{
playerRb.velocity = new Vector3(playerVector.x * jumpSpeed, playerRb.velocity.y, playerVector.z * jumpSpeed); // when jumping will create a new vector that will move according to the value on playerVector.x and playerVector.z multiplying by a moving speed on jump
}
if (joystickMove.Horizontal == 0 && joystickMove.Vertical == 0 /*&& Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0*/)
{
isMoving = false;
}
else
{
isMoving = true;
}
// moving rigidbody (player)
playerRb.AddForce(playerVector, ForceMode.VelocityChange);
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
OnSlope();
IsGrounded();
MovementAndJump();
}
public bool IsGrounded() // cria uma funçao bool que verifica se o player está no chão ou não
{
if (Physics.SphereCast(playerCollider.bounds.center, sphereRadius, raycastDirection, out hitInfo, castDistance, raycastLayers))
{
Debug.Log(hitInfo.normal);
if (hitInfo.collider.gameObject.layer == 7 || hitInfo.collider.gameObject.layer == 8) // se o layer do objeto que o raycast bateu for 7(Ground) então retorna um valor TRUE(significando que o play esta no chao)
{
Gizmos.color = Color.green;
Debug.Log(hitInfo.collider);
Debug.Log("TOUCHING GROUND!");
gameObject.transform.parent = null;
isJumping = false;
return true;
}
else if (hitInfo.collider.gameObject.layer == 6)
{
Gizmos.color = Color.green;
Debug.Log(hitInfo.collider);
Debug.Log("TOUCHING GROUND!");
gameObject.transform.SetParent(hitInfo.collider.transform, true);
isJumping = false;
return true;
}
else if (hitInfo.collider == null) // se o raycast nao detetar qualquer collider, o player nao está no chao
{
Gizmos.color = Color.red;
gameObject.transform.parent = null;
isJumping = true;
return false;
}
else // se o raycast nao detetar qualquer collider, o player nao está no chao
{
gameObject.transform.parent = null;
isJumping = true;
return false;
}
}
gameObject.transform.parent = null;
isJumping = true;
return false; // if the player isn't touching the ground he is jumping and not on any platform
}
public bool OnSlope()
{
if (Physics.Raycast(playerCollider.bounds.center, raycastDirection, out slopeHit, slopeCastDistance))
{
Debug.Log(slopeHit.normal);
if (slopeHit.normal != Vector3.up)
{
Debug.Log("I'm on slope");
slopeMoveDirection = Vector3.ProjectOnPlane(playerVector, slopeHit.normal); // projects a vector3 that is perpendicular to a normal surface
playerRb.AddForce(slopeMoveDirection.normalized, ForceMode.VelocityChange); // the velocity will be the playervector + slopemovedirection, which means the vector will move in slope direction
return true;
}
}
return false;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawRay(playerCollider.bounds.center, Vector3.down * castDistance);
Gizmos.DrawSphere(playerCollider.bounds.center, sphereRadius);
Gizmos.color = Color.yellow;
Gizmos.DrawRay(playerCollider.bounds.center, Vector3.down * slopeCastDistance);
Gizmos.color = Color.green;
Gizmos.DrawSphere(playerCollider.bounds.center, sphereRadiusNew);
}
// on collision frame
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.layer == 6 && IsGrounded() == true || collision.gameObject.layer == 7 && IsGrounded() == true || collision.gameObject.layer == 8 && IsGrounded() == true) // if the player hits one of these layers when colliding with them on colliding frame
{
ballBounceSFX.Play(); // play the bouncing ball sfx
}
}
}