• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by UnityNoob123 · Mar 08, 2018 at 06:45 AM · lerpnot workingoffsetquaternions

Another Quaternion.lerp Question

Hey, thanks for checking out my question. I am trying to do gun recoil with my camera so I am using quaternion.lerp, (not slerp because I want it to be linear), and when the player shoots I have the camera lerp to a quaternion that is the cameras local rotation being multiplied by a recoil value. This seems to work fine but I want the camera to come back to the rotation in which the player started shooting. So I also store the cameras local rotation when the player starts shooting, and then when they are done shooting I call a function to lerp the camera back to its initial rotation. I am having a problem where there seems to be an offset in which the camera is stopping 0.4 units before the initial rotation. This offset seems to be inconsistent as well but its around 0.4 units every time. Not sure why it would not be the same value every time or why it stops short in the first place. Ive been messing with it for a week now and still have not found what I am doing wrong. I will provide my code down below and thank you for the help in advance!

 void Update () {
         if (Input.GetKeyUp(KeyCode.Mouse0) && timeShooting > 0 || bulletsInMag <= 0 && Input.GetKeyUp(KeyCode.Mouse0)) {
             StartCoroutine(RecoverRecoil());
         }
         if (Input.GetKeyDown(KeyCode.Mouse0)) {
             initialShotRot = cam.transform.localRotation;
             recoilFinishRot = initialShotRot * Quaternion.Euler(maxRecoil, 0, 0);
         }
     }
 
 //Technically does not need to be in a Ienumerator currently 
 IEnumerator recoiling () {
         timeShooting += 1;
         float recoil = 1f;
         while (recoil > 0) {
             cam.transform.localRotation = Quaternion.Lerp(cam.transform.localRotation, recoilFinishRot, 0.1f);
             recoil -= 1f;
             if (Input.GetKeyUp(KeyCode.Mouse0) || bulletsInMag <= 0) {
                yield break;
             }
             yield return null;
         }
     }
     
     IEnumerator RecoverRecoil() {
         while (timeShooting > 0f) {
             cam.transform.localRotation = Quaternion.Lerp(cam.transform.localRotation, initialShotRot , 1f); //its 1 for testing purposes
             timeShooting -= 0.25f;
             yield return null;
         }
         timeShooting = 0;
     }

 

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image rightdroid · Mar 08, 2018 at 09:33 AM 1
Share

What exactly is timeShooting, and is it at any point anything above 1? You could print(); it before while loop in RecoverRecoil. Also, not exactly sure about the logic, but you might need to put "&& timeShooting <= 0" as an additional condition in the second if statement:

     if (Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.$$anonymous$$ouse0) && timeShooting > 0 || bulletsIn$$anonymous$$ag <= 0 && Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.$$anonymous$$ouse0)) {
      StartCoroutine(RecoverRecoil());
  }
  if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.$$anonymous$$ouse0) && timeShooting <= 0) {
      initialShotRot = cam.transform.localRotation;
      recoilFinishRot = initialShotRot * Quaternion.Euler(maxRecoil, 0, 0);
  }

so that you don't record the initial rotation on every Get$$anonymous$$eyDown (in the middle of lerping from previous shot or something like that).

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Harinezumi · Mar 08, 2018 at 11:20 AM

Hi,
where exactly is recoiling() called? In the code you shared it is not shown. I ask this, because I think what probably causes the bug is recoiling() and RecoverRecoil() executing in the same frame, but not always in the same order. Another possible source of the bug is that the global rotation of the camera (`camera.transform.rotation`) is modified somewhere else, e.g. in a mouse look script.

If you don't mind some advice, some other things that could cause bugs:
- as rightdroid commented, in case the player shoots again before RecoverRecoil() finishes, you will start another Lerp to an angle between. To avoid this, you can store the result of StartCoroutine() in a variable type Coroutine and before starting RecoverRecoil(), if it is not null, call StopCoroutine().
- you check mouse button down and up separately, and store rotation to recover to on button down. What if the player holds the button and turns 180 degrees, then releases? Instead, I would store the rotation to recover to just before stating RecoverRecoil() coroutine
- you don't have to store initialShotRot as a variable in the class, you can just pass it to the RecoverRecoil() coroutine as parameter (less variables in class, less possibility of reusing an outdated value)

Finally, I'm not sure it is a good idea from gameplay point of view to take away control from the player and automatically compensate for recoil. In most games the player has to manually recover from recoil and it adds to immersion (you feel the weight of the shot more). Of course, it could be an important element of your game, in which case just ignore this comment :)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image UnityNoob123 · Mar 08, 2018 at 05:25 PM 1
Share

Thanks for the great answer!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

78 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

[SOLVED] Rotation/angled offset in Quaternion.Lerp for a carried GameObject 2 Answers

Copy rotation of targetObject to current object with an influence in the range from 0-1. 0 Answers

Color.Lerp not lerping 2 Answers

How to use Lerp? 1 Answer

Need help rotating the inside of a cube correctly (lerp gets me mid-way there) 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges