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 /
  • Help Room /
avatar image
0
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
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

3 Replies

· Add your reply
  • Sort: 
avatar image
2
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
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
avatar image
0

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
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
avatar image
0

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

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

Animation plays by itself in regular state, once combined with blend tree not working 0 Answers

Animation sinks player into the ground 1 Answer

Create Idle/Walk/Run Blendtree 1 Answer

How to prevent colliders animating between animation states? Also prevent rotation on x axis of blend tree. 0 Answers

How can i blend two(or more) animations like a blend tree, but only with scripts? 1 Answer


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