/// <summary> /// Notifies the system to start recording a new undo command. Any changes to scene object fields after this is /// called will be recorded in the command. User must call <see cref="EndUndo"/> after the field is done being /// changed. /// </summary> /// <param name="name">Name of the field being changed.</param> private void StartUndo(string name) { if (activeSO != null) { GameObjectUndo.RecordSceneObjectHeader(activeSO, name); } }
/// <inheritdoc/> protected internal override void PostInput() { if (activeHandle != null) { if (activeHandle.IsDragged()) { if (!isDragged) { isDragged = true; SceneObject[] selectedSceneObjects = Selection.SceneObjects; GameObjectUndo.RecordSceneObjectHeader(selectedSceneObjects); activeSelection = new HandledObject[selectedSceneObjects.Length]; for (int i = 0; i < selectedSceneObjects.Length; i++) { activeSelection[i] = new HandledObject(selectedSceneObjects[i]); } initialHandlePosition = activeHandle.Position; initialHandleRotation = activeHandle.Rotation; } } else { if (isDragged) { GameObjectUndo.ResolveDiffs(); } isDragged = false; activeSelection = null; } activeHandle.PostInput(); if (activeHandle.IsDragged()) { switch (activeHandleType) { case SceneViewTool.Move: MoveHandle moveHandle = (MoveHandle)activeHandle; foreach (var selectedObj in activeSelection) { SceneObject parentSO = selectedObj.so.Parent; if (parentSO == null) { selectedObj.so.LocalPosition = selectedObj.initialPosition + moveHandle.Delta; } else { Vector3 parentRelativeDelta = parentSO.Rotation.Inverse.Rotate(moveHandle.Delta); selectedObj.so.LocalPosition = selectedObj.initialPosition + parentRelativeDelta; } } break; case SceneViewTool.Rotate: { RotateHandle rotateHandle = (RotateHandle)activeHandle; // Make sure we transform relative to the handle position SceneObject temporarySO = new SceneObject("Temp"); temporarySO.Position = initialHandlePosition; temporarySO.LocalRotation = initialHandleRotation; SceneObject[] originalParents = new SceneObject[activeSelection.Length]; for (int i = 0; i < activeSelection.Length; i++) { originalParents[i] = activeSelection[i].so.Parent; activeSelection[i].so.LocalPosition = activeSelection[i].initialPosition; activeSelection[i].so.LocalRotation = activeSelection[i].initialRotation; activeSelection[i].so.Parent = temporarySO; } temporarySO.LocalRotation *= rotateHandle.Delta; for (int i = 0; i < activeSelection.Length; i++) { activeSelection[i].so.Parent = originalParents[i]; } temporarySO.Destroy(); } break; case SceneViewTool.Scale: { ScaleHandle scaleHandle = (ScaleHandle)activeHandle; Vector3 origin = activeHandle.Position; for (int i = 0; i < activeSelection.Length; i++) { Vector3 posDiff = activeSelection[i].initialPosition - origin; Vector3 scale = activeSelection[i].initialScale; Vector3 newScale = scale + scaleHandle.Delta; Vector3 pctScale = new Vector3( newScale.x / scale.x, newScale.y / scale.y, newScale.z / scale.z); activeSelection[i].so.LocalScale = newScale; activeSelection[i].so.Position = origin + posDiff * pctScale; } } break; } SceneObject[] selectedSceneObjects = new SceneObject[activeSelection.Length]; for (int i = 0; i < activeSelection.Length; i++) { selectedSceneObjects[i] = activeSelection[i].so; } // Make sure to update handle positions for the drawing method (otherwise they lag one frame) UpdateActiveHandleTransform(selectedSceneObjects); EditorApplication.SetSceneDirty(); } } else { isDragged = false; activeSelection = null; } }