2
\$\begingroup\$
private bool hitted = false;
private Vector3 hitPosition;

private void Test()
    {
        RaycastHit hit;

        if (Physics.Raycast(start.position, Vector3.left, out hit, 1.5f)
             || Physics.Raycast(start.position, Vector3.right, out hit, 1.5f)
             || Physics.Raycast(start.position, Vector3.forward, out hit, 1.5f))
        {
            if (hit.transform.tag == "Test")
            {
                hitted = true;
                hitPosition = hit.transform.localPosition;
            }
        }
    }

    private void Update()
    {
        if (hitted == true)
        {
            player.localRotation = Quaternion.Lerp(player.localRotation, Quaternion.LookRotation(hitPosition), 1 * Time.deltaTime); 
        }
    }

What i want to detect is when the player finished rotating and then set back hitted to false.

\$\endgroup\$
1
  • 5
    \$\begingroup\$ The particular form of Lerp you've used here is an exponential ease-out - that means, mathematically, it never really "finishes" - it just gets closer and closer and closer to the target, slowing down as it goes. So, you can either test when the rotation has gotten "close enough," or switch to a form that completes the rotation in some fixed amount of time. What works better for your use case? \$\endgroup\$
    – DMGregory
    Commented Dec 3, 2017 at 0:25

2 Answers 2

6
\$\begingroup\$

You can check when your rotation has gotten "close enough" using a quaternion dot product, like so:

private void Update()
{
    if (hitted == true)
    {
        Quaternion targetRotation = Quaternion.LookRotation(hitDirection);

        // Ensure we're correctly compensating for variable framerate
        float sharpness = 0.1f;
        float blend = 1f - Mathf.Pow(1f - sharpness, 30f * Time.deltaTime);

        player.localRotation = Quaternion.Lerp(player.localRotation, targetRotation, blend); 

        // A Quaternion dot product gives you the cosine of the angle
        // between the rotations. Closer to 1 = more similar.
        if(Quaternion.Dot(transform.rotation, targetRotation) > 0.9999f) {
            // Now we're within 1 degree of the target rotation.
            // Put your "arrived" code here.
        }
    }
}

Or, if you don't need to precisely control the exact threshold you want to use, Unity's default == operator on quaternions includes a little wiggle room, so in many cases you can even just test:

if (player.localRotatiin == targetRotation)
\$\endgroup\$
0
\$\begingroup\$

You can just use the t Time. Instead of writing 1 * Time.deltaTime just make 4 fields, LerpTime, CurrentLerpingTime, Speed, T;

Then check whether the T is more than or equal to 1, if it is then the lerp has finished!.

private float LerpTime = 1.0f;
private float CurrentLerpingTime;
private float Speed = 25f;

private void Update(){

   ......

   if(hitted == true){

      CurrentLerpingTime = Mathf.Clamp01(CurrentLerpingTime + (speed * Time.deltaTime));          

      t = CurrentLerpingTime / LerpTime;

      player.localRotation = Quaternion.Lerp(player.localRotation, Quaternion.LookRotation(hitPosition), t);

      if(t >= 1){
        Debug.Log("Lerping Has Finished!");
      }
   }
}
\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .