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*;*
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 = currentSqrDistanceToInput;
angleDistancesToInput*=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().clip.name : “”)+” w=”+animationMixerPlayable.GetInputWeight(j));
}
#endif
return;
}
}
for (i = 0; i < numChildren; i++) {
//
//
childMotion = children*;*
//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*;*
currentAngleDistanceToInput=angleDistanceToInputSum * angleDistancesToInput*;*
//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().clip.name : “”)+” w=”+animationMixerPlayable.GetInputWeight(i));
}
#endif
RuntimeBlendTree blendTree = childMotion.subTree;
if (blendTree != null) {
blendTree.UpdateWeights(ref inputs, blendTree);
}
}
}