• 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 /
  • Help Room /
avatar image
Question by winxalex · Jun 22, 2016 at 09:53 AM · animationblendingblendtree

How weights of 2D Blending are calculated?

![alt text][1]Could you share information about how weights of 2D Blending are calculated. I've done 1D Blending. but have problems with 2D Freeform Cartesian. Even pseudo code sharing will be of help.

I also found function

 public static extern void CalculateRootBlendTreeChildWeights (Animator animator, int layerIndex, int stateHash, float[] weightArray, float blendX, float blendY);

but is in namespace UnityEditorInternal.

Thx

Example. Circles around Motion.positions are weights. How they are calculated? What algorithm is used. [1]: /storage/temp/72664-screen-shot-2016-06-22-at-120911-pm.png

screen-shot-2016-06-22-at-120911-pm.png (116.5 kB)
Comment

People who like this

0 Show 0
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

3 Replies

  • Sort: 
avatar image
Best Answer

Answer by runevision · Jun 27, 2016 at 03:30 PM

The 2D Freeform Cartesian blend type is based on the Gradient Band interpolation described in chapter 6.3 of my Master's Thesis.

The 2D Freeform Directional blend type is based on the Gradient Bands in Polar Space interpolation described in chapter 6.3.1.

A PDF version of my thesis is available here: http://runevision.com/thesis/

Comment
Baste
Propagant

People who like this

2 Show 0 · 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

Answer by SarperS · Jun 22, 2016 at 10:07 AM

One example is, say you want to blend between 4 different animations for your character's horizontal movement (forward, back, left strafe, right strafe). What you do is, you take the character's velocity, transform it into character's local transform space, normalize it. It gives you a velocity vector relative to the character's direction, a vector where you can see where the body is moving towards relative to the direction it faces, so you can tell if it's strafing or moving backwards etc.

So you feed this resulting vector into your 2D blending tree with the 4 animations set up correctly at Forward (Y:1) Backward (Y:-1) Right (X+1) Left (X-1) and it blends between those 4 animations. If the relative velocity vector is (0.5, 0, 0.5) the animation forward and right strafe will both play at 0.5 blend weight (If you set the max blending values at 1.0 that is).

Comment

People who like this

0 Show 0 · 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

Answer by winxalex · Jun 22, 2016 at 08:31 PM

alt text

