// clears the hovered object so it can re-hover public void Reset() { _hoveredCollider = null; _clickTarget = null; _grabTarget = null; _hoverTarget = null; _state = State.Seek; }
private void GoToInertState() { if (_hoverTarget != null) { _hoverTarget.HandleUnhover(this); } _hoveredCollider = null; _clickTarget = null; _grabTarget = null; _hoverTarget = null; _state = State.Inert; }
protected void Update() { if (_isActive == false) { return; } if (CanvasPointerCheck.IsOverCanvas) { GoToInertState(); _state = State.BlockedByCanvas; return; } // We're no longer pointed at a canvas: go to Seek state else if (_state == State.BlockedByCanvas) { _state = State.Seek; } // Store previous state Collider previousHoveredCollider = _hoveredCollider; IClickTarget previousClickTarget = _clickTarget; IGrabTarget previousGrabTarget = _grabTarget; IHoverTarget previousHoverTarget = _hoverTarget; bool isPrimaryButtonDown = IsPrimaryButtonDown(); // An inert state is triggered when the button is pressed without a target if (_state == State.Inert) { if (isPrimaryButtonDown == false) { // Continue with normal Seek behavior _state = State.Seek; } else { // Do nothing and clear current state _hoveredCollider = null; _clickTarget = null; _grabTarget = null; _hoverTarget = null; return; } } // Always identify the object under the pointer _hoveredCollider = GetHoveredCollider(); if (_hoveredCollider) { // note that these might be null _clickTarget = _hoveredCollider.transform.GetComponentInParent <IClickTarget>(); _hoverTarget = _hoveredCollider.transform.GetComponentInParent <IHoverTarget>(); } else { _clickTarget = null; _hoverTarget = null; } // Hover / Unhover if (_state == State.Seek) { // if we have a new target, unhover the old and hover the new if (_hoverTarget != previousHoverTarget) { if (previousHoverTarget != null) { previousHoverTarget.HandleUnhover(this); } if (_hoverTarget != null) { _hoverTarget.HandleHover(this); } } if (isPrimaryButtonDown) { if (_hoveredCollider == null) { GoToInertState(); } else { _buttonDownTime = Time.timeSinceLevelLoad; _state = State.Active; } } return; } // Button is down. Click, Grab, or Cancel. // NOTE: This means it is possible for objects to move between the pointer and the target and interrupt events. if (_state == State.Active) { // Did the hovered collider change? Then unhover and cancel. if (_hoveredCollider != previousHoveredCollider) { if (previousHoverTarget != null) { previousHoverTarget.HandleUnhover(this); } GoToInertState(); return; } // Still trying to click (mouse up within duration on same collider) if (ButtonDownDuration < _maxClickDuration) { // Try to click, then return to Seek if (isPrimaryButtonDown == false) { if (_clickTarget != null && _clickTarget == previousClickTarget) { _clickTarget.HandleClick(this); _clickTarget = null; _state = State.Seek; } } } // Button is still down, we are moving to grab state if we have a valid target else { _grabTarget = _hoveredCollider.transform.GetComponentInParent <IGrabTarget>(); if (_grabTarget != null && _grabTarget == previousGrabTarget) { _grabTarget.HandleGrab(this); _state = State.Grab; } else { GoToInertState(); } } return; } // The grabbed object has the reins at this point. We're just waiting for primary button up. if (_state == State.Grab) { if (isPrimaryButtonDown) { // the target was destroyed, bail. if (previousGrabTarget == null) { GoToInertState(); return; } } else // release { // the target was destroyed, bail. if (previousGrabTarget != null) { previousGrabTarget.HandleRelease(this); } _state = State.Seek; return; } } Debug.LogError("Pointer fell through to unknown state " + _state.ToString()); }