一些编辑器脚本,利用场景分类策略,自动打包。其实怎么打包看个人,只不过这样看起来比较有规律性,另外场景也是可以打包的,因为有些场景模型需要提前光烘,遮罩剔除,所以一般不会动态加载。记得把多个场景中可复用的对象剔除,场景中只保留独一无二的游戏对象,然后在打包场景,运行游戏时载入场景后,在动态的将之前移除的对象重新添加进来。就是把材质包,角色包,贴图包,特效包都打成一个包,之后依赖加载问题不大。场景中有多个组件对象,所以场景的包可能会更大一点。
在自动打标签的时候保存了json,资源文件和对应的ab包的引用关系,支持热更新更新这个json文件。
using System.IO;
using UnityEditor;
using UnityEngine;
using Newtonsoft.Json;
namespace ABFW
{
public static class ABEditor
{
static ABIni Ini = new ABIni();
/// <summary>
/// 自动设置AB包标签
/// 同时生成对应的配置文件
/// </summary>
[MenuItem("ABFW/自动标签")]
static void AutoSetABLabel()
{
//移除无用标签
AssetDatabase.RemoveUnusedAssetBundleNames();
//自动设置标签
AutoSetABLabel(ABEditorTools.Instance.ABResPath, 0);
//生成配置文件
File.WriteAllText(ABEditorTools.Instance.IniFilePath, JsonConvert.SerializeObject(Ini));
//清除记录
Ini.Clear();
}
private static void AutoSetABLabel(string filePath, int index, string abPrefix = null, string abSuffix = null)
{
if (File.Exists(filePath))
{
FileInfo fi = new FileInfo(filePath);
string resName; //配置文件内资源的名称
if (fi.Extension == ".meta")
return;
filePath = filePath.Substring(filePath.LastIndexOf("Assets"));
AssetImporter ai = AssetImporter.GetAtPath(filePath);
if (fi.Extension == ".unity")
{
ai.assetBundleName = abPrefix + "/" + abPrefix;
ai.assetBundleVariant = "u3d";
resName = fi.Name.Substring(0,fi.Name.LastIndexOf("."));
}
else
{
ai.assetBundleName = abPrefix + "/" + abSuffix;
ai.assetBundleVariant = "ab";
resName = fi.Name;
}
//添加配置文件
Ini.AddData(resName, ai.assetBundleName + "." + ai.assetBundleVariant);
}
else if (Directory.Exists(filePath))
{
if (index == 1)
{
abPrefix = filePath.Substring(filePath.LastIndexOf('\\') + 1);
}
else if (index == 2)
{
abSuffix = filePath.Substring(filePath.LastIndexOf('\\') + 1);
}
DirectoryInfo di = new DirectoryInfo(filePath);
FileSystemInfo[] fsInfos = di.GetFileSystemInfos();
for (int i = 0; i < fsInfos.Length; i++)
{
AutoSetABLabel(fsInfos[i].FullName, index + 1, abPrefix, abSuffix);
}
}
}
[MenuItem("ABFW/创建AB包")]
static void BuildAB()
{
string abPath = ABEditorTools.Instance.SaveABPackPath;
BuildPipeline.BuildAssetBundles(abPath, BuildAssetBundleOptions.ChunkBasedCompression, ABEditorTools.Instance.BudTar);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
[MenuItem("ABFW/清空AB")]
static void Clear()
{
if (Directory.Exists(ABEditorTools.Instance.SaveABPackPath))
{
Directory.Delete(ABEditorTools.Instance.SaveABPackPath, true);
AssetDatabase.Refresh();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEditor;
using System.IO;
namespace ABFW
{
/// <summary>
/// 发布的平台
/// 路径:
/// AB资源的位置
/// 打包AB包的保存位置
/// </summary>
public class ABEditorTools
{
private static ABEditorTools _Instance = new ABEditorTools();
public static ABEditorTools Instance
{
get
{
return _Instance;
}
}
private ABEditorTools()
{
BudTar = BuildTarget.StandaloneWindows;
ABResPath = "Assets/ABRes";
}
public BuildTarget BudTar;
public string ABResPath;
//AB包的打包保存路径
private string _SaveABPackPath = null;
public string SaveABPackPath
{
get
{
if(_SaveABPackPath==null)
{
_SaveABPackPath = GetABPackPath();
}
return _SaveABPackPath;
}
}
//配置文件路径
private string _IniFilePath = null;
public string IniFilePath
{
get
{
if(_IniFilePath==null)
{
_IniFilePath = GetIniPath();
}
return _IniFilePath;
}
}
/// <summary>
/// 获得配置文件路径
/// </summary>
/// <returns></returns>
private string GetIniPath()
{
string dir = GetABPackPath() + "/配置文件";
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
string filePath = Path.Combine(dir, "ABIni.json");
if(!File.Exists(filePath))
{
FileStream fs = File.Create(filePath);
fs.Close();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
return filePath;
}
/// <summary>
/// 获得AB包打包的保存路径
/// </summary>
/// <returns></returns>
private string GetABPackPath()
{
string path = string.Empty;
switch (BudTar)
{
case BuildTarget.StandaloneWindows:
path = Path.Combine(Application.streamingAssetsPath, "PC");
break;
case BuildTarget.iOS:
path = Path.Combine(Application.streamingAssetsPath, "IOS");
break;
case BuildTarget.Android:
path = Path.Combine(Application.streamingAssetsPath, "Android");
break;
}
if(!Directory.Exists(path))
{
Directory.CreateDirectory(path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
return path;
}
}
}