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.