호우동의 개발일지

Today :

article thumbnail

에셋 파일은 같은 프로젝트 내에서 GUID로 식별된다.

뿐만 아니라 이 GUID를 이용하여
에셋 파일을 호출하고, 조작하고, 생성하는 등 여러 가지 작업을 한다.

GUID에 대해서는 예전에 포스팅해 둔 글을 밑에 넣어둔다.
https://howudong.tistory.com/153

 

[Unity 3D] 유니티 에셋(Asset)의 식별되는 원리

유니티 에셋이란? 유니티 에셋은 게임 제작에 필요한 모든 요소들을 말한다. 3D 모델, 텍스쳐 이미지, 사운드, 파티클 효과, 유틸리티 등을 모두 유니티에서는 에셋이라고 부른다. 유니티 에셋 내

howudong.tistory.com

 


유니티 에셋 호출(불러오기)

using UnityEditor;

public class TestEditWindow : EditorWindow
{
    /*
    * AssetDatabase API 이용
    */
    private void OnGUI()
    {

        if(GUILayout.Button("Find All Materials"))
        {
            //"t는 type을 의미 -> material 타입의 에셋의 guid를 찾아
            var resultGuid = AssetDatabase.FindAssets("t:material");

            if(resultGuid != null)
            {
                for(int i = 0; i < resultGuid.Length; i++)
                {
                    Debug.Log("=============");

                    var guid = resultGuid[i];
                    // guid를 에셋 경로로 변환 -> guid를 통해 에셋의 위치 확인 가능
                    var path = AssetDatabase.GUIDToAssetPath(guid);

                    // AssetDatabase.AssetPathToGuID : 에셋 경로를 guid로 변환
                    // 에셋 경로를 통해 guid를 알 수도 있음. 
                    Debug.Log($"GUID : {guid}, Path {path}, 
                    GUID from path : {AssetDatabase.AssetPathToGUID(path)}");
                }
            }
        }
    }
}

위의 코드는 버튼을 눌렀을 때,
프로젝트 내에 있는 에셋 중
Material 타입의 에셋 파일만 불러서 호출하는 코드이다.

Asset의 guid와 경로를 찾는 데에는
모두 AssetDatabase API를 이용한다.

해당 코드를 통해 확인할 수 있는 것은
AssetDatabase.FindAssets()를 통해 에셋의 GUID를 얻는다.

이 GUID를 이용한 AssetDatabase.GUIDToAssetPath()를 통해
에셋이 위치한 경로를 알아낼 수 있다.

또한 그 반대도 가능한데, 해당 에셋이 위치한 경로를 알고 있을 때 이다.

AssetDatabase.AssetPathToGUID()
를 통해 그 에셋의 GUID를 얻을 수 있다.

어쨌거나 저쨌거나 에셋 조작의 핵심은 GUID라는 것이다.

프로젝트 내에 Material 타입의 에셋 3개가 있다.

매터리얼 3개

위 코드에 아래 코드를 추가한 뒤 실행시킨 후
MyTool -> OpenTool을 실행한 뒤 버튼을 눌러보자

    [MenuItem("MyTool/OpenTool %g")]
    static void Open()
    {
        var myWindow = GetWindow<TestEditWindow>();
        myWindow.titleContent = new GUIContent() { text = "MyTool" };
    }

출력 결과

위에 있던 Material 객체의 GUID와 위치 경로가 전부 인식되어 나오는 것을 확인할 수 있다.

 


에셋 불러오기 및 적용(오브젝트 만들기)

public class TestEditWindow : EditorWindow
{
    private void OnGUI()
    {
        if(GUILayout.Button("All Materials load and apply"))
        {

            // Scene에 있는 모든 렌더러를 찾아서 없앰 (초기화 작업)
            var allRenders = FindObjectsOfType<Renderer>();
            if(allRenders != null)
            {
                for (int i = 0; i < allRenders.Length; i++)
                    GameObject.DestroyImmediate(allRenders[i].gameObject);
            }

            var resultGUI = AssetDatabase.FindAssets("t:Material");
            if(resultGUI != null)
            {
                for(int i = 0; i< resultGUI.Length; i++)
                {
                    var guid = resultGUI[i];
                    var path = AssetDatabase.GUIDToAssetPath(guid);

                    // 경로로 변환한 Asset을 Material class로 불러옴 
                    var loadedMat = AssetDatabase.LoadAssetAtPath<Material>(path);
                    if(loadedMat != null)
                    {
                        Debug.Log($"Material loaded : {path}");

                        // 큐브 모양 생성
                        var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        cube.transform.position = new Vector3(i * 2, 0, 0);
                        cube.GetComponent<Renderer>().material = loadedMat;
                    }
                }
            }
        }
    }
}

버튼을 누르면 Scene에 있는 모든 Renderer를 가진 오브젝트를 없앤 뒤,
프로젝트에 있는 Material을 적용한 게임오브젝트를 하나씩 배치하는 코드이다.

여기서 프로젝트에 있는 Material을 가져오는 코드는
AssetDatabase.LoadedAssetAtpath <타입>(object)이다.

이렇게 가져온 Material class를 생성된 큐브의 material로 하면 적용된다.

여기서 위와 같이 MyTool/OpenTool을 추가하는 코드가 있다고 하고
이번에는 아래처럼 각 Mat 에셋들을 구분하기 쉽게 색을 바꿨다.

색별로 구분
빨강/.노랑/파랑

그 후 버튼을 눌러보면

색이 바뀐것을 확인 가능

이런 식으로 Scene에 각 Material의 색이 적용된 큐브들이 만들어진다.

 


에셋 생성

private void OnGUI()
{
    if (GUILayout.Button("Create Asset"))
    {
        // Material을 생성하는데 안에 Standard Shader을 넣어준.
        var loadedMat = new Material(Shader.Find("Standard"));

        // 해당 경로에 설정해준 Material 에셋을 생성
        AssetDatabase.CreateAsset(loadedMat, 
        $"Assets/HolyMoly{(int)Random.Range(0, 1000)}.mat");
     }
}

생성 함수는 간단하다.

만들고 싶은 에셋 타입의 클래스를 생성해 준다.
여기서는 Material에 standard 셰이더를 찾아서 넣었다.

그 후 AssetDatabase.CreateAsset(에셋, 경로)
 로 해당 경로에 오브젝트(에셋)를 생성한다.

생성확인

버튼을 눌러보면 이런 식으로 경로를 설정해 둔 곳에 Material 타입으로
설정해 둔 이름을 가진 에셋이 생성된다.