에셋 파일은 같은 프로젝트 내에서 GUID로 식별된다.
뿐만 아니라 이 GUID를 이용하여
에셋 파일을 호출하고, 조작하고, 생성하는 등 여러 가지 작업을 한다.
GUID에 대해서는 예전에 포스팅해 둔 글을 밑에 넣어둔다.
https://howudong.tistory.com/153
유니티 에셋 호출(불러오기)
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개가 있다.
위 코드에 아래 코드를 추가한 뒤 실행시킨 후
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 타입으로
설정해 둔 이름을 가진 에셋이 생성된다.