Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by tcz8 · Dec 11, 2019 at 06:23 AM · animationnavigationthird person controllerstate-machinestate machine

What is the proper way to implement a 180 turn while running (Plant and turn) animation?

Hello, I'm kind of in bind here. We're entering a contest in the coming weeks and I still can't make our Plant And Turn (180 rotation while running) animation work properly.

I'm hoping someone with experience can help. It would mean a lot to fix this.

Our setup:
We use root motion for forward movement and the rotation is handled in script relative to the player's orientation and the screen.

The "inputMagnitude" parameter is used in a blend tree to define if the player is in "slow walk", "walk", "jog" or "run" animation and an euler angle rotation (0 and 360 being in front of the player) is pushed to the animator to trigger the plant and turn animations.

Here are the current "plant and turn" transition conditions:

Plant and turn left:
upload_2019-12-10_16-30-4.png

Plant and turn right:
upload_2019-12-10_16-29-44.png

For the exit transition "Has exit time" is checked and "Exit time" is set to 1
I realize they are some gaps in the RelativeEulerDir coverage but it's not what's causing my problems.

Problem 1:
I'm having problems making the end rotation of the "plant and turn" line up with user input. The animation's rotation does a fixed 180 turn and once the animation finishes if the user's input is not perfectly aligned the player's rotation appears to snap when it catches up to the input position.

Note that input driven rotation is disabled when in the "plant and turn" state and when transitioning in and out of it, which is part of the problem but I can't let both the input and the animation drive the rotation.

I tried several things to make it work:

  • Completely overriding the root rotation and letting the input drive it

  • Disabling the root rotation once RelativeEulerDir = 0

  • Disabling the root rotation once RelativeEulerDir <= toleranceValue (like 0.1, 1, 5)

  • Using a long transition time



I could try using the remaining animation time with the current rotation and the input to scale the animation's rotation so it ends flush with the input but that would create new problems like... what if the player changes direction radically?

Problem 2:
Triggering the plant and turn not always reliable. On the keyboard it's easier (the change in direction is quite direct) but when using a game pad it's another story. We have to flip the joystick in the opposite direction quite fast/hard for it to work otherwise the inputMagnitude drops too fast.

Lowering the inputMagnitude works but then users walking at a slower pace can initiate a plant and turn if they try real hard.

Adding a velocity check could fix this but the velocity I get from unity's character controller is quite jittery, almost seems like movement from the animations gets added on top.

FYI: We use Rewired, that's why you see player.GetAxis, but beside that it's the same as Unity's input.

All parameters are updated in Update().

Input is refreshed as follows:

 inputVector.x = player.GetAxis ("Horizontal");
 inputVector.y = player.GetAxis ("Vertical");
 inputVectorRaw.x = player.GetAxisRaw ("Horizontal");
 inputVectorRaw.y = player.GetAxisRaw ("Vertical");


Animation parameters are pushed using hashes:

 animator.SetFloat(hash_InputX, inputVector.x);
 animator.SetFloat(hash_InputY, inputVector.y);
 animator.SetFloat(hash_InputMagnitude, inputMagnitude);
 animator.SetFloat(hash_InputMagnitudeRaw, inputMagnitudeRaw);
 animator.SetFloat(hash_Velocity, currentVelocity);


This code handles rotation and sets the RelativeEulerDir:

 // Get targetDirection relative to the camera in world space (filtered input for keyboard)
 Vector3 targetDirection = Camera.main.transform.TransformDirection(new Vector3(inputVector.x, 0f, inputVector.y));
  
 // Get targetDirectionRaw relative to the camera in world space (raw input for accuracy with animator)
 Vector3 targetDirectionRaw = Camera.main.transform.TransformDirection(new Vector3(inputVectorRaw.x, 0f, inputVectorRaw.y));
  
 // Make sure Y is zeroed
 targetDirection.y = 0;
 targetDirectionRaw.y = 0;
  
 // Init target rotations
 Quaternion targetRotation = Quaternion.identity;
 Quaternion targetRotationRaw = Quaternion.identity;
  
 // Translate targetDirectionRaw to player's local space
 Vector3 playerRelativeTargetDirRaw = transform.InverseTransformDirection(targetDirectionRaw);
  
 // Get the target rotations required to rotate the player to the target directions
 if (targetDirection != Vector3.zero) targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
 if (playerRelativeTargetDirRaw != Vector3.zero) targetRotationRaw = Quaternion.LookRotation(playerRelativeTargetDirRaw);
  
 // Rotate the player transform
 transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, freeRunRotationSpeed * Time.deltaTime);
  
 // Inform the animator of the requested rotation
 animator.SetFloat(hash_RelativeEulerDir, targetRotationRaw.eulerAngles.y);


Can someone help?

Comment
Add comment
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

1 Reply

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

Answer by tcz8 · Dec 12, 2019 at 09:57 PM

Here are the solutions:

Problem 1

In a state machine behavior:

  1. Override and set to zero Y axis of the values you get from animator.deltaRotation.eulerAngles

  2. Apply the modified root rotation to your character using something like transform.Rotate(rotation)

In your character controller:

  1. Do the rotation manually using transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, customRotationSpeed * Time.deltaTime);

  2. Detect when the character is in transition to and out of your plant and turn

  3. Detect when the character is IN the plant and turn state

  4. Apply a custom rotation speed reserved just for the plant and turn

  5. Adjust the speed until its perfect

If you still have issues after this (animation looks weird) its believe it's because Quaternion.RotateTowards will always rotate to a target rotation using the shortest rotation possible. So sometimes it'll turn left other times it'll turns right.

I haven't implemented it yet but what you need to do is define if you need to turn left or right by detecting which transition you are in (plant and turn left or right) and the apply either negative or positive rotation until the target rotation is reached. You want to force the direction of the rotation until your are done transitionning out of the plant and turn anim (not just he state itself, you must detect the transitions!)

OR you can look into implementing your own Quaternion.RotateTowards. Use google, the source code is out there.

Problem 2

This fix was two fold:

  1. I Implemented a low pass filter on the values I push to the "velocity" animation parameter to filter out the noise (it was too noisy making it unreliable to trigger transitions). Here is the code: newVelocity = (charCtrl.velocity.magnitude * velocityLowPassFactor) + (prevVelocity * (1.0f - velocityLowPassFactor));

  2. I made sure we only set the RelativeEulerDir animation parameter when it is within range of the plant and turns and when we do set it, do not set it again for a configurable delay. The value was changing too fast making it hard to meet all the requited transition conditions

With all the parameters, speeds, delays and transition properly adjusted it now looks like this: https://youtu.be/RVnRhFQuzpA

Comment
Add comment · 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

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

299 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 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 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 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

Easier way of creating transitions in the animator? 1 Answer

Why does Unity animator makes calling children's SetActive fail? 0 Answers

Unity OnStateExit StateMachineBehaviour is never getting called 0 Answers

Can an empty state in Animator cause performance issues? 1 Answer

Mec Anim transition Bug? 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