Hi @AlbinoRacoon, well, I took your question as a challenge to create a very generalized way of solving the problem. This is a little overkill for your problem, but not really - the problem is you can let go of the key at any time, so you don’t want it to snap back. Either way it should give you the idea even if don’t use the complete code:
One easy and very common way to get smooth animation is to employ a LERP - a “Linear Interpolation.”
There are several LERPs in unity, and they are are a handy way of finding values between a “from” value and a “to” value based on a fraction that represents the point in between the two.
The general form is LERP( from, to, fraction) .
Some examples:
LERP( 1, 2, 0.0 ) = 0
LERP( 1, 2, 0.5 ) = 1
LERP( 1, 2, 0.75 ) = 1.5
LERP( 1, 2, 0.9 ) = 1.8
and LERP( 1, 2, 1.0 ) = 2
You get the idea?
As long as the fraction is between 0 and 1 inclusive, LERP will return the correct value from the “from” value to the “to” value.
It is common to calculate the fraction based on the the current time of the animation divided by total amount of time that you want the animation to take.
So you have to decide how much time you want the crouch to take.
The code here uses ‘speed’ as the total time, and you need to enter into the inspector as well as the endPos - end Position. The startPos will use your camera’s current position as the start
Note this code will correctly animate even if you let go of the “S” key half way through the animation. To that end, we are employing Vecto3.Lerp instead of Mathf.Lerp which in your situation would might be faster but more difficult because, on the other hand, it does not LERP in negative directions - so we’d have to add more code for moving in the opposite direction.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Crouch : MonoBehaviour {
public float speed = 1f; // speed is the total time to crouch
public Vector3 endPos; // set the low position of the crouch
private Vector3 currentPos;
private Vector3 toPos;
private Vector3 fromPos;
private float currentTime;
private float currentTotalTime;
private float totalDistance;
private Vector3 startPos;
private void Start() {
currentTime = speed + 1; // make sure no LERP at start
currentTotalTime = speed;
startPos = transform.position;
currentPos = transform.position;
totalDistance = Vector3.Distance( endPos, startPos );
}
void Update() {
if( Input.GetKeyDown( KeyCode.S ) ) { // change to your keycode
toPos = endPos;
// this line of code ensures the correct LERP if you let go part way
// through a crouch, so calculate how far we are and convert to remaining time
currentTotalTime = Vector3.Distance( endPos, currentPos ) / totalDistance * speed;
fromPos = currentPos;
currentTime = 0;
}
if( Input.GetKeyUp( KeyCode.S ) ) {
toPos = startPos;
currentTotalTime = Vector3.Distance( startPos, currentPos ) / totalDistance * speed;
fromPos = currentPos;
currentTime = 0;
}
// do the LERP only if you press or let go of your key
if( currentTime <= currentTotalTime ) {
float timeRatio = currentTime / currentTotalTime;
currentPos = Vector3.Lerp( fromPos, toPos, timeRatio );
currentTime += Time.deltaTime;
transform.position = currentPos;
}
}
}
LERP on Dude (or Dudette, what ever your preference)!