chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View File

@@ -0,0 +1,292 @@
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using CustomAssetBundleSystem;
/// <summary>
/// Unity Editor tool to build AssetBundles and generate catalog.json
/// Menu: Tools > AssetBundles > Build for Android
/// </summary>
public class AssetBundleBuilder : EditorWindow
{
private static string outputPath = "ServerData/AssetBundles/Android";
private static BuildTarget buildTarget = BuildTarget.Android;
[MenuItem("Tools/AssetBundles/Build for Android")]
public static void BuildAssetBundles()
{
Debug.Log("=== Custom AssetBundle Builder ===");
// Create output directory
string fullOutputPath = Path.Combine(Application.dataPath, "..", outputPath);
if (!Directory.Exists(fullOutputPath))
{
Directory.CreateDirectory(fullOutputPath);
Debug.Log($"Created output directory: {fullOutputPath}");
}
// Build options
BuildAssetBundleOptions options = BuildAssetBundleOptions.ChunkBasedCompression |
BuildAssetBundleOptions.StrictMode;
// Build the bundles
Debug.Log($"Building AssetBundles to: {fullOutputPath}");
Debug.Log($"Target platform: {buildTarget}");
AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(
fullOutputPath,
options,
buildTarget
);
if (manifest == null)
{
Debug.LogError("✗ AssetBundle build failed!");
EditorUtility.DisplayDialog("Build Failed", "AssetBundle build failed! Check console for errors.", "OK");
return;
}
Debug.Log("✓ AssetBundles built successfully!");
// Generate the JSON catalog
GenerateCatalog(fullOutputPath, manifest);
Debug.Log("=== Build Complete ===");
EditorUtility.DisplayDialog("Build Complete",
$"AssetBundles built successfully!\n\nOutput: {fullOutputPath}\n\nNext: Upload to VPS",
"OK");
}
/// <summary>
/// Generate catalog.json from built AssetBundles
/// </summary>
private static void GenerateCatalog(string outputPath, AssetBundleManifest manifest)
{
Debug.Log("Generating catalog.json...");
var catalog = new RemoteAssetCatalog
{
version = Application.version,
timestamp = System.DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
baseUrl = "https://assetbundle.uncaptured.co",
bundles = new List<RemoteAssetCatalog.BundleEntry>()
};
// Get all bundle names
string[] allBundles = manifest.GetAllAssetBundles();
foreach (string bundleName in allBundles)
{
string bundlePath = Path.Combine(outputPath, bundleName);
if (!File.Exists(bundlePath))
{
Debug.LogWarning($"Bundle file not found: {bundlePath}");
continue;
}
// Get file info
FileInfo fileInfo = new FileInfo(bundlePath);
// Calculate hash
string hash = CalculateMD5(bundlePath);
// Get scenes in this bundle
var scenePaths = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName);
var sceneNames = new List<string>();
foreach (var scenePath in scenePaths)
{
if (scenePath.EndsWith(".unity"))
{
string sceneName = Path.GetFileNameWithoutExtension(scenePath);
sceneNames.Add(sceneName);
}
}
// Get dependencies
var dependencies = new List<string>();
string[] bundleDeps = manifest.GetAllDependencies(bundleName);
dependencies.AddRange(bundleDeps);
// Create bundle entry
var entry = new RemoteAssetCatalog.BundleEntry
{
bundleName = Path.GetFileNameWithoutExtension(bundleName),
fileName = bundleName,
hash = hash,
size = fileInfo.Length,
scenes = sceneNames,
dependencies = dependencies
};
catalog.bundles.Add(entry);
Debug.Log($" ✓ Added bundle: {bundleName}");
Debug.Log($" - Size: {fileInfo.Length / 1024f / 1024f:F2} MB");
Debug.Log($" - Hash: {hash}");
Debug.Log($" - Scenes: {sceneNames.Count}");
Debug.Log($" - Dependencies: {dependencies.Count}");
}
// Save catalog as JSON
string catalogPath = Path.Combine(outputPath, "catalog.json");
string json = JsonUtility.ToJson(catalog, true);
File.WriteAllText(catalogPath, json);
Debug.Log($"✓ Catalog generated: {catalogPath}");
Debug.Log($" Total bundles: {catalog.bundles.Count}");
Debug.Log($" Catalog size: {json.Length / 1024f:F2} KB");
// Also save a pretty-printed version for debugging
string prettyPath = Path.Combine(outputPath, "catalog_readable.json");
File.WriteAllText(prettyPath, json);
Debug.Log($"✓ Readable catalog: {prettyPath}");
}
/// <summary>
/// Calculate MD5 hash of a file
/// </summary>
private static string CalculateMD5(string filePath)
{
using (var md5 = MD5.Create())
using (var stream = File.OpenRead(filePath))
{
byte[] hash = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
}
[MenuItem("Tools/AssetBundles/Open Output Folder")]
public static void OpenOutputFolder()
{
string fullPath = Path.Combine(Application.dataPath, "..", outputPath);
if (Directory.Exists(fullPath))
{
EditorUtility.RevealInFinder(fullPath);
}
else
{
Debug.LogWarning($"Output folder doesn't exist: {fullPath}");
}
}
[MenuItem("Tools/AssetBundles/Clear Cache")]
public static void ClearCache()
{
if (EditorUtility.DisplayDialog("Clear AssetBundle Cache?",
"This will delete all cached AssetBundles. Continue?",
"Yes", "Cancel"))
{
Caching.ClearCache();
Debug.Log("✓ AssetBundle cache cleared");
}
}
[MenuItem("Tools/AssetBundles/Settings")]
public static void ShowSettings()
{
var window = GetWindow<AssetBundleBuilder>("AssetBundle Builder");
window.Show();
}
// Editor Window GUI
void OnGUI()
{
GUILayout.Label("Custom AssetBundle Builder", EditorStyles.boldLabel);
GUILayout.Space(10);
EditorGUILayout.HelpBox(
"This tool builds AssetBundles and generates a JSON catalog for remote loading.\n\n" +
"1. Mark your scenes/assets with AssetBundle names\n" +
"2. Click 'Build for Android'\n" +
"3. Upload ServerData/AssetBundles/Android/ to your VPS",
MessageType.Info);
GUILayout.Space(10);
// Output path
GUILayout.Label("Output Path:", EditorStyles.boldLabel);
outputPath = EditorGUILayout.TextField(outputPath);
GUILayout.Space(5);
// Build target
GUILayout.Label("Build Target:", EditorStyles.boldLabel);
buildTarget = (BuildTarget)EditorGUILayout.EnumPopup(buildTarget);
GUILayout.Space(10);
// Build button
if (GUILayout.Button("Build AssetBundles", GUILayout.Height(40)))
{
BuildAssetBundles();
}
GUILayout.Space(5);
// Utility buttons
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("Open Output Folder"))
{
OpenOutputFolder();
}
if (GUILayout.Button("Clear Cache"))
{
ClearCache();
}
}
GUILayout.Space(20);
// Info section
GUILayout.Label("Current Settings:", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Unity Version:", Application.unityVersion);
EditorGUILayout.LabelField("App Version:", Application.version);
EditorGUILayout.LabelField("Company:", Application.companyName);
GUILayout.Space(10);
// Quick guide
if (GUILayout.Button("Show Quick Guide"))
{
ShowQuickGuide();
}
}
private static void ShowQuickGuide()
{
EditorUtility.DisplayDialog("AssetBundle Quick Guide",
"STEP 1: Mark Assets for Bundling\n" +
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
"• Select your Game scene in Project window\n" +
"• In Inspector, find 'AssetBundle' dropdown (bottom)\n" +
"• Select 'New...' and name it 'gamescene'\n\n" +
"STEP 2: Build AssetBundles\n" +
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
"• Tools → AssetBundles → Build for Android\n" +
"• Wait for build to complete\n" +
"• Files created in ServerData/AssetBundles/Android/\n\n" +
"STEP 3: Upload to VPS\n" +
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
"• scp -r ServerData/AssetBundles/Android/* user@server:/var/www/AssetBundles/Android/\n\n" +
"STEP 4: Update Your Code\n" +
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +
"• Replace Addressables calls with CustomAssetBundleSceneLoader\n" +
"• Build APK and test!",
"Got it!");
}
}