Why button must be hit twice before full code goes?

I’m fiddling with a “walk on walls” code.
I’ve made it so the player can jump off the wall, and will drop to the ground (basically… if its holding on to the surface “touching” it’ll stay oriented on the face of the wall) but if you jump, then gravity takes hold, reorients you to have your normal aligned with the world.

I can get it to work “if” I hit the button twice.

Then… there’s the double (and in this case… unlimited) jumping aspect… that I do not want. If I’m on the normal ground, I can repeatedly hit the jump button and I climb higher and higher. My code has a bool that basically toggles… so “jumping = false” normally, but when I hit the jump button, it calls a “jump off” method that has jumping = true; That method calls another method that is Ienumerator, and then makes jumping = false…

So… why is the button not disabled while I’m jumping? (my input command is

if (Input.GetButtonDown && !jumping){
JumpOffWall();
}

but regardless of my location in space, on ground, on wall… I can repeatedly hit the jump button and climb higher and higher. If I jump off a wall just once I fall back to the wall without orienting…(the code has it jump in the “myNormal” direction then reorient on the ground) but hitting it the second time runs the full code for reorienting… and falling… but then I can hit button again and again to climb higher… again

here is the code I’m currently using (I got it from
Basic Movement: Walking on Walls

I have tweaked it a little bit…

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

 /// <summary>
	/// C# translation from http://answers.unity3d.com/questions/155907/basic-movement-walking-on-walls.html
	/// Author: UA @aldonaletto 
	/// </summary>
	
 // Prequisites: create an empty GameObject, attach to it a Rigidbody w/ UseGravity unchecked
		// To empty GO also add BoxCollider and this script. Makes this the parent of the Player
		// Size BoxCollider to fit around Player model.
		
public class QM_CharController : MonoBehaviour {
 
		private float moveSpeed = 6; // move speed
	private float turnSpeed = 90; // turning speed (degrees/second)
	private float lerpSpeed = 10; // smoothing speed
	private float gravity = 10; // gravity acceleration
    private bool isGrounded;
	private float deltaGround = 0.2f; // character is grounded up to this distance
	private float jumpSpeed = 10; // vertical jump initial speed
	private float climbRange = 5; // range to detect target wall
	private Vector3 surfaceNormal; // current surface normal
    private Vector3 myNormal; // character normal
	private float distGround; // distance from character position to ground
	private bool jumping = false; // flag "I'm jumping to wall"
	private float vertSpeed = 10; // vertical jump current speed
	private bool climbing = false;
	
    private Transform myTransform;
	public BoxCollider boxCollider; // drag BoxCollider ref in editor
	
	private void Start(){
		myNormal = transform.up; // normal starts as character up direction
         myTransform = transform;
		rigidbody.freezeRotation = true; // disable physics rotation
		// distance from transform.position to ground
		distGround = boxCollider.extents.y - boxCollider.center.y;
		
     }
	
	private void FixedUpdate(){
		// apply constant weight force according to character normal:
		rigidbody.AddForce(-gravity*rigidbody.mass*myNormal);
 }
	
	private void Update(){
		// climb code - jump off wall or simple jump
		if (climbing) return; // abort Update while climbing to a wall
		if (jumping)return; // abort Update while jumping
			Ray ray;
		RaycastHit hit;
		
		if (Input.GetButtonDown("Climb")){ // climb pressed:
         ray = new Ray(myTransform.position, myTransform.forward);
			if (Physics.Raycast(ray, out hit, climbRange)){ // wall ahead?
				ClimbToWall(hit.point, hit.normal); // yes: climb on the wall
			}
		}
		if(Input.GetButtonDown ("Jump") && !jumping){ // no: if grounded, jump up

				JumpOffWall ();
		}

		
		// movement code - turn left/right with Horizontal axis:
     myTransform.Rotate(0, Input.GetAxis("Turn")*turnSpeed*Time.deltaTime, 0);
		// update surface normal and isGrounded:
		ray = new Ray(myTransform.position, -myNormal); // cast ray downwards
		if (Physics.Raycast(ray, out hit)){ // use it to update myNormal and isGrounded
			isGrounded = hit.distance <= distGround + deltaGround;
         surfaceNormal = hit.normal;
		}
		else {
			isGrounded = false;
			// assume usual ground normal to avoid "falling forever"
         surfaceNormal = Vector3.up;
		}
		myNormal = Vector3.Lerp(myNormal, surfaceNormal, lerpSpeed*Time.deltaTime);
		// find forward direction with new myNormal:
		Vector3 myForward = Vector3.Cross(myTransform.right, myNormal);
     // align character to the new myNormal while keeping the forward direction:
			Quaternion targetRot = Quaternion.LookRotation(myForward, myNormal);
		myTransform.rotation = Quaternion.Lerp(myTransform.rotation, targetRot, lerpSpeed*Time.deltaTime);
		// move the character forth/back with Vertical axis:
		myTransform.Translate(0, 0, Input.GetAxis("Forward")*moveSpeed*Time.deltaTime);
 }
	
	private void ClimbToWall(Vector3 point, Vector3 normal){
		// climb to wall
		climbing = true; // signal it's jumping to wall
     rigidbody.isKinematic = true; // disable physics while climbing
		Vector3 orgPos = myTransform.position;
		Quaternion orgRot = myTransform.rotation;
		Vector3 dstPos = point + normal * (distGround + 0.5f); // will jump to 0.5 above wall
		Vector3 myForward = Vector3.Cross(myTransform.right, normal);
     Quaternion dstRot = Quaternion.LookRotation(myForward, normal);
		
		StartCoroutine (jumpTime (orgPos, orgRot, dstPos, dstRot, normal, 0.4f));
		//jumptime
	}


	private void JumpOffWall(){
		// jump off wall 
		jumping = true; 
		Vector3 orgPos = myTransform.position;
		Quaternion orgRot = myTransform.rotation;
		Vector3 myForward = Vector3.Cross(myTransform.right, Vector3.right);
		Quaternion dstRot = Quaternion.LookRotation(myForward, Vector3.up);
		
		StartCoroutine (jumpTime (orgPos, orgRot, orgPos, dstRot, Vector3.up, 0.2f));
		//jumptime
	}
	
	private IEnumerator jumpTime(Vector3 orgPos, Quaternion orgRot, Vector3 dstPos, Quaternion dstRot, Vector3 normal, float time) {
		rigidbody.velocity += jumpSpeed * myNormal;
		for (float t = 0.0f; t < time; ){
			t += Time.deltaTime;
			myTransform.position = Vector3.Lerp(orgPos, dstPos, t);
             myTransform.rotation = Quaternion.Slerp(orgRot, dstRot, t);
			yield return null; // return here next frame
		}
		myNormal = normal; // update myNormal
	    rigidbody.isKinematic = false; // enable physics
        climbing = false; // climbing is accomplished
		jumping = false;
	}

	void OnTriggerEnter(Collider other){
		Ray ray;
		RaycastHit hit;
				if (other.gameObject.tag == "tree") {
						ray = new Ray (myTransform.position, myTransform.forward);
						if (Physics.Raycast (ray, out hit, climbRange)) { // wall ahead?
								ClimbToWall (hit.point, hit.normal); // yes: climb on the wall

						}
				}
		}
	
}

Well… eventually got it to do what I wanted to… yeeeey!

I think what had been happening was the script was running a co-routine that was interfering with itself, hitting the button twice allowed it to go through it … before it could interfere?? well anyways… I ended up using “Invoke” with a time delay, and some bools… and it is working :smiley: 98% of the time anyways…