private void SnapToElement(SnapTo snapTo) { _origin = horizontal ? this.horizontalScrollbar.value : this.verticalScrollbar.value; _snapStartTime = Time.time; float prev = Mathf.Floor(_origin * _nbSteps) / _nbSteps; float next = Mathf.Ceil(_origin * _nbSteps) / _nbSteps; switch (snapTo) { case SnapTo.Next: _target = next; break; case SnapTo.Previous: _target = prev; break; case SnapTo.Closest: if (_origin - prev > next - _origin) { _target = next; } else { _target = prev; } break; } }
Vector2 RelativePosition(Vector2 pos, SnapTo corner) { Vector2 r = new Vector2(); switch (corner) { case SnapTo.BottomLeft: case SnapTo.TopLeft: r.x = pos.x; break; case SnapTo.TopRight: case SnapTo.BottomRight: r.x = rectTransform.rect.size.x - pos.x; break; } switch (corner) { case SnapTo.TopLeft: case SnapTo.TopRight: r.y = rectTransform.rect.size.y - pos.y; break; case SnapTo.BottomLeft: case SnapTo.BottomRight: r.y = pos.y; break; } return(r); }
public override void OnEndDrag(PointerEventData eventData) { base.OnEndDrag(eventData); SnapTo snapTo = SnapTo.Closest; if (Time.time - _dragStartTime < 0.2) { if (horizontal) { snapTo = eventData.position.x > eventData.pressPosition.x ? SnapTo.Previous : SnapTo.Next; } else { snapTo = eventData.position.y > eventData.pressPosition.y ? SnapTo.Previous : SnapTo.Next; } } SnapToElement(snapTo); }
public GameObject getNearestSnappable() { DragObject targetScript = target.GetComponent <DragObject>(); GameObject[] snapToObjects = GameObject.FindGameObjectsWithTag("snap"); GameObject nearestObject = null; double largestDistance = double.PositiveInfinity; //get the nearest snappable object within its threshold for (int i = 0; i < snapToObjects.Length; i++) { GameObject g = snapToObjects[i]; SnapTo gSnap = g.GetComponent <SnapTo>(); Vector2 newPos = gameObject.transform.position; //if the target wants to snap to the bottom, calculate distance based on the bottom of the sprite //so it'll feel more accurate to the player if (gSnap.snapBottom) { SpriteRenderer spr = gameObject.GetComponent <SpriteRenderer>(); newPos = new Vector2(gameObject.transform.position.x, spr.bounds.min.y); } //check this.threshold and the other object's threshold to find the closest float d = GetDistance(newPos, g.transform.position); //various error checking if ((d < threshold || d < g.GetComponent <SnapTo>().threshold) && d < largestDistance && (!targetScript.snapExclusive || targetScript.snapToNameTag.Contains(g.name) || targetScript.snapToNameTag.Contains(g.tag)) && g != gameObject && g != target && g != null && (!gSnap.exclusive || gSnap.acceptNameTag.Contains(target.name) || gSnap.acceptNameTag.Contains(target.tag)) && !gSnap.holdingObject) { nearestObject = g; } } return(nearestObject); }
void UpdateSnapping(ref State updateState) { // Check where to snap to if ((teleportOnNextSnap == false) && (IsSnappedToContent == false)) { // Move to the closest object if (horizontal == true) { horizontalNormalizedPosition = Mathf.SmoothDamp(horizontalNormalizedPosition, SnapTo.HorizontalRatio(numberOfSnappingPoints.Horizontal), ref horizontalSpeed, elasticity); } if (vertical == true) { verticalNormalizedPosition = Mathf.SmoothDamp(verticalNormalizedPosition, SnapTo.VerticalRatio(numberOfSnappingPoints.Vertical), ref verticalSpeed, elasticity); } } else { // Move to the closest object if (horizontal == true) { horizontalNormalizedPosition = SnapTo.HorizontalRatio(numberOfSnappingPoints.Horizontal); } if (vertical == true) { verticalNormalizedPosition = SnapTo.VerticalRatio(numberOfSnappingPoints.Vertical); } // Update flags horizontalSpeed = 0; verticalSpeed = 0; teleportOnNextSnap = false; updateState = State.Still; // Run content changed event if (OnClosestContentChanged != null) { UpdateContentChanged(); } } }
//Drag the object public void OnMouseDown() { if (locked) { return; } //this is for when the object's parent should be dragged instead targetScript = target.GetComponent <DragObject>(); targetScript.dragged = true; //if it's draggable if (draggable) { target = this.gameObject; } //if not, if it has a draggable parent else if (gameObject.transform.parent != null && gameObject.transform.parent.gameObject.GetComponent <DragObject>() != null && !draggable) { target = gameObject.transform.parent.gameObject; } //so if it's not and neither is the parent else { } //keep track of snapped object if (targetScript.snappedObject != null) { SnapTo snappedTo = targetScript.snappedObject.GetComponent <SnapTo>(); snappedTo.holdingObject = false; snappedObject = null; } screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position); offset = target.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)); }
void OnGUI() { EditorGUILayout.LabelField("Duplicate Special", EditorStyles.boldLabel); around = ( SnapTo )EditorGUILayout.EnumPopup("Operation", around); EditorGUI.BeginChangeCheck(); space = ( Space )EditorGUILayout.EnumPopup("Space", space); dir = ( Direction )EditorGUILayout.EnumPopup("Direction", dir); useEpsilon = EditorGUILayout.Toggle("Use Epsilon", useEpsilon); randomizeYRotation = EditorGUILayout.Toggle("Randomize Y Rotation", randomizeYRotation); randomizeScale = EditorGUILayout.Toggle("Randomize Scale", randomizeScale); randomizeSpacing = EditorGUILayout.Toggle("Randomize Spacing", randomizeSpacing); if (randomizeSpacing) { radius = EditorGUILayout.FloatField("Radius", radius); } else { radius = 0; } if (EditorGUI.EndChangeCheck()) { SceneView.RepaintAll(); } count = EditorGUILayout.IntField("Count", count); if (GUILayout.Button("Duplicate")) { if (Selection.activeGameObject) { instantiatedObjects.Clear(); Transform selection = Selection.activeGameObject.transform; referenceObject = selection.gameObject; if (space == Space.Global) { int index = Mathf.Abs(( int )dir); Vector3 vDir = indexToDirection(index); bounds = new Bounds(selection.position, Vector3.zero); MeshRenderer [] renderers = selection.GetComponentsInChildren <MeshRenderer>(); foreach (var renderer in renderers) { bounds.Encapsulate(renderer.bounds); } float f = bounds.extents [Mathf.Abs(( int )dir) - 1] * 2; if (useEpsilon) { f -= Mathf.Epsilon; } for (int i = 1; i <= count; i++) { Vector3 position = selection.position + vDir * f * i; Quaternion rotation = selection.rotation; Vector3 scale = selection.localScale; if (randomizeSpacing) { position = selection.position + vDir * i * radius; Vector2 rndCircle = UnityEngine.Random.insideUnitCircle * radius * .5f; position += new Vector3(rndCircle.x, 0f, rndCircle.y); } if (randomizeYRotation) { rotation = Quaternion.AngleAxis(UnityEngine.Random.value * 360f, Vector3.up) * Quaternion.AngleAxis(UnityEngine.Random.value * 10f, Vector3.right) * Quaternion.AngleAxis(UnityEngine.Random.value * 10f, Vector3.forward); } if (randomizeScale) { scale = new Vector3(UnityEngine.Random.Range(1f, 1.5f), UnityEngine.Random.Range(1f, 1.5f), UnityEngine.Random.Range(1f, 1.5f)); } if (PrefabUtility.IsPartOfAnyPrefab(selection.gameObject)) { GameObject go = ( GameObject )PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath( PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(Selection.activeObject), typeof(GameObject)), selection.parent); go.transform.position = position; go.transform.rotation = rotation; go.transform.localScale = scale; instantiatedObjects.Add(go); } else { GameObject go = Instantiate(selection.gameObject, position, rotation); go.transform.SetParent(selection.parent, true); go.transform.localScale = scale; instantiatedObjects.Add(go); } } } else if (space == Space.Local) { } } else { Debug.LogError("DuplicateSpecial : Selected object is null."); } } if (GUILayout.Button("Undo")) { instantiatedObjects.ForEach(x => UnityEngine.Object.DestroyImmediate(x)); } }
public void SnapTo(GameObject nearestObject) { //else, continue as normal snappedOnce = true; targetScript.snappedObject = nearestObject; SnapTo snappedTo = nearestObject.GetComponent <SnapTo>(); //future proof :^) snappedTo.Accept(target); if (snappedTo.destroyOnSnap) { return; } //try to nest them for moving and remove the drag ability (optional) if (targetScript.snappedObject.transform.parent != null) { target.transform.parent = targetScript.snappedObject.transform.parent; } //otherwise, just nest directly to the parent else { target.transform.parent = targetScript.snappedObject.transform; } spr = target.GetComponent <SpriteRenderer>(); //snap to the bottom if (snappedTo.snapBottom) { float xPos = nearestObject.transform.position.x; float bottomY = nearestObject.transform.position.y - nearestObject.GetComponent <SpriteRenderer>().sprite.bounds.extents.y; float offset = spr.bounds.extents.y; float yPos = bottomY + offset; target.transform.position = new Vector2(xPos, yPos); } else //or just the target transform { target.transform.Translate(nearestObject.transform.position.x - target.transform.position.x, nearestObject.transform.position.y - target.transform.position.y, 0); } //edit the snapped object properties nearestObject.GetComponent <SnapTo>().holdingObject = true; if (lockOnSnap) { draggable = false; //now if this is dragged it'll drag the parent } //update the drag target //if it's draggable //make the target the parent on mouseUp for highlighting fixes if (gameObject.transform.parent != null && gameObject.transform.parent.gameObject.GetComponent <DragObject>() != null) { target = gameObject.transform.parent.gameObject; //THIS FIXES THE HIGHLIGHT ISSUE FOR SOME REASON } else if (draggable) { target = gameObject; } //if not, if it has a draggable parent else if (gameObject.transform.parent != null && gameObject.transform.parent.gameObject.GetComponent <DragObject>() != null && !draggable) { target = gameObject.transform.parent.gameObject; } lastSnappedTo = nearestObject; }