Example #1
0
    //---------------------------------------------------------------------------	UPDATE
    public void OnUpdate_Cursor()
    {
        // Called in CGame.update() to update our cursor
        //=== Switch edit mode if the corresponding key was pressed ===
        //###DESIGN!!!!! How / when to map these important keys???			###TODO!!!!  Only change mode when in pose edit mode, enforce 'play mode' to always move!

        if (CGame.INSTANCE._bGameModeBasicInteractions == false) {
            if (Input.GetKeyDown(KeyCode.T)) {					// Toggle between move and rotate mode when not in basic game interaction mode
                if (_EditMode == EEditMode.Move)
                    SetEditMode(EEditMode.Rotate);
                else
                    SetEditMode(EEditMode.Move);
            }
        }

        //=== Determine which layer we search for hotspot on ===
        int nLayerTarget = C_Layer_HotSpot;					//###BUG??? Send this layer mask to derived classes???
        //if (Input.GetKey(KeyCode.Space))					//###CHECK: Proper?  Hunt for hotspots on hand layer if proper key pressed
        //	nLayerTarget = C_Layer_HotSpotHands;
        uint nLayerTargetMask = (uint)1 << nLayerTarget;

        //###WEAK?  The changes above to cursor mode operation are specific to the game and take away some of the generic behavior that may be useful for other purposes
             if (Input.GetKeyDown(KeyCode.W))	SetEditMode(EEditMode.Move);		// W = Move
        else if (Input.GetKeyDown(KeyCode.T))	SetEditMode(EEditMode.Rotate);      // T = roTate               //###WEAK: Conflicts with reset!  Which to keep??
                                                                                    //else if (Input.GetKeyDown(KeyCode.E)) 	SetEditMode(EEditMode.Scale);		// E = Expand = Scale		//###DESIGN: Any value in scale / select for game??
                                                                                    //else if (Input.GetKeyDown(KeyCode.Q))	SetEditMode(EEditMode.Select);		// Q = Select

        //=== Test what collider is under the mouse cursor.  This is used to process the various stages of mouse interactivity as well as to adjust the '3D depth' of the cursor ===
        CGame.SetGuiMessage(EGameGuiMsg.CursorStat1, "Cursor Mode: " + _eModeCursor.ToString());
        _oRayHit_LayerHotSpot = GetHitOnLayerAtMousePos(0xFFFFFFFF);
        if (_oRayHit_LayerHotSpot.collider != null)
            CGame.SetGuiMessage(EGameGuiMsg.CursorStat2, "Cursor Collider: " + _oRayHit_LayerHotSpot.transform.name);
        else
            CGame.SetGuiMessage(EGameGuiMsg.CursorStat2, "Cursor Collider: None");
        _oRayHit_LayerHotSpot = GetHitOnLayerAtMousePos(nLayerTargetMask);
        if (_oRayHit_LayerHotSpot.collider != null)
            _nDepth = _oRayHit_LayerHotSpot.distance * _DefaultCursorDepthOnHotspots;         // We adjust the '3D depth' of mouse cursor only when a collider is found.  ###IMPROVE: Implement slerp to gracefully change depth?

          //      GameObject oSelectedUI = EventSystem.current.currentSelectedGameObject;     // EventSystem.current.IsPointerOverGameObject()) {        // If cursor is over Unity UI widget set cursor directly there and don't process further cursor functionality
          //      if (oSelectedUI != null) {
        //    CGame.SetGuiMessage(EGameGuiMsg.CursorStat3, "Cursor GUI: " + oSelectedUI.name);
          //          //transform.position = Camera.main.ScreenToWorldPoint(;
          //          //PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
          //          //eventDataCurrentPosition.position = screenPosition;
          //          //GraphicRaycaster uiRaycaster = canvas.gameObject.GetComponent<GraphicRaycaster>();
          //          //List<RaycastResult> results = new List<RaycastResult>();
          //          //uiRaycaster.Raycast(eventDataCurrentPosition, results);
          //          //return results.Count > 0;
          //          _nDepth = Vector3.Distance(oSelectedUI.transform.position, Camera.main.transform.position);
        //} else {
          //          CGame.SetGuiMessage(EGameGuiMsg.CursorStat3, "(Cursor: No GUI control)");
          //      }

        if (_oCurrentGuiObject_HACK != null)        //###CHECK: Proper transforms for VR??  For SpaceNavigator??
            _nDepth = Vector3.Distance(_oCurrentGuiObject_HACK.position, Camera.main.transform.position);     //###DESIGN: Override hotspot depth above??   ###IDEA: Have cursor a child of panel when it is hovering on top??

        Vector3 vecMouse2D = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _nDepth);		//###OPT: Cache localPosition??
        Vector3 vecMouse3D = Camera.main.ScreenToWorldPoint(vecMouse2D);
        transform.position = vecMouse3D;

        if (_oCurrentGuiObject_HACK != null)
            return;			//####SOON ####PROBLEM: Detecting what widget for width (solution offered in post)

        bool bClickLeftDown		= Input.GetMouseButtonDown(0);
        bool bClickRightDown	= Input.GetMouseButtonDown(1);
        bool bClickMiddleDown	= Input.GetMouseButtonDown(2);
        bool bClickDown = bClickLeftDown || bClickRightDown || bClickMiddleDown;

        //=== Process the finite state machine that systematically walks through each step of hotspot search, hovering, activation with bridge to hotspot's OnUpdate_HotSpot() for further 'OnUpdate()' processing ===
        switch (_eModeCursor) {
            case EModeCursor.S1_SearchingForHotspot:					// Default/startup mode: We don't have an interactive selected and are looking for one through 'mouse hover'
                if (_oRayHit_LayerHotSpot.collider != null) {
                    _oHotSpotCurrent = _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>();
                    if (_oHotSpotCurrent) {
                        _oHotSpotCurrent.OnHoverBegin();
                        _eModeCursor = EModeCursor.S2_HoveringOverHotspot;
                    }
                } else {
                    //if (iGUICode_Root.INSTANCE._oPaneContextMenu != null) {								// We kill panel when we're not hovering over any Gui collider and panel exists. (makes it have a very short lifespan exactly like a 'tooltip')
                    //	iGUICode_Root.INSTANCE._oPaneContextMenu.removeAll();
                    //	iGUICode_Root.INSTANCE._oPaneContextMenu.setEnabled(false);			//###IMPROVE!!! Implement 'tooltip-like' functionality for popup menu?
                    //	iGUICode_Root.INSTANCE._oPaneContextMenu = null;
                    //}
                }
                break;

            case EModeCursor.S2_HoveringOverHotspot:							// The user is now hovering over a valid Hotspot, but has not yet selected it with left mouse button.  (3D cursor displays name of Hotspot for visual feedback)
                if (bClickDown) {
                    if (CGame.INSTANCE._bGameModeBasicInteractions == false || bClickRightDown) {	// If we're in full edit mode we wait for up-click, activate and display full gizmo.
                        _eModeCursor = EModeCursor.S3_WaitingForMouseUp;
                    } else {													// If we're in reduced edit mode, we fast-track to immediate movement along Y,Z axis without showing gizmo
                        _oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown, bClickMiddleDown);
                        _eModeCursor = EModeCursor.S4_ActivatedHotspot;
                    }
                    _nTimeAtMouseButtonDown = Time.time;			// Remember the start time of mouse button down to prevent acting on very long mouse clicks
                    _vecPosAtMouseButtonDown = Input.mousePosition;	// Remember mouse position so we can cancel if too far on mouse up
                } else {			// No click on hovering hotspot, check to see if we're still on a hotspot and cancel if not.
                    CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null;
                    if (oHotSpot != _oHotSpotCurrent) {
                        _oHotSpotCurrent.OnHoverEnd();
                        _oHotSpotCurrent = null;
                        _eModeCursor = EModeCursor.S1_SearchingForHotspot;
                    }
                }
                break;

            case EModeCursor.S3_WaitingForMouseUp:							// The user has down-clicked a hotspot.  We await up-click to see if same hotspot is still under the mouse before activating the hotspot
                bool bClickLeftUp		= Input.GetMouseButtonUp(0);
                bool bClickRightUp		= Input.GetMouseButtonUp(1);
                bool bClickMiddleUp		= Input.GetMouseButtonUp(2);
                if (bClickLeftUp|| bClickRightUp) {
                    if (_nTimeAtMouseButtonDown + C_TimeMaxForMouseClick >= Time.time && (Input.mousePosition - _vecPosAtMouseButtonDown).magnitude < 10) {
                        CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null;
                        if (oHotSpot == _oHotSpotCurrent) {			// User has released mouse button on the same hotspot as mouse down.  Activate the hotspot
                            _oHotSpotCurrent.OnActivate(bClickLeftUp, bClickRightUp, bClickMiddleUp);
                            _eModeCursor = EModeCursor.S4_ActivatedHotspot;
                        } else {											// User has released button on nothing or on another hotspot.  Return to start state
                            _oHotSpotCurrent.OnHoverEnd();
                            _oHotSpotCurrent = null;
                            _eModeCursor = EModeCursor.S1_SearchingForHotspot;
                        }
                    } else {		// User took too long, just ignore both mouse down & mouse up and return to search state
                        _eModeCursor = EModeCursor.S1_SearchingForHotspot;
                    }
                }
                break;

            case EModeCursor.S4_ActivatedHotspot:							// The user is now hovering over a valid Hotspot, but has not yet selected it with left mouse button.  (3D cursor displays name of Hotspot for visual feedback)
                if (bClickDown) {
                    RaycastHit oRayHit_LayerHotSpotAndGizmo = GetHitOnLayerAtMousePos(nLayerTargetMask | CCursor.C_LayerMask_Gizmo);	// Test to see if user clicked on nothing in gizmo or hotspot layers (in 'void')

                    if (oRayHit_LayerHotSpotAndGizmo.collider == null) {			// If user didn't click on anything we cancel hotspot activation and return to start state.
                        _oHotSpotCurrent.OnDeactivate();
                        _oHotSpotCurrent.OnHoverEnd();
                        _oHotSpotCurrent = null;
                        _eModeCursor = EModeCursor.S1_SearchingForHotspot;
                    //} else {												// We hit a valid hotspot or gizmo collider...	//###BROKEN! Was creating multiple gizmos!
                    //	CHotSpot oHotSpot = _oRayHit_LayerHotSpot.collider ? _oRayHit_LayerHotSpot.collider.GetComponent<CHotSpot>() : null;
                    //	if (oHotSpot != null) {
                    //		if (oHotSpot == _oHotSpotCurrent) {				// If user clicked same hotspot simply route the 'activate' call to it so it can display menu or start editing
                    //			_oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown);	//###IMPROVE: Test and add quick activation??
                    //		//} else {										// If user clicked another hotspot we deactivate the old one and activate the new
                    //		//	_oHotSpotCurrent.OnDeactivate();
                    //		//	_oHotSpotCurrent.OnHoverEnd();
                    //		//	_oHotSpotCurrent = oHotSpot;
                    //		//	_oHotSpotCurrent.OnHoverBegin();
                    //		//	_oHotSpotCurrent.OnActivate(bClickLeftDown, bClickRightDown);		//###CHECK!
                    //		}
                    //	}													// In this if clause is also the possibility of a left/right click on a gizmo collider.  This is handled below by hotspot
                    }
                }
                if (_oHotSpotCurrent != null) {				// Only the active hotspot gets the chance to trap events (typically to reroute to the gizmo it manages) ===
                    _oHotSpotCurrent.OnUpdate_ActiveHotspot();
                    //=== Handle special case if we're not showing helper object and the left or middle mouse button is not pressed -> destroy everything and returning to start state to complete the highly transient operation
                    if (CGame.INSTANCE._bGameModeBasicInteractions && Input.GetMouseButton(0) == false && Input.GetMouseButton(2) == false) {
                        _oHotSpotCurrent.OnDeactivate();
                        _oHotSpotCurrent.OnHoverEnd();
                        _oHotSpotCurrent = null;
                        _eModeCursor = EModeCursor.S1_SearchingForHotspot;
                    }
                }
                break;
        }
    }
Example #2
0
 public void CancelEditing()
 {
     // Cancels editing by deactivating hots pot which will destroy gizmo if it exists.
     if (_oHotSpotCurrent) {
         _oHotSpotCurrent.OnDeactivate();
         _oHotSpotCurrent.OnHoverEnd();
     }
     _oHotSpotCurrent = null;
     _eModeCursor = EModeCursor.S1_SearchingForHotspot;
 }