Skip to content

Commit 8f01bf3

Browse files
dooly123claude
andcommitted
Include rotation in movement detection for foot blend
When turning on the spot, hips translate very little but rotate significantly. The speed calculation only used horizontal translation, so rotation kept blendWeight at 1.0 and feet stayed planted at their old positions instead of following the turn animation. Now angular velocity of the hips is converted to equivalent linear speed at foot level (angularSpeed * legLength) and added to the total speed. Rotation triggers the animation blend just like walking does, so feet follow the turning animation and re-plant at correct positions when the turn completes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 674b146 commit 8f01bf3

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

Basis/Packages/com.basis.framework/IK/FootPlacement/BasisLocalFootDriver.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class BasisLocalFootDriver
7979
// Blend weight: 0 = full animation, 1 = full ground placement
8080
float blendWeight = 1f;
8181
Vector3 lastHipsWorldPos;
82+
Quaternion lastHipsWorldRot;
8283

8384
// ===================== Public Results =====================
8485

@@ -210,6 +211,7 @@ public void Initialize()
210211
InitFootPose(rightState);
211212

212213
lastHipsWorldPos = hipsTransform.position;
214+
lastHipsWorldRot = hipsTransform.rotation;
213215
blendWeight = 1f;
214216

215217
initialized = true;
@@ -266,13 +268,26 @@ public void Update(
266268
if (!initialized || avatarTransform == null || hipsTransform == null) return;
267269
if (deltaTime <= 0f) return;
268270

269-
// --- Compute player speed from hips movement (horizontal only) ---
271+
// --- Compute player speed from hips movement + rotation ---
270272
Vector3 currentHipsPos = hipsTransform.position;
273+
Quaternion currentHipsRot = hipsTransform.rotation;
274+
271275
Vector3 hipsDelta = currentHipsPos - lastHipsWorldPos;
276+
float angleDelta = Quaternion.Angle(lastHipsWorldRot, currentHipsRot);
277+
272278
lastHipsWorldPos = currentHipsPos;
279+
lastHipsWorldRot = currentHipsRot;
280+
281+
// Horizontal translation speed
282+
float linearSpeed = new Vector2(hipsDelta.x, hipsDelta.z).magnitude / deltaTime;
283+
284+
// Angular speed converted to equivalent foot-level linear speed:
285+
// how fast the feet move in a circle when the body rotates in place
286+
float avgLegLen = (leftState.totalLegLen + rightState.totalLegLen) * 0.5f;
287+
float rotationalSpeed = (angleDelta * Mathf.Deg2Rad * avgLegLen) / deltaTime;
273288

274-
// Horizontal speed only (ignore vertical movement from crouching/jumping)
275-
float playerSpeed = new Vector2(hipsDelta.x, hipsDelta.z).magnitude / deltaTime;
289+
// Combined speed: either translation or rotation triggers animation blend
290+
float playerSpeed = linearSpeed + rotationalSpeed;
276291

277292
// --- Compute blend weight: 0 = full animation, 1 = full ground placement ---
278293
float targetWeight = 1f - Mathf.InverseLerp(idleSpeedThreshold, walkSpeedThreshold, playerSpeed);

0 commit comments

Comments
 (0)