Adaid's Workroom

[IC] Isometric 타일맵 에디터 제작기 (8) - Tile 클래스와 동적 Prefab 로드 본문

프로젝트/Infinite Cocktail

[IC] Isometric 타일맵 에디터 제작기 (8) - Tile 클래스와 동적 Prefab 로드

어데이드 2018. 1. 6. 02:43

18.01.05

오늘 개발끗

Tile 클래스

IsometricTile을 추상 클래스로 하여 여러 클래스를 만들었다. 


IsometricTile: SetOrder 함수만 있는 추상 클래스

GroundTile: IsometricTile 상속. SetOrder: Transform을 리스트로 인수로 받아 Z값 조정.

ObjectTile: IsometricTile 상속. SetOrder: Renderer를 리스트로 인수로 받아 order 조정.

DynamicObjectTile: ObjectTile 상속. Update 함수에서 SetOrder 호출

abstract public class IsometricTile : MonoBehaviour
{
    abstract public void SetOrder();
}
public class GroundTile : IsometricTile
{
    public List targetTransforms;

    public override void SetOrder()
    {
        for(int i = 0;i < targetTransforms.Count;i++)
        {
            Vector3 newPos = targetTransforms[i].transform.position;
            newPos.z = transform.position.y * 0.01f - i * 0.0001f;
            targetTransforms[i].transform.position = newPos;
        }
    }
}

public class ObjectTile : IsometricTile { public List

targetRenderers; public override void SetOrder() { for (int i = 0; i < targetRenderers.Count; i++) { targetRenderers[i].sortingOrder = 1000 - (int)(transform.position.y * 100); Vector3 newPos = targetRenderers[i].transform.position; newPos.z = - i * 0.01f; targetRenderers[i].transform.position = newPos; } } }
public class DynamicObjectTile : ObjectTile
{
	void Update ()
    {
        //이건 나중에 플레이어가 움직일 시에만 작동하게 하면 될듯?
        SetOrder();
    }
}

동적 Prefab 로드

땅, 오브젝트 Prefab들을 동적으로 불러와 그것을 편집모드때 선택할 수 있게 하였다.

파일 경로문제 때문에 뜬 수십개의 오류와 사투 끝에 결국 완성할 수 있었다.


먼저 OnEnable에서 특정 경로에 저장되어 있는 프리팹 이름들을 불러와 저장한다.

    void OnEnable()
    {
        mapManager = (MapManager)target;

        //Ground 타일 불러옴
        string folderPath = Application.dataPath + "/Resources/Tiles/Ground";
        string[] groundTileStrings = System.IO.Directory.GetFiles(folderPath, "*.prefab");

        groundTileNames = new string[groundTileStrings.Length];
        for (int i = 0; i < groundTileStrings.Length; i++)
        {
            string filename = System.IO.Path.GetFileNameWithoutExtension(groundTileStrings[i]);
            groundTileNames[i] = filename;
        }

        //Object 타일 불러옴
        folderPath = Application.dataPath + "/Resources/Tiles/Object";
        string[] objectTileStrings = System.IO.Directory.GetFiles(folderPath, "*.prefab");

        objectTileNames = new string[objectTileStrings.Length];
        for (int i = 0; i < objectTileStrings.Length; i++)
        {
            string filename = System.IO.Path.GetFileNameWithoutExtension(objectTileStrings[i]);
            objectTileNames[i] = filename;
        }
    }

이 Ground/Object 프리팹들은 각각 Ground/Object 편집 모드에서 버튼으로 보여진다.




    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        //편집 버튼
        if(actionType == ActionType.NONE)
        {
            ...
        }
        else
        {
            GUI.color = Color.red;
            if (GUILayout.Button("Stop Editing"))
            {
                actionType = ActionType.NONE;
            }

            GUI.color = Color.yellow;
            if (actionType == ActionType.GROUND_EDIT)
            {
                //Ground 타일들 버튼
                selectedTile = GUILayout.SelectionGrid(selectedTile, groundTileNames, 3);
            }
            else if (actionType == ActionType.OBJECT_EDIT)
            {
                //Object 타일들 버튼
                selectedTile = GUILayout.SelectionGrid(selectedTile, objectTileNames, 3);
            }
        }
    }

편집 모드로 들어가면 편집 중단 버튼 밑에 각각의 모드에 맞는 버튼들이 나오게 된다.

그리고 선택한 정보는 int형의 selectedTile에 저장된다.

Create 함수는 이 정보를 바탕으로 알맞은 프리팹을 생성한다.


    private void Create(int gridSize, int x, int y)
    {
        ...
        if (actionType == ActionType.GROUND_EDIT)
        {
            container = mapManager.groundContainer;
            nameFormat = string.Format("Ground{0}_{1}_{2}", gridSize, x, y);
            prefabPath = "Tiles/Ground/" + groundTileNames[selectedTile];
        }
        else if(actionType == ActionType.OBJECT_EDIT)
        {
            container = mapManager.objectContainer;
            nameFormat = string.Format("Object{0}_{1}_{2}", gridSize, x, y);
            prefabPath = "Tiles/Object/" + objectTileNames[selectedTile];
        }
        ...
        tilePrefab = Resources.Load(prefabPath);
        makeTile = Instantiate(tilePrefab).transform;
        ...
    } 

처음에 AssetDatabase.LoadAssetAtPath로 해보려다 잘 되지 않아 프리팹들을 Resources 폴더에 이동시키고 Resource.Load로 어떻게든 구현해냈다. 그와중에 뜨는 버그는 덤



여러 프리팹들을 만들어 에디터를 사용해 배치해보았다.


PS.

티스토리가 코드를 태그로 인식한다....

나중에 예외처리하는 방법 알아봐야할듯

Comments