Skip to content

Commit

Permalink
modified replace by hash feature
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelO committed Oct 6, 2022
1 parent cc3e394 commit e590858
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 60 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog (unofficial)

## [1.6.1] - 2022-10-06
- Modified ReplaceByHash feature load manifest from build folder to replace, not use append hash to bundle name to replace.

## [1.6.0] - 2022-10-05
- Added WithoutManifest feature for build advenced settings.
- Added ReplaceByHash feature for build advenced settings.
Expand Down
84 changes: 35 additions & 49 deletions Editor/AssetBundleBuildTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

using AssetBundleBrowser.AssetBundleDataSource;
using System.Linq;

namespace AssetBundleBrowser
{
Expand Down Expand Up @@ -182,7 +180,7 @@ internal void OnEnable(EditorWindow parent)

m_TargetContent = new GUIContent("Build Target", "Choose target platform to build for.");
m_CompressionContent = new GUIContent("Compression", "Choose no compress, standard (LZMA), or chunk based (LZ4)");
m_BundleNameContent = new GUIContent("Bundle Name", "Choose none, append hash, or replace by hash (Including manifest)");
m_BundleNameContent = new GUIContent("Bundle Name", "Choose none, append hash, or replace by hash");

if (m_UserData.m_UseDefaultPath)
{
Expand Down Expand Up @@ -396,10 +394,7 @@ private void ExecuteBuild()
if (m_UserData.m_BundleNameOption == BundleNameOptions.AppendHash)
opt |= BuildAssetBundleOptions.AppendHashToAssetBundleName;
else if (m_UserData.m_BundleNameOption == BundleNameOptions.ReplaceByHash)
{
opt |= BuildAssetBundleOptions.AppendHashToAssetBundleName;
replaceByHash = true;
}

// toggle options
foreach (var tog in m_ToggleData)
Expand Down Expand Up @@ -494,73 +489,64 @@ private void ResetPathToDefault()
/// Remove manifest file from build folder
/// </summary>
/// <param name="outputDirectory"></param>
internal static void WithoutManifestFile(string outputDirectory)
internal static bool WithoutManifestFile(string outputDirectory)
{
// filter only extension is manifest
string[] files = Directory.GetFiles(outputDirectory, "*.manifest", SearchOption.AllDirectories);
foreach (string file in files)
{
if (File.Exists(file)) File.Delete(file);
}

return true;
}

/// <summary>
/// Repace bundle name by hash (keep hash)
/// Repace bundle name by hash (read hash from manifest to replace)
/// </summary>
/// <param name="outputDirectory"></param>
internal static void ReplaceBundleNameByHash(string outputDirectory)
internal static bool ReplaceBundleNameByHash(string outputDirectory)
{
// set replacement map for manifest file to replace hash
Dictionary<string, string> dictReplacement = new Dictionary<string, string>();
// outputDirectory last path name = manifestName
var firstIdx = outputDirectory.LastIndexOf("\\") == -1 ? outputDirectory.LastIndexOf("/") : outputDirectory.LastIndexOf("\\");
string manifestName = outputDirectory.Substring(firstIdx + 1, outputDirectory.Length - firstIdx - 1);

string manifestFullPath = string.Empty;

// get all file
// search from all file to find menifest
string[] files = Directory.GetFiles(outputDirectory, "*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
// get fileName without extension
string fileName = Path.GetFileNameWithoutExtension(file);

// Hash128 = 16 bytes (hex str => 0xFF = 1 bytes = 1 set, 16 * 2 = 32)
int hashSize = 32;

// append hash has _
var lastIdx = file.LastIndexOf("_");
// path \ for win, / for mac, linux
var firstIdx = (file.LastIndexOf("\\") == -1 ? file.LastIndexOf("/") : file.LastIndexOf("\\"));

// fileName.Length > hashSize = including hash code
if (lastIdx != -1 && firstIdx != -1 && fileName.Length > hashSize)
if (file.IndexOf(manifestName) != -1)
{
string originFileName = file.Substring(firstIdx + 1, lastIdx - firstIdx - 1);
string hash = file.Substring(firstIdx + 2 + originFileName.Length, hashSize);

// set pair
dictReplacement.Add(originFileName, hash);

// replace origin file name to empty (only keep hash code)
string newFile = file.Replace($"{originFileName}_", string.Empty);

// rename it
if (File.Exists(file)) File.Move(file, newFile);
manifestFullPath = Path.GetFullPath(file);
break;
}
}

// get all manifest file
string[] manifestFiles = Directory.GetFiles(outputDirectory, "*.manifest", SearchOption.AllDirectories);
foreach (string file in manifestFiles)
// file stream to read manifest
var fs = new FileStream(manifestFullPath, FileMode.Open, FileAccess.Read, FileShare.None);
var bundle = AssetBundle.LoadFromStream(fs);
fs.Dispose();

// load manifest asset
AssetBundleManifest manifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

// replace all bundle file name by hash
foreach (var file in files)
{
foreach (var pair in dictReplacement)
{
string originFileName = pair.Key;
string hash = pair.Value;
string bundleName = file.Replace(outputDirectory, string.Empty);
bundleName = bundleName.Substring(1, bundleName.Length - 1);
// skip process manifest & .manifest extension
if (bundleName.IndexOf(manifestName) != -1 || file.IndexOf(".manifest") != -1) continue;

if (file.IndexOf(originFileName) != -1)
{
string newFile = file.Replace(originFileName, hash);
if (File.Exists(file)) File.Move(file, newFile);
}
}
string fileName = Path.GetFileNameWithoutExtension(file);
string hash = manifest.GetAssetBundleHash(bundleName).ToString();
string newFile = file.Replace(fileName, hash);
if (File.Exists(file)) File.Move(file, newFile);
}

return true;
}

//Note: this is the provided BuildTarget enum with some entries removed as they are invalid in the dropdown
Expand Down
21 changes: 15 additions & 6 deletions Editor/BundleBuildMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,19 +547,28 @@ public static bool BuildAssetBundles(string outputDirectory, AssetBundleBuild[]
{
if (!Directory.Exists(outputDirectory)) Directory.CreateDirectory(outputDirectory);

// set option first
if (replaceByHash) options |= BuildAssetBundleOptions.AppendHashToAssetBundleName;

var buildManifest = BuildPipeline.BuildAssetBundles(outputDirectory, buildMap, options, buildTarget);
if (buildManifest == null)
{
Debug.Log("Error in build");
return false;
}

// after build
if (withoutManifest) AssetBundleBuildTab.WithoutManifestFile(outputDirectory);
if (replaceByHash) AssetBundleBuildTab.ReplaceBundleNameByHash(outputDirectory);
// after build (without manifest)
if (withoutManifest)
{
bool completes = AssetBundleBuildTab.WithoutManifestFile(outputDirectory);
if (!completes) Debug.Log("Error in process remove manifest.");
else Debug.Log($"<color=#60ffb0>Remove all manifest file completes.</color>");
}

// after build (replace by hash)
if (replaceByHash)
{
bool completes = AssetBundleBuildTab.ReplaceBundleNameByHash(outputDirectory);
if (!completes) Debug.Log("Error in process replace by hash.");
else Debug.Log($"<color=#60ffb0>Replace all bundle name by hash completes.</color>");
}

if (onBuild != null)
{
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,22 @@ When enabled sync feature can sync asset data to other BuildMap <font color=#005
return;
}
// outPath
string fullBundleOutPath = Path.Combine(Application.dataPath, $"../AssetBundles/MyBundle");
// output path
string outputDirectory = Path.Combine(Application.dataPath, $"../AssetBundles/MyBundle");
// platform
BuildTarget target = BuildTarget.StandaloneWindows;
// LZ4
BuildAssetBundleOptions bundleOptions = BuildAssetBundleOptions.ChunkBasedCompression;
BundleBuildMap.BuildAssetBundles(fullBundleOutPath, bundleBuildMap.GetBuildMap(), bundleOptions, target, null);
// regular
BundleBuildMap.BuildAssetBundles(outputDirectory, bundleBuildMap.GetBuildMap(), bundleOptions, target, null);
// including withoutManifest and replaceByHash params
bool withoutManifest = true;
bool replaceByHash = true;
BundleBuildMap.BuildAssetBundles(fullBundleOutPath, bundleBuildMap.GetBuildMap(), bundleOptions, target, withoutManifest, replaceByHash, null);
BundleBuildMap.BuildAssetBundles(outputDirectory, bundleBuildMap.GetBuildMap(), bundleOptions, target, withoutManifest, replaceByHash, null);
```

### Extension Advenced Settings
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"name": "com.unity.assetbundlebrowser.plus",
"displayName": "Asset Bundle Browser Plus",
"version": "1.6.0",
"version": "1.6.1",
"unity": "2018.1",
"description": "The Asset Bundle Browser tool enables the user to view and edit the configuration of asset bundles for their Unity project. It will block editing that would create invalid bundles, and inform you of any issues with existing bundles. It also provides basic build functionality.\n\nUse this tool as an alternative to selecting assets and setting their asset bundle manually in the inspector. It can be dropped into any Unity project with a version of 5.6 or greater. It will create a new menu item in Window > AssetBundle Browser. The bundle configuration, build functionality, and built-bundle inspection are split into three tabs within the new window.",
"keywords": ["asset", "bundle", "bundles", "assetbundles"],
Expand Down

0 comments on commit e590858

Please sign in to comment.