Search Unity

Using ProjectOnPlane for Rigidbody to stick to slopes and avoid getting stuck on difficult terrain?

Discussion in 'Scripting' started by ynm11, Jan 31, 2022.

  1. ynm11

    ynm11

    Joined:
    Jul 6, 2021
    Posts:
    57
    I have a simple Rigidbody movement script. I am having difficulty getting the rigidbody to stick to slopes, and also to collide with difficult terrain without getting stuck.

    I read that ProjectOnPlane can be a solution to both issues. I have tried implementing it in the code below (
    Vector3 force = Vector3.ProjectOnPlane(movDirection, colliderNormal) * speed
    where
    colliderNormal
    is retrieved from
    OnCollisionEnter
    ).

    However, the results are that:

    1- The rigidbody still does not stick to the ground on slopes.

    2- If the rigidbody collides with difficult terrain like a cone pointing upward, it still gets stuck against it rather than moving along the slope of the cone.

    How can ProjectOnPlane properly be used to move ALONG slopes (and presumably stick to them)?

    Code (CSharp):
    1.     using System.Collections;
    2.     using System.Collections.Generic;
    3.     using UnityEngine;
    4.  
    5.     public class Move3 : MonoBehaviour
    6.     {
    7.         public Rigidbody r;
    8.         public float horizontalInput;
    9.         public float verticalInput;
    10.         public Vector3 moveDirection;
    11.         public float speed;
    12.         Vector3 colliderNormal;
    13.  
    14.         void Awake()
    15.         {
    16.             r = this.GetComponent<Rigidbody>();
    17.         }
    18.  
    19.         void Update()
    20.         {
    21.             horizontalInput = Input.GetAxis("Horizontal");
    22.             verticalInput = Input.GetAxis("Vertical");
    23.             moveDirection = new Vector3(horizontalInput, 0.0f, verticalInput).normalized;  
    24.         }
    25.  
    26.         public void FixedUpdate()
    27.         {
    28.             Vector3 force = Vector3.ProjectOnPlane(moveDirection, colliderNormal) * speed;
    29.             r.AddForce(force, ForceMode.Force);
    30.         }      
    31.  
    32.         private void OnCollisionEnter(Collision other)
    33.         {
    34.             colliderNormal = other.contacts[0].normal; //new "up" of input
    35.         }
    36.  
    37.     }
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    Maybe you should check out where exactly is the point of contact? I can imagine you are using a capsule as a collider for your character. Where exactly does it touch the world colliders? And what's the direction of the contact normal?

    Draw some gizmos and test your assumptions.
     
    ynm11 likes this.