Stage and anim lengths display

This commit is contained in:
AbstractConcept 2022-10-14 14:00:57 -05:00
parent ab5a2a4c02
commit cc28ac4bd4
174 changed files with 604 additions and 245 deletions

View file

@ -28,6 +28,8 @@ namespace RimWorldAnimationStudio
public Toggle stretchKeyframesToggle;
public InputField playBackSpeedField;
public Button playToggleButton;
public Text stageLengthText;
public Text animationLengthText;
[Header("Prefabs")]
public ActorBody actorBodyPrefab;
@ -47,6 +49,12 @@ namespace RimWorldAnimationStudio
public void MakeTimelineDirty()
{ isTimelineDirty = true; }
public bool IsDirty()
{ return isDirty; }
public bool IsTimelineDirty()
{ return isTimelineDirty; }
public void Update()
{
// No animation, exit
@ -56,6 +64,25 @@ namespace RimWorldAnimationStudio
if (Workspace.animationDef != null && isDirty)
{ Initialize(); }
// Update animation lengths
if (stageLoopDropdown.value == 3)
{
stageLengthText.text = "Stage length (quickie): " + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick + " (" + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick / 60f + " s)";
animationLengthText.text = "Animation length (quickie): " + Workspace.animationDef.animationTimeTicksQuick + " (" + Workspace.animationDef.animationTimeTicksQuick / 60f + " s)";
LayoutRebuilder.ForceRebuildLayoutImmediate(stageLengthText.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(animationLengthText.GetComponent<RectTransform>());
}
else
{
stageLengthText.text = "Stage length (normal): " + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks + " (" + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks / 60f + " s)";
animationLengthText.text = "Animation length (normal): " + Workspace.animationDef.animationTimeTicks + " (" + Workspace.animationDef.animationTimeTicks / 60f + " s)";
LayoutRebuilder.ForceRebuildLayoutImmediate(stageLengthText.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(animationLengthText.GetComponent<RectTransform>());
}
// Update tick if animating
stageTick = Mathf.Clamp(stageTick, Constants.minTick, Workspace.StageWindowSize);
@ -123,10 +150,7 @@ namespace RimWorldAnimationStudio
public void UpdateAnimation()
{
if (AnimationTimelinesNeedUpdate())
{
ResetAnimationTimeline();
InitializeAnimationTimeline();
}
{ InitializeAnimationTimeline(); }
List<ActorBody> _actorBodies = actorBodies.GetComponentsInChildren<ActorBody>().ToList();
@ -217,59 +241,73 @@ namespace RimWorldAnimationStudio
public void Initialize()
{
isDirty = true;
Debug.Log("Initializing animation preview");
foreach (Transform child in transform)
{ child.gameObject.SetActive(true); }
Reset();
InitializeAnimationTimeline();
StageCardManager.Instance.Initialize();
isDirty = false;
}
public void Reset()
{
Workspace.stageID = 0;
isAnimating = false;
timeSinceLastUpdate = 0;
cycleIndex = 0;
}
public void InitializeAnimationTimeline()
{
isTimelineDirty = true;
cyclesNormalField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks / Workspace.StageWindowSize), 1).ToString();
cyclesFastField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick / Workspace.StageWindowSize), 0).ToString();
Workspace.animationDef.animationStages[Workspace.stageID].isLooping = int.Parse(cyclesNormalField.text) > 1 ? true : false;
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
{
ActorBody actorBody = Instantiate(actorBodyPrefab, actorBodies.transform);
actorBody.Initialize(actorID);
int actorCount = Workspace.animationDef.actors.Count;
int childCount = animationTimelines.GetComponentsInChildren<AnimationTimeline>().Count();
AnimationTimeline animationTimeline = Instantiate(animationTimelinePrefab, animationTimelines).GetComponentInChildren<AnimationTimeline>();
animationTimeline.Initialize(actorID);
for (int actorID = 0; actorID < Mathf.Max(actorCount, childCount); actorID++)
{
// Add new actors as required
if (actorID >= childCount)
{
Instantiate(animationTimelinePrefab, animationTimelines);
Instantiate(actorBodyPrefab, actorBodies.transform);
}
// Get objects to update
AnimationTimeline animationTimeline = animationTimelines.GetComponentsInChildren<AnimationTimeline>()[actorID];
ActorBody actorBody = actorBodies.GetComponentsInChildren<ActorBody>()[actorID];
// Update values
if (actorID < actorCount)
{
animationTimeline.Initialize(actorID);
actorBody.Initialize(actorID);
}
// Remove excess objects as required
else
{
Destroy(animationTimeline.transform.parent.gameObject);
Destroy(actorBody.gameObject);
}
}
animationClipLengthField.text = Workspace.StageWindowSize.ToString();
stageTimelineSlider.maxValue = Workspace.StageWindowSize;
isTimelineDirty = false;
}
public void Reset()
{
Workspace.stageID = 0;
isAnimating = false;
ResetAnimationTimeline();
StageCardManager.Instance.Reset();
}
public void ResetAnimationTimeline()
{
timeSinceLastUpdate = 0;
cycleIndex = 0;
foreach (ActorBody actorBody in actorBodies.GetComponentsInChildren<ActorBody>())
{ Destroy(actorBody.gameObject); }
foreach (AnimationTimeline animationTimeline in animationTimelines.GetComponentsInChildren<AnimationTimeline>())
{ Destroy(animationTimeline.transform.parent.gameObject); }
foreach (AnimationTimeline timeline in animationTimelines.GetComponentsInChildren<AnimationTimeline>())
{ timeline.InitiateUpdateOfGhostFrames(); }
}
public void AddActor()
@ -436,41 +474,6 @@ namespace RimWorldAnimationStudio
Workspace.Instance.RecordEvent("Keyframe pasted");
}
/*public void PastePawnKeyframes()
{
foreach (PawnKeyframe keyframe in Workspace.copiedKeyframes)
{
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[keyframe.actorID];
if (Workspace.Instance.DoesPawnKeyframeExistAtTick(Workspace.stageID, keyframe.actorID, stageTick))
{
PawnKeyframe oldKeyframe = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[keyframe.actorID].keyframes.First(x => x.atTick == stageTick);
RemovePawnKeyframe(keyframe.actorID, oldKeyframe.keyframeID, true);
}
keyframe.GenerateKeyframeID(keyframe.actorID);
keyframe.atTick = stageTick;
PawnKeyframe nextKeyframe = clip.keyframes.FirstOrDefault(x => x.atTick > stageTick);
if (nextKeyframe != null)
{ clip.keyframes.Insert(clip.keyframes.IndexOf(nextKeyframe), keyframe); }
else
{ clip.keyframes.Add(keyframe); }
clip.BuildSimpleCurves();
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[keyframe.actorID].AddPawnKeyFrame(keyframe.keyframeID);
clip.BuildSimpleCurves();
}
Workspace.Instance.RecordEvent("Keyframe pasted");
}*/
public void RemovePawnKeyframe()
{
foreach (int keyframeID in Workspace.keyframeID)
@ -541,10 +544,7 @@ namespace RimWorldAnimationStudio
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
if (stretchKeyframesToggle.isOn)
{
List<PawnKeyframe> keyframes = Workspace.animationDef.animationStages[Workspace.stageID].animationClips.SelectMany(x => x.keyframes)?.ToList();
StretchKeyframes(keyframes, Workspace.StageWindowSize, newStageWindowSize);
}
{ StretchKeyframes(newStageWindowSize); }
else
{
@ -569,7 +569,7 @@ namespace RimWorldAnimationStudio
ResizeStageWindowSize(newStageWindowSize);
}
/*public void StretchKeyframes(int newStageWindowSize)
public void StretchKeyframes(int newStageWindowSize)
{
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
@ -583,39 +583,6 @@ namespace RimWorldAnimationStudio
clip.BuildSimpleCurves();
}
}*/
public void StretchKeyframes(List<PawnKeyframe> keyframesToStretch, int v1, int v2)
{
int v0 = keyframesToStretch.Min(x => x.atTick.Value);
if (v1 == v0)
{ OffsetKeyframes(keyframesToStretch, v1, v2); return; }
float scaleFactor = (float)(v2 - v0) / (v1 - v0);
foreach (PawnKeyframe keyframe in keyframesToStretch)
{
keyframe.atTick = Mathf.RoundToInt(scaleFactor * (keyframe.atTick.Value - v0) + v0);
}
foreach(PawnAnimationClip clip in Workspace.animationDef.animationStages[Workspace.stageID].animationClips)
{ clip.BuildSimpleCurves(); }
}
public void OffsetKeyframes(List<PawnKeyframe> keyframesToOffset, int v1, int v2)
{
float offset = v2 - v1;
foreach (PawnKeyframe keyframe in keyframesToOffset)
{
keyframe.atTick = Mathf.RoundToInt(keyframe.atTick.Value + offset);
Debug.Log(keyframe.atTick);
Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID).BuildSimpleCurves();
}
foreach (PawnAnimationClip clip in Workspace.animationDef.animationStages[Workspace.stageID].animationClips)
{ clip.BuildSimpleCurves(); }
}
public void ResizeStageWindowSize(int newStageWindowSize)

