- Home /
Lerp 180 degrees while holding B and lerp back 180 degrees when let go of B.
Hey guys. I am trying to make it so that the player turns around 180 degrees (in a lerping fashion) when holding down B and turns back around (also in a lerping fashion) when let go of B. So far the first half works. The player turns around 180 degrees and stays in that direction as long as he holds B, but when he lets go the player instantly goes back to his starting rotation, and doesn't lerp back like I want it to. I don't know what is wrong with my function. (Btw all seemingly undeclared variables are actualy global variables. In case you were wondering.)
void TurnAroundLerp()
{
if (Input.GetButtonUp("B") == false)
{
if (Input.GetButtonDown("B"))
{
turnAroundStartRotation = transform.rotation;
turnAroundTargetRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + 180, transform.rotation.eulerAngles.z);
turnAroundStartTime = Time.time;
turnAroundCurrentTime = turnAroundStartTime;
}
else if (Input.GetButton("B"))
{
turnAroundCurrentTime += Time.deltaTime;
percentageDone = (turnAroundCurrentTime - turnAroundStartTime) / turnAroundLerpTime;
if (percentageDone < 1f)
{
transform.rotation = Quaternion.Lerp(turnAroundStartRotation, turnAroundTargetRotation, percentageDone);
}
else
{
Quaternion targetRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + 180, transform.rotation.eulerAngles.z);
transform.rotation = targetRotation;
}
}
}
else if (Input.GetButtonUp("B") == true)
{
percentageDone = 0;
turnAroundStartRotation = transform.rotation;
turnAroundTargetRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + 180, transform.rotation.eulerAngles.z);
turnAroundStartTime = Time.time;
turnAroundCurrentTime = turnAroundStartTime;
while (percentageDone < 1)
{
Debug.Log(percentageDone);
turnAroundCurrentTime += Time.deltaTime;
percentageDone = (turnAroundCurrentTime - turnAroundStartTime) / turnAroundLerpTime;
transform.rotation = Quaternion.Lerp(turnAroundStartRotation, turnAroundTargetRotation, percentageDone);
}
}
}
Answer by kevojo · Sep 19, 2018 at 09:17 PM
There are a lot of things you're doing here that I don't understand why. Why would you check every frame if the button wasn't released before making all those calculations? If the "getButtonUp' was true, there's no way "getButton" or "getButtonDown" could ever be true in the same frame, even if it wasn't embedded under that condition. Also when you say "If (Statement == true)", you don't need to say "else if (statement == false" - simply saying "else" is the same thing when it's a binary condition.
As for rotating the character - I think you might be overthinking this one a little bit (although I don't know how you are controlling rotation passively, so I don't know what you are working around. The simplest way I can think of to do this would be to have two external transforms, one aiming forward, one aiming backwards.
void AimTransforms (Transform FwdAim, Transform BckAim)
{
FwdAim.localEulerAngles = new Vector3(0, mainCamera.transform.y,0);
BwdAim.LocalEulerAngles = new Vector3(0, mainCamera.Transform.y+180, 0);
}
Then, use two lerp speeds, one for when the player is changing direction, one for when the player is matching the camera.
bool ChangingDirection;
bool AimForward
float TurnSpeed; //the slower speed
float AimSpeed; // the faster, almost instantaneous speed
void CheckAimDir()
{
if Input.getKey(Keycode.B)
{
AimForward = false;
if (Vector3.angle(player.transform.forward, BckAim, player.transform.up) > 1)
{
ChangingDirection = true;
}
else
{
ChangingDirection = false;
}
}
else
{
AimForward = true;
if (Vector3.angle(player.transform.forward, FwdAim, player.transform.up) > 1)
{
ChangingDirection = true;
}
else
{
ChangingDirection = false;
}
}
}
For there, you just have to check the "Changing direction" bool to decide whether to use the fast/instantaneously matching camera lerp, or the slow, turning backwards/forwards lerp.
void CalculateTurn()
{
float Speed;
if (ChangingDirection)
{
Speed = TurnSpeed;
}
else
{
Speed = AimSpeed;
}
if (AimForward)
{
player.transform.rotation = Quaternion.lerp(player.transform.rotation, FwdAim.rotation, Speed*Time.deltaTime);
}
else
{
player.transform.rotation = Quaternion.lerp(player.transform.rotation, BwdAim.rotation, Speed*Time.deltaTime);
}
}
Answer by Hellium · Sep 19, 2018 at 09:33 PM
using UnityEngine;
public class Rotate : MonoBehaviour
{
public float RotationSpeed = 1;
public KeyCode RotateKey = KeyCode.B ;
private Quaternion startRotation ;
private Quaternion endRotation ;
private Quaternion initialRotation ;
private Quaternion flippedRotation ;
private float rotationProgress ;
void Start()
{
initialRotation = startRotation = endRotation = transform.rotation ;
flippedRotation = Quaternion.Euler( 0, 180, 0 ) * transform.rotation ;
rotationProgress = 1 ;
}
void Update()
{
TurnAroundLerp();
}
void TurnAroundLerp()
{
if( Input.GetKeyDown( RotateKey ) )
{
startRotation = initialRotation ;
endRotation = flippedRotation ;
rotationProgress = 1 - rotationProgress;
}
else if( Input.GetKeyUp( RotateKey ) )
{
startRotation = flippedRotation ;
endRotation = initialRotation ;
rotationProgress = 1 - rotationProgress;
}
rotationProgress = Mathf.Clamp01( rotationProgress + RotationSpeed * Time.deltaTime ) ;
transform.rotation = Quaternion.Slerp( startRotation, endRotation, rotationProgress ) ;
}
}