xcode 在 Unity 中构建和加载 Assetbundle

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47030894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:23:32  来源:igfitidea点击:

Build and load Assetbundles in Unity

c#iosxcodeunity3dassetbundle

提问by Gideons

I cannot get Unity Assetbundles working in an iOS build.

我无法在 iOS 版本中使用 Unity Assetbundle。

In Unity I build the assetbundles:

在 Unity 中,我构建了资产包:

using UnityEditor;

public class CreateAssetBundles
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.iOS);
    }
 }

And they work fine in Unity. using them with

它们在 Unity 中运行良好。使用它们

AssetBundle bundleLoadRequest = AssetBundle.LoadFromFile("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString());

and/or

和/或

WWW wwww = WWW.LoadFromCacheOrDownload("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString(), 4); 

(Without the "file://" prefix, the bundles won't work in Unity nor Xcode)

(没有“file://”前缀,这些包在 Unity 和 Xcode 中都不起作用)

I build the project to Xcode and run it in Xcode and receive this error:

我将项目构建到 Xcode 并在 Xcode 中运行它并收到此错误:

Unable to open archive file: /Users/user/Documents/Workspaces/unityproject/Assets/AssetBundles/iOS/lchairanimations

无法打开存档文件:/Users/user/Documents/Workspaces/unityproject/Assets/AssetBundles/iOS/lchairanimations

It might be related somehow to setting the correct path, but as I have copied the assetbundle folder afterwards to Xcode project, the problem persists.

它可能与设置正确的路径有某种关系,但是当我之后将 assetbundle 文件夹复制到 Xcode 项目时,问题仍然存在。

回答by Programmer

In this example below, I will demonstrate how to add new asset called "dog"to our AssetBundle named "animals"and build it then load it during run-time.

在下面的这个示例中,我将演示如何将名为“dog”的新资产添加到名为“animals”的AssetBundle 中并构建它,然后在运行时加载它。

Setting Up Build Folders:

设置构建文件夹:

1. Select the asset such as image file. In this case, that's the "dog.jpeg"file. See the menu in the "Inspector" tab. Sometimes, the AssetBundle option it is hidden, drag it up to show it. See the animated gif below for how to do this. The default AssetBundle is "None". Click on the "None"option then go to the "New"option and create new AssetBundle and name it "animals"

1. 选择资产,例如图像文件。在这种情况下,就是“dog.jpeg”文件。请参阅“检查器”选项卡中的菜单。有时,AssetBundle 选项是隐藏的,向上拖动以显示它。请参阅下面的动画 gif 以了解如何执行此操作。默认的 AssetBundle 是 "None"。单击“无”选项,然后转到“新建”选项并创建新的 AssetBundle 并将其命名为“animals”

enter image description here

在此处输入图片说明

2. Create a folder named StreamingAssetsin the Assets folder. This is the folder we are going to build the AssetBundle into. Spelling counts and it's case sensitive so make sure to name it correctly.

2. 创建一个StreamingAssets在 Assets 文件夹中命名的文件夹。这是我们要在其中构建 AssetBundle 的文件夹。拼写很重要,并且区分大小写,因此请确保正确命名。

enter image description here

在此处输入图片说明

3. Create sub-folder in the StreamingAssetsfolder to hold the AssetBundle. For this example, name this folder AssetBundlesso that you can use it to recognize what's in it.

3. 在StreamingAssets文件夹中创建子文件夹以保存 AssetBundle。在此示例中,为此文件夹命名,AssetBundles以便您可以使用它来识别其中的内容。

enter image description here

在此处输入图片说明



Building AssetBundle:

构建 AssetBundle:

4. Below is the build script.

4. 下面是构建脚本。

A. Create a script named ExportAssetBundlesand put it in a folder named "Editor"in the Assets folder then copy the code below inside it:

一个。创建一个名为的脚本ExportAssetBundles并将其放在Assets 文件夹中名为“Editor”的文件夹中,然后将下面的代码复制到其中:

using System.IO;
using UnityEditor;
using UnityEngine;

public class ExportAssetBundles
{
    [MenuItem("Assets/Build AssetBundle")]
    static void ExportResource()
    {
        string folderName = "AssetBundles";
        string filePath = Path.Combine(Application.streamingAssetsPath, folderName);

        //Build for Windows platform
        BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

        //Uncomment to build for other platforms
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.iOS);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.Android);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.WebGL);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);

        //Refresh the Project folder
        AssetDatabase.Refresh();
    }
}

enter image description here

在此处输入图片说明

B. Build your AssetBudle by going to Assets--> Build AssetBundlemenu.

。通过转到Assets--> Build AssetBundle菜单来构建您的 AssetBudle 。

