- UI SFX v3: procedurally synthesized one-shots (Tools/synth_ui_sfx.py) wired to buttons, rewards, errors and red dots via UiSfx, gated by the SFX setting. - Five formal enemies (Hornlet, Dashlet, Shellhorn, HornCaptain, GreatHorn): Hunyuan 50k -> 2000-tri XPbr, DGXA TokenRig, Idle/Walk/Attack, nested per type in PrototypeArena; PrototypeBattle.Enemy gains presentation-only Moving/Strikes. - Formal partners for all ten pets in the arena and portraits, including new VineSprite, ThunderLeopard and TideWhale. - Pipeline fixes: reject local TokenRig fallback, drop loose mesh islands, configurable Unity run_script timeout, companion static stage. - Also includes concurrent work from another tool in this working tree (FlameLion, enemy combat FX, challenge mode, home explorer, server updates). - Resources registered in Doc/ResDesc_*.md; verified on isolated :18081. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
105 lines
4.1 KiB
C#
105 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Newtonsoft.Json;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using YooAsset.Editor;
|
|
|
|
// Pipeline: import UI SFX WAVs under Bundles/Sound/SFX/UI and register Art/Sound collector.
|
|
public static class ImportUiSfx
|
|
{
|
|
const string Folder = "Assets/Bundles/Sound/SFX/UI";
|
|
|
|
public static string ConfigureAndVerify()
|
|
{
|
|
if (EditorApplication.isPlaying)
|
|
throw new InvalidOperationException("Import UI SFX in Edit Mode.");
|
|
|
|
string repo = Directory.GetParent(Application.dataPath).Parent.FullName;
|
|
string designDir = Path.Combine(repo, "Doc/Design/Sound/UiSfx");
|
|
Directory.CreateDirectory(designDir);
|
|
|
|
string[] guids = AssetDatabase.FindAssets("t:AudioClip", new[] { Folder });
|
|
if (guids.Length == 0)
|
|
throw new Exception("No AudioClips under " + Folder);
|
|
|
|
var items = new List<object>();
|
|
foreach (string guid in guids)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
var importer = AssetImporter.GetAtPath(path) as AudioImporter;
|
|
if (importer == null)
|
|
throw new Exception("AudioImporter missing: " + path);
|
|
|
|
var sample = importer.defaultSampleSettings;
|
|
sample.loadType = AudioClipLoadType.DecompressOnLoad;
|
|
sample.compressionFormat = AudioCompressionFormat.PCM;
|
|
sample.sampleRateSetting = AudioSampleRateSetting.PreserveSampleRate;
|
|
sample.preloadAudioData = true;
|
|
importer.defaultSampleSettings = sample;
|
|
importer.forceToMono = false;
|
|
importer.loadInBackground = false;
|
|
importer.SaveAndReimport();
|
|
|
|
var clip = AssetDatabase.LoadAssetAtPath<AudioClip>(path);
|
|
if (clip == null || clip.channels < 1 || clip.frequency != 44100)
|
|
throw new Exception("Unexpected AudioClip: " + path);
|
|
|
|
items.Add(new {
|
|
asset = path,
|
|
guid,
|
|
address = Path.GetFileNameWithoutExtension(path),
|
|
clip.length,
|
|
clip.samples,
|
|
clip.channels,
|
|
clip.frequency,
|
|
loadType = importer.defaultSampleSettings.loadType.ToString(),
|
|
compression = importer.defaultSampleSettings.compressionFormat.ToString()
|
|
});
|
|
}
|
|
|
|
var package = BundleCollectorSettingData.Setting.Packages.Find(p => p.PackageName == "Art");
|
|
if (package == null)
|
|
throw new Exception("Existing Art package missing.");
|
|
var group = package.Groups.Find(g => g.GroupName == "Sound");
|
|
if (group == null)
|
|
group = BundleCollectorSettingData.CreateGroup(package, "Sound");
|
|
group.ActiveRuleName = nameof(EnableGroup);
|
|
group.AssetTags = "art";
|
|
BundleCollectorSettingData.ModifyGroup(package, group);
|
|
|
|
var collector = group.Collectors.Find(c => c.CollectPath == Folder);
|
|
if (collector == null)
|
|
{
|
|
collector = new BundleCollector {
|
|
CollectPath = Folder,
|
|
CollectorGUID = AssetDatabase.AssetPathToGUID(Folder),
|
|
CollectorType = ECollectorType.MainAssetCollector,
|
|
AddressRuleName = nameof(AddressByFileName),
|
|
PackRuleName = nameof(PackSeparately),
|
|
FilterRuleName = nameof(CollectAll),
|
|
AssetTags = "art"
|
|
};
|
|
BundleCollectorSettingData.CreateCollector(group, collector);
|
|
}
|
|
package.CheckConfigError();
|
|
BundleCollectorSettingData.SaveFile();
|
|
|
|
var report = new {
|
|
folder = Folder,
|
|
count = items.Count,
|
|
items,
|
|
package = "Art",
|
|
group = "Sound",
|
|
packRule = collector.PackRuleName,
|
|
runtimePlaybackWired = false,
|
|
bundleBuilt = false,
|
|
verifiedUtc = DateTime.UtcNow.ToString("o")
|
|
};
|
|
string json = JsonConvert.SerializeObject(report, Formatting.Indented);
|
|
File.WriteAllText(Path.Combine(designDir, "unity_validation.json"), json);
|
|
return json;
|
|
}
|
|
}
|