//Performs realistic motion control private void UpdateRealistic() { if (Time.deltaTime == 0f) { return; } //Compute Current Error CurrentError = TargetValue - CurrentValue; //Minimum distance to stop: s = |(v^2)/(2a_max)| + |a/2*t^2| + |v*t| float stoppingDistance = Mathf.Abs((CurrentVelocity * CurrentVelocity) / (2f * Joint.GetMaximumAcceleration() * Slowdown)) + Mathf.Abs(CurrentAcceleration) / 2f * Time.deltaTime * Time.deltaTime + Mathf.Abs(CurrentVelocity) * Time.deltaTime; if (Mathf.Abs(CurrentError) > stoppingDistance) { //Accelerate CurrentAcceleration = Mathf.Sign(CurrentError) * Mathf.Min(Mathf.Abs(CurrentError) / Time.deltaTime, Joint.GetMaximumAcceleration() * Speedup); } else { //Deccelerate CurrentAcceleration = -Mathf.Sign(CurrentVelocity) * Mathf.Min(Mathf.Abs(CurrentVelocity) / Time.deltaTime, Joint.GetMaximumAcceleration(), Mathf.Abs((CurrentVelocity * CurrentVelocity) / (2f * CurrentError))); } CurrentVelocity += CurrentAcceleration * Time.deltaTime; //Update Current Value CurrentValue += CurrentVelocity * Time.deltaTime; }
public override void OnInspectorGUI() { Undo.RecordObject(Target, Target.name); using (var scope = new EditorGUILayout.VerticalScope("Button")) { EditorGUILayout.HelpBox("Geometry", MessageType.None); Target.SetJointType((JointType)EditorGUILayout.EnumPopup("Joint Type", Target.GetJointType())); Target.SetAnchor(EditorGUILayout.Vector3Field("Anchor", Target.GetAnchor())); Target.SetOrientation(EditorGUILayout.Vector3Field("Orientation", Target.GetOrientation())); } using (var scope = new EditorGUILayout.VerticalScope("Button")) { EditorGUILayout.HelpBox("Motion", MessageType.None); Target.SetMotionType((MotionType)EditorGUILayout.EnumPopup("Motion Type", Target.GetMotionType())); Target.SetSmoothing(EditorGUILayout.Slider("Smoothing", Target.GetSmoothing(), 0f, 1f)); if (Target.GetMotionType() == MotionType.Realistic) { Target.SetMaximumVelocity(EditorGUILayout.FloatField("Max Velocity", Target.GetMaximumVelocity())); Target.SetMaximumAcceleration(EditorGUILayout.FloatField("Max Acceleration", Target.GetMaximumAcceleration())); if (Target.GetMaximumVelocity() == 0f || Target.GetMaximumAcceleration() == 0f) { EditorGUILayout.HelpBox("Velocity and Acceleration must be assigned, or nothing will move.", MessageType.Warning); } } DrawMotionInspector(Target.GetXMotion(), "X"); DrawMotionInspector(Target.GetYMotion(), "Y"); DrawMotionInspector(Target.GetZMotion(), "Z"); } /* * EditorGUILayout.HelpBox( * "Current Value: " + Target.GetCurrentValue().ToString("F3") + "\n" + * "Current Error: " + Target.GetCurrentError().ToString("F3") + "\n" + * "Current Velocity: " + Target.GetCurrentVelocity().ToString("F3") + "\n" + * "Current Acceleration: " + Target.GetCurrentAcceleration().ToString("F3"), MessageType.None); */ EditorUtility.SetDirty(Target); /* * using (var scope = new EditorGUILayout.VerticalScope ("Button")) { * EditorGUILayout.HelpBox("Debug", MessageType.None); * EditorGUILayout.Vector3Field("Anchor", Target.GetAnchor()); * EditorGUILayout.Vector3Field("World Anchor", Target.GetAnchorInWorldSpace()); * EditorGUILayout.Vector3Field("Orientation", Target.GetOrientation()); * EditorGUILayout.Vector3Field("X Axis", Target.GetXMotion().Axis); * EditorGUILayout.Vector3Field("Y Axis", Target.GetYMotion().Axis); * EditorGUILayout.Vector3Field("Z Axis", Target.GetZMotion().Axis); * EditorGUILayout.Vector3Field("Default Reference Position", Target.GetDefaultReferencePosition()); * EditorGUILayout.Vector3Field("Default Reference Rotation", Target.GetDefaultReferenceRotation().eulerAngles); * } */ }