1
0
Fork 0

Add Animator and Audio to MineshaftStartTile

This commit is contained in:
ivan tkachenko 2025-08-02 22:59:02 +03:00
parent f131ad7148
commit 05749ff122
2 changed files with 63 additions and 6 deletions

View File

@ -11,9 +11,15 @@ namespace MuzikaGromche
{ {
static class PoweredLightsAnimators static class PoweredLightsAnimators
{ {
private const string PoweredLightTag = "PoweredLight";
private delegate void ManualPatch(GameObject animatorContainer); private delegate void ManualPatch(GameObject animatorContainer);
private readonly record struct AnimatorPatch(string AnimatorContainerPath, RuntimeAnimatorController AnimatorController, ManualPatch? ManualPatch); private readonly record struct AnimatorPatch(
string AnimatorContainerPath,
RuntimeAnimatorController AnimatorController,
bool AddTagAndAnimator,
ManualPatch? ManualPatch);
private readonly record struct TilePatch(string TileName, AnimatorPatch[] Patches) private readonly record struct TilePatch(string TileName, AnimatorPatch[] Patches)
{ {
@ -21,13 +27,17 @@ namespace MuzikaGromche
public readonly string TileCloneName = $"{TileName}(Clone)"; public readonly string TileCloneName = $"{TileName}(Clone)";
} }
private readonly record struct AnimatorPatchDescriptor(string AnimatorContainerPath, string AnimatorControllerAssetPath, ManualPatch? ManualPatch = null) private readonly record struct AnimatorPatchDescriptor(
string AnimatorContainerPath,
string AnimatorControllerAssetPath,
bool AddTagAndAnimator = false,
ManualPatch? ManualPatch = null)
{ {
public AnimatorPatch Load(AssetBundle assetBundle) public AnimatorPatch Load(AssetBundle assetBundle)
{ {
var animationController = assetBundle.LoadAsset<RuntimeAnimatorController>(AnimatorControllerAssetPath) var animationController = assetBundle.LoadAsset<RuntimeAnimatorController>(AnimatorControllerAssetPath)
?? throw new FileNotFoundException($"RuntimeAnimatorController not found: {AnimatorControllerAssetPath}", AnimatorControllerAssetPath); ?? throw new FileNotFoundException($"RuntimeAnimatorController not found: {AnimatorControllerAssetPath}", AnimatorControllerAssetPath);
return new(AnimatorContainerPath, animationController, ManualPatch); return new(AnimatorContainerPath, animationController, AddTagAndAnimator, ManualPatch);
} }
} }
@ -47,6 +57,10 @@ namespace MuzikaGromche
private static IDictionary<string, TilePatch> Patches = new Dictionary<string, TilePatch>(); private static IDictionary<string, TilePatch> Patches = new Dictionary<string, TilePatch>();
private static AudioClip AudioClipOn = null!;
private static AudioClip AudioClipOff = null!;
private static AudioClip AudioClipFlicker = null!;
public static void Load() public static void Load()
{ {
const string BundleFileName = "muzikagromche_poweredlightsanimators"; const string BundleFileName = "muzikagromche_poweredlightsanimators";
@ -54,6 +68,10 @@ namespace MuzikaGromche
var assetBundle = AssetBundle.LoadFromFile(bundlePath) var assetBundle = AssetBundle.LoadFromFile(bundlePath)
?? throw new NullReferenceException("Failed to load bundle"); ?? throw new NullReferenceException("Failed to load bundle");
AudioClipOn = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightOn.ogg");
AudioClipOff = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightOff.ogg");
AudioClipFlicker = assetBundle.LoadAsset<AudioClip>("Assets/LethalCompany/Mods/MuzikaGromche/AudioClips/LightFlicker.ogg");
const string BasePath = "Assets/LethalCompany/Mods/MuzikaGromche/AnimatorControllers/"; const string BasePath = "Assets/LethalCompany/Mods/MuzikaGromche/AnimatorControllers/";
const string PointLight4 = $"{BasePath}Point Light (4) (Patched).controller"; const string PointLight4 = $"{BasePath}Point Light (4) (Patched).controller";
@ -61,6 +79,7 @@ namespace MuzikaGromche
const string LightbulbsLine = $"{BasePath}lightbulbsLineMesh (Patched).controller"; const string LightbulbsLine = $"{BasePath}lightbulbsLineMesh (Patched).controller";
const string CeilingFan = $"{BasePath}CeilingFan (originally GameObject) (Patched).controller"; const string CeilingFan = $"{BasePath}CeilingFan (originally GameObject) (Patched).controller";
const string LEDHangingLight = $"{BasePath}LEDHangingLight (Patched).controller"; const string LEDHangingLight = $"{BasePath}LEDHangingLight (Patched).controller";
const string MineshaftStartTileSpotlight = $"{BasePath}MineshaftStartTileSpotlight (New).controller";
TilePatchDescriptor[] descriptors = TilePatchDescriptor[] descriptors =
[ [
@ -98,13 +117,17 @@ namespace MuzikaGromche
new("HangingLEDBarLight (3)", LEDHangingLight), new("HangingLEDBarLight (3)", LEDHangingLight),
new("HangingLEDBarLight (4)", LEDHangingLight, new("HangingLEDBarLight (4)", LEDHangingLight,
// This HangingLEDBarLight's IndirectLight is wrongly named, so animator couldn't find it // This HangingLEDBarLight's IndirectLight is wrongly named, so animator couldn't find it
RenameGameObjectPatch("IndirectLight (1)", "IndirectLight")), ManualPatch: RenameGameObjectPatch("IndirectLight (1)", "IndirectLight")),
]), ]),
new("PoolTile", [ new("PoolTile", [
new("PoolLights/HangingLEDBarLight", LEDHangingLight), new("PoolLights/HangingLEDBarLight", LEDHangingLight),
new("PoolLights/HangingLEDBarLight (4)", LEDHangingLight), new("PoolLights/HangingLEDBarLight (4)", LEDHangingLight),
new("PoolLights/HangingLEDBarLight (5)", LEDHangingLight), new("PoolLights/HangingLEDBarLight (5)", LEDHangingLight),
]), ]),
new("MineshaftStartTile", [
new("Cylinder.001 (1)", MineshaftStartTileSpotlight, AddTagAndAnimator: true),
new("Cylinder.001 (2)", MineshaftStartTileSpotlight, AddTagAndAnimator: true),
]),
]; ];
Patches = descriptors Patches = descriptors
@ -134,7 +157,41 @@ namespace MuzikaGromche
#pragma warning restore CS0162 // Unreachable code detected #pragma warning restore CS0162 // Unreachable code detected
} }
var animator = animationContainerTransform.gameObject.GetComponent<Animator>(); GameObject animationContainer = animationContainerTransform.gameObject;
Animator animator = animationContainer.GetComponent<Animator>();
if (patch.AddTagAndAnimator)
{
animationContainer.tag = PoweredLightTag;
if (animator == null)
{
animator = animationContainer.AddComponent<Animator>();
}
if (!animationContainer.TryGetComponent<PlayAudioAnimationEvent>(out var audioScript))
{
audioScript = animationContainer.AddComponent<PlayAudioAnimationEvent>();
audioScript.audioClip = AudioClipOn;
audioScript.audioClip2 = AudioClipOff;
audioScript.audioClip3 = AudioClipFlicker;
}
if (!animationContainer.TryGetComponent<AudioSource>(out var audioSource))
{
// Copy from an existing AudioSource of another light animator
var otherSource = tile.gameObject.GetComponentInChildren<AudioSource>();
if (otherSource != null)
{
audioSource = animationContainer.AddComponent<AudioSource>();
audioSource.spatialBlend = 1;
audioSource.playOnAwake = false;
audioSource.outputAudioMixerGroup = otherSource.outputAudioMixerGroup;
audioSource.spread = otherSource.spread;
audioSource.rolloffMode = otherSource.rolloffMode;
audioSource.maxDistance = otherSource.maxDistance;
audioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, otherSource.GetCustomCurve(AudioSourceCurveType.CustomRolloff));
}
}
}
if (animator == null) if (animator == null)
{ {
#if DEBUG #if DEBUG
@ -145,7 +202,7 @@ namespace MuzikaGromche
#pragma warning restore CS0162 // Unreachable code detected #pragma warning restore CS0162 // Unreachable code detected
} }
patch.ManualPatch?.Invoke(animationContainerTransform.gameObject); patch.ManualPatch?.Invoke(animationContainer);
animator.runtimeAnimatorController = patch.AnimatorController; animator.runtimeAnimatorController = patch.AnimatorController;
Debug.Log($"{nameof(MuzikaGromche)} {nameof(PoweredLightsAnimatorsPatch)} {tilePatch.TileName}/{patch.AnimatorContainerPath}: Replaced animator controller"); Debug.Log($"{nameof(MuzikaGromche)} {nameof(PoweredLightsAnimatorsPatch)} {tilePatch.TileName}/{patch.AnimatorContainerPath}: Replaced animator controller");