public void OnSceneGUI() { if (SceneUpdater.IsActive) { //Repaint Inspector in order to update movement changes of the doors Repaint(); //Check if the selected object has been deleted if (doorDefinitions.doors.Count == 0) { selectedDoor = null; } //Autoselect new door //This will also result in initial clamping, see below if (newDoorCreated) { selectedDoor = doorDefinitions.doors [doorDefinitions.doors.Count - 1]; newDoorCreated = false; } //Display doors as rectangle, color them red if selected //It seems like Handles have the limitation of having only floats as size input //Therefore I only support doors with same height / width, sadly foreach (DoorDefinition door in doorDefinitions.doors) { Handles.color = (door == selectedDoor) ? Color.red : Color.blue; if (Handles.Button(door.WorkingPosition, Quaternion.LookRotation(door.Direction), door.Extends.x, door.Extends.x, Handles.RectangleHandleCap)) { selectedDoor = door; } if (SceneUpdater.HideGizmos) { Handles.Label(door.Position, door.Name); } } //Handle logic for selected door if (selectedDoor == null) { doorDefinitions.DraggingDoor = null; } else { //Chewing gum effect. The handles are using the working position of the doors //Since also the offset is changed (below) the actual position of the door is bein calculated regardless //When releasing the mouse, set the working position to the current, calculated position //They may differ, since the working position is NOT aligned to the grid if (Event.current.type == EventType.MouseDown) { doorDefinitions.DraggingDoor = selectedDoor; } if (Event.current.type == EventType.MouseUp) { doorDefinitions.DraggingDoor = null; doorDefinitions.AdjustWorkingPosition(selectedDoor); } Vector3 horHandleDir = Vector3.Cross(Vector3.up, selectedDoor.Direction); if (horHandleDir.magnitude == 0f) { selectedDoor = null; return; } float sliderSize = HandleUtility.GetHandleSize(selectedDoor.WorkingPosition) * 1.5f; //Draw Move Arrows, use Normal in order to point it at the right direction Handles.color = horHandleDir.normalized == Vector3.right || horHandleDir.normalized == Vector3.left ? Color.red : Color.blue; selectedDoor.WorkingPosition = Handles.Slider(selectedDoor.WorkingPosition, horHandleDir, selectedDoor.Extends.x * sliderSize, Handles.ArrowHandleCap, 1f); Handles.color = Color.green; selectedDoor.WorkingPosition = Handles.Slider(selectedDoor.WorkingPosition, Vector3.up, selectedDoor.Extends.y * sliderSize, Handles.ArrowHandleCap, 1f); //Eventhough the position is already being clamped in the preview function of doorsPositions, //This clamp is important since several frames may pass before the next call of preview doorDefinitions.ClampPosition(selectedDoor); //Calculate Offset to the selected corner. Essential for docking //DoorDefinitions later calculates the position from the corner pos and offset selectedDoor.Offset = selectedDoor.WorkingPosition - doorDefinitions.AbstractBounds.Corners[selectedDoor.CornerIndex]; doorDefinitions.UpdateYOffset(selectedDoor.Offset.y); //Uniform handle size factor float directionHandleSize = HandleUtility.GetHandleSize(selectedDoor.WorkingPosition) * 0.8f; //Get one of four directions. The direction represent the wall the door is locked to. Vector3 newDirection = EditorGUIExtension.DirectionHandleVec(selectedDoor.WorkingPosition, directionHandleSize, selectedDoor.Direction, new Vector3(1f, 0f, 1f)); if (newDirection != selectedDoor.Direction) { selectedDoor.Direction = newDirection; //Default docking corner is at index one, bottom middle. See AbstractBounds for corner indices. selectedDoor.CornerIndex = doorDefinitions.AbstractBounds.CornerIndicesByDirection(newDirection) [1]; selectedDoor.Position = doorDefinitions.AbstractBounds.Corners [selectedDoor.CornerIndex]; doorDefinitions.ClampPosition(selectedDoor); doorDefinitions.AdjustWorkingPosition(selectedDoor); } //Retrieve all corner positions belonging to a certain wall defined by a direction vector int[] indices = doorDefinitions.AbstractBounds.CornerIndicesByDirection(selectedDoor.Direction); //Draw docking buttons foreach (int i in indices) { float dockHandleSize = HandleUtility.GetHandleSize(doorDefinitions.AbstractBounds.Corners[i]) * 0.1f; if (Handles.Button(doorDefinitions.AbstractBounds.Corners [i], Quaternion.identity, dockHandleSize, dockHandleSize, Handles.DotHandleCap)) { selectedDoor.Position = doorDefinitions.AbstractBounds.Corners [i]; selectedDoor.Offset = Vector2.up * doorDefinitions.GlobalYOffset; selectedDoor.CornerIndex = i; ApplyCornerHeight(i); doorDefinitions.AdjustWorkingPosition(selectedDoor); } } } } }