Changing Value over Time

Hi guys…I know it may appear I’m being lazy, but in fact I’ve been trying to figure this out for two days, really trying to avoid asking and figuring it out myself. I’ve gotten an awful lot accomplished in the past two weeks so hopefully this won’t be too bad.

First the code:

if (crouchDetected.crouchButtonDown) 
		{
			var crouchControl : CharacterController = GetComponent(CharacterController);

			isCrouching = crouchDetected.crouchToggle;

			if (isCrouching) 
			{
				crouchControl.height = 1.2; 
				cameraHinge.transform.localPosition = Vector3 ( 0, -1.4, 0);
				speed = 3.0;
				jumpSpeed = 6.0;
         }
			
			else 
			{
				if (!isCrouching  crouchControl.height != 2.0)
				{
					transform.Translate ( 0, 0.4, 0); 
				    crouchControl.height = 2.0;
				    cameraHinge.transform.localPosition = Vector3 ( 0, -0.9, 0);
					speed = 6.0;
					jumpSpeed = 8.0;
				}
			}
		}

I simply want crouchControl.height and cameraHinge.transform.localPosition to LERP from their ‘crouched’ ( if(isCrouching) ) values to their ‘standing’ ( if(!isCrouching…) ) values over a period of say one second.

I’ve tried every combination of if statements I could think of, I attempted (and failed quickly) to use coroutines and while loops (yikes again) and I just don’t think I’m seeing it.

I had it all set up correctly with Mathf.Lerp (stuff) but I believe the problem involves my if statements, though at this point I’m not sure. The trick is that I’ve released the button (in this case an iPhone GUI button) so I’m not entirely sure what to test to continue to allow those two variables to transition to their respective goal values over time.

I attempted to test the height of the controller continuously, placing the if statement in the body of the function to no avail…

…I might have stared at this too long to see the answer unfortunately…

…though fortunately that at the very least, my crouching works just fine, only when the player stands up, it pops up instantaneously; it works but it could be refined and elegant.

Any help is very much appreciated. :slight_smile:

-Steve

how about something like this ( btw i’m not actually test this though… so try this at your own risk :lol: )

private var busyDoing = false;
function AnimateCrouch(myDuration: float, heightGoal : float, hingeGoal : Vector3)
{
	if (busyDoing) return;
	busyDoing = true;
	var crouchingTime = 0.0;
	
	while (crouchingTime <= myDuration) // while less than myDuration
	{
		// Lerp the Height
		crouchControl.height = Mathf.Lerp(crouchControl.height, heightGoal, crouchingTime);
		// Lerp the Hinge
		cameraHinge.transform.localPosition = Vector3.Lerp(cameraHinge.transform.localPosition, hingeGoal, crouchingTime);
		crouchingTime += Time.deltaTime;
		yield;
	}
	// Done
	busyDoing = false;
}



// -----------------------
// Your original code here....
// -----------------------


if (isCrouching)
{
   AnimateCrouch(1.0, 1.2, Vector3(0, -1.4, 0));

   speed = 3.0;
   jumpSpeed = 6.0;
}
else if (!isCrouching  crouchControl.height != 2.0)
{
   transform.Translate ( 0, 0.4, 0);
   AnimateCrouch(1.0, 2.0, Vector3(0, -0.9, 0));

   speed = 6.0;
   jumpSpeed = 8.0;
}

Potan beautiful! I didn’t reply until I got it in, working and refined…and it’s PERFECT.

Here’s the VERY slight adjustment I made:

function AnimateCrouch ( myDuration: float, heightGoal : float, hingeGoal : Vector3, centerGoal : Vector3) 
{ 
	
	var crouchControl : CharacterController = GetComponent(CharacterController);
	
	if (busyDoing) return;
	 
	busyDoing = true;
	
	 
	var crouchingTime = 0.0; 

	while (crouchingTime <= myDuration) // while less than myDuration 
	{ 
	      		// Lerp the Height 
	    crouchControl.height = Mathf.Lerp(crouchControl.height, heightGoal, crouchingTime); 
	      		// Lerp the Hinge 
	    cameraHinge.transform.localPosition = Vector3.Lerp(cameraHinge.transform.localPosition, hingeGoal, crouchingTime);
			      // Lerp the Center
		crouchControl.center = Vector3.Lerp(crouchControl.center,centerGoal, crouchingTime);
	 
	    crouchingTime += Time.deltaTime;
	 
		yield; 
	} 
	
	   	// Done 
	busyDoing = false;
	
}

My old method was very crude and giving me an unwelcome jitter…

…so instead of translating the CharController upward to compensate for the scaling of the Height parameter (which scales from the CENTER of the Controller, regardless of what you set your “Center” XYZ to, thus causing the Controller to scale into the floor and fall into the void)…

…I, by simply LERPING the Center Y value relative to the Height value (40% in my case, got a PERFECT scaling of the CharController from it’s base, not it’s center…and when I say perfect I mean it is flawless…I love it! :smile:

Thank you so much bud!

-Steve

P.S. Just FYI, your code, untested as you said, dropped right in exactly how you wrote it; I did practically nothing, and simply added one thing to the function. :smile:

You could also use AniMate:

function AnimateCrouch (myDuration: float, heightGoal : float, hingeGoal : Vector3, centerGoal : Vector3) 
{
    // *snip*
    Ani.Mate.To(crouchControl, myDuration, {"height": heightGoal, "center": centerGoal});
    Ani.Mate.To(cameraHinge.transform, myDuration, {"localPosition": hingeGoal});
    // *snip*
}

You only need to call this function once this way.

Awesome, thank you Adrian…I believe I saw this some time ago and completely overlooked it’s significance…funny considering I’m an animator by trade. :stuck_out_tongue:

-Steve

dangit…i never know that AniMate is meant to do something like this… really cool and looks simple clean on the codes too…

I’m gonna play around with it, thx Adrian
maaaan… i learn something new everyday i visit this forum :smile: