25 [Header(
"UI Control")]
27 [Tooltip(
"When set to false, this UI control will not be functional. Use this instead "
28 +
"of disabling the component itself when you want to disable the user's "
29 +
"ability to affect this UI control while keeping the GameObject active and, "
30 +
"for example, rendering, and able to receive primaryHover state.")]
31 [SerializeField, FormerlySerializedAs(
"controlEnabled")]
32 private bool _controlEnabled =
true;
34 get {
return _controlEnabled; }
35 set { _controlEnabled = value; }
38 [Header(
"Motion Configuration")]
47 [Tooltip(
"The minimum and maximum heights the button can exist at.")]
54 [Tooltip(
"The height that this button rests at; this value is a lerp in between the min and max height.")]
63 private float _springForce = 0.1f;
78 [FormerlySerializedAs(
"OnPress")]
79 private UnityEvent _OnPress =
new UnityEvent();
82 [FormerlySerializedAs(
"OnUnpress")]
83 private UnityEvent _OnUnpress =
new UnityEvent();
95 [Obsolete(
"Deprecated. Use isPressed instead.",
false)]
103 [Obsolete(
"Deprecated. Use pressedThisFrame instead.",
false)]
111 [Obsolete(
"Deprecated. Use unpressedThisFrame instead.",
false)]
114 private float _pressedAmount = 0F;
122 [Obsolete(
"Deprecated. Use pressedAmount instead.",
false)]
154 private Rigidbody _lastDepressor;
155 private Vector3 _localDepressorPosition;
156 private Vector3 _physicsVelocity = Vector3.zero;
157 private bool _physicsOccurred;
158 private bool _initialIgnoreGrasping =
false;
159 private Quaternion _initialLocalRotation;
183 if (_lockedInteractingController !=
null) {
193 Debug.LogError(
"This button has no parent! Please ensure that it is parented to something!",
this);
210 _initialLocalRotation =
transform.localRotation;
223 if (!_physicsOccurred) {
224 _physicsOccurred =
true;
228 float localPhysicsDisplacementPercentage
234 && _physicsVelocity == Vector3.zero
235 && Mathf.Abs(localPhysicsDisplacementPercentage -
restingHeight) < 0.01F) {
240 if (_physicsVelocity.ContainsNaN()) {
241 _physicsVelocity = Vector3.zero;
251 private const float FRICTION_COEFFICIENT = 30F;
252 private const float DRAG_COEFFICIENT = 60F;
265 transform.localRotation = _initialLocalRotation;
268 if (_physicsOccurred) {
269 _physicsOccurred =
false;
284 localPhysicsPosition =
new Vector3(localSlidePosition.x,
285 localSlidePosition.y,
290 Vector3 localPhysicsVelocity =
transform.parent.InverseTransformVector(
rigidbody.velocity);
292 Vector3 curLocalDepressorPos =
transform.parent.InverseTransformPoint(_lastDepressor.position);
293 Vector3 origLocalDepressorPos =
transform.parent.InverseTransformPoint(
transform.TransformPoint(_localDepressorPosition));
294 localPhysicsVelocity = Vector3.back * 0.05f;
301 Vector3 originalLocalVelocity = localPhysicsVelocity;
304 localPhysicsVelocity +=
305 Mathf.Clamp(_springForce * 10000F
311 * Time.fixedDeltaTime * Vector3.forward;
314 float velMag = originalLocalVelocity.magnitude;
315 var frictionDragVelocityChangeAmt = 0f;
318 var frictionForceAmt = velMag * FRICTION_COEFFICIENT;
319 frictionDragVelocityChangeAmt
320 += Time.fixedDeltaTime *
transform.parent.lossyScale.x * frictionForceAmt;
323 float velSqrMag = velMag * velMag;
324 var dragForceAmt = velSqrMag * DRAG_COEFFICIENT;
325 frictionDragVelocityChangeAmt
326 += Time.fixedDeltaTime *
transform.parent.lossyScale.x * dragForceAmt;
330 var newVelMag = Mathf.Max(0, velMag - frictionDragVelocityChangeAmt);
331 localPhysicsVelocity = localPhysicsVelocity / velMag * newVelMag;
338 _physicsVelocity =
transform.parent.TransformVector(localPhysicsVelocity);
357 _physicsVelocity = _physicsVelocity * 0.1f;
359 _lastDepressor =
null;
367 _lastDepressor =
null;
377 _lastDepressor =
null;
397 _lastDepressor =
null;
423 _physicsVelocity = _physicsVelocity * 0.1f;
426 if (_lockedInteractingController !=
null && !
isPressed) {
428 _lockedInteractingController =
null;
432 protected virtual void OnCollisionEnter(Collision collision) { trySetDepressor(collision.collider); }
433 protected virtual void OnCollisionStay(Collision collision) { trySetDepressor(collision.collider); }
436 protected virtual void OnTriggerEnter(Collider collider) { trySetDepressor(collider); }
437 protected virtual void OnTriggerStay(Collider collider) { trySetDepressor(collider); }
440 private void trySetDepressor(Collider collider) {
444 _lastDepressor = collider.attachedRigidbody;
445 _localDepressorPosition =
transform.InverseTransformPoint(collider.attachedRigidbody.position);
455 Gizmos.matrix =
transform.parent.localToWorldMatrix;
462 Gizmos.color =
Color.red;
463 Gizmos.DrawLine(originPosition + (Vector3.back * heights.x), originPosition + (Vector3.back * heights.y));
464 Gizmos.color =
Color.green;
465 Gizmos.DrawLine(originPosition + (Vector3.back * heights.x), originPosition + (Vector3.back * Mathf.Lerp(heights.x, heights.y,
restingHeight)));
471 #region Public Methods
481 [Obsolete(
"Deprecated. Use SetMinHeight instead.",
false)]
494 [Obsolete(
"Deprecated. Use SetMaxHeight instead.",
false)]
InteractionBehaviours are components that enable GameObjects to interact with interaction controllers...
ContactForceMode contactForceMode
InteractionController primaryHoveringController
Gets the closest primary hovering interaction controller for this object, if it has one....
Action OnGraspBegin
Called when the object becomes grasped, if it was not already held by any interaction controllers on ...
Rigidbody rigidbody
The Rigidbody associated with this interaction object.
GraspedMovementType graspedMovementType
bool isPrimaryHovered
Gets whether this object is the primary hover for any interaction controller.
InteractionController graspingController
Gets the controller currently grasping this object. Warning: If allowMultigrasp is enabled on this ob...
Action OnGraspEnd
Called when the object is no longer grasped by any interaction controllers.
bool isGrasped
Gets whether this object is grasped by any interaction controller.
InteractionManager manager
float primaryHoverDistance
Gets the distance to the primary hover point whose controller is primarily hovering over this object....
void LockPrimaryHover(InteractionBehaviour intObj)
Sets the argument interaction object to be the current primary hover of this interaction controller a...
bool primaryHoverLocked
When set to true, locks the current primarily hovered object, even if the hand gets closer to a diffe...
Dictionary< Rigidbody, ContactBone > contactBoneBodies
Maps a Rigidbody to its attached ContactBone, if the Rigidbody is part of an interaction controller.