Unknown Force Applied When Programming Custom Gravity

I’m working on programming a way for gravity to switch directions based on the direction the face of the mesh the player is touching.

I’m shooting out a ray in front, behind, and below the player.
If the ray hits something in front of the player, the player’s upward vector becomes the direction of the face that is in front of the player. If there is nothing in front of the player, the process is applied if there is something below the player. If there is nothing below the player, then the process is applied to the upward vector.

When the player is not grounded, a force is added to the player in the opposite direction of the upDirection.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gravity : MonoBehaviour
{
    public  Vector3 upDirection;

    public bool isGrounded;
    public Rigidbody rb;


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        upDirection = Vector3.up;
    }


    void Update()
    {
        transform.up = upDirection;
    }

    private void FixedUpdate()
    {
        RaycastHit down_hit;
        Physics.Raycast(transform.position, -transform.up, out down_hit);

        RaycastHit forward_hit;
        Physics.Raycast(transform.position, transform.forward, out forward_hit);

        RaycastHit back_hit;
        Physics.Raycast(transform.position, -transform.forward, out back_hit);



        if (down_hit.collider != null)
        {
            Debug.DrawLine(transform.position, down_hit.point, Color.green);
        }

        if(forward_hit.collider != null)
        {
            Debug.DrawLine(transform.position, forward_hit.point, Color.blue);
        }

        if(back_hit.collider != null)
        {
            Debug.DrawLine(transform.position, back_hit.point, Color.cyan);
        }



        if(Vector3.Distance(forward_hit.point, transform.position) < 1f && forward_hit.collider != null)
        {
            upDirection = forward_hit.normal;

        }
        else if(Vector3.Distance(back_hit.point, transform.position) < 1f && back_hit.collider != null)
        {
            upDirection = back_hit.normal;
        }
        else if (Vector3.Distance(down_hit.point, transform.position) < 1f && down_hit.collider != null)
        {
            isGrounded = true;
            upDirection = down_hit.normal;

        }
        else
        {
            isGrounded = false;
        }




        if (!isGrounded)
        {
            rb.velocity = -upDirection * 9.81f;
        }
    }



}

However, there is an issue, when the player goes over corners. The player starts to get pushed by a force that shouldn’t be applied even when I’m not controlling the player.

This can be seen once the player reaches the top of the green block in this video:
ezgif-5-3720ba2756

What debugging have you done so far?

1 Like

I made up direction viewable in the inspector to see if the players up direction was what it was supposed to be. Since my gravity should only be affected by the variable upDiection, it should show anything out of the ordinary in the inspector. However, everything seems to be looking normal in the inspector.

I also made sure to draw debug lines towards the points that gravity should be pushing the player. Again, everything is working as expected.

So it’s not the force, or the player not detecting properly.

So what Debug.Log calls, or managed debugging, have you done to see what the flow of execution is, and what values are being fed to your rigidbody?

Simply looking at the inspector isn’t meaningful debugging.

1 Like

I added in debug.log statements describing the direction of the normal that is applied to the character.

        if(Vector3.Distance(forward_hit.point, transform.position) < 1f && forward_hit.collider != null)
        {
            upDirection = forward_hit.normal;
            print("Gravity Force is: " +  upDirection);

        }
        else if(Vector3.Distance(back_hit.point, transform.position) < 1f && back_hit.collider != null)
        {
            upDirection = back_hit.normal;
            print("Gravity Force is: " + upDirection);
        }
        else if (Vector3.Distance(down_hit.point, transform.position) < 1f && down_hit.collider != null)
        {
            isGrounded = true;
            upDirection = down_hit.normal;
            print("Gravity Force is: " + upDirection);

        }

However, again, there was nothing that was unexpected. Every log consecutively printed the correct direction.
There was no switching between directions (which is what I thought the issue probably was). The correct direction gets printed consecutively until the player switches faces, and then the correct direction gets printed consecutively once more.

This is my entire code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gravity : MonoBehaviour
{
    public  Vector3 upDirection;

    public bool isGrounded;
    public Rigidbody rb;


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        upDirection = Vector3.up;
    }


    void Update()
    {
        transform.up = upDirection;
    }

    private void FixedUpdate()
    {
        RaycastHit down_hit;
        Physics.Raycast(transform.position, -transform.up, out down_hit);

        RaycastHit forward_hit;
        Physics.Raycast(transform.position, transform.forward, out forward_hit);

        RaycastHit back_hit;
        Physics.Raycast(transform.position, -transform.forward, out back_hit);



        if (down_hit.collider != null)
        {
            Debug.DrawLine(transform.position, down_hit.point, Color.green);
        }

        if(forward_hit.collider != null)
        {
            Debug.DrawLine(transform.position, forward_hit.point, Color.blue);
        }

        if(back_hit.collider != null)
        {
            Debug.DrawLine(transform.position, back_hit.point, Color.cyan);
        }



        if(Vector3.Distance(forward_hit.point, transform.position) < 1f && forward_hit.collider != null)
        {
            upDirection = forward_hit.normal;
            print("Gravity Force is: " +  upDirection);

        }
        else if(Vector3.Distance(back_hit.point, transform.position) < 1f && back_hit.collider != null)
        {
            upDirection = back_hit.normal;
            print("Gravity Force is: " + upDirection);
        }
        else if (Vector3.Distance(down_hit.point, transform.position) < 1f && down_hit.collider != null)
        {
            isGrounded = true;
            upDirection = down_hit.normal;
            print("Gravity Force is: " + upDirection);

        }
        else
        {
            isGrounded = false;
        }




        if (!isGrounded)
        {
            rb.velocity = -upDirection * 9.81f;
        }
    }



}

It’s pretty short, and there aren’t many places I can debug. This is all I could think of to catch any potential errors.

I couldn’t find anything out of the ordinary.

Okay, I realized that there was “left over force” when I switch directions. All I needed to do was set velocity to Vector3.zero whenever I switch directions, and all was good.