How do i make crouching on 2 keys at the same time?

Hello.
I have a little problem while trying to make player crouching on 2 buttons, the thing is it pretty much works all good but when i try holding shift and pressing ctrl it does crouching twice, and since my player is teleporting -0.5f while crouching (and also shrinking by 0.5f while crouching) it kind of clips through wall a little bit and it just looks bad. Can i somehow make it so it ignores 1 key while other one is pressed?

crouching = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftShift); //tracks if crouching

if (Input.GetKeyDown(KeyCode.LeftControl) || Input.GetKeyDown(KeyCode.LeftShift))
		{
			if (Input.GetKeyDown(KeyCode.LeftControl) && !Input.GetKeyDown(KeyCode.LeftShift))
			{
				
			}
			else if (crouching)
			{
				StartCrouch();
			}

			if (Input.GetKeyDown(KeyCode.LeftShift) && !Input.GetKeyDown(KeyCode.LeftControl))
			{

			}
			else if (crouching)
			{
				StartCrouch();
			}
		}

		if (Input.GetKeyUp(KeyCode.LeftControl) || Input.GetKeyUp(KeyCode.LeftShift))
		{
			if (!crouching)
			{
				StopCrouch();
			}
		}

the “crouching = input.GetKey…” thing works all good and tracks it pretty much good, the stop crouch thing also works good, but when i hold CTRL and press SHIFT (or on the contrary holding shift and pressing CTRL) it does trigger the StartCrouch(); event which pretty much breaks everything…
Sorry for bad grammar.

EDIT: i fixed it by just adding a “isShifting” and “isCtrling” bools, and putting them in ifs. works kinda goofy but works! i still would like any tips on how to make it less wonky and more effiecent tho. Thanks.

heh heh… your instincts are good with this desire, for sure.

What you want is to separate gathering of the input from processing of it.

So basically gather LCtrl and LShift “GetKey()” values into a temporary variable:

private bool crouchIntent;
private bool previousCrouchIntent;

// and then in your Update:

// gather the raw intent, never deal with Input again after this
crouchIntent = Input.GetKeyUp(KeyCode.LeftControl() || Input.GetKeyUp(KeyCode.LeftShift);

// process raw intent into edge-triggered intents here
bool crouchWentDown = crouchIntent && !previousCrouchIntent;
bool crouchWentUp = !crouchIntent && previousCrouchIntent;

// now process edge-triggered intents

// Do all your decide logic here, based only on
// crouchWentDown, crouchWentUp, nothing else

The basic idea is that instead of a long bristly bush of logic that cares about what key is what for so much linear code distance, you instead gather, collapse, process and collapse then finally use the result.

It keeps the authorship and flow of the data (input) to the logic very clean.