Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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 vexe · Aug 15, 2014 at 12:53 PM · animatormecanimaim

Very peculiar aiming issue - OnAnimatorMove()

So I'm ripping my hair off atm (what's left of it)

Basically I have 3 aim animations that I blend together to create smooth straight/up/down aiming. And I have a 'gunTip' transform at the tip of the character's gun. The 'forward' of the tip is coming out of the gun's barrel. This is where I shoot from.

When I fire, I cast a ray from the tip with the tip's forward being the direction. The animations are handled from script (not root motion). For some reason, if I call the shoot method from OnAnimatorMove, the raycast doesn't seem to want to follow the tip's forward when I aim up/down!

I made a video showing the problem, my code, and the two different aid-band fixes I made.

  1. The first fix is calling TryShoot from the PlayerController's Update, and not OnAnimatorMove, it worked pretty well, but of course without an animation.

  2. The second fix, just to prove that the animation has nothing to do with the problem, I created a tipFwd Vector3 in Weapon, and assigned it to the gun's tip in Update, and used that variable when I do raycast.

The first fix actually produces more accurate results than the second. Notice in my OnDrawGizmos I draw a red sphere (which I get its position from the shooting hit point) and a yellow sphere which I draw from the hit point I get from raycasting in OnDrawGizmos. What drives me crazy is that I'm using the "SAME" raycast both when I shoot and OnDrawGizmos, yet the red sphere doesn't appear where it should, while the yellow one is placed appropriately....

Here's my PlayerController's Update and OnAnimatorMove:

     private void Update()
     {
         if (animator)
         {
             animator.speed = animationSpeed;
             animator.SetFloat("Speed", Input.GetAxis("Vertical"));
             animator.SetBool("IsAiming", Input.GetMouseButton(1));
             animator.SetBool("IsRunning", Input.GetKey(KeyCode.LeftShift));
         }
         transform.Rotate(0f, Input.GetAxis("Horizontal") * Time.deltaTime * rotationSpeed * 100f, 0f);
     }

     private void OnAnimatorMove()
     {
         var baseLayer = animator.GetCurrentAnimatorStateInfo(0);
         var secondLayer = animator.GetCurrentAnimatorStateInfo(1);
         Func<int, bool> baseIsInState = hash => baseLayer.nameHash == hash;
         Func<int, bool> secondLayerIsInState = hash => secondLayer.nameHash == hash;

         bool isAiming = Input.GetMouseButton(1) && secondLayerIsInState(aimState);

         if (isAiming)
         {
             if (!resetAim)
             {
                 resetAim = true;
                 animator.SetFloat("AimY", 0f);
             }
             animator.SetFloat("AimY", Mathf.Clamp(animator.GetFloat("AimY") + Input.GetAxis("Mouse Y"), -1f, 1f));
             animator.SetBool("IsShooting", Input.GetMouseButton(0) && weapon.TryShoot());
         }
         else
         {
             resetAim = false;
         }

         // Movement...
     }


And here's my Weapon's Shoot/TryShoot:

     public bool TryShoot()
     {
         if (shooting conditions are not met)
         {
             return false;
         }

         Shoot();
         return true;
     }

     private void Shoot()
     {
         // Sound, muzzle and ammo decreasing...

         RaycastHit hit;
         if (Physics.Raycast(gunTip.position, gunTip.forward, out hit, Distance, shootingMask))
         {
             dbgLastShot = hit.point; // this is how I determine the red sphere's position
             // irrelevant code...
         }
     }

The problem doesn't make any sense to me... But I have a good amount of certainty that it's a gotcha related to Animator/Mecanim and/or OnAnimatorMove... If you have any idea I'd really appreciate it!

Thanks a lot!

Comment
Add comment · Show 6
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 vexe · Aug 15, 2014 at 01:12 PM 0
Share

Although shooting from Update ins$$anonymous$$d of OnAnimator$$anonymous$$ove is a sort of an acceptable band-aid fix, but I would love to know/understand what's happening, and why...

avatar image Scribe · Aug 15, 2014 at 01:53 PM 0
Share

perhaps it is just to do with the animation starting before the raycast is sent. You are more knowledgable than me about this I expect but could you try yielding the result of Shoot() in TryShoot() before returning true or is that done automatically when you put them in that order:

 //pseudo
 yield Shoot();
 return true;