You should see the built AssetBundles inside the Assets/StreamingAssets/AssetBundlesdirectory. If not, refresh the Project tab.

您应该会在Assets/StreamingAssets/AssetBundles目录中看到构建的 AssetBundles 。如果没有,请刷新“项目”选项卡。

enter image description here

在此处输入图片说明



Loading the AssetBundle during run-time:

在运行时加载 AssetBundle

5. When loading it, Application.streamingAssetsPathshould be used to access the StreamingAssetsfolder. To access all the folders use, Application.streamingAssetsPath + "/AssetBundle/" + assetbunlenameWithoutExtension;. The AssetBundleand AssetBundleRequestAPI are used to load the AssetBundle. Since this is an image, Texture2Dis passed to them. If using a prefab, pass GameObjectinstead then instantiate it. See comment in code for where these changes should be made. It is recommended to use Path.Combineto combine path names so the code below should use that instead.

5. 加载它时,Application.streamingAssetsPath应该使用访问StreamingAssets文件夹。要访问所有文件夹,请使用Application.streamingAssetsPath + "/AssetBundle/" + assetbunlenameWithoutExtension;. 的AssetBundleAssetBundleRequestAPI被用来加载AssetBundle。由于这是一个图像,Texture2D因此传递给他们。如果使用预制件,请GameObject改为传递然后实例化它。有关应在何处进行这些更改,请参阅代码中的注释。建议使用Path.Combine组合路径名,因此下面的代码应该使用它。

Below is a simple loading function:

下面是一个简单的加载函数:

IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad)
{
    string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
    filePath = System.IO.Path.Combine(filePath, assetBundleName);

    //Load "animals" AssetBundle
    var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
    yield return assetBundleCreateRequest;

    AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;

    //Load the "dog" Asset (Use Texture2D since it's a Texture. Use GameObject if prefab)
    AssetBundleRequest asset = asseBundle.LoadAssetAsync<Texture2D>(objectNameToLoad);
    yield return asset;

    //Retrieve the object (Use Texture2D since it's a Texture. Use GameObject if prefab)
    Texture2D loadedAsset = asset.asset as Texture2D;

    //Do something with the loaded loadedAsset  object (Load to RawImage for example) 
    image.texture = loadedAsset;
}

Things to before loading note:

加载前注意事项:

A. Name of Assetbundle is animals.

一个。Assetbundle 的名称是animals.

B. Name of the asset/object we want to load from the animals Assetbundle is dogThis is a simple jpg of a dog.

。我们要从动物 Assetbundle 加载的资产/对象的名称是dog这是一个简单的狗 jpg。

enter image description here

在此处输入图片说明

C. The loading is simple as this:

Ç。加载很简单,如下所示:

string nameOfAssetBundle = "animals";
string nameOfObjectToLoad = "dog";

public RawImage image; 

void Start()
{
    StartCoroutine(LoadAsset(nameOfAssetBundle, nameOfObjectToLoad));
}

回答by mholmes

I have a suggestion as well that might be more accommodating to developers like me who want something more .Net based. You might consider building a "Launcher" using Unity. I would build it using Unity so it remains cross platform. Next, consider bundling your updates in a DLL since Unity supports .Net framework or store them as a image in a web folder. You can grab your data using Webclient. Article here:

我还有一个建议,它可能更适合像我这样想要更多基于 .Net 的开发人员。您可能会考虑使用 Unity 构建“启动器”。我会使用 Unity 构建它,因此它仍然是跨平台的。接下来,考虑将更新捆绑在 DLL 中,因为 Unity 支持 .Net 框架或将它们作为图像存储在 Web 文件夹中。您可以使用 Webclient 获取数据。文章在这里:

https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfile?view=netframework-4.8#System_Net_WebClient_DownloadFile_System_Uri_System_String_

https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfile?view=netframework-4.8#System_Net_WebClient_DownloadFile_System_Uri_System_String_

A launcher might be a better way to grab or update your content. I've been toying with the idea every since I played Lord of the Rings Online and I like their Launcher. So I wanted to make one for my own games. In your code you would use "DownloadFile(Uri, String)" to get your data. I would use an API or something to first check your current version of the game or DLL etc. Then check the data base for laest version. Finally the API or something could build a list of new files needed or updated files needed and just loop through requesting the files and download what you need.

启动器可能是获取或更新内容的更好方式。自从我玩指环王在线以来,我就一直在琢磨这个想法,我喜欢他们的 Launcher。所以我想为我自己的游戏制作一个。在您的代码中,您将使用“DownloadFile(Uri, String)”来获取数据。我会使用 API 或其他东西首先检查您当前版本的游戏或 DLL 等。然后检查数据库以获取最新版本。最后,API 或其他东西可以构建所需的新文件或更新文件的列表,然后循环请求文件并下载您需要的文件。