192 lines
6.8 KiB
C#
192 lines
6.8 KiB
C#
using UnityEditor;
|
|
using UnityEngine;
|
|
using AnimatorAsCode.V1;
|
|
using System.Collections.Generic;
|
|
using gay.lilyy.aaccore;
|
|
using gay.lilyy.aacshared.runtimecomponents;
|
|
using gay.lilyy.Common;
|
|
|
|
namespace gay.lilyy.aacshared.layers
|
|
{
|
|
/**
|
|
<summary>
|
|
ported from v5
|
|
</summary>
|
|
*/
|
|
[InitializeOnLoad]
|
|
public class LanternFlicker : LayerGroup
|
|
{
|
|
private static readonly LanternFlicker _instance = new();
|
|
|
|
static LanternFlicker() { }
|
|
|
|
public override string DisplayName => "Lantern Flicker";
|
|
public override string SystemName => "lantern_flicker";
|
|
public override bool shouldWarnIfNotApplicable => false;
|
|
|
|
private Transform GetLantern(AACAssets assets)
|
|
{
|
|
return AACUtils.FindChildRecursive(assets.ctx.AvatarRootTransform, "Lantern Floater");
|
|
}
|
|
|
|
public override bool IsApplicable(AACAssets assets)
|
|
{
|
|
var definition = ComponentHelper.GetComponentInChildrenWithError<LanternFlickerDefinition>(assets.ctx.AvatarRootObject);
|
|
if (definition == null) return false;
|
|
if (!definition.enabled) return false;
|
|
var lamp = GetLantern(assets);
|
|
if (lamp == null)
|
|
{
|
|
Logger.LogWarning("Lamp Light could not be found!");
|
|
return false;
|
|
}
|
|
var light = lamp.GetComponentInChildren<Light>();
|
|
return light != null;
|
|
}
|
|
|
|
private void CreateFlickerLayer(AACAssets assets)
|
|
{
|
|
var lamp = GetLantern(assets);
|
|
var light = lamp.GetComponentInChildren<Light>();
|
|
|
|
var layer = assets.fx.NewLayer("Lantern Flicker");
|
|
var flickerParam = layer.BoolParameter("LanternFlicker");
|
|
|
|
var off = layer.NewState("Off").WithAnimation(
|
|
assets.aac.NewClip().Animating(anim =>
|
|
{
|
|
if (light != null) {
|
|
anim.Animates(light, "m_Enabled").WithFrameCountUnit(sec =>
|
|
{
|
|
sec.Constant(0, 0);
|
|
});
|
|
anim.Animates(light, "m_Intensity").WithFrameCountUnit(sec =>
|
|
{
|
|
sec.Constant(0, light.intensity);
|
|
});
|
|
}
|
|
})
|
|
);
|
|
|
|
layer.WithDefaultState(off);
|
|
|
|
var on = layer.NewState("Flicker").WithAnimation(
|
|
assets.aac.NewClip().Animating(anim =>
|
|
{
|
|
AnimateLantern(assets, anim, lamp);
|
|
}).Looping()
|
|
);
|
|
|
|
off.TransitionsTo(on).When(flickerParam.IsEqualTo(true));
|
|
on.TransitionsTo(off).When(flickerParam.IsEqualTo(false));
|
|
}
|
|
|
|
private void CreateBrightnessLayer(AACAssets assets)
|
|
{
|
|
var lamp = GetLantern(assets);
|
|
var light = lamp.GetComponentInChildren<Light>();
|
|
if (light == null) return;
|
|
|
|
var layer = assets.fx.NewLayer("Lantern Brightness");
|
|
var brightnessParam = layer.FloatParameter("LanternBrightness");
|
|
|
|
var state = layer.NewState("Brightness").WithAnimation(
|
|
assets.aac.NewClip().Animating(anim =>
|
|
{
|
|
anim.Animates(light, "m_Enabled").WithUnit(AacFlUnit.Frames, sec =>
|
|
{
|
|
sec.Linear(0, 0);
|
|
sec.Linear(1, 1);
|
|
});
|
|
anim.AnimatesColor(light, "m_Color").WithUnit(AacFlUnit.Frames, sec =>
|
|
{
|
|
sec.Linear(0, light.color * 0);
|
|
sec.Linear(100, light.color);
|
|
});
|
|
})
|
|
).WithMotionTime(brightnessParam);
|
|
}
|
|
|
|
private void AnimateLantern(AACAssets assets, AacFlEditClip anim, Transform lantern)
|
|
{
|
|
var renderer = lantern.GetComponent<MeshRenderer>();
|
|
var light = lantern.GetComponentInChildren<Light>();
|
|
if (renderer == null)
|
|
{
|
|
Logger.LogWarning("AnimateLantern: Missing renderer on lantern");
|
|
return;
|
|
}
|
|
|
|
|
|
var rng = new System.Random("lillithlanternrandomseed".GetHashCode());
|
|
|
|
var keyframes = new List<(float time, double value)>();
|
|
float time = 0;
|
|
while (time < 60)
|
|
{
|
|
double value = rng.NextDouble();
|
|
keyframes.Add((time, value));
|
|
|
|
time += (float)(rng.NextDouble() * (0.3 - 0.05) + 0.05);
|
|
}
|
|
|
|
if (keyframes.Count == 0)
|
|
{
|
|
Logger.LogWarning("AnimateLantern: No keyframes generated");
|
|
}
|
|
|
|
if (light != null)
|
|
{
|
|
anim.Animates(light, "m_Intensity").WithSecondsUnit(sec =>
|
|
{
|
|
foreach (var (t, v) in keyframes)
|
|
{
|
|
sec.Easing(t, (float)v * light.intensity);
|
|
}
|
|
});
|
|
}
|
|
if (assets.isPC) {
|
|
Logger.LogInfo("Using PC material for lantern flicker");
|
|
Color initialColor = renderer.sharedMaterial.GetColor("_Emission_Color");
|
|
// ValueFactory Orbits
|
|
var prop = "material._Emission_Color";
|
|
void animateChannel(string suffix, float initial)
|
|
{
|
|
anim.Animates(renderer, $"{prop}.{suffix}").WithSecondsUnit(sec =>
|
|
{
|
|
foreach (var (t, v) in keyframes)
|
|
{
|
|
sec.Easing(t, initial * (float)v);
|
|
}
|
|
});
|
|
}
|
|
animateChannel("x", initialColor.r);
|
|
animateChannel("y", initialColor.g);
|
|
animateChannel("z", initialColor.b);
|
|
animateChannel("w", initialColor.a);
|
|
}
|
|
else
|
|
{
|
|
// Toon Standard
|
|
Logger.LogInfo("Using Non-PC material for lantern flicker");
|
|
|
|
// float initialStrength = renderer.sharedMaterial.GetFloat("_EmissionStrength");
|
|
// this still isnt running before vqt for some cursed reason so im just gonna hardcode this
|
|
var initialStrength = 2;
|
|
anim.Animates(renderer, "material._EmissionStrength").WithSecondsUnit(sec =>
|
|
{
|
|
foreach (var (t, v) in keyframes)
|
|
{
|
|
sec.Easing(t, initialStrength * (float)v);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
public override void Run(AACAssets assets)
|
|
{
|
|
CreateFlickerLayer(assets);
|
|
CreateBrightnessLayer(assets);
|
|
}
|
|
}
|
|
}
|