Skip to content

Commit

Permalink
Identify shared animation names on layers with sequencing as "Slave",…
Browse files Browse the repository at this point in the history
… so they can randomize. Fix randomize time not being synced to shared animation names. Fix incorrect sequencing time resulting in multiple animations playing at once, allows using shared names in create animation UI, minor improvements to add animation UI
  • Loading branch information
acidbubbles committed Aug 27, 2021
1 parent 19fe16a commit 22e70aa
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 19 deletions.
57 changes: 53 additions & 4 deletions src/AtomAnimations/Animations/AtomAnimation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class IsPlayingEvent : UnityEvent<AtomAnimationClip> { }
private static readonly Regex _lastDigitsRegex = new Regex(@"^(?<name>.+)(?<index>[0-9]+)$", RegexOptions.Compiled);

public const string RandomizeAnimationName = "(Randomize)";
public const string SlaveAnimationName = "(Slave)";
public const string RandomizeGroupSuffix = "/*";

public UnityEvent onAnimationSettingsChanged = new UnityEvent();
Expand Down Expand Up @@ -176,7 +177,7 @@ public AtomAnimationClip CreateClip([NotNull] string animationLayer, [NotNull] s
if (animationLayer == null) throw new ArgumentNullException(nameof(animationLayer));
if (animationName == null) throw new ArgumentNullException(nameof(animationName));

if (clips.Any(c => c.animationName == animationName)) throw new InvalidOperationException($"Animation '{animationName}' already exists");
if (clips.Any(c => c.animationLayer == animationLayer && c.animationName == animationName)) throw new InvalidOperationException($"Animation '{animationLayer}::{animationName}' already exists");
var clip = new AtomAnimationClip(animationName, animationLayer);
if (position == -1)
AddClip(clip);
Expand Down Expand Up @@ -212,7 +213,8 @@ public string GetNewAnimationName(AtomAnimationClip source)
for (var i = animationNameInt + 1; i < 999; i++)
{
var animationName = animationNameBeforeInt + i;
if (clips.All(c => c.animationName != animationName)) return animationName;
if (index.ByLayer(source.animationLayer).All(c => c.animationName != animationName))
return animationName;
}
return Guid.NewGuid().ToString();
}
Expand Down Expand Up @@ -308,9 +310,13 @@ public void PlayClip(AtomAnimationClip clip, bool sequencing, bool allowPreserve
return;

if (previousMain.loop && previousMain.preserveLoops && clip.loop && clip.preserveLoops)
{
ScheduleNextAnimation(previousMain, clip, previousMain.animationLength - clip.blendInDuration / 2f - previousMain.clipTime);
}
else
{
ScheduleNextAnimation(previousMain, clip, 0);
}
}
else
{
Expand All @@ -323,8 +329,11 @@ public void PlayClip(AtomAnimationClip clip, bool sequencing, bool allowPreserve
clip.animationPattern.SetBoolParamValue("loopOnce", false);
clip.animationPattern.ResetAndPlay();
}

if (sequencing && clip.nextAnimationName != null)
{
AssignNextAnimation(clip);
}

onIsPlayingChanged.Invoke(clip);
}
Expand Down Expand Up @@ -584,6 +593,9 @@ private void AssignNextAnimation(AtomAnimationClip source)
if (source.nextAnimationTime <= 0)
return;

if (source.nextAnimationName == SlaveAnimationName)
return;

AtomAnimationClip next;

string group;
Expand Down Expand Up @@ -626,8 +638,18 @@ private void ScheduleNextAnimation(AtomAnimationClip source, AtomAnimationClip n
if (source.preserveLoops && next.preserveLoops)
{
if (source.nextAnimationTimeRandomize > 0f)
nextTime = Random.Range(nextTime - source.animationLength * 0.49f, nextTime + source.nextAnimationTimeRandomize.RoundToNearest(source.animationLength) + source.animationLength * 0.49f);
nextTime = nextTime.RoundToNearest(source.animationLength) - next.blendInDuration / 2f - source.clipTime;
{
nextTime += Random
.Range(source.animationLength * -0.49f, source.nextAnimationTimeRandomize.RoundToNearest(source.animationLength) + source.animationLength * 0.49f)
.RoundToNearest(source.animationLength);
}
else
{

nextTime = nextTime.RoundToNearest(source.animationLength);
}
nextTime = nextTime - next.blendInDuration / 2f + (source.animationLength - source.clipTime);
//SuperController.LogMessage($"T{Time.time:0.000}s: clip: {source.clipTime}, next: {nextTime:0.000}s");
}
else if (source.nextAnimationTimeRandomize > 0f)
{
Expand Down Expand Up @@ -656,6 +678,33 @@ private void ScheduleNextAnimation(AtomAnimationClip source, AtomAnimationClip n
source.playbackScheduledFadeOutAtRemaining = float.NaN;
}
}
SyncSiblingClips(source, next);
}