I think u are speaking about 2D Simple Directional, and I was more interested to FreeForm and Cartesian flavour, but even this if you experiment with red dot can see that blue points weights depend of distance to red dot(input) and also I think to angular distance. So if we use Formula 1/d1/(1/d1+1/d2+1/d3...) d1 can be just distance or combination of distance + angular distance....

  void UpdateSimpleDirectional2D(ref float[] inputs, RuntimeBlendTree runtimeBlendTree) {
             int numChildren;
 
             if (runtimeBlendTree.children == null || (numChildren = runtimeBlendTree.children.Length) == 0)  return;
 
 
             AnimationMixerPlayable animationMixerPlayable = runtimeBlendTree.mixerPlayable;
 
             if (numChildren == 1) {
                 animationMixerPlayable.SetInputWeight(0, 1f);
             }
 
 
 
 
             __inputVector2.x = inputs[runtimeBlendTree.index0];
             __inputVector2.y = inputs[runtimeBlendTree.index1];
 
 #if DEBUG
 
             //__inputVector2.x=0.5f;
 
             if(showLog){
             Debug.Log("RuntimeBlendTree "+runtimeBlendTree+" "+runtimeBlendTree.blendType+" numChildren="+runtimeBlendTree.children.Length);
             Debug.Log("Input Vector: "+__inputVector2);
 
             }
             #endif
 
 
             //FORMULA  // 1/dc /(1/di+1/di+1+1/dc+..1/dn)
             //dc - distance of "c" point to "input" point
 
             //FORMULA  // 1/ac /(1/ai+1/ai+1+1/ac+..1/an)
             //ac - angular distance of "c" point to "input" point
 
 
             float[] sqrDistancesToInput = new float[numChildren];
             float[] angleDistancesToInput = new float[numChildren];
 
             int i = 0;
             float weight = 0f;
             float currentSqrDistanceToInput;
             float currentAngleDistanceToInput;
             float sqrDistanceToInputSum = 0f;
             float angleDistanceToInputSum = 0f;
             RuntimeChildMotion childMotion;
 
 
             //calculate distances of every childMotion.position to input
             for (; i < numChildren; i++) {
                 childMotion = children[i];
 
                 currentSqrDistanceToInput = (__inputVector2 - childMotion.position).sqrMagnitude;
 
                 if (currentSqrDistanceToInput > 0) {
 
                     //??? Could I bind together this distances together??
 
                     //currentAngleDistanceToInput=Vector2.Angle(__inputVector2,childMotion.position);
 
 
                     //cosinus similarity from -1f to -1f shifted to 0 to 1f( same angle cosinus similarity=0f and max opposite direction -1f)
                     currentAngleDistanceToInput=(Mathf.Clamp(Vector2.Dot(__inputVector2.normalized,childMotion.position.normalized),-1f,1f)-1f)*(-0.5f);
 
                     // 1/d1+1/d2+1/d3...
                     sqrDistanceToInputSum+=1/currentSqrDistanceToInput;
 
 
                     if(currentAngleDistanceToInput>0)
                     angleDistanceToInputSum+=1/currentAngleDistanceToInput;
 
 
 
                     sqrDistancesToInput[i] = currentSqrDistanceToInput;
 
                     angleDistancesToInput[i]=currentAngleDistanceToInput;
 
                 }
                 else {
                     //input is same with childMotion.position
 
 
 
                     //reset all to  min weight
                     for (int j = 0; j < numChildren; j++) {
 
 
                         animationMixerPlayable.SetInputWeight(j, 0f);
                     }
 
                     //maximum weight of playable channel where input(value/position) and childMotion.position overlapped
                     animationMixerPlayable.SetInputWeight(i, 1f);
 
 
 
 #if DEBUG
 
                     if(showLog){
                     for (int j = 0; j < numChildren; j++)
 
                     Debug.Log(j+": "+((Playable.GetTypeOf(animationMixerPlayable.GetInput(j)) is AnimationClipPlayable) ? animationMixerPlayable.GetInput(j).CastTo<AnimationClipPlayable>().clip.name : "")+" w="+animationMixerPlayable.GetInputWeight(j));
 
 
                     }
                 #endif
 
                     return;
                 }
 
             }
 
 
             for (i = 0; i < numChildren; i++) {
                 //
                 //
                 childMotion = children[i];
 
 
 
 
                 //reuse currentSqrDistanceToInput var
 
                 // 1/d1 /(1/d1+1/d2+..1/dn)/1 => 1/(d1*(1/d1+1/d2+..1/dn))
 
                 //(d1*(1/d1+1/d2+..1/dn))
                 currentSqrDistanceToInput = sqrDistanceToInputSum * sqrDistancesToInput[i];
                 currentAngleDistanceToInput=angleDistanceToInputSum * angleDistancesToInput[i];
 
                 //1/(d1*(1/d1+1/d2+..1/dn))
                 if(currentSqrDistanceToInput>0 && currentAngleDistanceToInput>0)
                     weight = (1 / currentSqrDistanceToInput)*0.5f + (1/currentAngleDistanceToInput)*0.5f;
                 else if(currentSqrDistanceToInput>0)
                     weight = (1 / currentSqrDistanceToInput)*0.5f + 0.5f;//have same direction so 0.5f 
                 else
                     weight=0;
 
                 animationMixerPlayable.SetInputWeight(i, weight);
 
 
 
 #if DEBUG
 
                 if(showLog){
                 Debug.Log(i+": "+((Playable.GetTypeOf(animationMixerPlayable) is AnimationClipPlayable) ? animationMixerPlayable.CastTo<AnimationClipPlayable>().clip.name : "")+" w="+animationMixerPlayable.GetInputWeight(i));
 
                 }
                 #endif
 
                 RuntimeBlendTree blendTree = childMotion.subTree;
 
                 if (blendTree != null) {
                     blendTree.UpdateWeights(ref inputs, blendTree);
                 }
             }
         }



screen-shot-2016-06-22-at-34232-pm.png (148.9 kB)
Comment

People who like this

0 Show 0 · 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

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

103 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

Related Questions

Animations on a tilemap mesh and blending between different tiles 0 Answers

Where i should add some unusual animations in mecanim? 0 Answers

i have stuck on this blendtree animations driverik steering wheel hands 2 Answers

Blending lower body and upper body animations 0 Answers

How to make players upper body look at the mouse direction, while lower body plays forward,backward or side ways strafe accordingly ? 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