콘텍스트 메뉴에서 룸 노드를 모두 동시에 선택할 수 있는 메뉴 버튼을 추가해보자.
/// <summary>
/// Show the context menu
/// </summary>
private void ShowContextMenu(Vector2 mousePosition)
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Create Room Node "), false, CreateRoomNode, mousePosition);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Select All Room Nodes"), false, SelectAllRoomNodes);
menu.ShowAsContext();
}
/// <summary>
/// Select all room nodes
/// </summary>
private void SelectAllRoomNodes()
{
foreach (RoomNodeSO roomnode in currentRoomNodeGraph.roomNodeList)
{
roomnode.isSelected = true;
}
GUI.changed = true;
}
이제 노드 그래프 편집기에서 우클릭 시 모든 노드 선택하기 버튼이 콘텍스트 메뉴에 추가된 것을 확인할 수 있다.
모든 노드가 선택된 것을 확인할 수 있다.
룸 노드 그래프 편집기에서 룸 노드, 노드 간의 연결을 삭제할 수 있는 기능을 구현해보자.
/// <summary>
/// Remove childID from the node (returns true if the node has been removed, false otherwise)
/// </summary>
public bool RemoveChildRoomNodeIDFromRoomNode(string childID)
{
// if the node contatins the child ID then remove it
if (childRoomNodeIDList.Contains(childID))
{
childRoomNodeIDList.Remove(childID);
return true;
}
return false;
}
/// <summary>
/// Remove parentID from the node (returns true if the node has been removed, false otherwise)
/// </summary>
public bool RemoveParentRoomNodeIDFromRoomNode(string parentID)
{
// if the node contatins the parent ID then remove it
if (parentRoomNodeIDList.Contains(parentID))
{
parentRoomNodeIDList.Remove(parentID);
return true;
}
return false;
}
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 (roomNodeTypeList.list[selected].isCorridor && !roomNodeTypeList.list[selected].isCorridor || !roomNodeTypeList.list[selected].isCorridor
&& roomNodeTypeList.list[selected].isCorridor || !roomNodeTypeList.list[selected].isBossRoom && roomNodeTypeList.list[selection].isBossRoom)
{
if (childRoomNodeIDList.Count > 0)
{
for (int i = childRoomNodeIDList.Count - 1; i >= 0; i--)
{
// Get child room node
RoomNodeSO childRoomNode = roomNodeGraph.GetRoomNode(childRoomNodeIDList[i]);
// If the child room node is not null
if (childRoomNode != null)
{
// Remove childID from parent room node
RemoveChildRoomNodeIDFromRoomNode(childRoomNode.id);
// Remove parentID from child room node
childRoomNode.RemoveParentRoomNodeIDFromRoomNode(id);
}
}
}
}
}
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(this);
GUILayout.EndArea();
}
/// <summary>
/// Show the context menu
/// </summary>
private void ShowContextMenu(Vector2 mousePosition)
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Create Room Node "), false, CreateRoomNode, mousePosition);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Select All Room Nodes"), false, SelectAllRoomNodes);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Delete Selected Room Node Links"), false, DeleteSelectedRoomNodeLinks);
menu.AddItem(new GUIContent("Delete Selected Room Nodes"), false, DeleteSelectedRoomNodes);
menu.ShowAsContext();
}
/// <summary>
/// Delete the links between the selected room nodes
/// </summary>
private void DeleteSelectedRoomNodeLinks()
{
// Iterate through all room nodes
foreach (RoomNodeSO roomNode in currentRoomNodeGraph.roomNodeList)
{
if (roomNode.isSelected && roomNode.childRoomNodeIDList.Count > 0)
{
for (int i = roomNode.childRoomNodeIDList.Count- 1; i >= 0; i--)
{
// Get child room node
RoomNodeSO childRoomNode = currentRoomNodeGraph.GetRoomNode(roomNode.childRoomNodeIDList[i]);
// If the child room node is selected
if (childRoomNode != null && childRoomNode.isSelected)
{
// Remove childID from parent room node
roomNode.RemoveChildRoomNodeIDFromRoomNode(childRoomNode.id);
// Remove parentID from child room node
childRoomNode.RemoveParentRoomNodeIDFromRoomNode(roomNode.id);
}
}
}
}
//Clear all selected room nodes
ClearAllSelectedRoomNodes();
}
룸 노드를 삭제할 때 삭제 대기자 큐를 만들어서 삭제하는 이유는 삭제 요청이 올 때마다 노드를 모두 삭제해 버리면 노드 간 연결이라던가, 노드 그래프의 노드 리스트와 같은 것들에서 오류가 발생할 수 있기 때문에 일단은 대기자 큐에 넣어놓고 삭제할 수 있는 것들을 삭제하는 방식을 사용한다.
우클릭 시에 Delete 메뉴 두 개가 추가 된 것을 확인할 수 있다.
룸 노드가 정상적으로 삭제되면서 링크도 같이 삭제되는 것을 확인할 수 있다.
이처럼 links도 잘 삭제되는 것을 확인할 수 있다.
복도에서 복도로는 정상적으로 연결되지 않는다.