Esempio n. 1
0
    // Update is called once per frame
    void Update()
    {
        Vector2 leapScreen = new Vector2(_leapManager.pointerPositionScreen.x,
                                         _leapManager.pointerPositionScreen.y);

        Vector2 parentScreen = new Vector2(_uiCam.WorldToScreenPoint(gameObject.transform.parent.position).x,
                                           _uiCam.WorldToScreenPoint(gameObject.transform.parent.position).y);

        Vector2 menuScreen = new Vector2(_uiCam.WorldToScreenPoint(gameObject.transform.position).x,
                                         _uiCam.WorldToScreenPoint(gameObject.transform.position).y);

        Vector2 parentToFinger = leapScreen - parentScreen;
        Vector2 toFrontFinger  = leapScreen - menuScreen;

        //Menu Wide Updates per state
        switch (_currentState)
        {
        case MenuState.INACTIVE:

            if (parentToFinger.magnitude < _activation_radius && _leapManager.pointerPositionWorld.z > _deactivate_z)
            {
                _activationStartTime = Time.time;
                _currentState        = MenuState.ACTIVATING;
            }

            if (_hasSubLabel && _currentSelection != -1 && _currentSelection < _text.Length && _text[_currentSelection] != null)
            {
                _subLabel.text = _text[_currentSelection];
            }
            break;

        case MenuState.ACTIVATING:
            _selectionMade = false;
            if (Time.time <= _activationStartTime + _activationTime)
            {
                float currentScale = _activationCurve.Evaluate((Time.time - _activationStartTime) / (_activationTime));
                gameObject.transform.localScale = new Vector3(currentScale,
                                                              currentScale,
                                                              1);
            }
            else
            {
                gameObject.transform.localScale = new Vector3(1,
                                                              1,
                                                              1);
                _currentState = MenuState.ACTIVE;
                return;
            }
            break;

        case MenuState.ACTIVE:
            if (_leapManager.pointerPositionWorld.z < _deactivate_z)
            {
                _selectionMade = false;
                _scalingFactor = 1.0f;
                _currentState  = MenuState.DEACTIVATION;
                return;
            }

            if (Time.time >= _selectionCooldownTime)
            {
                _closest         = -1;
                _closestDistance = float.MaxValue;
            }
            break;

        case MenuState.SELECTION:

            _scalingFactor          = Mathf.Clamp(_scalingFactor - (_scaleDownSpeed * Time.deltaTime), 0.0f, 1.0f);
            _currentSelectionOffset = Mathf.Clamp((float)(Time.time - _selectionEndTime + _selectionDelayTime) / (float)(_selectionSnapTime), 0.0f, 1.0f) * _selectionSnapDistance;
            if (Time.time >= _selectionEndTime)
            {
                _selectionMade = true;
                _currentState  = MenuState.DEACTIVATION;
                return;
            }
            break;

        case  MenuState.DEACTIVATION:
            if (gameObject.transform.localScale.x > 0)
            {
                gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x - (_deactivationSpeed * Time.deltaTime),
                                                              gameObject.transform.localScale.y - (_deactivationSpeed * Time.deltaTime),
                                                              1);
            }
            else
            {
                gameObject.transform.localScale = new Vector3(0, 0, 1);
                _currentState = MenuState.INACTIVE;
                return;
            }
            break;
        }

        //Per Button Updates per state
        for (int i = 0; i < _buttonCount; i++)
        {
            ArcMaker current = _buttons[i].GetComponent(typeof(ArcMaker)) as ArcMaker;
            current._bottom = _radius - (_thickness / 2.0f);
            current._top    = _radius + (_thickness / 2.0f);

            if (i != _closest)
            {
                current.makeInactive();
                if (i == _currentSelection)
                {
                    _buttons[i].renderer.material.color = Color.Lerp(_buttons[i].renderer.material.color, _selectedColor, 0.25f);
                }
                else
                {
                    _buttons[i].renderer.material.color = Color.Lerp(_buttons[i].renderer.material.color, _baseColor, 0.25f);
                }
            }

            if (i == _currentSelection)
            {
                current.makeActive();
            }

            switch (_currentState)
            {
            case MenuState.INACTIVE:
                _buttons[i].SetActive(false);
                break;

            case MenuState.ACTIVATING:
                _buttons[i].SetActive(true);
                current._contentScaleFactor = 1.0f;
                break;

            case MenuState.ACTIVE:
                Vector2 buttonCenter = _uiCam.WorldToScreenPoint(_buttons[i].renderer.bounds.center);
                Vector2 toButton     = (Vector2)leapScreen - (Vector2)buttonCenter;

                if (Time.time >= _selectionCooldownTime && toButton.magnitude < _closestDistance)
                {
                    _closestDistance = toButton.magnitude;
                    _closest         = i;
                }

                current._contentScaleFactor = 1.0f;
                break;

            case MenuState.SELECTION:
                if (i != _closest)
                {
                    current._bottom            *= _scalingFactor;
                    current._top               *= _scalingFactor;
                    current._contentScaleFactor = _scalingFactor;
                }
                else
                {
                    current._bottom = _selection_radius + _currentSelectionOffset - (_thickness / 2.0f);
                    current._top    = _selection_radius + _currentSelectionOffset + (_thickness / 2.0f);
                }
                break;

            case MenuState.DEACTIVATION:
                if (i != _closest || !_selectionMade)
                {
                    current._bottom *= _scalingFactor;
                    current._top    *= _scalingFactor;
                }
                else if (_selectionMade)
                {
                    current._bottom = _selection_radius - (_thickness / 2.0f);
                    current._top    = _selection_radius + (_thickness / 2.0f);
                }
                break;
            }
        }

        //Behavior for selected item
        if (_currentState == MenuState.ACTIVE)
        {
            if (_closest != _lastClosest)
            {
                _lastClosest           = _closest;
                _selectionCooldownTime = Time.time + _selectionCooldown;
            }

            //do things with the closest menu
            if (_closest != -1)
            {
                ArcMaker selected = _buttons[_closest].GetComponent(typeof(ArcMaker)) as ArcMaker;

                float pixelDistance = (menuScreen - leapScreen).magnitude;

                //convert world distance from pixels to world units.
                float worldDistance = pixelDistance * ((_uiCam.orthographicSize * 2.0f) / (float)_uiCam.pixelHeight);

                if (_buttonActions[_closest] == ButtonAction.NONE)
                {
                    if (worldDistance > _radius + (_thickness / 2.0f))
                    {
                        _selectionMade = false;
                        _scalingFactor = 1.0f;
                        _currentState  = MenuState.DEACTIVATION;
                        return;
                    }
                }
                else
                {
                    selected.makeActive();

                    if (_hasSubLabel && _closest != -1 && _closest < _text.Length && _text[_closest] != null)
                    {
                        _subLabel.text = _text[_closest];
                    }

                    //pull out wedge
                    if (worldDistance - _captureOffset > _radius)
                    {
                        selected._bottom = worldDistance - _captureOffset - (_thickness / 2.0f);
                        selected._top    = worldDistance - _captureOffset + (_thickness / 2.0f);

                        if (worldDistance - _captureOffset > _selection_radius)
                        {
                            _selectionEndTime = Time.time + _selectionDelayTime;
                            _currentSelection = _closest;
                            _scalingFactor    = 1.0f;

                            if (_eventHandler != null && _closest < _buttonActions.Length)
                            {
                                _eventHandler.recieveMenuEvent(_buttonActions[_closest]);
                            }

                            _currentState = MenuState.SELECTION;
                        }
                    }

                    float highlightPercent = Mathf.Clamp((worldDistance - _fullHighlight) / (_startHighlight - _fullHighlight), 0.0f, 1.0f);
                    if (_closest == _currentSelection)
                    {
                        _buttons[_closest].renderer.material.color = Color.Lerp(_selectedColor, _highlightColor, highlightPercent);
                    }
                    else
                    {
                        _buttons[_closest].renderer.material.color = Color.Lerp(_baseColor, _highlightColor, highlightPercent);
                    }
                    selected._contentScaleFactor = 1.0f + (highlightPercent * _highlightPercentGrowth);
                }
            }
        }
    }