Add AIServer, character art pipeline, and Art package boot integration.
Bring in MaleExplorer assets/shaders, model tooling and Hunyuan updates, plus boot/YooAsset Art package support. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using YooAsset.Editor;
|
||||
|
||||
namespace AOT.Editor.YooAssetTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建 Art 包(角色等)并暂存 CDN / StreamingAssets。
|
||||
/// </summary>
|
||||
public static class BuildAndStageArt
|
||||
{
|
||||
public const string PackageName = "Art";
|
||||
public const string AppVersion = "1.0.0";
|
||||
public const string Channel = "wechat";
|
||||
|
||||
static string RepoRoot => Path.GetFullPath(Path.Combine(Application.dataPath, "..", ".."));
|
||||
static string CdnRoot => Path.Combine(RepoRoot, "Tools", "cdn_root");
|
||||
static string ProjectBundlesRoot => BundleBuilderHelper.GetDefaultBuildOutputRoot();
|
||||
|
||||
[MenuItem("AIGame/YooAsset/Build And Stage Art")]
|
||||
public static string BuildAndStage()
|
||||
{
|
||||
SetupM3Character.SetupAll();
|
||||
|
||||
var target = EditorUserBuildSettings.activeBuildTarget;
|
||||
string packageVersion = DateTime.Now.ToString("yyyyMMdd.HHmmss");
|
||||
var buildResult = BuildArtPackage(target, packageVersion);
|
||||
if (!buildResult.Success)
|
||||
return $"fail: {buildResult.ErrorInfo}";
|
||||
|
||||
string packageDir = buildResult.OutputPackageDirectory;
|
||||
string stageDir = Path.Combine(CdnRoot, Channel, AppVersion, PackageName);
|
||||
StageDirectory(packageDir, stageDir);
|
||||
|
||||
// 合并 version.json packages 列表
|
||||
MergeVersionPackages(packageVersion);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
return $"ok ver={packageVersion} dir={packageDir} stage={stageDir}";
|
||||
}
|
||||
|
||||
static BuildResult BuildArtPackage(BuildTarget target, string packageVersion)
|
||||
{
|
||||
var uniqueBundleName = BundleCollectorSettingData.Setting.UniqueBundleName;
|
||||
var packRuleResult = DefaultBundlePackRule.CreateShadersPackRuleResult();
|
||||
var builtinShaderBundleName = packRuleResult.GetBundleName(PackageName, uniqueBundleName);
|
||||
|
||||
var buildParameters = new ScriptableBuildParameters
|
||||
{
|
||||
BuildOutputRoot = ProjectBundlesRoot,
|
||||
BundledFileRoot = BundleBuilderHelper.GetStreamingAssetsRoot(),
|
||||
BuildPipeline = EBuildPipeline.ScriptableBuildPipeline.ToString(),
|
||||
BuildBundleType = (int)EBundleType.AssetBundle,
|
||||
BuildTarget = target,
|
||||
PackageName = PackageName,
|
||||
PackageVersion = packageVersion,
|
||||
EnableSharePackRule = true,
|
||||
VerifyBuildingResult = true,
|
||||
FileNameStyle = EFileNameStyle.HashName,
|
||||
BundledCopyOption = EBundledCopyOption.ClearAndCopyAll,
|
||||
BundledCopyParams = string.Empty,
|
||||
CompressOption = ECompressOption.LZ4,
|
||||
ClearBuildCacheFiles = false,
|
||||
UseAssetDependencyDB = true,
|
||||
BuiltinShadersBundleName = builtinShaderBundleName,
|
||||
};
|
||||
|
||||
var pipeline = new ScriptableBuildPipeline();
|
||||
return pipeline.Run(buildParameters, true);
|
||||
}
|
||||
|
||||
static void StageDirectory(string src, string dst)
|
||||
{
|
||||
if (Directory.Exists(dst))
|
||||
Directory.Delete(dst, true);
|
||||
Directory.CreateDirectory(dst);
|
||||
foreach (var file in Directory.GetFiles(src, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
var rel = file.Substring(src.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
var destFile = Path.Combine(dst, rel);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destFile) ?? dst);
|
||||
File.Copy(file, destFile, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void MergeVersionPackages(string resVersion)
|
||||
{
|
||||
var path = Path.Combine(CdnRoot, Channel, "version.json");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path) ?? CdnRoot);
|
||||
var localCdn = $"http://127.0.0.1:8787/{Channel}/{AppVersion}/{BuildAndStageHotUpdate.PackageName}";
|
||||
var json =
|
||||
"{\n" +
|
||||
$" \"appVersionMin\": \"{AppVersion}\",\n" +
|
||||
$" \"appVersionMax\": \"{AppVersion}\",\n" +
|
||||
$" \"resVersion\": \"{resVersion}\",\n" +
|
||||
$" \"cdnRoot\": \"{localCdn}\",\n" +
|
||||
" \"packages\": [ \"DefaultPackage\", \"Art\" ],\n" +
|
||||
" \"forceUpdate\": false,\n" +
|
||||
" \"notice\": \"\"\n" +
|
||||
"}\n";
|
||||
File.WriteAllText(path, json);
|
||||
File.WriteAllText(Path.Combine(Application.streamingAssetsPath, "cdn", "version.json"), json);
|
||||
|
||||
var prod =
|
||||
"{\n" +
|
||||
$" \"appVersionMin\": \"{AppVersion}\",\n" +
|
||||
$" \"appVersionMax\": \"{AppVersion}\",\n" +
|
||||
$" \"resVersion\": \"{resVersion}\",\n" +
|
||||
$" \"cdnRoot\": \"https://www.xworld.ren/{Channel}/{AppVersion}/{BuildAndStageHotUpdate.PackageName}\",\n" +
|
||||
" \"packages\": [ \"DefaultPackage\", \"Art\" ],\n" +
|
||||
" \"forceUpdate\": false,\n" +
|
||||
" \"notice\": \"\"\n" +
|
||||
"}\n";
|
||||
File.WriteAllText(Path.Combine(CdnRoot, Channel, "version.prod.json"), prod);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db0c7c0cdfa612f47bea89cc1bd02a6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -3,13 +3,12 @@ using AOT.Boot;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using YooAsset;
|
||||
|
||||
namespace AOT.Editor.YooAssetTools
|
||||
{
|
||||
/// <summary>
|
||||
/// 切换 BootDriver 的 M1 验证模式(Offline / Host / Direct)。
|
||||
/// 切换 BootDriver 的运行模式 / 服务器地址。
|
||||
/// </summary>
|
||||
public static class ConfigureBootPlayMode
|
||||
{
|
||||
@@ -30,6 +29,33 @@ namespace AOT.Editor.YooAssetTools
|
||||
versionUrl: "http://127.0.0.1:8787/wechat/version.json",
|
||||
defaultCdn: "http://127.0.0.1:8787/wechat/1.0.0/DefaultPackage");
|
||||
|
||||
[MenuItem("AIGame/Boot/Server/Production game.xworld.ren")]
|
||||
public static string SetServerProd() => ApplyServer(
|
||||
"https://game.xworld.ren",
|
||||
"wss://game.xworld.ren/ws?pid={pid}&token={token}");
|
||||
|
||||
[MenuItem("AIGame/Boot/Server/Local AIServer :8080")]
|
||||
public static string SetServerLocal() => ApplyServer(
|
||||
"http://127.0.0.1:8080",
|
||||
"ws://127.0.0.1:8080/ws?pid={pid}&token={token}");
|
||||
|
||||
static string ApplyServer(string httpBase, string wsTemplate)
|
||||
{
|
||||
var scene = EditorSceneManager.OpenScene(BootScene, OpenSceneMode.Single);
|
||||
var boot = Object.FindObjectOfType<BootDriver>();
|
||||
if (boot == null)
|
||||
return "fail: BootDriver not found in Boot scene";
|
||||
|
||||
var so = new SerializedObject(boot);
|
||||
var settings = so.FindProperty("settings");
|
||||
settings.FindPropertyRelative("HttpBase").stringValue = httpBase;
|
||||
settings.FindPropertyRelative("WsUrlTemplate").stringValue = wsTemplate;
|
||||
so.ApplyModifiedPropertiesWithoutUndo();
|
||||
EditorSceneManager.MarkSceneDirty(scene);
|
||||
EditorSceneManager.SaveScene(scene);
|
||||
return $"ok http={httpBase} ws={wsTemplate}";
|
||||
}
|
||||
|
||||
static string Apply(EPlayMode playMode, bool editorDirect, string versionUrl = null, string defaultCdn = null)
|
||||
{
|
||||
var scene = EditorSceneManager.OpenScene(BootScene, OpenSceneMode.Single);
|
||||
|
||||
Reference in New Issue
Block a user