// Updates our supported state to true with the new given normal. // Also updates our velocity to keep the same perpendicular speed // we had relative to our last support if we can move on this slope private void TransferSupport(Vector2 newSupportNormal, Vector2 netForce, bool allowWallRunning) { Vector2 forceDirection = netForce.normalized; Vector2 oldSupport = -forceDirection; if (supported) { oldSupport = supportNormal; } bool wasSliding = Sliding(); UpdateNormal(newSupportNormal, forceDirection, allowWallRunning, false); if (!supported || (!allowWallRunning && (sliding || wasSliding))) { // Remove movement in the direction of our normal vector float velocityIntoNormal = Vector2.Dot(velocity, newSupportNormal); if (velocityIntoNormal < 0.0f) { velocity -= velocityIntoNormal * newSupportNormal; } } else { // Move perpendicular to our normal in the same way we were moving // perpendicular to our last normal. float perpSpeed = Vector2.Dot(velocity, Vector2.Perpendicular(oldSupport)); Vector2 targetPerp = Vector2.Perpendicular(newSupportNormal); float velocityTowardsTransferDirection = Vector2.Dot(velocity, targetPerp); bool flipped = false; if (Mathf.Abs(velocityTowardsTransferDirection) > Mathf.Epsilon && Mathf.Sign(velocityTowardsTransferDirection) != Mathf.Sign(perpSpeed)) { targetPerp *= -1; flipped = true; } velocity = perpSpeed * targetPerp; data.MarkMomentumTransfer(oldSupport, supportNormal, perpSpeed * Vector2.Perpendicular(oldSupport), perpSpeed * targetPerp, flipped, velocityTowardsTransferDirection * Vector2.Perpendicular(newSupportNormal)); } }