How to limit ProjectOnPlane on a cylinder gravity object?

I am trying to have my character walk around a cylinder. The cylinder has an outer radius around itself that acts as a gravity zone, and then a outer fall off radius that reduces gravity until the player is out of that radius, where gravity then returns to zero gravity.

I only want gravity being an influence on the outer or inner side of the cylinder, not the top or bottom. I have managed to achieve this with this code, however the gravity extends past the cylinder’s top and bottom, as if the sides of the cylinder were infinite. How can I either limit ProjectOnPlane’s length or use another method to make gravity become null once you are past the origin point or the height of the object?

[SerializeField]
    float gravity = 9.81f;

    [SerializeField, Min(0f)]
    float innerFalloffRadius = 1f, innerRadius = 5f;

    [SerializeField, Min(0f)]
    float outerRadius = 10f, outerFalloffRadius = 15f;

    [SerializeField, Min(0f)]
    float height;

    float innerFalloffFactor, outerFalloffFactor;



    public override Vector3 GetGravity (Vector3 position) {

        Vector3 vector = Vector3.ProjectOnPlane(transform.position - position, transform.up);

        Vector3 position2 = new Vector3(transform.position.x, transform.position.y * height, transform.position.z);
        float distance = vector.magnitude;

        if (distance > outerFalloffRadius || distance < innerFalloffRadius ) {
            return Vector3.zero;
        }
        float g = gravity / distance;
        if (distance > outerRadius) {
            g *= 1f - (distance - outerRadius) * outerFalloffFactor;
        }
        else if (distance < innerRadius) {
            g *= 1f - (innerRadius - distance) * innerFalloffFactor;
        }
        return g * vector;
    }

You can not limit ProjectOnPlane because this is a pure mathematical function and the plane is defined as an infinite plane. It has no position, scale or borders. It only has an offset from the origin and a normal, that’s it. If you need to restrict the area of influence you have to check for that yourself.

There are several things unclear. First of all on which object is this script attached to? The player or the cylinder? So what does “transform” refer to in the code and what position do you pass in?

Assuming this is on the actual cylinder (which is the only thing that makes a bit of sense) and transform.up indicates the axis of the cylinder, your calculated radial “distance” value would be correct. To determine if you are in the lateral range, you can simply use the Dot product between your cylinder axis and your relative position. Assuming the origin of the cylinder is in the center, the resulting dot product must be larger than -halfCylinderHeight and smaller than halfCylinderHeight. If that lateral distance is outside that range, you’re not “to the side” of the cylinder but above or below.