iOS용 플러그인 빌드
iOS에서 WWW 요청 커스터마이즈(Customising WWW Requests on iOS)

“인앱 구매”가 가능하도록 애플리케이션 준비(Preparing your application for “In App Purchases”)

이 장에서는 게임을 Apple의 StoreKit API와 통합하는 방법에 대해 설명하지 않습니다. 사용자가 네이티브 코드 플러그인을 통해 StoreKit과 이미 통합했다고 가정합니다.

Apple StoreKit 문서에서는 인앱 구매 프로세스를 통해 판매할 수 있는 다음 네 가지 종류의 상품을 정의합니다.

  • 콘텐츠
  • 기능
  • 서비스
  • 구독

이 장에서는 첫 번째인 종류만 다루고, 주로 다운로드 가능 콘텐츠의 개념에 초점을 맞춥니다. Unity에서 다운로드 가능 콘텐츠를 구현하는 데는 에셋 번들이 권장되며, 여기서는 에셋 번들의 생성과 런타임 사용에 대해 모두 설명합니다.

iOS에서 사용할 에셋 익스포트

때로는 메인 애플리케이션과 이 앱에서 사용할 다운로드 가능 에셋 번들에 대해 별도의 프로젝트를 유지하면 유용합니다. 하지만 에셋 번들에서 오브젝트가 레퍼런스하는 모든 스크립트 는 메인 게임 실행 파일에 있어야 한다는 데 주의해야 합니다. 에셋 번들을 만드는 데 사용하는 프로젝트에서는 iOS가 선택된 빌드 타겟이어야 합니다. 에셋 번들 파일의 콘텐츠는 iOS와 다른 플랫폼 간에 호환되지 않기 때문입니다.

에셋 번들은 에디터 스크립트를 사용하여 만듭니다. 아래는 간단한 예입니다.

// C#
using UnityEngine;
using UnityEditor;

public class ExportBundle : MonoBehaviour {
    [MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies")]
    static void DoExport() {
        string str = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name, "assetbundle");
        if (str.Length != 0) {
            BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
        }
    }
}

// JS
@MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies")
static function ExportBundle() {
    var str : String = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name, "assetbundle");
    if (str.Length != 0) {
        BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
    }
}

코드를 ExportBundle 파일로 저장하고 Editor 폴더에 넣어야 합니다. 프로젝트에 폴더가 아직 없으면 새로 만들면 됩니다. 스크립트는 에디터의 에셋 메뉴에 “Build AssetBundle From Selection - Track dependencies”라는 메뉴 항목을 추가합니다.

번들에 포함시킬 콘텐츠는 프리팹 형태로 준비해야 합니다. 프로젝트 뷰에서 프리팹을 선택한 다음, Assets > Build AssetBundle From Selection - Track dependencies(즉, ExportBundle 스크립트에서 추가된 메뉴 항목)를 선택합니다. 명령을 실행하면 저장 다이얼로그가 나타나고, 여기서 에셋 번들 파일의 이름과 위치를 선택할 수 있습니다.

iOS에서 에셋 다운로드(Downloading your assets on iOS)

참고: Apple은 데이터 쓰기 권한이 있는 폴더 위치를 변경할 수 있습니다. 항상 최신 Apple 문서를 확인하여 애플리케이션이 호환될 것인지 확인해야 합니다. 이 내용은 2013년 초에 작성되었습니다.

WWW 클래스를 사용하여 에셋 번들을 다운로드할 수 있습니다. 전송이 완료되면 번들에 포함된 에셋에 액세스할 수 있습니다. 다음 예와 같이 LoadFromCacheOrDownload를 사용하여 에셋 번들을 다운로드하는 것을 권장합니다.

// C#
IEnumerator GetAssetBundle() {
    WWW download;
    string url = "http://somehost/somepath/someassetbundle.assetbundle";

    while (!Caching.ready)
        yield return null;

    download = WWW.LoadFromCacheOrDownload(url, 0);

    yield return download;

    AssetBundle assetBundle = download.assetBundle;
    if (assetBundle != null) {
        // Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
        Object go = assetBundle.mainAsset;
            
        if (go != null)
            Instantiate(go);
        else
            Debug.Log("Couldn't load resource");    
    } else {
        Debug.Log("Couldn't load resource");    
    }
}

// JS
function GetAssetBundle() {
    var download : WWW;
    var url = "http://somehost/somepath/someassetbundle.assetbundle";
    var download = WWW.LoadFromCacheOrDownload (url, 0);

    yield download;

    var assetBundle = download.assetBundle;
    if (assetBundle != null) {
        // Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
        var go : Object = assetBundle.mainAsset;
            
        if (go != null)
            Instantiate(go);
        else
            Debug.Log("Couldn't load resource");    
    } else {
        Debug.Log("Couldn't load resource");    
    }
}

다운로드한 에셋 번들 파일은 iOS 애플리케이션 샌드박스의 Library 폴더에 저장되고, 파일에 No Backup 플래그가 지정됩니다. 즉, 해당 파일이 OS에 의해 실수로 삭제되지 않고 iCloud에 백업되지 않습니다.

에셋 번들 파일 저장 위치를 정확히 지정해야 하는 경우 표준 WWW 다운로드를 사용(간단히 LoadFromCacheOrDownload 대신 생성자 사용)한 다음 다운로드한 데이터를 .NET 파일 API를 사용하여 디스크에 저장할 수 있습니다. 필요한 파일은 Application.temporaryCachePath 폴더 (OS에 의해 규칙적으로 “정리”되는 Library/Caches 에 저장됨) 또는 Application.persistentDataPath 폴더(OS에서 정리되지 않는 Documents 에 저장됨)에 저장할 수 있습니다. 이런 파일에 대해서는 iOS.Device.SetNoBackupFlag를 사용해 No Backup 플래그를 설정하여 파일이 iCloud에 백업되지 않도록 해야 합니다.

참고: 백업 불가 플래그를 설정하지 않으면 앱을 앱 스토어에 제출할 때 앱이 거부될 수 있습니다.

저장된 파일에는 file:///pathtoyourapplication/Library/savedassetbundle.assetbundle 형식의 URL을 사용해 WWW 오브젝트를 만들어서 액세스할 수 있습니다.

// C#
string cachedAssetBundle = Application.temporaryCachePath + "/savedassetbundle.assetbundle"; 
System.IO.FileStream cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create);
cache.Write(download.bytes, 0, download.bytes.Length);
cache.Close();

iOS.Device.SetNoBackupFlag(cachedAssetBundle);

Debug.Log("Cache saved: " + cachedAssetBundle);

// JS
private var cachedAssetBundle : String = Application.temporaryCachePath + "/savedassetbundle.assetbundle"; 
var cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create);
cache.Write(download.bytes, 0, download.bytes.Length);
cache.Close();

iOS.Device.SetNoBackupFlag(cachedAssetBundle);

Debug.Log("Cache saved: " + cachedAssetBundle);

참고: 파일 공유 를 활성화하면 Documents 폴더에 저장된 파일에 대해 읽기 테스트를 수행할 수 있습니다. Info.plist에서 UIFileSharingEnabled을 참(true)으로 설정하면 iTunes에서 Documents 폴더에 액세스할 수 있습니다. Documents 폴더의 콘텐츠는 iCloud에 캐싱되므로 출시할 최종 빌드에서는 이 위치를 에셋 번들을 저장하는 데 사용하지 않아야 합니다. 자세한 내용은 Apple iOS 문서의 파일 시스템 기초를 참조하십시오.

iOS용 플러그인 빌드
iOS에서 WWW 요청 커스터마이즈(Customising WWW Requests on iOS)