private void FixedUpdate() { if (IsScaling) { var playerTransform = PlayerController.gameObject.transform; var center = selectionFilter.GetCenter(); if (Math3d.ClosestPointsOnTwoLines(out _, out Vector3 point, playerTransform.position, playerTransform.forward, center, scaleDirection)) { Vector3Int min = selectionFilter.min; Vector3Int max = selectionFilter.max; float desiredLength = Vector3.Dot(point - center, scaleDirection); if (desiredLength > 0) { Vector3 offsetCenter = center + scaleDirection; Vector3Int size = selectionFilter.GetSize(); float currentLength = Mathf.Abs(Vector3.Dot(size, scaleDirection)) / 2; // determine closest point to scaling direction: if ((min - offsetCenter).sqrMagnitude < (max - offsetCenter).sqrMagnitude) { min += scaleDirection * Mathf.RoundToInt(desiredLength - currentLength); } else { max += scaleDirection * Mathf.RoundToInt(desiredLength - currentLength); } selectionFilter = SelectionFilter.FromSelection(min, max, ~gizmoLayerMask); OnSelect(selectionFilter); } } } if (IsSelecting) { var playerTransform = PlayerController.gameObject.transform; if (Physics.Raycast(playerTransform.position, playerTransform.forward, out RaycastHit hit, 500, ~gizmoLayerMask)) { selectionFilter.DoSelection(hit); } } }
/// <summary> /// /// </summary> /// <param name="keyDown"></param> /// <param name="stretchModifier">do selection in plane(s) between 2 selected points</param> /// <returns>Started/ended selection or scaling of selection</returns> public bool Selection(bool keyDown, bool stretchModifier = false) { if (!gameObject.activeInHierarchy) { Debug.LogWarning("'SelectionGizmo.Selection' available AFTER doing SetActive!"); return(false); } var playerTransform = PlayerController.gameObject.transform; if (keyDown && Physics.Raycast(playerTransform.position, playerTransform.forward, out RaycastHit hit, 500, gizmoLayerMask)) { MeshRenderer hitMeshRenderer = hit.collider.GetComponent <MeshRenderer>(); if (new List <MeshRenderer> { XFace, XNegFace, YFace, YNegFace, ZFace, ZNegFace }.Contains(hitMeshRenderer)) { IsScaling = true; scaleDirection = Vector3Int.RoundToInt(hit.normal); selectedFace = hitMeshRenderer; return(true); } return(false); // i hit something on the gizmo layer but it's not any of what i need, something else needs to handle it } if (!keyDown && (IsScaling || IsSelecting)) { IsScaling = false; IsSelecting = false; OnSelect(selectionFilter); return(true); } IsScaling = false; if (keyDown && Physics.Raycast(playerTransform.position, playerTransform.forward, out RaycastHit raycastHit, 500, ~gizmoLayerMask)) { if (stretchModifier && HasSelection()) { SelectionFilter newSelection = SelectionFilter.NewSelection(raycastHit); Vector3Int newMin = newSelection.min; Vector3Int newMax = newSelection.max; Vector3Int currentMin = selectionFilter.min; Vector3Int currentMax = selectionFilter.max; Vector3Int finalMin = currentMin; Vector3Int finalMax = currentMax; if (Math.Min(newMin.x, newMax.x) >= Math.Max(currentMin.x, currentMax.x) || Math.Max(newMin.x, newMax.x) <= Math.Min(currentMin.x, currentMax.x)) { finalMin.x = -100000; finalMax.x = 100000; } if (Math.Min(newMin.y, newMax.y) >= Math.Max(currentMin.y, currentMax.y) || Math.Max(newMin.y, newMax.y) <= Math.Min(currentMin.y, currentMax.y)) { finalMin.y = -100000; finalMax.y = 100000; } if (Math.Min(newMin.z, newMax.z) >= Math.Max(currentMin.z, currentMax.z) || Math.Max(newMin.z, newMax.z) <= Math.Min(currentMin.z, currentMax.z)) { finalMin.z = -100000; finalMax.z = 100000; } var bigSelection = SelectionFilter.FromSelection(finalMin, finalMax, ~gizmoLayerMask); Collider[] colliders = Physics.OverlapBox(bigSelection.GetCenter(), (Vector3)bigSelection.GetSize() * 0.4999f, Quaternion.identity, ~gizmoLayerMask); if (finalMax.x == 100000) { finalMin.x = (int)colliders.Min(collider => collider.bounds.min.x); finalMax.x = (int)colliders.Max(collider => collider.bounds.max.x); } if (finalMax.y == 100000) { finalMin.y = (int)colliders.Min(collider => collider.bounds.min.y); finalMax.y = (int)colliders.Max(collider => collider.bounds.max.y); } if (finalMax.z == 100000) { finalMin.z = (int)colliders.Min(collider => collider.bounds.min.z); finalMax.z = (int)colliders.Max(collider => collider.bounds.max.z); } selectionFilter = SelectionFilter.FromSelection(finalMin, finalMax, ~gizmoLayerMask); OnSelect(selectionFilter); HideFaces(); } else { IsSelecting = true; selectionFilter = SelectionFilter.NewSelection(raycastHit); } return(true); } return(false); }