//This helps keep the size consistent no matter how far we are from it. float GetDistanceMultiplier() { if (target == null) { return(0f); } return(Mathf.Max(.01f, Mathf.Abs(ExtVector3.MagnitudeInDirection(target.position - transform.position, myCamera.transform.forward)))); }
//Assumes the point is already on the line somewhere public static Vector3 ClampToSegment(Vector3 point, Vector3 linePoint1, Vector3 linePoint2) { Vector3 lineDirection = linePoint2 - linePoint1; if (!ExtVector3.IsInDirection(point - linePoint1, lineDirection)) { point = linePoint1; } else if (ExtVector3.IsInDirection(point - linePoint2, lineDirection)) { point = linePoint2; } return(point); }
IEnumerator TransformSelected(TransformType type) { isTransforming = true; totalScaleAmount = 0; totalRotationAmount = Quaternion.identity; Vector3 originalTargetPosition = target.position; Vector3 planeNormal = (transform.position - target.position).normalized; Vector3 axis = GetSelectedAxisDirection(); Vector3 projectedAxis = Vector3.ProjectOnPlane(axis, planeNormal).normalized; Vector3 previousMousePosition = Vector3.zero; while (!Input.GetMouseButtonUp(0)) { Ray mouseRay = myCamera.ScreenPointToRay(Input.mousePosition); Vector3 mousePosition = Geometry.LinePlaneIntersect(mouseRay.origin, mouseRay.direction, originalTargetPosition, planeNormal); if (previousMousePosition != Vector3.zero && mousePosition != Vector3.zero) { if (type == TransformType.Move) { float moveAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projectedAxis) * moveSpeedMultiplier; target.Translate(axis * moveAmount, Space.World); } if (type == TransformType.Scale) { Vector3 projected = (selectedAxis == Axis.Any) ? transform.right : projectedAxis; float scaleAmount = ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * scaleSpeedMultiplier; //WARNING - There is a bug in unity 5.4 and 5.5 that causes InverseTransformDirection to be affected by scale which will break negative scaling. Not tested, but updating to 5.4.2 should fix it - https://issuetracker.unity3d.com/issues/transformdirection-and-inversetransformdirection-operations-are-affected-by-scale Vector3 localAxis = (space == TransformSpace.Local && selectedAxis != Axis.Any) ? target.InverseTransformDirection(axis) : axis; if (selectedAxis == Axis.Any) { target.localScale += (ExtVector3.Abs(target.localScale.normalized) * scaleAmount); } else { target.localScale += (localAxis * scaleAmount); } totalScaleAmount += scaleAmount; } if (type == TransformType.Rotate) { if (selectedAxis == Axis.Any) { Vector3 rotation = transform.TransformDirection(new Vector3(Input.GetAxis("Mouse Y"), -Input.GetAxis("Mouse X"), 0)); target.Rotate(rotation * allRotateSpeedMultiplier, Space.World); totalRotationAmount *= Quaternion.Euler(rotation * allRotateSpeedMultiplier); } else { Vector3 projected = (selectedAxis == Axis.Any || ExtVector3.IsParallel(axis, planeNormal)) ? planeNormal : Vector3.Cross(axis, planeNormal); float rotateAmount = (ExtVector3.MagnitudeInDirection(mousePosition - previousMousePosition, projected) * rotateSpeedMultiplier) / GetDistanceMultiplier(); target.Rotate(axis, rotateAmount, Space.World); totalRotationAmount *= Quaternion.Euler(axis * rotateAmount); } } } previousMousePosition = mousePosition; yield return(null); } totalRotationAmount = Quaternion.identity; totalScaleAmount = 0; isTransforming = false; }