Add formal enemies, remaining formal partners and synthesized UI SFX
- 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>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user