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\$
  • 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 Dec 3 '17 at 0:25
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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.