private void RotateTargets() { var boundsQConfig = GetBoundsQConfig(); float rotationAmount = InputDeviceManager.Get.MouseDelta.x * SharedSettings.RotationSensitivity; EditorUndoEx.RecordObjectTransforms(_targetParents); foreach (var grabTarget in _grabTargets) { if (grabTarget == null) { continue; } OOBB targetOOBB = ObjectBounds.CalcHierarchyWorldOOBB(grabTarget.GameObject, boundsQConfig); if (!targetOOBB.IsValid) { continue; } var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer); if (layerGrabSettings.IsActive) { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, layerGrabSettings.AlignAxis ? grabTarget.SittingPlane.normal : Vector3.up); grabTarget.Transform.RotateAroundPivot(rotation, targetOOBB.Center); } else { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, SharedSettings.AlignAxis ? grabTarget.SittingPlane.normal : Vector3.up); grabTarget.Transform.RotateAroundPivot(rotation, targetOOBB.Center); } } CalculateGrabTargetsAnchorVectors(); }
private void RotateTargetsAroundAnchor() { EditorUndoEx.RecordObjectTransforms(_targetParents); float rotationAmount = InputDeviceManager.Get.MouseDelta.x * SharedSettings.RotationSensitivity; foreach (var grabTarget in _grabTargets) { if (grabTarget == null) { continue; } var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer); if (layerGrabSettings.IsActive) { if (layerGrabSettings.AlignAxis) { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, _grabSurfaceInfo.AnchorNormal); grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint); grabTarget.AnchorVector = rotation * grabTarget.AnchorVector; } else { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, Vector3.up); grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint); grabTarget.AnchorVector = rotation * grabTarget.AnchorVector; } } else { if (SharedSettings.AlignAxis) { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, _grabSurfaceInfo.AnchorNormal); grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint); grabTarget.AnchorVector = rotation * grabTarget.AnchorVector; } else { Quaternion rotation = Quaternion.AngleAxis(rotationAmount, Vector3.up); grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint); grabTarget.AnchorVector = rotation * grabTarget.AnchorVector; } } } SnapTargetsToSurface(); }
private void OffsetTargetsFromAnchor() { EditorUndoEx.RecordObjectTransforms(_targetParents); float scaleFactor = 1.0f + InputDeviceManager.Get.GetMouseCaptureDelta(_deltaCaptureId).x *SharedSettings.OffsetFromAnchorSensitivity; foreach (var grabTarget in _grabTargets) { if (grabTarget == null) { continue; } grabTarget.Transform.position = (_grabSurfaceInfo.AnchorPoint + grabTarget.AnchorVectorSnapshot * scaleFactor); } CalculateGrabTargetsAnchorVectors(); SnapTargetsToSurface(); }
private void ScaleTargets() { EditorUndoEx.RecordObjectTransforms(_targetParents); foreach (var grabTarget in _grabTargets) { if (grabTarget == null) { continue; } //float maxAbsScaleComp = grabTarget.WorldScaleSnapshot.GetMaxAbsComp(); //float scaleFactor = 1.0f + inputDevice.GetCaptureDelta(_inputDevScaleDeltaCaptureId).x * (Settings.ScaleDeviceSensitivity / maxAbsScaleComp); float scaleFactor = 1.0f + InputDeviceManager.Get.GetMouseCaptureDelta(_deltaCaptureId).x *SharedSettings.ScaleSensitivity; Vector3 newScale = grabTarget.WorldScaleSnapshot * scaleFactor; grabTarget.GameObject.SetHierarchyWorldScaleByPivot(newScale, grabTarget.SittingPoint + grabTarget.SittingPlane.normal * grabTarget.OffsetFromSurface); } CalculateGrabTargetsAnchorVectors(); //SnapTargetsToSurface(); }
public void RenderEditorGUI(UnityEngine.Object undoRecordObject) { bool newBool; const float toggleWidth = 65.0f; // Shortcut name label EditorGUILayout.BeginVertical("Box"); EditorGUILayoutEx.SectionHeader(Name); // Enabled/disabled var content = new GUIContent(); content.text = "Is enabled"; content.tooltip = "Allows you to enable/disable a shortcut key."; newBool = EditorGUILayout.ToggleLeft(content, IsEnabled); if (newBool != IsEnabled) { EditorUndoEx.Record(undoRecordObject); IsEnabled = newBool; } // For each possible key, let the user specify its key code for (int keyIndex = 0; keyIndex < _maxNumberOfKeys; ++keyIndex) { int selectedIndex = _availableKeyNames.IndexOf(_keys[keyIndex].ToString()); int newIndex = EditorGUILayout.Popup("Key" + keyIndex.ToString(), selectedIndex, _availableKeyNames.ToArray()); if (newIndex != selectedIndex) { EditorUndoEx.Record(undoRecordObject); _keys[keyIndex] = _availableKeys[newIndex]; } } // Modifiers EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical("Box"); newBool = EditorGUILayout.ToggleLeft("LCtrl", _lCtrl, GUILayout.Width(toggleWidth)); if (newBool != _lCtrl) { EditorUndoEx.Record(undoRecordObject); _lCtrl = newBool; } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("Box"); newBool = EditorGUILayout.ToggleLeft("LCmd", _lCmd, GUILayout.Width(toggleWidth)); if (newBool != _lCmd) { EditorUndoEx.Record(undoRecordObject); _lCmd = newBool; } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("Box"); newBool = EditorGUILayout.ToggleLeft("LAlt", _lAlt, GUILayout.Width(toggleWidth)); if (newBool != _lAlt) { EditorUndoEx.Record(undoRecordObject); _lAlt = newBool; } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("Box"); newBool = EditorGUILayout.ToggleLeft("LShift", _lShift, GUILayout.Width(toggleWidth)); if (newBool != _lShift) { EditorUndoEx.Record(undoRecordObject); _lShift = newBool; } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); }
private void SnapTargetsToSurface() { if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Invalid) { return; } Surface.ObjectSnapConfig snapConfig = new Surface.ObjectSnapConfig(); snapConfig.SurfaceHitPoint = _grabSurfaceInfo.AnchorPoint; snapConfig.SurfaceHitNormal = _grabSurfaceInfo.AnchorNormal; snapConfig.SurfaceHitPlane = _grabSurfaceInfo.AnchorPlane; snapConfig.SurfaceObject = _grabSurfaceInfo.SceneRaycastHit.WasAnObjectHit ? _grabSurfaceInfo.SceneRaycastHit.ObjectHit.HitObject : null; snapConfig.SurfaceType = Surface.Type.UnityTerrain; if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Mesh) { snapConfig.SurfaceType = Surface.Type.Mesh; } else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Grid) { snapConfig.SurfaceType = Surface.Type.SceneGrid; } else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.SphericalMesh) { snapConfig.SurfaceType = Surface.Type.SphericalMesh; } else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.TerrainMesh) { snapConfig.SurfaceType = Surface.Type.TerrainMesh; } EditorUndoEx.RecordObjectTransforms(_targetParents); foreach (var grabTarget in _grabTargets) { if (grabTarget.GameObject == null) { continue; } grabTarget.Transform.position = _grabSurfaceInfo.AnchorPoint + grabTarget.AnchorVector; var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer); if (layerGrabSettings.IsActive) { snapConfig.AlignAxis = layerGrabSettings.AlignAxis; snapConfig.AlignmentAxis = layerGrabSettings.AlignmentAxis; snapConfig.OffsetFromSurface = layerGrabSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface; } else { snapConfig.AlignAxis = SharedSettings.AlignAxis; snapConfig.AlignmentAxis = SharedSettings.AlignmentAxis; snapConfig.OffsetFromSurface = SharedSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface; } var snapResult = Surface.SnapHierarchy(grabTarget.GameObject, snapConfig); if (snapResult.WasSnapped) { grabTarget.SittingPlane = snapResult.SittingPlane; grabTarget.SittingPoint = snapResult.SittingPoint; } } }
protected override void RenderContent(UnityEngine.Object undoRecordObject) { bool newBool; float newFloat; int newInt; TransformAxis newTransformAxis; EditorGUILayoutEx.SectionHeader("Alignment"); var content = new GUIContent(); content.text = "Align axis"; content.tooltip = "If this is checked, the grabbed objects will have their local axes aligned with the grab surface normal."; newBool = EditorGUILayout.ToggleLeft(content, AlignAxis); if (newBool != AlignAxis) { EditorUndoEx.Record(undoRecordObject); AlignAxis = newBool; } content.text = "Alignment axis"; content.tooltip = "When axis alignment is turned on, this is the axis that will be aligned to the surface normal."; newTransformAxis = (TransformAxis)EditorGUILayout.EnumPopup(content, AlignmentAxis); if (newTransformAxis != AlignmentAxis) { EditorUndoEx.Record(undoRecordObject); AlignmentAxis = newTransformAxis; } EditorGUILayout.Separator(); EditorGUILayoutEx.SectionHeader("Sensitivity"); content.text = "Rotation"; content.tooltip = "Allows you to control how sensitive object rotation is to the input device."; newFloat = EditorGUILayout.FloatField(content, RotationSensitivity); if (newFloat != RotationSensitivity) { EditorUndoEx.Record(undoRecordObject); RotationSensitivity = newFloat; } content.text = "Scale"; content.tooltip = "Allows you to control how sensitive object scaling is to the input device."; newFloat = EditorGUILayout.FloatField(content, ScaleSensitivity); if (newFloat != ScaleSensitivity) { EditorUndoEx.Record(undoRecordObject); ScaleSensitivity = newFloat; } content.text = "Offset from surface"; content.tooltip = "Sensitivity value used when offseting objects from the surface on which they are sitting."; newFloat = EditorGUILayout.FloatField(content, OffsetFromSurfaceSensitivity); if (newFloat != OffsetFromSurfaceSensitivity) { EditorUndoEx.Record(undoRecordObject); OffsetFromSurfaceSensitivity = newFloat; } content.text = "Offset from anchor"; content.tooltip = "Sensitivity value used when offseting objects from the anchor point."; newFloat = EditorGUILayout.FloatField(content, OffsetFromAnchorSensitivity); if (newFloat != OffsetFromAnchorSensitivity) { EditorUndoEx.Record(undoRecordObject); OffsetFromAnchorSensitivity = newFloat; } EditorGUILayout.Separator(); EditorGUILayoutEx.SectionHeader("Surface"); content.text = "Default offset"; content.tooltip = "A default offset value which controls the distance between the objects and the surface they are sitting on. Negative values can be used to embed objects in the surface."; newFloat = EditorGUILayout.FloatField(content, DefaultOffsetFromSurface); if (newFloat != DefaultOffsetFromSurface) { EditorUndoEx.Record(undoRecordObject); DefaultOffsetFromSurface = newFloat; } content.text = "Surface flags"; content.tooltip = "Allows you to specify the types of surfaces that can be used during a grab session."; newInt = (int)((ObjectGrabSurfaceFlags)EditorGUILayout.EnumMaskPopup(content, (ObjectGrabSurfaceFlags)SurfaceFlags)); if (newInt != (int)SurfaceFlags) { EditorUndoEx.Record(undoRecordObject); SurfaceFlags = (ObjectGrabSurfaceFlags)newInt; } content.text = "Surface layers"; content.tooltip = "Allows you to specify which layers can be used as snap surface during a grab session."; newInt = EditorGUILayoutEx.LayerMaskField(content, SurfaceLayers); if (newInt != SurfaceLayers) { EditorUndoEx.Record(undoRecordObject); SurfaceLayers = newInt; } content.text = "Spherical mesh layers"; content.tooltip = "Objects that belong to these layers will be treated as spherical meshes (spheres). This allows the system to make " + "certain assumptions about the surface geometry in order to produce the correct results."; newInt = EditorGUILayoutEx.LayerMaskField(content, SphericalMeshLayers); if (newInt != SphericalMeshLayers) { EditorUndoEx.Record(undoRecordObject); SphericalMeshLayers = newInt; } content.text = "Terrain mesh layers"; content.tooltip = "Objects that belong to these layers will be treated as terrain meshes (meshes that resemble a terrain but are NOT Unity Terrains). This allows the system to make " + "certain assumptions about the surface geometry in order to produce the correct results."; newInt = EditorGUILayoutEx.LayerMaskField(content, TerrainMeshLayers); if (newInt != TerrainMeshLayers) { EditorUndoEx.Record(undoRecordObject); TerrainMeshLayers = newInt; } EditorGUILayout.Separator(); EditorGUILayoutEx.SectionHeader("Per layer settings"); EditorGUILayout.BeginHorizontal(); content.text = "Add"; content.tooltip = "Adds grab settings which apply only to the chosen layer. Objects which belong to that layer will use these settings during a grab session."; if (GUILayout.Button(content, GUILayout.Width(70.0f))) { EditorUndoEx.Record(undoRecordObject); GetLayerGrabSettings(_newLayer).IsActive = true; } newInt = EditorGUILayout.LayerField(_newLayer); if (newInt != _newLayer) { EditorUndoEx.Record(undoRecordObject); _newLayer = newInt; } EditorGUILayout.EndHorizontal(); foreach (var layerGrabSettings in _layerGrabSettings) { if (layerGrabSettings.IsActive) { EditorGUILayout.BeginVertical("Box"); EditorGUILayout.HelpBox(LayerMask.LayerToName(layerGrabSettings.Layer), MessageType.None); content.text = "Align axis"; content.tooltip = "If this is checked, the grabbed objects that belong to this layer will have their local axes aligned with the grab surface normal."; newBool = EditorGUILayout.ToggleLeft(content, layerGrabSettings.AlignAxis); if (newBool != layerGrabSettings.AlignAxis) { EditorUndoEx.Record(undoRecordObject); layerGrabSettings.AlignAxis = newBool; } content.text = "Alignment axis"; content.tooltip = "When axis alignment is turned on, this is the axis that will be aligned to the surface normal."; newTransformAxis = (TransformAxis)EditorGUILayout.EnumPopup(content, layerGrabSettings.AlignmentAxis); if (newTransformAxis != layerGrabSettings.AlignmentAxis) { EditorUndoEx.Record(undoRecordObject); layerGrabSettings.AlignmentAxis = newTransformAxis; } content.text = "Default offset from surface"; content.tooltip = "A default offset value which controls the distance between the objects and the surface they are sitting on. Negative values can be used to embed objects in the surface."; newFloat = EditorGUILayout.FloatField(content, layerGrabSettings.DefaultOffsetFromSurface); if (newFloat != layerGrabSettings.DefaultOffsetFromSurface) { EditorUndoEx.Record(undoRecordObject); layerGrabSettings.DefaultOffsetFromSurface = newFloat; } content.text = "Remove"; content.tooltip = "Removes the settings for this layer."; if (GUILayout.Button(content, GUILayout.Width(70.0f))) { EditorUndoEx.Record(undoRecordObject); layerGrabSettings.IsActive = false; } EditorGUILayout.EndVertical(); } } }
protected override void RenderContent(UnityEngine.Object undoRecordObject) { bool newBool; Color newColor; float newFloat; var content = new GUIContent(); content.text = "Show anchor lines"; content.tooltip = "If this is checked, a line will be drawn between each object's position and the intersection point between the mouse cursor and the snap surface."; newBool = EditorGUILayout.ToggleLeft(content, ShowAnchorLines); if (newBool != ShowAnchorLines) { EditorUndoEx.Record(undoRecordObject); ShowAnchorLines = newBool; } content.text = "Show target boxes"; content.tooltip = "If this is checked, a wire box will be rendered for all hierarchies that are involved in a surface snap session."; newBool = EditorGUILayout.ToggleLeft(content, ShowTargetBoxes); if (newBool != ShowTargetBoxes) { EditorUndoEx.Record(undoRecordObject); ShowTargetBoxes = newBool; } content.text = "Show anchor line ticks"; content.tooltip = "If this is checked, ticks will be drawn at the beginning and end points of anchor lines."; newBool = EditorGUILayout.ToggleLeft(content, ShowAnchorLineTicks); if (newBool != ShowAnchorLineTicks) { EditorUndoEx.Record(undoRecordObject); ShowAnchorLineTicks = newBool; } content.text = "Anchor line color"; content.tooltip = "Allows you to change the color of the anchor lines. These are the lines that are drawn from the " + "object positions to the intersection point between the mouse cursor and the snap surface."; newColor = EditorGUILayout.ColorField(content, AnchorLineColor); if (newColor != AnchorLineColor) { EditorUndoEx.Record(undoRecordObject); AnchorLineColor = newColor; } content.text = "Target wire box color"; content.tooltip = "Allows you to change the wire color of target boxes. These are the boxes that are drawn for each hierarchy " + "that is controlled by a snap session."; newColor = EditorGUILayout.ColorField(content, TargetWireBoxColor); if (newColor != TargetWireBoxColor) { EditorUndoEx.Record(undoRecordObject); TargetWireBoxColor = newColor; } content.text = "Anchor line tick color"; content.tooltip = "Allows you to change the color of the anchor line ticks."; newColor = EditorGUILayout.ColorField(content, AnchorLineTickColor); if (newColor != AnchorLineTickColor) { EditorUndoEx.Record(undoRecordObject); AnchorLineTickColor = newColor; } content.text = "Anchor line tick size"; content.tooltip = "Allows you to change the size of the anchor line ticks."; newFloat = EditorGUILayout.FloatField(content, AnchorLineTickSize); if (newFloat != AnchorLineTickSize) { EditorUndoEx.Record(undoRecordObject); AnchorLineTickSize = newFloat; } }