public Vector3?GetTorque(FollowOrientation_Args e) { GetDesiredVector(out Vector3 unit, out float length, e, Direction); if (unit.IsNearZero()) { return(null); } float torque = Value; // Since this is copied into unity and inertia is a vector, just add directly to the rigid body as an acceleration //if (IsAccel) //{ // // f=ma // torque *= e.MomentInertia; //} if (IsSpring) { torque *= e.Rotation_Angle; } if (IsDrag) { torque *= -length; // negative, because it needs to be a drag force } // Gradient % if (Gradient != null) { torque *= GradientEntry.GetGradientPercent(e.Rotation_Angle, Gradient); } return(unit * torque); }
public void Tick() { if (_desiredOrientation == null) { return; } Quaternion rotation = Quaternion.FromToRotation(_body.rotation.ToWorld(_initialDirectionLocal), _desiredOrientation.Value); if (rotation == Quaternion.identity) // there might be some exotic torque definitions that only care about velocity. Just wait a frame and the diff won't be identity { return; } var args = new FollowOrientation_Args(_body.angularVelocity, rotation); // Call each worker foreach (var worker in _workers) { Vector3?localForce = worker.GetTorque(args); if (localForce == null) { continue; } ForceMode mode = worker.IsAccel ? ForceMode.Acceleration : ForceMode.Force; _body.AddTorque(localForce.Value * Percent, mode); } }
private static void GetDesiredVector(out Vector3 unit, out float length, FollowOrientation_Args e, FollowDirectionType direction) { switch (direction) { case FollowDirectionType.Drag_Velocity_Along: unit = e.AngVelocityAlongUnit; length = e.AngVelocityAlongLength; break; case FollowDirectionType.Drag_Velocity_AlongIfVelocityAway: unit = e.AngVelocityAlongUnit; length = Vector3.Dot(e.AngVelocityUnit, e.Rotation_Axis) < 0 ? e.AngVelocityAlongLength : 0f; break; case FollowDirectionType.Drag_Velocity_AlongIfVelocityToward: unit = e.AngVelocityAlongUnit; length = Vector3.Dot(e.AngVelocityUnit, e.Rotation_Axis) >= 0 ? e.AngVelocityAlongLength : 0f; break; case FollowDirectionType.Attract_Direction: unit = e.Rotation_Axis; length = e.Rotation_Angle; break; case FollowDirectionType.Drag_Velocity_Any: unit = e.AngVelocityUnit; length = e.AngVelocityLength; break; case FollowDirectionType.Drag_Velocity_Orth: unit = e.AngVelocityOrthUnit; length = e.AngVelocityOrthLength; break; default: throw new ApplicationException($"Unknown DirectionType: {direction}"); } }