MapManager.cs 소스입니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapManager : MonoBehaviour
{
public readonly int SIZE = 16; // Inspector의 한 페이지에 표시 될 Cell 의 최대 갯수
public GameObject[] GrassMaps; // 타일 맵 오브젝트의 배열
[HideInInspector] public int curGrassMap; // 현재 타일 맵의 포지션
[HideInInspector] public int pageIndex; // 현재 Page Index
[HideInInspector] public Transform MapsTR; // Maps 오브젝트의 Tranform
[HideInInspector] public GameObject PreviewMap;
[HideInInspector] public Material PreviewMapMt;
public void MovePage(bool isPrevious)
{
int maxPageIndex = GrassMaps.Length / SIZE;
if (isPrevious)
{
if (--pageIndex < 0) pageIndex = maxPageIndex;
}
else
{
if (++pageIndex > maxPageIndex) pageIndex = 0;
}
}
public float RoundFloat(float f)
{
float gap = f % 100;
float floorFloat = 0;
if (f > 0) floorFloat = f - gap;
else floorFloat = f - gap - 100;
return floorFloat;
}
}
MapEditor.cs 소스입니다
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MapManager)), CanEditMultipleObjects]
class MapEditor : Editor
{
MapManager MM; // MapManager Script
int selectToolIndex = 0;
// 해당 Object가 마우스로 선택되어 사용가능한 상태에 딱 1번 호출됨.. (초기화 구문을 적는것이 좋음)
void OnEnable()
{
MM = GameObject.FindWithTag("MapManager").GetComponent<MapManager>();
}
void OnDisable()
{
if (MM.PreviewMap != null) DestroyImmediate(MM.PreviewMap);
}
// 일반적인 Scene Script의 Update 생명주기와 같다고 보면 됨..
protected virtual void OnSceneGUI()
{
Ray mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
Vector3 mousePos = mouseRay.GetPoint((-mouseRay.origin.y) / mouseRay.direction.y);
Event current = Event.current;
// 미리보기
if (selectToolIndex == 1)
{
Vector3 RoundPos = new Vector3(MM.RoundFloat(mousePos.x), 0, MM.RoundFloat(mousePos.z));
if (MM.PreviewMap == null)
{
MM.PreviewMap = Instantiate(MM.GrassMaps[MM.curGrassMap], RoundPos, Quaternion.identity);
MM.PreviewMap.transform.SetParent(MM.MapsTR);
MM.PreviewMap.transform.SetAsFirstSibling();
MM.PreviewMap.name = "PreviewMap";
MM.PreviewMap.GetComponent<MeshCollider>().enabled = false;
Material originMt = MM.GrassMaps[MM.curGrassMap].GetComponent<Renderer>().sharedMaterial;
Renderer PreviewRenderer = MM.PreviewMap.GetComponent<Renderer>();
PreviewRenderer.sharedMaterial = MM.PreviewMapMt;
PreviewRenderer.sharedMaterial.mainTexture = originMt.mainTexture;
PreviewRenderer.sharedMaterial.color = new Color(originMt.color.r, originMt.color.g, originMt.color.b, 0.4f);
PreviewRenderer.sharedMaterial.SetColor("_SpecColor", originMt.GetColor("_SpecColor"));
}
MM.PreviewMap.transform.position = RoundPos;
}
if (current.type == EventType.MouseDown && current.button == 0)
{
if (selectToolIndex == 0) return;
GameObject hitObj = null;
Vector3 screenPosition = Event.current.mousePosition;
screenPosition.y = Camera.current.pixelHeight - screenPosition.y;
Ray ray = Camera.current.ScreenPointToRay(screenPosition);
if (Physics.Raycast(ray, out RaycastHit hit)) hitObj = hit.collider.gameObject;
if (selectToolIndex == 1)
{
// 생성
if (hitObj != null) return;
Vector3 RoundPos = new Vector3(MM.RoundFloat(mousePos.x), 0, MM.RoundFloat(mousePos.z));
GameObject curGrassMap = MM.GrassMaps[MM.curGrassMap];
/* Spawn Object 생성 */
Transform spawnParentTR = new GameObject(curGrassMap.name).transform;
spawnParentTR.position = RoundPos + new Vector3(50, 0, 50);
spawnParentTR.name = curGrassMap.name;
Transform spawnTR = Instantiate(curGrassMap, RoundPos, Quaternion.identity).transform;
spawnTR.name = curGrassMap.name;
spawnTR.SetParent(spawnParentTR);
spawnParentTR.SetParent(MM.MapsTR);
}
else if (selectToolIndex == 2)
{
// 회전
if (hitObj == null) return;
hitObj.transform.parent.Rotate(0, 90, 0);
}
else if (selectToolIndex == 3)
{
// 파괴
if (hitObj == null) return;
DestroyImmediate(hitObj.transform.parent.gameObject);
}
}
if (current.type == EventType.Layout)
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
}
// Inspector의 GUI를 조작할 시에 호출 됨.. ex ) 마우스 오버, Inspector내에 값 수정...
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Event current = Event.current;
/* Paging Control Button Area */
GUILayout.BeginHorizontal();
if (GUILayout.Button("<", GUILayout.Width(70), GUILayout.Height(30))) { MM.MovePage(true); MM.curGrassMap = -1; }
GUILayout.FlexibleSpace();
selectToolIndex = GUILayout.SelectionGrid(selectToolIndex, new string[4] { "없음", "생성", "회전", "파괴" }, 4, GUILayout.Width(300), GUILayout.Height(30));
GUILayout.FlexibleSpace();
if (GUILayout.Button(">", GUILayout.Width(70), GUILayout.Height(30))) { MM.MovePage(false); MM.curGrassMap = -1; }
GUILayout.EndHorizontal();
/* Map Object의 Thumnail 을 가져옴 */
Texture[] GrassTextures = new Texture[MM.SIZE];
for (int i = 0; i < MM.SIZE; i++)
{
int curIndex = i + MM.SIZE * MM.pageIndex;
if (curIndex >= MM.GrassMaps.Length) break;
GrassTextures[i] = AssetPreview.GetAssetPreview(MM.GrassMaps[curIndex]);
}
/* 선택 된 Map Object의 Index 를 가져옴.. */
EditorGUI.BeginChangeCheck();
int selectMapIndex = GUILayout.SelectionGrid(MM.curGrassMap % MM.SIZE, GrassTextures, 4);
if (EditorGUI.EndChangeCheck())
{
MM.curGrassMap = selectMapIndex + MM.SIZE * MM.pageIndex;
if(MM.PreviewMap != null) DestroyImmediate(MM.PreviewMap);
}
}
}