需求:实现用AssetBundle打包和加载场景、预制体。 这是参照一位大佬的拿来改了一点,但是现在没找到大佬的文章,就先这样吧。
实现打AB包方法一:
打包工具AssetBundleBuilder.cs
using UnityEngine;
using UnityEditor;
using System.IO;
public class AssetBundleBuilder : EditorWindow
{
[MenuItem("打包/Windows/资源包和场景")]
public static void BuildAbsAndScenesWindows()
{
AssetBundleBuilder assetBundleBuilder = EditorWindow.GetWindow<AssetBundleBuilder>();
assetBundleBuilder.Show();
}
static string outPath;
private void OnGUI()
{
GUILayout.Space(10);
GUI.skin.label.fontSize = 12;
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label("AssetBundle文件名称:", GUILayout.MaxWidth(160));
outPath = EditorGUILayout.TextField(outPath);
EditorGUI.EndDisabledGroup();
if (GUILayout.Button("开始打包场景和资源"))
{
BuildAbsAndScenes(BuildTarget.StandaloneWindows);
}
}
[MenuItem("打包/Android/资源包和场景")]
public static void BuildAbsAndScenesAndroid()
{
BuildAbsAndScenes(BuildTarget.Android);
}
[MenuItem("打包/IOS/资源包和场景")]
public static void BuildAbsAndScenesIOS()
{
BuildAbsAndScenes(BuildTarget.iOS);
}
[MenuItem("打包/Windows/资源包")]
public static void BuildAbsWindows()
{
BuildAssetBundles(BuildTarget.StandaloneWindows);
}
[MenuItem("打包/Android/资源包")]
public static void BuildAbsAndroid()
{
BuildAssetBundles(BuildTarget.Android);
}
[MenuItem("打包/IOS/资源包")]
public static void BuildAbsIOS()
{
BuildAssetBundles(BuildTarget.iOS);
}
[MenuItem("打包/Windows/场景")]
public static void BuildScenesWindows()
{
BuildScenes(BuildTarget.StandaloneWindows);
}
[MenuItem("打包/Android/场景")]
public static void BuildScenesAndroid()
{
BuildScenes(BuildTarget.Android);
}
[MenuItem("打包/IOS/场景")]
public static void BuildScenesIOS()
{
BuildScenes(BuildTarget.iOS);
}
public static void BuildAbsAndScenes(BuildTarget platform)
{
BuildAssetBundles(platform);
BuildScenes(platform);
}
private static void BuildAssetBundles(BuildTarget platform)
{
if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
EditorUtility.DisplayProgressBar("信息", "打包资源包", 0f);
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.DeterministicAssetBundle, platform);
AssetDatabase.Refresh();
Debug.Log("所有资源包打包完毕");
}
private static void BuildScenes(BuildTarget platform)
{
string scenePath = Application.dataPath + "/AbResources/Scenes";
if (Directory.Exists(scenePath))
{
if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
string[] scenes = GetAllFiles(scenePath, "*.unity");
for (int i = 0; i < scenes.Length; i++)
{
string url = scenes[i].Replace("\\", "/");
int index = url.LastIndexOf("/");
string scene = url.Substring(index + 1, url.Length - index - 1);
string msg = string.Format("打包场景{0}", scene);
EditorUtility.DisplayProgressBar("信息", msg, 0f);
scene = scene.Replace(".unity", ".scene");
Debug.Log(string.Format("打包场景{0}到{1}", url, outPath + scene));
BuildPipeline.BuildPlayer(scenes, outPath + scene, BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes);
AssetDatabase.Refresh();
}
EditorUtility.ClearProgressBar();
Debug.Log("所有场景打包完毕");
}
}
private static string[] GetAllFiles(string directory, params string[] types)
{
if (!Directory.Exists(directory)) return new string[0];
string searchTypes = (types == null || types.Length == 0) ? "*.*" : string.Join("|", types);
string[] names = Directory.GetFiles(directory, searchTypes, SearchOption.AllDirectories);
return names;
}
}
加载ABTest.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class ABTest : MonoBehaviour
{
public Text textProgress;
private void Awake()
{
LoadScene(Application.streamingAssetsPath + "/Abs/" + "test");
LoadPrefabs(Application.streamingAssetsPath + "/Abs/" + "cube.ab");
}
public void LoadPrefabs(string url)
{
StartCoroutine(DownloadPrefab(url));
}
IEnumerator DownloadPrefab(string url)
{
AssetBundle ab;
using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url))
{
request.SendWebRequest();
while (!request.isDone)
{
Debug.Log(request.downloadProgress);
yield return null;
}
if (request.isDone)
{
Debug.Log(100);
}
ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
if (ab == null)
{
Debug.LogError("AB包为空");
yield break;
}
}
GameObject ga = ab.LoadAsset<GameObject>("Assets/Prefabs/cube.prefab");
Instantiate<GameObject>(ga);
Debug.Log("成功");
yield break;
}
public void LoadScene(string url)
{
StartCoroutine(DownloadScene(url));
}
IEnumerator DownloadScene(string url)
{
myLoadedAssetBundle = AssetBundle.LoadFromFile(url);
scenePaths = myLoadedAssetBundle.GetAllScenePaths();
SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single);
Debug.Log("成功");
yield break;
}
private AssetBundle myLoadedAssetBundle;
private string[] scenePaths;
}
这里面的加载场景有两种方式,但是最关键、核心的就是这句代码 scenePaths = myLoadedAssetBundle.GetAllScenePaths();
以上就是打包和加载了 但是这样的打包存在一定的局限性,不太建议使用这种方式。还有一种方式就是使用官方的AssetBundleBrowser来进行打包和加载(也是个人比较推荐的)。
实现打AB包方法二:
1、去PackageManager里面下载Asset Bundle Browser; 2、打开Asset Bundle Browser窗口; 3、把资源拖进去 (这里报感叹号弄成依赖资源就可以去掉了,当然也可以不管) 然后build根据个人需求修改就可以打包了 至此,打包结束。
然后就是加载资源:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
public class DemoLoadBundle : MonoBehaviour
{
public string bundleName = "dogpbr";
public string assetName = "dogpbr";
private void Start()
{
DontDestroyOnLoad(gameObject);
LoadDependencies();
LoadBundleScene();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
InstantiateBundlePrefab();
}
}
void LoadDependencies()
{
AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows");
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependenciesPrefab = manifest.GetAllDependencies(bundleName);
foreach (var dependencie in dependenciesPrefab)
{
var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie);
}
string[] dependencieScene = manifest.GetAllDependencies(sceneName);
foreach (var dependencie in dependencieScene)
{
var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie);
}
}
private void InstantiateBundlePrefab()
{
AssetBundle asset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + bundleName);
var asset_go = asset.LoadAsset<GameObject>(assetName);
Instantiate(asset_go);
}
public string sceneName = "abtestscene";
#region 方式一
IEnumerator LoadABScene()
{
AssetBundle ab;
using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(""))
{
request.SendWebRequest();
while (!request.isDone)
{
Debug.Log(request.downloadProgress);
yield return null;
}
if (request.isDone)
{
Debug.Log(100);
}
ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
if (ab == null)
{
Debug.LogError("AB包为空");
yield break;
}
string[] s = ab.GetAllScenePaths();
SceneManager.LoadScene(s[0], LoadSceneMode.Single);
}
}
#endregion
#region 方式二
private void LoadBundleScene()
{
myLoadedAssetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + sceneName);
scenePaths = myLoadedAssetBundle.GetAllScenePaths();
SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single);
}
private AssetBundle myLoadedAssetBundle;
private string[] scenePaths;
#endregion
}
以上就是一整套的打包和加载了。
|