Or perhaps passing the gunTip.forward to TryShoot() when you call it at line 30 in your first script

 animator.SetBool("IsShooting", Input.Get$$anonymous$$ouseButton(0) && weapon.TryShoot(gunTip.position, gunTip.foward));

with the additional changes in the other scripts.

avatar image vexe · Aug 15, 2014 at 02:28 PM 0
Share

Hi @Scribe thanks for your input!

perhaps it is just to do with the animation starting before the raycast is sent

That's incorrect;

 animator.SetBool("IsShooting", weapon.TryShoot());

The value of weapon.TryShoot() is passed as an argument to SetBool so it's first calculated. The value returned is used as the value for "IsShooting"

I've tried yielding, but no dice.

I'll try to pass the position and direction to TryShoot, although I'm not a fan of that syntax...

avatar image Scribe · Aug 15, 2014 at 09:40 PM 0
Share

Yeah I realised that would probably be the case, after watching your video a few more times it looks like the gunTip (and probably other objects) are somehow set to default values, I thought when I had watched it before that the spot was always higher than the shot but I notice that's not the case it is simply always directly forward on the x/z axis, though the rotation around y seems to be correct. It is indeed very peculiar, sorry I can be of much help, I'd be interested to know what the issue is if you solve it, perhaps a bug report to unity would be worth a try!

Scribe

P.S. Do you have any links to tutorials or reading about the Func <,> syntax, I probably should know it but as I'm self taught there is no structure to my knowledge :P

P.P.S sorry for the grammar, wiring on my phone!

avatar image meat5000 ♦ · Aug 15, 2014 at 10:06 PM 0
Share

OnAnimator$$anonymous$$ove - ( OA$$anonymous$$() )

This callback will be invoked at each frame after the state machines and the animations have been evaluated

In OnAnimator$$anonymous$$ove you are actually setting parameters of the Animator. So, the Animator will be re-evaluated before the changes occur. This could be resetting your Late changes to Root $$anonymous$$otion.

There is a mismatch between what you expect and what you get as a result.

Try moving the bones transform in OA$$anonymous$$() ins$$anonymous$$d of moving via Animator from OA$$anonymous$$() and see if this still happens.

OnAnimator$$anonymous$$ove is for making direct changes to transforms, essentially; not for making loop-backs to the Animator.

Show more comments

1 Reply

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

Answer by meat5000 · Aug 16, 2014 at 03:02 PM

I refer you back to the InPlace page. Notice how simple they have kept it, modifying transforms only. It is perfectly fine to Get parameters from the Animator but Setting them here is not a good idea, as far as I know.

In OAM() you can directly modify the transform of a bone. For example rotating the spine, arms etc to re-position them as desired. I did this same thing to make custom IK in Free Edition, so I could swing a sword and always cut through a particular point in space (or target).

Comment
Add comment · Show 5 · 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 vexe · Aug 16, 2014 at 05:41 PM 0
Share

Alright I guess, lesson learned.

avatar image meat5000 ♦ · Aug 16, 2014 at 06:20 PM 0
Share

No problem. Lets keep this open a while; hopefully someone out there will have more information/experience on what IS possible in OnAnimator$$anonymous$$ove. Added the function name to the title, hope you don't $$anonymous$$d.

avatar image vexe · Aug 16, 2014 at 10:17 PM 0
Share

Sure. Do you want me to untick your answer for the time being?

avatar image meat5000 ♦ · Aug 17, 2014 at 11:55 AM 0
Share

Depends if you use it in solving your problem :) I'm indifferent; just glad to help.

avatar image vexe · Aug 17, 2014 at 12:56 PM 0
Share

Thanks! I think I'll leave it. I'm not setting params in OA$$anonymous$$ everything's fine so far :)

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.

Follow this Question

Answers Answers and Comments

23 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

Related Questions

Best Way to script Mecanim Animation CrossFade? 0 Answers

16 identical Mecanim Animator errors....why? 2 Answers

Mecanim Animate Physics - When to use? 0 Answers

Macanim Mouse Buttons interaction c# 1 Answer

Animator MatchTarget Problem 0 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