Inconsistent results when comparing distances

Sorry for the somewhat sloppy code, but this is all my implementation phase stuff, so it’s a bit of a mess. My game has the player using a grappling hook that deals damage as they move away from enemies or as enemies move away from them. At least, that’s what I’d like to have happen. As it stands now, distance comparisons don’t seem to be working so hot.

Here’s the code for the grappling itself:

    void GrappleEnemy () {
        forwardGrapplingDirection = (grappleTarget.transform.position - this.transform.position).normalized;
        float grapplingDot = Vector3.Dot (forwardGrapplingDirection, transform.TransformDirection (fpsController.moveDirectionNorm));
        Vector3 thisPosition = new Vector3 (transform.position.x, 0f, transform.position.z);
        Vector3 grappleDistance = new Vector3 (grappleObject.transform.position.x, 0f, grappleObject.transform.position.z);
        float distanceThisFrame = Vector3.Distance (thisPosition, grappleDistance);

        Debug.Log (distanceThisFrame - distanceLastFrame);


        if (distanceThisFrame > distanceLastFrame) {
            grappleObject.BeingGrappled (true, transform.forward, damagePerSecond * Mathf.Abs(grapplingDot));
        } else {
            grappleObject.BeingGrappled (true, transform.forward, -grappleObject.regenSpeed);
        }

        fpsController.moveSpeed = grappleLandSpeed * Remap (Vector3.Dot (forwardGrapplingDirection, transform.TransformDirection (fpsController.moveDirectionNorm)), -1f, 1f, 0.25f, 1f);
        distanceThisFrame = 0f;
    }

The key things at play are the distanceThisFrame variable, and the distanceLastFrame variable, which I store at the end of the update loop here:

void Update () {

        CheckRay ();

        if (!fpsController.isDead && player.GetButtonDown ("Grapple") && CastRay ()) {
            grappleTarget.SetActive (true);
            grappleTarget.transform.position = hit.point;
            grappleTarget.transform.SetParent (hit.transform);
            bufferVelocity = controller.velocity;
            if (hit.transform.gameObject.tag == "GrappleObject") {
                grapplingState = GrapplingState.grapplingEnemy;
            } else {
                grapplingState = GrapplingState.grapplingWorld;
            }
        }

        if (grapplingState == GrapplingState.grapplingWorld && player.GetButton ("Grapple")) {
            GrappleWorld ();
        } else if (grapplingState == GrapplingState.grapplingEnemy && player.GetButton ("Grapple")) {
            GrappleEnemy ();
        }

        if (player.GetButtonUp ("Grapple")) {
            grappleTarget.SetActive(false);
            grapplingState = GrapplingState.grapplingNothing;
            grapplingEnemy = false;
            if (grappleObject != null) {
                grappleObject.BeingGrappled (false, transform.forward, 0f);
            }
            grappleLerp = 0f;
            fpsController.isGrappling = false;
        }

        if (grapplingState == GrapplingState.grapplingNothing) {
            fpsController.moveSpeed = internalSpeed;
        }

        ShowEnemyHealth ();
        DrawLine ();
        CheckDistance ();

        if (grapplingState == GrapplingState.grapplingEnemy) {
            Vector3 thisPosition = new Vector3 (transform.position.x, 0f, transform.position.z);
            Vector3 grappleDistance = new Vector3 (grappleObject.transform.position.x, 0f, grappleObject.transform.position.z);
            distanceLastFrame = Vector3.Distance (transform.position, grappleObject.transform.position);
        } else {
            distanceLastFrame = 0f;
        }
    }

Unfortunately, as I move away from a simple target I’ve scripted to move up and down, the behaviour of the distance value becomes erratic, even though I’m not accounting for Y position in any of my calculations. This is mostly so the player can’t stand on top of enemies and jump up and down on them until they die.

If you want to see the current state of things, you can download one of the builds I’ve made off itch.io here.

What exactly am I doing wrong here? I want some of the enemies to charge at the player so they have to weave around them to do damage, which is core to the gameplay in a few areas, but I can’t do that if I cant get past this bug.

What I would do is create two small cubes. Then every update place the cubes at the position you calculated. This will help debug your code to verify the positions you calculate are what you expect.

Vector3
thisPosition = new Vector3 (transform.position.x, 0f, transform.position.z);
Vector3 grappleDistance = new Vector3 (grappleObject.transform.position.x, 0f, grappleObject.transform.position.z);

debugCube1.transform.position = thisPosition;
debugCube2.transform.position = grappleDistance;

Verify the debugCubes are where you expect them to be.

It’s possible the gameObject pivot point is not where you expect. If so, you could use the boundsCenter instead of the pivot point in the calculations so to use the center of the mesh in the calculations rather than the pivot point

The lack of a facepalm emoticon here is unfortunate.

As soon as I did this, I noticed that one of the cubes was moving up and down when it shouldn’t have been. It turns out that I was using the old 3D values when establishing my previous frame distance which was throwing off all my calculations. Thanks!