예제 #1
0
    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);
                    }
                }
            }
        }
    }