private void SyncSiblingClips(AtomAnimationClip source, AtomAnimationClip next)
{
AtomAnimationClip siblingSourceClip = null;
AtomAnimationClip siblingNextClip = null;

var layers = index.ByLayer();
for (var i = 0; i < layers.Count; i++)
{
var layer = layers[i];
if (layer[0].animationLayer == source.animationLayer) continue;
for (var j = 0; j < layer.Count; j++)
{
var clip = layer[j];
if (clip.animationName == source.animationName) siblingSourceClip = clip;
else if (clip.animationName == next.animationName) siblingNextClip = clip;
if (siblingSourceClip != null && siblingNextClip != null) break;
}
if (siblingSourceClip != null && siblingNextClip != null) break;
}

if (siblingSourceClip == null || siblingNextClip == null) return;

siblingSourceClip.playbackScheduledNextAnimationName = siblingNextClip.animationName;
siblingSourceClip.playbackScheduledNextTimeLeft = source.playbackScheduledNextTimeLeft;
}

#endregion
Expand Down
6 changes: 3 additions & 3 deletions src/AtomAnimations/Utils/FloatExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public static float ExponentialScale(this float value, float midValue, float max
return a + b * Mathf.Exp(c * value);
}

public static float RoundToNearest(this float value, float multiple)
public static float RoundToNearest(this float value, float modulo)
{
var half = multiple / 2;
return value + half - (value + half) % multiple;
var half = modulo / 2;
return value + half - (value + half) % modulo;
}
}
}
12 changes: 4 additions & 8 deletions src/UI/Screens/AddAnimationScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,8 @@ public override void Init(IAtomPlugin plugin, object arg)

prefabFactory.CreateHeader("Add animations", 1);

prefabFactory.CreateSpacer();
prefabFactory.CreateHeader("Add animations", 2);

InitCreateAnimationUI();

prefabFactory.CreateSpacer();
prefabFactory.CreateHeader("Add options", 2);

InitCreateAnimationOptionsUI();
Expand Down Expand Up @@ -82,17 +78,17 @@ private void InitCreateAnimationUI()

private void InitCreateAnimationOptionsUI()
{
_createName = new JSONStorableString("New animation name", "");
prefabFactory.CreateTextInput(_createName);

_createPosition = new JSONStorableStringChooser(
"Add at position",
new List<string> { _positionFirst, _positionPrevious, _positionNext, _positionLast },
_positionNext,
"Add at position");
prefabFactory.CreatePopup(_createPosition, false, true);

_createName = new JSONStorableString("Name", "");
prefabFactory.CreateTextInput(_createName);

_createInOtherAtoms = new JSONStorableBool("Create in other atoms", _previousCreateInOtherAtoms, val => _previousCreateInOtherAtoms = val);
_createInOtherAtoms = new JSONStorableBool("Auto create in other atoms", _previousCreateInOtherAtoms, val => _previousCreateInOtherAtoms = val);
prefabFactory.CreateToggle(_createInOtherAtoms);
}

Expand Down
15 changes: 11 additions & 4 deletions src/UI/Screens/SequencingScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ private void InitRandomizeLengthUI()

private void ChangeRandomizeLength(float val)
{
current.nextAnimationTimeRandomize = current.preserveLoops ? val.RoundToNearest(current.animationLength) : val.Snap(animationEditContext.snap);
_randomizeRangeJSON.valNoCallback = current.nextAnimationTimeRandomize;
SyncPlayNext();
}

private void InitPreviewUI()
Expand Down Expand Up @@ -365,13 +364,19 @@ private void SyncPlayNext()
RoundNextTimeToNearestLoop();
var nextTime = _nextAnimationTimeJSON.val;
var nextName = _nextAnimationJSON.val;
var randomizeTime = current.preserveLoops ? _randomizeRangeJSON.val.RoundToNearest(current.animationLength) : _randomizeRangeJSON.val.Snap(animationEditContext.snap);

if (nextName == _noNextAnimation)
if (nextName == "(Slave)")
{
// Do nothing, but this shouldn't be "set"
}
else if (nextName == _noNextAnimation)
{
foreach (var clip in animation.GetClips(current.animationName))
{
clip.nextAnimationName = null;
clip.nextAnimationTime = 0f;
clip.nextAnimationTimeRandomize = 0f;
}
}
else
Expand All @@ -392,11 +397,13 @@ private void SyncPlayNext()
if (!NextExists(clip, nextName))
continue;

clip.nextAnimationName = _nextAnimationJSON.val;
clip.nextAnimationName = clip == current ? _nextAnimationJSON.val : AtomAnimation.SlaveAnimationName;
clip.nextAnimationTime = nextTime;
clip.nextAnimationTimeRandomize = randomizeTime;
}

_nextAnimationTimeJSON.valNoCallback = nextTime;
_randomizeRangeJSON.valNoCallback = randomizeTime;
}

RefreshTransitionUI();
Expand Down

0 comments on commit 22e70aa

Please sign in to comment.