어떤 상황에서는 씬의 일부로 로드하지 않고 프로젝트에서 사용할 수 있게 하는 것이 유용합니다. 예를 들어, 게임의 모든 씬에 등장할 수 있지만 드물게 사용되는 캐릭터 또는 기타 오브젝트가 있을 수 있습니다(가령 이것은 “비밀” 기능, 오류 메시지 또는 하이스코어 알림일 수 있습니다). 또한, 초기 다운로드 시간을 단축하거나 게임 콘텐츠를 교체하기 위해 별도의 파일 또는 URL에서 에셋을 로드할 수 있습니다.
Unity는 프로젝트에서 리소스 폴더 를 지원하여 콘텐츠가 메인 게임 파일에 공급될 수 있게 하지만, 요청이 있을 때까지 로드하지 않습니다. 또한, 에셋 번들 을 만들 수도 있습니다. 에셋 번들은 메인 게임 파일에서 완전히 분리된 파일로 게임이 요청했을 때 파일 또는 URL에서 엑세스할 수 있는 에셋을 포함합니다.
에셋 번들
에셋 번들(Asset Bundles)은 에셋의 외부 컬렉션입니다. 여러 개의 에셋 번들을 가질 수 있기 때문에 다른 에셋의 외부 컬렉션도 다수 가질 수 있습니다. 이러한 파일은 빌드된 Unity 플레이어의 외부에 존재하기 때문에 일반적으로 웹 서버에 있으며, 최종 사용자가 동적으로 액세스할 수 있습니다.
리소스 폴더(Resource Folders)는 빌드된 Unity 플레이어의 에셋 컬렉션이지만, 인스펙터에서 어떤 게임 오브젝트와 반드시 연결되어야 하는 것은 아닙니다.
리소스 폴더에 무언가를 넣으려면 프로젝트 뷰(Project View) 에 새 폴더를 만들고 폴더 이름을 “Resources”로 지정해야 합니다. 프로젝트에 여러 리소스 폴더를 다른 형태로 배치할 수 있습니다. 폴더 중 하나에서 에셋을 로드하고 싶다면 Resources.Load()를 호출해야 합니다.
참고
Resources 폴더의 모든 에셋 및 종속성은 resources.assets_이라는 파일에 저장됩니다. 에셋이 이미 다른 레벨에서 사용되는 경우 해당 레벨의 .sharedAssets_에 저장됩니다. Edit -> PlayerSettingsFirst Streamed Level 설정에 따라 _resources.assets_가 모아져 빌드에 포함될 레벨을 결정합니다.
“First streamed Level” 보다 이전 레벨이 Resource 폴더의 에셋을 포함하는 경우, 에셋은 해당 레벨의 에셋으로 저장됩니다. 이후에 포함될 경우 해당 레벨은 “resources.assets”의 에셋을 레퍼런스합니다.
Resources 폴더 에 있는 에셋만이 Resources.Load()를 통해 액세스될 수 있습니다. 그러나 종속성을 지니고 있으면 더 많은 에셋이 “resources.assets” 파일에 포함될 수 있습니다(예를 들어, Resources 폴더의 머티리얼은 Resources 폴더 외부의 텍스처를 레퍼런스할 수 있습니다).
리소스 언로드
AssetBundle.Unload()를 호출해서 에셋 번들의 리소스를 언로드할 수 있습니다. unloadAllLoadedObjects 파라미터에 true 을 전달하면 에셋 번들에서 내부적으로 보유한 오브젝트와 AssetBundle.LoadAsset()을 사용하여 에셋 번들에서 로드된 오브젝트가 모두 삭제되고 번들에 의해 사용된 메모리가 릴리스됩니다.
에셋 번들을 로드한 후 원하는 오브젝트를 인스턴스화하고 오브젝트를 유지하면서 번들이 사용하던 메모리를 해제하고 싶은 경우가 있습니다. 다른 에셋 번들을 위한 인스턴스 로드 등, 다른 작업을 위해 메모리를 비울 수 있다는 게 장점입니다. 이 경우 파라미터에 false 를 전달해야 합니다. 번들이 삭제된 후에는 해당 번들에서 오브젝트를 로드할 수 없게 됩니다.
유니티로 빌드하면 에셋이 묶여서 엑세스가 불가하게 된다. 대량의 에셋을 추가하려면 에셋 번들을 이용하면 되는데, 이런 경우 말고 직접 리소스를 추가하고 싶은 경우가 있다.
최근 프로젝트에서 필요해서 하는김에 간단히 정리해봤다. 처음 하는 사람들에게 도움이 되길 -_-*
# Resource.Load 사용하기
private void ResourceLoadSample(){ Texture2D texture = new Texture2D(0, 0); string PATH = "Texture/image.jpg"; // 이미지 파일 패스를 써준다. //중요한 것은 유니티 프로젝트 Assets/Resource/ 폴더 이후의 경로를 써주는 것이다. 이 폴더는 맘대로 바꿀 수가 없다. texture = Resources.Load(PATH,typeof(Texture2D)) as Texture2D; // 이미지 로드 targetObject.mainTexture = texture; // 타겟 오브젝트에 메인 텍스쳐를 넣어준다. }
# System.File.IO로 직접 가져오기 Resource 폴더가 아니라 다른 폴더 특히 StreamingAssets에서 가져오려면
Resource.Load 함수를 쓰지 말고 직접 System.File.IO 로 가져와야 한다. byte[] 로 가져온 다음에 Texture2D.LoadImage()를 사용하여 텍스쳐2D로 읽어오면 된다.
private void SystemIOFileLoad(){ byte[] byteTexture = System.IO.File.ReadAllBytes(Path); if (byteTexture.Length > 0) { texture = new Texture2D(0, 0); texture.LoadImage(byteTexture); } }
추가사항) 이 폴더 역시 Standard Assets 폴더와 마찬가지로 다른 소스들보다 먼저 빌드되어진다.
( 최상위 폴더에만 위치해야 한다. )
"Resources"
해당폴더에 있는 리소스 파일들은 빌드시에 언제나 포함된다.
사용하지 않는 리소스들 이더라도 모두 포함되어 용량을 차지할 수 있으니, 사용하지 않는 리소스는 정리하는것이 좋다.
이 폴더는 최상위 폴더가 아닌, 프로젝트 어디에서나 생성하여 사용 할 수 있다.
그러나 빌드시에 결국 하나의 asset 으로 합쳐지기 때문에, 파일 이름, 경로 등을 잘 설정해야 한다.
다른 폴더의 리소스 폴더에 들어있는 파일이라도, 이름이 같을 경우 이를 구분할 방법이 없다.
"Editor Default Resources"
리소스 폴더와 마찬가지의 일을 한다, 한가지 다른점은 이름에서와 같이 에디터 전용이다.
빌드시에는 포함하지 않고 에디터용 플러그인을 위한 리소스를 관리할때 사용한다.
EditorGUIUtility.Load() 함수를 이용하여 불러올 수 있다.
"Gizmos"
에디터 전용 폴더로, Gizmos.DrawIcon() 에 사용 될 리소스를 담는 폴더이다.
"StreamingAssets"
이 폴더에 넣는 파일들은 변형되지 않고 그대로 빌드에 포함시킨다
( 다만 web, mobile 빌드 시에는 변형된다. )
빌드 후 Application.streamingAssetsPath 를 통해 접근 할 수 있다.
추가사항)
일반적으로 System.IO.File.ReadAllText 와 같이 직접 주소를 불러도 되지만
안드로이드의 경우 하나의 파일로 압축되어져 보관된다.
따라서 WWW 의 도움을 받아 접근 해야 한다.
WWW 가 알아서 압축해제 후 해당 파일을 가져와주는 일을 대신 수행한다.
직접 해당 부분을 구현해서 사용해도 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { public string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile"); public string result = ""; IEnumerator Example() { if (filePath.Contains("://")) { WWW www = new WWW(filePath); yield return www; result = www.text; } else result = System.IO.File.ReadAllText(filePath); } }