View file

@ -78,7 +78,20 @@ namespace RimWorldAnimationStudio
public void RunPostLoadOperations(AnimationDef animationDef)
{
if (animationDef.animationTimeTicksQuick <= 0)
{
if (animationDef.animationStages.Count > 1)
{
for (int i = 0; i < animationDef.animationStages.Count; i++)
{
if (i == 0) continue;
animationDef.animationStages[i].playTimeTicksQuick = animationDef.animationStages[i].playTimeTicks;
}
}
else if (animationDef.animationStages.Count == 0)
{ animationDef.animationStages[0].playTimeTicksQuick = animationDef.animationStages[0].playTimeTicks; }
}
}
public void TryToSaveAnimation()

View file

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
@ -14,6 +15,27 @@ namespace RimWorldAnimationStudio
{
foreach(AnimationStage stage in Workspace.animationDef.animationStages)
{ MakeStageCard(stage.stageName); }
int stageCount = Workspace.animationDef.animationStages.Count;
int childCount = GetComponentsInChildren<StageCard>().Count();
for (int i = 0; i < Mathf.Max(stageCount, childCount); i++)
{
// Add new stage cards as required
if (i >= childCount)
{ Instantiate(stageCardPrefab, transform); }
// Get objects to update
StageCard stageCard = GetComponentsInChildren<StageCard>()[i];
// Update values
if (i < stageCount)
{ stageCard.Initialize(Workspace.animationDef.animationStages[i].stageName); }
// Remove excess objects as required
else
{ Destroy(stageCard.gameObject); }
}
}
public void Reset()
@ -41,7 +63,6 @@ namespace RimWorldAnimationStudio
public bool AddAnimationStage()
{
AnimationStage stage = new AnimationStage();
Workspace.Instance.RecordEvent("Stage addition");
return stage.MakeNew();