Hello! I am working on this game and I have discovered a bug in the crouching mechanics. I am using vector3.lerp to reduce the scale of the player in order to crouch (the player is a character controller with a hand attached to it so this is the easiest way). When the player crouches the movement is very smooth and silky (perfect!) but when he gets up it stutters horribly and overall just looks bad. See the crouch mechanic code below and any help is welcome!
Let’s simplify things, you will need to refactor your code, it’s a big mess.
For starters, let’s make it more readable, make two “constant” Vector3s:
private readonly Vector3 _crouching = new Vector3(1,0.5f,1);
private readonly Vector3 _standing = new Vector3(1,1,1);
Then replace the 12th line t this: transform.localScale = Vector3.Lerp(_standing, _crouching, elapse1/time_lerp);
and the 36th to this: transform.localScale = Vector3.Lerp(_crouching, _standing, elapse2/time_lerp);
Hi, I tried this, the problem remains. When the player crouches it’s smooth and nice, only when he gets up the movement is stuttery. Also this gameobject is the parent of the maincamera. Can it be that?
Okay so update. I managed to fix it by using vector3.smoothdamp but the function seems to not finish (stuck at 0.99999 and around there) and is constantly changing the velocity which does not allow my character to jump. How can I fix it?
Also, is it actually stuttery or is there just a snap when he stands? The various methods suggested here except for your initial one should not stutter, so I’m wondering maybe you mean something else?
See enclosed package. Supports toggle button or hold-to-crouch (see code).
Note how it does precisely what my first post above says.
Script here, full package attached:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// @kurtdekker - ultra simple crouch sequence, smooth and reliable.
public class Croucher : MonoBehaviour
{
public Transform ObjectToScale;
Vector3 StandingScale = new Vector3( 1, 1, 1);
Vector3 CrouchScale = new Vector3( 1, 0.5f, 1);
// this tweens between the two above values
float CurrentCrouchAlpha;
// and this is how fast it tweens (alpha per second)
float CrouchAlphaRate = 5.0f;
bool crouched;
// the ONLY output of this function should be to set the bool crouched
void GatherInputToggle()
{
// simple toggle, use two keys if you want, or a held key, doesn't matter
if (Input.GetKeyDown( KeyCode.C))
{
crouched = !crouched;
}
}
void GatherInputHold()
{
// straight reads the C key into crouched
crouched = Input.GetKey( KeyCode.C);
}
void ProcessCrouching()
{
// determine the alpha (terp between standing and crouched)
float DesiredCrouchAlpha = 0.0f; // means "standing"
if (crouched)
{
DesiredCrouchAlpha = 1.0f; // means "crouched"
}
// tween the alpha smoothly
CurrentCrouchAlpha = Mathf.MoveTowards(
CurrentCrouchAlpha,
DesiredCrouchAlpha,
CrouchAlphaRate * Time.deltaTime);
// drive the scale appropriately.
ObjectToScale.localScale = Vector3.Lerp(
StandingScale, // alpha of 0.0
CrouchScale, // alpha of 1.0
CurrentCrouchAlpha); // the alpha
}
void Update()
{
GatherInputToggle();
// uncomment this next line if you want "hold to stay crouched.
// GatherInputHold();
ProcessCrouching();
}
}