private void FixedUpdate() { PhysicsBallAnchor anchor = GetClosestAnchor(); if (!anchor) { UpdateAnimationWeight(-5); return; } Vector3 ballPosition = ballRigidbody.position; Vector3 vectorToBall = ballPosition - anchor.targetPosition; float distanceToBall = vectorToBall.magnitude; Vector3 normalToBall = vectorToBall.normalized; float distanceRatio = Mathf.Clamp01(distanceToBall / anchor.radius); Vector3 velocity = ballRigidbody.velocity; Vector3 force = -normalToBall * anchor.pullForce * distanceRatio; force += -Physics.gravity; velocity += force * Time.fixedDeltaTime; velocity /= 1.0f + anchor.damper * Time.fixedDeltaTime; ballRigidbody.velocity = velocity; Vector3 angularVelocity = ballRigidbody.angularVelocity; Quaternion anchorRelativeRotation = Quaternion.Inverse(anchor.transform.rotation) * transform.rotation; Vector3 anchorRelativeEulerAngles = anchorRelativeRotation.eulerAngles; Vector3 correctionTorque = new Vector3(); correctionTorque.x = Mathf.DeltaAngle(anchorRelativeEulerAngles.x, 0); correctionTorque.y = Mathf.DeltaAngle(anchorRelativeEulerAngles.y, 0); correctionTorque.z = Mathf.DeltaAngle(anchorRelativeEulerAngles.z, 0); correctionTorque = anchor.transform.TransformDirection(correctionTorque); angularVelocity += correctionTorque * Mathf.Deg2Rad * anchor.angularCorrection * Time.fixedDeltaTime; angularVelocity /= 1.0f + anchor.angularDamper * Time.fixedDeltaTime; ballRigidbody.angularVelocity = angularVelocity; if (velocity.magnitude < 1.0) { UpdateAnimationWeight(1); } }
private PhysicsBallAnchor GetClosestAnchor() { anchors.RemoveWhere(v => !v); PhysicsBallAnchor best = null; float bestDist = Mathf.Infinity; foreach (var anchor in anchors) { float dist = Vector3.Distance(anchor.transform.position, transform.position); if (dist < bestDist) { best = anchor; bestDist = dist; } } return(best); }