[Unity] Dungeon Gunner (8) - Dungeon Creation Design [6]

suhan0304·2024년 1월 17일
0
post-thumbnail

룸 노드 잠금 기능

새로 생성한 룸 노드가 Entarnce 노드에 연결되면 잠금되서 룸 타입을 바꾸지 못하도록 룸 노드 잠금을 추가한다. 이때 룸 노드를 하나라도 생성하면 자동으로 Entrance 노드가 생성되도록 하고 Entrance 노드에 연결되야만 룸 노드가 잠금되도록 스크립트를 작성한다.

이렇게 룸 노드 타입이 결정되고 잠금이 되면 더 이상 해당 룸 노드에 대해서는 유효성 검사를 추가로 진행하지 않는다.

RoomNodeGraphEditor.cs

public class RoomNodeGraphEditor : EditorWindow //편집기
{
    private GUIStyle roomNodeSelectedStyle;
    
	private void OnEnable()
    {
        // Subscribe to the inspector selection changed event
        Selection.selectionChanged += InspectorSelectionChanged;

        // Define node layout style
        roomNodeStyle = new GUIStyle();
        roomNodeStyle.normal.background = EditorGUIUtility.Load("node1") as Texture2D;
        roomNodeStyle.normal.textColor = Color.white;
        roomNodeStyle.padding = new RectOffset(nodePadding, nodePadding, nodePadding, nodePadding);
        roomNodeStyle.border = new RectOffset(nodeBorder, nodeBorder, nodeBorder, nodeBorder);

        // Define selected node style
        roomNodeSelectedStyle = new GUIStyle();
        roomNodeSelectedStyle.normal.background = EditorGUIUtility.Load("node1 on") as Texture2D;
        roomNodeSelectedStyle.normal.textColor = Color.white;
        roomNodeSelectedStyle.padding = new RectOffset(nodePadding, nodePadding, nodePadding, nodePadding);
        roomNodeSelectedStyle.border = new RectOffset(nodeBorder, nodeBorder, nodeBorder, nodeBorder);

        // Load Room Node types
        roomNodeTypeList = GameResources.Instance.roomNodeTypeList;
        Selection.selectionChanged -= InspectorSelectionChanged;
    }

    private void OnDisable()
    {
        // Unsubscribe from the inspector selection changed event
    }


    /// <summary>
    /// Process mouse down events on the room node graph (not over a node)
    /// </summary>
    private void ProcessMouseDownEvent(Event currentEvent)
    {
        // Process right click mouse down on graph event (show context menu)
        if(currentEvent.button == 1)
        {
            ShowContextMenu(currentEvent.mousePosition);
        }
        // Process left click mouse down on graph event
        else if(currentEvent.button == 0)
        {
            ClearLineDrag();
            ClearAllSelectedRoomNodes();
        }


    /// <summary>
    /// Clear selection from all room nodes
    /// </summary>
    private void ClearAllSelectedRoomNodes()
    {
        foreach (RoomNodeSO roomNode in currentRoomNodeGraph.roomNodeList)
        {
            if (roomNode.isSelected)
            {
                roomNode.isSelected = false;

                GUI.changed = true;
            }
        }
    }


    /// <summary>
    /// Draw room nodes in the graph window
    /// </summary>
    private void DrawRoomNodes()
    {
        // Loop through all room nodes and draw them
        foreach (RoomNodeSO roomNode in currentRoomNodeGraph.roomNodeList)
        {
            if (roomNode.isSelected)
            {
                roomNode.Draw(roomNodeSelectedStyle);
            }
            else
            {
                roomNode.Draw(roomNodeStyle);
            }
        }

        GUI.changed = true;
    }

    /// <summary>
    /// Selection changed in the inspector
    /// </summary>
    private void InspectorSelectionChanged()
    {
        RoomNodeGraphSO roomNodeGraph = Selection.activeObject as RoomNodeGraphSO;

        if (roomNodeGraph != null)
        {
            currentRoomNodeGraph = roomNodeGraph;
            GUI.changed = true;
        }
    }
}

RoomNodeSO.cs

public class RoomNodeSO : ScriptableObject
{
	public void Draw(GUIStyle nodeStyle)
    {
        // Draw Node Box Using Begin Area
        GUILayout.BeginArea(rect, nodeStyle);

        // Start Region To Detect Popup Selection Changes
        EditorGUI.BeginChangeCheck();

        // if the room node has a parent or is of type entrance then display a label else display a popupo
        if (parentRoomNodeIDList.Count > 0 || roomNodeType.isEntrance)
        {
            // Display a label that can't be changed
            EditorGUILayout.LabelField(roomNodeType.roomNodeTypeName);
        }
        else
        {
            // Display a popup using the RoomNodeType name values that can be selected from (default to the currently set roomNodeType) 
            int selected = roomNodeTypeList.list.FindIndex(x => x == roomNodeType);

            int selection = EditorGUILayout.Popup("", selected, GetRoomNodeTypeToDisplay());

            roomNodeType = roomNodeTypeList.list[selection];
        }

        if (EditorGUI.EndChangeCheck())
            EditorUtility.SetDirty(this);

        GUILayout.EndArea();
    }
}

이제 룸 노드 생성 시 Entrance 노드가 하나 새로 생성되는 것을 확인할 수 있다.

또한 우클릭 드래그를 해서 연결된 노드, 즉 부모 노드가 생긴 노드는 잠기면서 타입이 더 이상 변경이 불가능해진다.


이제 노드를 선택 시 SelectedStyle이 따로 적용되서 선택된 노드들을 확인할 수 있다. 아래 사진처럼 Medium Room 노드가 선택된 모습을 확인할 수 있다.

이 때 노드가 아닌 공간을 클릭하면 모든 노드의 선택이 해제된다.


추가적인 룸 노드 그래프를 만들고 다른 룸 노드 그래프 편집기가 열린 상태에서 해당 룸 노드 그래프를 더블 클릭하면 해당 룸 노드 그래프가 편집기에 새로 나타나는 것을 확인할 수 있다.

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글

관련 채용 정보