/// <summary> /// Remove an object from the selection and reverts the shader /// </summary> /// <param name="go"></param> /// <param name="invokeSelectionChangeEvent"></param> protected void RemoveObjectFromSelection(GameObject go, bool invokeSelectionChangeEvent = true) { if (selectedObjects.Remove(go)) { go.GetComponent <Selectable>().RevertShader(); if (invokeSelectionChangeEvent && ChangeSelectionEvent != null) { ChangeSelectionEvent.Invoke(Array.AsReadOnly(new GameObject[] { }), Array.AsReadOnly(new GameObject[] { go }), SelectedObjects); } } }
/// <summary> /// Clears the selection and resets the shaders /// </summary> public void ClearSelection() { selectedObjects.ForEach(o => { if (o != null) { o.GetComponent <Selectable>().RevertShader(); } }); if (ChangeSelectionEvent != null) { ChangeSelectionEvent.Invoke(Array.AsReadOnly(new GameObject[] { }), SelectedObjects, new List <GameObject>().AsReadOnly()); } selectedObjects.Clear(); }
/// <summary> /// Adds an object to the selection, changes the shader and shows and hides the appropriate canvas /// </summary> /// <param name="go">The Gameobject which is added</param> protected void AddObjectToSelection(GameObject go, bool invokeSelectionChangeEvent = true) { if (selectedObjects.Contains(go)) { return; } if (go == null) { return; } Selectable selectable = go.GetComponent <Selectable>(); if (selectable == null) { throw new Exception("You tried to Add an GameObject which hans't a Selectable component on it: (Gameobject: " + go + ")"); } selectable.SetShader(); selectedObjects.Add(go); if (selectedObjects.Count == 1) { ShowObjectUi(selectedObjects.First()); } else if (!eventSystem.IsPointerOverGameObject()) { HideObjectUi(); } if (SelectionContainsListeners.ContainsKey(go)) { foreach (var l in SelectionContainsListeners[go]) { l.Invoke(go, selectedObjects.AsReadOnly()); } } if (invokeSelectionChangeEvent && ChangeSelectionEvent != null) { ChangeSelectionEvent.Invoke(Array.AsReadOnly(new GameObject[] { go }), Array.AsReadOnly(new GameObject[] {}), SelectedObjects); } }
void Update() { bool mousePressed = Input.GetButton("LeftMouse") || Input.GetButton("RightMouse"); bool mouseDown = Input.GetButtonDown("LeftMouse") || Input.GetButtonDown("RightMouse"); bool mouseUp = Input.GetButtonUp("LeftMouse") || Input.GetButtonUp("RightMouse"); bool leftMouse = Input.GetButton("LeftMouse") || Input.GetButtonDown("LeftMouse") || Input.GetButtonUp("LeftMouse"); //switches between the modes depending on the controll key if (SelectionMode != SelectionModeEnum.MultipleAdd && Input.GetButton("Control")) { SelectionMode = SelectionModeEnum.MultipleAdd; } if (SelectionMode == SelectionModeEnum.MultipleAdd && !Input.GetButton("Control")) { SelectionMode = SelectionModeEnum.MultipleClear; } //Clears the selection if the selection mode isn't addative if (mouseDown && SelectionMode != SelectionModeEnum.MultipleAdd && leftMouse) { ClearSelection(); ClearSecundarySelection(); } else if (mouseDown && SelectionMode != SelectionModeEnum.MultipleAdd && !leftMouse) { ClearSecundarySelection(); } //saves the start position of the mouse for the selection box if (mouseDown && !multipleSelectionActive) { selectionStartMousePos = Input.mousePosition; } //Checks if the mouse position has changed since the user clicked the LeftMouse Button. If the distance is greater then 0.1 (a threadshold) then multiselecting is activated if (mousePressed && Mathf.Abs(Vector2.Distance(selectionStartMousePos, Input.mousePosition)) > 0.1 && !multipleSelectionActive) { multipleSelectionActive = true; SelectionMode = SelectionModeEnum.MultipleClear; //the default selection mode } //Updates the cursor texture if (SelectionMode == SelectionModeEnum.MultipleAdd) { Cursor.SetCursor(cursorAddSelectionTexture, Vector2.zero, CursorMode.Auto); } else { Cursor.SetCursor(cursorSelectionTexture, Vector2.zero, CursorMode.Auto); } //In here is the main multi selection logic //here is the selecting and the setting of the shader logic if (multipleSelectionActive && mouseUp) { //precalculates the bounds Bounds viewportBounds = GetViewportBounds(camera, selectionStartMousePos, Input.mousePosition); var addedGos = new List <GameObject>(); var removedGos = new List <GameObject>(); //goes through every object which can be selected ( foreach (var go in Selectable.SelectGameObjects) { if (go == null) { continue; } if (viewportBounds.Contains(camera.WorldToViewportPoint(go.transform.position))) { if (leftMouse) { if (selectedObjects.Contains(go)) { RemoveObjectFromSelection(go, false); removedGos.Add(go); } else { AddObjectToSelection(go, false); addedGos.Add(go); } } else { if (SecundarySelectedObjects.Contains(go)) { RemoveObjectFromSecundarySelection(go, false); removedGos.Add(go); } else { AddObjectToSecundarySelection(go, false); addedGos.Add(go); } } } } if (ChangeSelectionEvent != null) { if (leftMouse) { ChangeSelectionEvent.Invoke(addedGos.AsReadOnly(), removedGos.AsReadOnly(), SelectedObjects); } else { ChangeSecundarySelectionEvent.Invoke(addedGos.AsReadOnly(), removedGos.AsReadOnly(), SecundarySelectedObjects); } } } //hides the last ui canvas if (mouseDown && !eventSystem.IsPointerOverGameObject() && leftMouse) { HideObjectUi(); } //Here is the single selection in if (mouseUp && !multipleSelectionActive) { Ray ray = camera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; Debug.DrawRay(ray.origin, ray.direction * 100, Color.blue, 10); if (Physics.Raycast(ray, out hit, 1000.0f) && !EventSystem.current.IsPointerOverGameObject()) { GameObject hittedGo = hit.collider.gameObject; if (hittedGo.GetComponent <Selectable>() != null) { if (selectedObjects.Contains(hittedGo)) { if (leftMouse) { RemoveObjectFromSelection(hittedGo); } else { RemoveObjectFromSecundarySelection(hittedGo); } } else { if (leftMouse) { AddObjectToSelection(hittedGo); } else { AddObjectToSecundarySelection(hittedGo); } } } else { if (!leftMouse) { selectedPosition = hit.point; if (ChangePositionEvent != null) { ChangePositionEvent.Invoke(selectedPosition); } } } } else { Debug.LogWarning("Didn't hit terain with raycast!"); } } //disables the multiple selection mode if (mouseUp && multipleSelectionActive) { multipleSelectionActive = false; SelectionMode = SelectionModeEnum.Single; } }