위 사진과 같이 던전 룸 노드 그래프를 생성하고 해당 그래프를 던전 맵으로 형성할 예정이다. 각기 다른 Room templates를 통해 다양한 던전 룸을 구현하고 불러올 예정이고 레벨에 따라 방의 개수와 종류를 다양화할 예정이다.
다음과 같이 던전 룸 노드 그래프를 그리고 나면 Room Templates에서 해당하는 룸을 가져와서 타일 맵으로 맵을 생성해준다. 이때 던전 생성은 던전 생성 알고리즘을 기반으로 실행한다. 각기 다른 Room이 연결되고, 겹치지 않도록 해주도록 던전 생성 알고리즘을 작성해야한다.
이러한 던전 생성에서 노드 그래프를 유니티에서 자체적으로 편집할 수 있도록 지원한다.
이러한 노드 편집기를 이용하여 맵을 구성할 뿐만 아니라 NPC 대화 시스템을 구축하거나 RPG용 스킬 진행 트리 또는 제작 트리를 구축할 수 있다.
노드 그래프가 위치할 폴더를 하나 새로 만들어주고 RoomNodeGraphEditor 스크립트를 생성해준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Codice.Client.Common.GameUI;
public class RoomNodeGraphEditor : EditorWindow //편집기
{
[MenuItem("Room Node Graph Editor", menuItem = "Window/Dungeon Editor/Room Node Graph Editor")]
private static void OpenWindow()
{
GetWindow<RoomNodeGraphEditor>("Room Node Graph Editor");
}
}
UnityEditor 네임스페이스 안에 EditorWindow를 통해 편집기를 쉽게 구현할 수 있다.
이처럼 Window에 Room Node Graph Editor 창을 열 수 있게 생긴것을 확인할 수 있다. 당연하게도 해당 창 안에 어떤 기능도 추가하지 않았기 때문에 실행하면 빈 창만 뜨는 것을 확인할 수 있다.
이처럼 게임 개발에 있어서 원하는 창을 새로 만들어서 개발 과정에서 해당 창을 이용해서 개발 과정을 수월하게 수행해 낼 수 있다. 편집 기능을 가진 에디터 뿐만 아니라 다양한 역할로 내가 원하는 창을 만들어낼 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class RoomNodeGraphEditor : EditorWindow //편집기
{
private GUIStyle roomNodeStyle;
//Node layout Values
private const float nodeWidth = 160f;
private const float nodeHeight = 75f;
private const int nodePadding = 25;
private const int nodeBorder = 12;
[MenuItem("Room Node Graph Editor", menuItem = "Window/Dungeon Editor/Room Node Graph Editor")]
private static void OpenWindow()
{
GetWindow<RoomNodeGraphEditor>("Room Node Graph Editor");
}
private void OnEnable()
{
// 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);
}
/// Draw Editor GUI
private void OnGUI()
{
GUILayout.BeginArea(new Rect(new Vector2(100f, 100f), new Vector2(nodeWidth, nodeHeight)), roomNodeStyle);
EditorGUILayout.LabelField("Node 1");
GUILayout.EndArea();
GUILayout.BeginArea(new Rect(new Vector2(300f, 300f), new Vector2(nodeWidth, nodeHeight)), roomNodeStyle);
EditorGUILayout.LabelField("Node 1");
GUILayout.EndArea();
}
}
위와 같이 GUI 스타일을 설정해두고 우리가 만든 방 노드 스타일을 이용해서 상자를 그리도록 할 수 있다. 실제로 실행하면 두 개의 상자가 만들어지는 것을 확인할 수 있다.
좀 더 자세히 설명하자면 아래와 같다.
private void OnEnable()
{
// 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);
}
우리가 만들 상자가 이제부터 Room Node가 될 예정이다. 따라서 노드를 만들 때 노드의 스타일을 미리 설정해 줄 수 있는데 위의 코드로 노드 스타일을 설정해 주는 것이다. 배경색과 글자색, 여러 속성을 설정해주었다.
private void OnGUI()
{
GUILayout.BeginArea(new Rect(new Vector2(100f, 100f), new Vector2(nodeWidth, nodeHeight)), roomNodeStyle);
EditorGUILayout.LabelField("Node 1");
GUILayout.EndArea();
GUILayout.BeginArea(new Rect(new Vector2(300f, 300f), new Vector2(nodeWidth, nodeHeight)), roomNodeStyle);
EditorGUILayout.LabelField("Node 1");
GUILayout.EndArea();
}
이제 이 부분에서 노드를 그리게 되는데 OnGUI 함수는 언제 호출되면 창 위에서 어떠한 이벤트(마우스 움직임, 클릭, 키보드 입력) 등, 등의 이벤트가 있을때마다 호출되는 함수라고 이해하면 된다. 창이 열릴 때 OnGUI도 자동으로 실행되면서 노드를 그린다. 이 때 BeginArea가 노드를 그려주기 시작하는 함수이고 LabelFiled가 노드 안에 들어갈 레이블, 텍스트를 입력해주는 코드이고 EndArea는 노드 그리기가 끝났다는 것을 의미한다. 해당 스크립트에 대한 자세한 설명은 유니티 스크립팅 API를 통해 확인할 수 있다.
더 자세한 설명은 유니티 문서를 참조
이를 통해 우리가 원하는 창에서 상자, 즉 노드를 원하는 위치에 원하는 스타일, 원하는 사이즈로 생성할 수 있는 것을 알았다. 이제 다음에는 이러한 노드들을 우리가 원하는 던전 룸 노드 그래프 형식으로 그려질 수 있도록 스크립트를 추가 작성할 예정이다.
유니티 스크립팅 API를 통해 통합 메뉴얼과 스크립트를 참조할 수 있다.
버전에 따라서 메뉴얼과 스크립트를 참조할 수 있다.
그 중에서 MenuItmem에 대한 스크립트를 참조해보자. (한국어로 번역한 내용)
이처럼 개발 과정에서 스크립트에 대한 메뉴얼을 참고하고 싶으면 유니티 스크립팅 API를 통해 해당 스크립트에 대항 설명과 어떤 코드가 어떤 역할을 하는지 파악할 수 있다. 일종의 도움말 사전 같은 역할을 한다고 할 수 있다. 구글링을 통해 코드를 참고해서 작성한다고 해도 일차원적으로 그대로 옮겨적는 것이 아니라 모르는 내용은 해당 유니티 스크립팅 API의 메뉴얼을 찾아보면서 어떤 기능을 위해 추가했는지를 이해하면서 코딩하면 큰 도움이 될 것이다.