mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Code refactor
This commit is contained in:
parent
cd4711a8e5
commit
757badf4f6
517 changed files with 2534 additions and 2221 deletions
|
@ -13,7 +13,7 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
[Header("Animation settings")]
|
||||
public bool isAnimating = false;
|
||||
public int stageTick = Constants.minTick;
|
||||
|
||||
|
||||
[Header("Object references")]
|
||||
public Slider stageTimelineSlider;
|
||||
|
@ -70,7 +70,7 @@ namespace RimWorldAnimationStudio
|
|||
// 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)";
|
||||
stageLengthText.text = "Stage length (quickie): " + Workspace.GetCurrentAnimationStage().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>());
|
||||
|
@ -79,7 +79,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
else
|
||||
{
|
||||
stageLengthText.text = "Stage length (normal): " + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks + " (" + Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks / 60f + " s)";
|
||||
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>());
|
||||
|
@ -87,7 +87,7 @@ namespace RimWorldAnimationStudio
|
|||
}
|
||||
|
||||
// Update tick if animating
|
||||
stageTick = Mathf.Clamp(stageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||
Workspace.StageTick = Mathf.Clamp(Workspace.StageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||
|
||||
if (isAnimating)
|
||||
{
|
||||
|
@ -97,29 +97,29 @@ namespace RimWorldAnimationStudio
|
|||
{ return; }
|
||||
|
||||
timeSinceLastUpdate -= 1 / (playBackSpeed * 60f);
|
||||
stageTick += 1;
|
||||
Workspace.StageTick += 1;
|
||||
|
||||
if (stageTick > Workspace.StageWindowSize)
|
||||
if (Workspace.StageTick > Workspace.StageWindowSize)
|
||||
{
|
||||
if (stageLoopDropdown.value == 1)
|
||||
{ stageTick = Constants.minTick; }
|
||||
{ Workspace.StageTick = Constants.minTick; }
|
||||
|
||||
else if (stageLoopDropdown.value >= 2)
|
||||
{
|
||||
++cycleIndex;
|
||||
stageTick = Constants.minTick;
|
||||
Workspace.StageTick = Constants.minTick;
|
||||
|
||||
if ((stageLoopDropdown.value == 2 && cycleIndex >= int.Parse(cyclesNormalField.text)) ||
|
||||
(stageLoopDropdown.value == 3 && cycleIndex >= int.Parse(cyclesFastField.text)))
|
||||
{
|
||||
++Workspace.stageID;
|
||||
++Workspace.StageID;
|
||||
cycleIndex = 0;
|
||||
}
|
||||
|
||||
if (Workspace.stageID > Workspace.animationDef.animationStages.Count - 1)
|
||||
if (Workspace.StageID > Workspace.animationDef.AnimationStages.Count - 1)
|
||||
{
|
||||
Workspace.stageID = Workspace.animationDef.animationStages.Count - 1;
|
||||
stageTick = Workspace.StageWindowSize;
|
||||
Workspace.StageID = Workspace.animationDef.AnimationStages.Count - 1;
|
||||
Workspace.StageTick = Workspace.StageWindowSize;
|
||||
isAnimating = false;
|
||||
}
|
||||
}
|
||||
|
@ -136,12 +136,12 @@ namespace RimWorldAnimationStudio
|
|||
animationClipTimeField.interactable = isAnimating == false;
|
||||
animationClipLengthField.interactable = isAnimating == false;
|
||||
|
||||
if (lastStageTick != stageTick)
|
||||
if (lastStageTick != Workspace.StageTick)
|
||||
{
|
||||
stageTimelineSlider.value = stageTick;
|
||||
animationClipTimeField.text = stageTick.ToString();
|
||||
stageTimelineSlider.value = Workspace.StageTick;
|
||||
animationClipTimeField.text = Workspace.StageTick.ToString();
|
||||
|
||||
lastStageTick = stageTick;
|
||||
lastStageTick = Workspace.StageTick;
|
||||
}
|
||||
|
||||
playToggleButton.image.color = isAnimating ? Constants.ColorGoldYellow : Constants.ColorWhite;
|
||||
|
@ -152,37 +152,27 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void UpdateAnimation()
|
||||
{
|
||||
if (AnimationTimelinesNeedUpdate())
|
||||
{ InitializeAnimationTimeline(); }
|
||||
|
||||
List<ActorBody> _actorBodies = actorBodies.GetComponentsInChildren<ActorBody>().ToList();
|
||||
|
||||
for (int actorID = 0; actorID < _actorBodies.Count; actorID++)
|
||||
{
|
||||
if (Workspace.stageID >= Workspace.animationDef?.animationStages.Count)
|
||||
{ return; }
|
||||
if (Workspace.StageID >= Workspace.animationDef?.AnimationStages.Count) return;
|
||||
|
||||
if (actorID >= Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips.Count)
|
||||
{ return; }
|
||||
Actor actor = Workspace.GetActor(actorID);
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
|
||||
|
||||
Actor actor = Workspace.animationDef.actors[actorID];
|
||||
PawnAnimationClip clip = Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips[actorID];
|
||||
bool quiver = isAnimating && Workspace.GetCurrentOrPreviousKeyframe(actorID).Quiver == true;
|
||||
bool requiresGenitals = actor.RequiredGenitals.Any(x => x == "Penis") || actor.IsFucking;
|
||||
|
||||
float clipPercent = clip.GetStageTickPercentage();
|
||||
if (Workspace.StageTick > Constants.minTick && Workspace.StageTick == clip.duration) clipPercent = 1f;
|
||||
|
||||
if (Workspace.GetCurrentAnimationStage().IsLooping == false)
|
||||
{ clipPercent = (float)Workspace.StageTick / clip.duration; }
|
||||
|
||||
if (clip == null)
|
||||
{ continue; }
|
||||
|
||||
bool quiver = isAnimating && Workspace.Instance.GetCurrentOrPreviousKeyframe(actorID).quiver == true;
|
||||
bool requiresGenitals = actor.requiredGenitals.Any(x => x == "Penis") || Workspace.animationDef.actors[actorID].isFucking;
|
||||
|
||||
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
||||
if (stageTick > Constants.minTick && stageTick == clip.duration) clipPercent = 1f;
|
||||
|
||||
if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false)
|
||||
{ clipPercent = (float)stageTick / clip.duration; }
|
||||
|
||||
AlienRaceDef alienRaceDef = actor.GetAlienRaceDef();
|
||||
PawnRaceDef pawnRaceDef = actor.GetPawnRaceDef();
|
||||
ActorBody actorBody = _actorBodies[actorID];
|
||||
string bodyType = alienRaceDef.isHumanoid ? actor.bodyType : "None";
|
||||
string bodyType = pawnRaceDef.isHumanoid ? actor.bodyType : "None";
|
||||
|
||||
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
|
||||
|
||||
|
@ -212,27 +202,27 @@ namespace RimWorldAnimationStudio
|
|||
actorBody.appendageRenderer.transform.localPosition = new Vector3(appendagePos.x, appendagePos.z, 0f);
|
||||
actorBody.appendageRenderer.transform.eulerAngles = new Vector3(0, 0, -appendageRotation);
|
||||
|
||||
actorBody.bodyRenderer.sprite = alienRaceDef.GetBodyTypeGraphic((CardinalDirection)bodyFacing, bodyType);
|
||||
actorBody.headRenderer.sprite = alienRaceDef.isHumanoid ? alienRaceDef.GetHeadGraphic((CardinalDirection)headFacing) : null;
|
||||
actorBody.appendageRenderer.sprite = requiresGenitals && alienRaceDef.isHumanoid && bodyFacing != 0 ? Resources.Load<Sprite>("Textures/Humanlike/Appendages/Appendage" + bodyFacing) : null;
|
||||
actorBody.bodyRenderer.sprite = pawnRaceDef.GetBodyTypeGraphic((CardinalDirection)bodyFacing, bodyType);
|
||||
actorBody.headRenderer.sprite = pawnRaceDef.isHumanoid ? pawnRaceDef.GetHeadGraphic((CardinalDirection)headFacing) : null;
|
||||
actorBody.appendageRenderer.sprite = requiresGenitals && pawnRaceDef.isHumanoid && bodyFacing != 0 ? Resources.Load<Sprite>("Textures/Humanlike/Appendages/Appendage" + bodyFacing) : null;
|
||||
|
||||
actorBody.bodyRenderer.gameObject.SetActive(actorBody.bodyRenderer.sprite != null);
|
||||
actorBody.headRenderer.gameObject.SetActive(actorBody.headRenderer.sprite != null);
|
||||
actorBody.appendageRenderer.gameObject.SetActive(actorBody.appendageRenderer.sprite != null);
|
||||
|
||||
actorBody.bodyRenderer.sortingLayerName = clip.layer;
|
||||
actorBody.headRenderer.sortingLayerName = clip.layer;
|
||||
actorBody.bodyRenderer.sortingLayerName = clip.Layer;
|
||||
actorBody.headRenderer.sortingLayerName = clip.Layer;
|
||||
actorBody.headRenderer.sortingOrder = bodyFacing == 0 ? -1 : 1;
|
||||
actorBody.appendageRenderer.sortingLayerName = clip.layer;
|
||||
actorBody.appendageRenderer.sortingLayerName = clip.Layer;
|
||||
|
||||
actorBody.bodyRenderer.flipX = bodyFacing == 3;
|
||||
actorBody.headRenderer.flipX = headFacing == 3;
|
||||
//actorBody.appendageRenderer.flipX = bodyFacing == 3;
|
||||
|
||||
actorBody.transform.localScale = new Vector3(alienRaceDef.scale, alienRaceDef.scale, alienRaceDef.scale);
|
||||
actorBody.transform.localScale = new Vector3(pawnRaceDef.scale, pawnRaceDef.scale, pawnRaceDef.scale);
|
||||
|
||||
// ActorKeyframeCard update
|
||||
if (actorID != Workspace.actorID) continue;
|
||||
if (actorID != Workspace.ActorID) continue;
|
||||
if (ActorKeyframeCard.Instance.positionXField.isFocused == false) { ActorKeyframeCard.Instance.positionXField.text = bodyPos.x.ToString("0.000"); }
|
||||
if (ActorKeyframeCard.Instance.positionZField.isFocused == false) { ActorKeyframeCard.Instance.positionZField.text = bodyPos.y.ToString("0.000"); }
|
||||
if (ActorKeyframeCard.Instance.rotationField.isFocused == false) { ActorKeyframeCard.Instance.rotationField.text = bodyAngle.ToString("0.000"); }
|
||||
|
@ -240,27 +230,27 @@ namespace RimWorldAnimationStudio
|
|||
if (ActorKeyframeCard.Instance.headRotationField.isFocused == false) { ActorKeyframeCard.Instance.headRotationField.text = headAngle.ToString("0.000"); }
|
||||
if (ActorKeyframeCard.Instance.appendageRotationField.isFocused == false) { ActorKeyframeCard.Instance.appendageRotationField.text = appendageRotation.ToString("0.000"); }
|
||||
|
||||
if (actorID == Workspace.actorID)
|
||||
if (actorID == Workspace.ActorID)
|
||||
{
|
||||
handLeftControls.SetActive(clip.GetActorAddon("left hand").render);
|
||||
handRightControls.SetActive(clip.GetActorAddon("right hand").render);
|
||||
sexToyControls.SetActive(clip.GetActorAddon("dildo").render);
|
||||
//handLeftControls.SetActive(clip.GetActorAddon("left hand").Render);
|
||||
//handRightControls.SetActive(clip.GetActorAddon("right hand").Render);
|
||||
//sexToyControls.SetActive(clip.GetActorAddon("dildo").Render);
|
||||
}
|
||||
|
||||
foreach (ActorAddon addon in clip.addons)
|
||||
foreach (ActorAddon addon in clip.Addons)
|
||||
{
|
||||
ActorBodyPart bodyPart = actorBody.GetComponentsInChildren<ActorBodyPart>()?.FirstOrDefault(x => x.addonName == addon.addonName);
|
||||
ActorBodyPart bodyPart = actorBody.GetComponentsInChildren<ActorBodyPart>()?.FirstOrDefault(x => x.addonName == addon.AddonName);
|
||||
if (bodyPart == null) continue;
|
||||
|
||||
Vector3 anchor;
|
||||
|
||||
ActorBody anchoringActorBody = actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.anchoringActor);
|
||||
ActorBody anchoringActorBody = actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
|
||||
bodyPos = new Vector3(anchoringActorBody.transform.position.x, anchoringActorBody.transform.position.y, 0);
|
||||
alienRaceDef = Workspace.animationDef.actors[addon.anchoringActor].GetAlienRaceDef();
|
||||
Actor anchoringActor = Workspace.animationDef.actors[addon.anchoringActor];
|
||||
bodyFacing = (int)Workspace.animationDef.animationStages[Workspace.stageID].animationClips[addon.anchoringActor].BodyFacing.Evaluate(clipPercent);
|
||||
pawnRaceDef = Workspace.animationDef.Actors[addon.AnchoringActor].GetPawnRaceDef();
|
||||
Actor anchoringActor = Workspace.animationDef.Actors[addon.AnchoringActor];
|
||||
bodyFacing = (int)Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[addon.AnchoringActor].BodyFacing.Evaluate(clipPercent);
|
||||
|
||||
switch (addon.anchorName)
|
||||
switch (addon.AnchorName)
|
||||
{
|
||||
case "torso": anchor = bodyPos; break;
|
||||
case "head": anchor = new Vector3(anchoringActorBody.transform.Find("ActorHead").position.x, anchoringActorBody.transform.Find("ActorHead").position.y, 0); break;
|
||||
|
@ -272,7 +262,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
bodyPart.transform.position = anchor + new Vector3(addon.PosX.Evaluate(clipPercent), addon.PosZ.Evaluate(clipPercent), 0);
|
||||
bodyPart.transform.eulerAngles = new Vector3(0, 0, -addon.Rotation.Evaluate(clipPercent));
|
||||
bodyPart.GetComponent<SpriteRenderer>().sortingLayerName = addon.layer;
|
||||
bodyPart.GetComponent<SpriteRenderer>().sortingLayerName = addon.Layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,12 +294,12 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
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();
|
||||
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;
|
||||
Workspace.animationDef.AnimationStages[Workspace.StageID].IsLooping = int.Parse(cyclesNormalField.text) > 1 ? true : false;
|
||||
|
||||
int actorCount = Workspace.animationDef.actors.Count;
|
||||
int actorCount = Workspace.animationDef.Actors.Count;
|
||||
int childCount = animationTimelines.GetComponentsInChildren<AnimationTimeline>().Count();
|
||||
|
||||
for (int actorID = 0; actorID < Mathf.Max(actorCount, childCount); actorID++)
|
||||
|
@ -349,226 +339,19 @@ namespace RimWorldAnimationStudio
|
|||
{ timeline.InitiateUpdateOfGhostFrames(); }
|
||||
}
|
||||
|
||||
public void AddActor()
|
||||
{
|
||||
Actor actor = new Actor();
|
||||
actor.MakeNew();
|
||||
|
||||
Workspace.Instance.RecordEvent("Actor addition");
|
||||
}
|
||||
|
||||
public void RemoveActor()
|
||||
{
|
||||
if (Workspace.animationDef.actors.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("Cannot delete actor - the animation must contain at least one actor.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{ stage.animationClips.RemoveAt(Workspace.actorID); }
|
||||
|
||||
Workspace.animationDef.actors.RemoveAt(Workspace.actorID);
|
||||
Workspace.actorID = Workspace.actorID >= Workspace.animationDef.actors.Count ? Workspace.actorID = Workspace.animationDef.actors.Count - 1 : Workspace.actorID;
|
||||
|
||||
Workspace.Instance.RecordEvent("Actor deletion");
|
||||
}
|
||||
|
||||
public void AddPawnKeyframe()
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
|
||||
List<PawnKeyframe> keyframes = clip?.keyframes;
|
||||
|
||||
if (clip == null || keyframes == null)
|
||||
{ Debug.LogWarning("Cannot add pawn keyframe - the AnimationDef is invalid"); return; }
|
||||
|
||||
if (keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
|
||||
{ Debug.LogWarning("Cannot add pawn keyframe - a keyframe already exists at this tick"); return; }
|
||||
|
||||
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
||||
|
||||
PawnKeyframe keyframe = new PawnKeyframe();
|
||||
keyframe.bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
|
||||
keyframe.headAngle = clip.HeadAngle.Evaluate(clipPercent);
|
||||
keyframe.headBob = clip.HeadBob.Evaluate(clipPercent);
|
||||
keyframe.bodyOffsetX = clip.BodyOffsetX.Evaluate(clipPercent);
|
||||
keyframe.bodyOffsetZ = clip.BodyOffsetZ.Evaluate(clipPercent);
|
||||
keyframe.headFacing = clip.HeadFacing.Evaluate(clipPercent);
|
||||
keyframe.bodyFacing = clip.BodyFacing.Evaluate(clipPercent);
|
||||
keyframe.genitalAngle = clip.GenitalAngle.Evaluate(clipPercent);
|
||||
|
||||
keyframe.atTick = stageTick;
|
||||
|
||||
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > stageTick);
|
||||
|
||||
if (nextKeyframe != null)
|
||||
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), keyframe); }
|
||||
|
||||
else
|
||||
{ keyframes.Add(keyframe); }
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[Workspace.actorID].AddPawnKeyFrame(keyframe.keyframeID);
|
||||
|
||||
Workspace.Instance.RecordEvent("Keyframe addition");
|
||||
}
|
||||
|
||||
public void ClonePawnKeyframe()
|
||||
{
|
||||
List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframesByID(Workspace.keyframeID);
|
||||
|
||||
foreach (PawnKeyframe keyframe in keyframesToClone)
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID);
|
||||
|
||||
if (clip == null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - no clip owns this keyframe"); continue; }
|
||||
|
||||
if (clip.keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
|
||||
|
||||
PawnKeyframe cloneFrame = keyframe.Copy();
|
||||
cloneFrame.GenerateKeyframeID(clipID);
|
||||
cloneFrame.atTick = stageTick;
|
||||
|
||||
PawnKeyframe nextKeyframe = clip.keyframes.FirstOrDefault(x => x.atTick > stageTick);
|
||||
|
||||
if (nextKeyframe != null)
|
||||
{ clip.keyframes.Insert(clip.keyframes.IndexOf(nextKeyframe), cloneFrame); }
|
||||
|
||||
else
|
||||
{ clip.keyframes.Add(cloneFrame); }
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[clipID].AddPawnKeyFrame(cloneFrame.keyframeID);
|
||||
}
|
||||
|
||||
Workspace.Instance.RecordEvent("Keyframe clone");
|
||||
}
|
||||
|
||||
public void CopyPawnKeyframes()
|
||||
{
|
||||
Workspace.copiedKeyframes.Clear();
|
||||
|
||||
List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframesByID(Workspace.keyframeID);
|
||||
|
||||
foreach (PawnKeyframe keyframe in keyframesToClone)
|
||||
{ Workspace.copiedKeyframes.Add(keyframe.Copy()); }
|
||||
}
|
||||
|
||||
public void PastePawnKeyframes()
|
||||
{
|
||||
MakeTimelineDirty();
|
||||
|
||||
int originalWindowSize = Workspace.StageWindowSize;
|
||||
|
||||
|
||||
List<int> actorsInvolved = Workspace.copiedKeyframes.Select(x => x.actorID)?.ToList();
|
||||
actorsInvolved = actorsInvolved?.Distinct()?.ToList();
|
||||
|
||||
if (actorsInvolved.NullOrEmpty()) { Debug.Log("Cannot paste keyframes - there were no copied keyframes to paste"); return; }
|
||||
if (actorsInvolved.Count > 1 && actorsInvolved.Contains(Workspace.actorID) == false) { Debug.Log("Cannot paste keyframes - keyframes copied across multiple timelines can only be pasted back into these source timelines"); return; }
|
||||
|
||||
int earliestTick = actorsInvolved.Count == 1 ? Workspace.Instance.GetEarliestAtTickInCopiedKeyframes(actorsInvolved[0]) : Workspace.Instance.GetEarliestAtTickInCopiedKeyframes(Workspace.actorID);
|
||||
if (earliestTick < 1) { Debug.Log("Unknown error occured during keyframe paste operation"); return; }
|
||||
|
||||
foreach (PawnKeyframe copiedKeyframe in Workspace.copiedKeyframes)
|
||||
{
|
||||
int tickToPasteAt = stageTick + (copiedKeyframe.atTick.Value - earliestTick);
|
||||
|
||||
if (tickToPasteAt < 1) continue;
|
||||
if (tickToPasteAt > Workspace.StageWindowSize)
|
||||
{
|
||||
if (stretchKeyframesToggle.isOn)
|
||||
{ ResizeStageWindowSize(tickToPasteAt); }
|
||||
|
||||
else continue;
|
||||
}
|
||||
|
||||
int targetActorID = actorsInvolved.Count == 1 ? Workspace.actorID : copiedKeyframe.actorID;
|
||||
|
||||
if (Workspace.Instance.DoesPawnKeyframeExistAtTick(Workspace.stageID, targetActorID, tickToPasteAt))
|
||||
{
|
||||
PawnKeyframe oldKeyframe = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[targetActorID].keyframes.First(x => x.atTick == tickToPasteAt);
|
||||
RemovePawnKeyframe(targetActorID, oldKeyframe.keyframeID, true);
|
||||
}
|
||||
|
||||
PawnKeyframe clonedKeyframe = copiedKeyframe.Copy();
|
||||
clonedKeyframe.GenerateKeyframeID(targetActorID);
|
||||
clonedKeyframe.atTick = tickToPasteAt;
|
||||
|
||||
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[targetActorID];
|
||||
PawnKeyframe nextKeyframe = clip.keyframes.FirstOrDefault(x => x.atTick > tickToPasteAt);
|
||||
|
||||
if (nextKeyframe != null)
|
||||
{ clip.keyframes.Insert(clip.keyframes.IndexOf(nextKeyframe), clonedKeyframe); }
|
||||
|
||||
else
|
||||
{ clip.keyframes.Add(clonedKeyframe); }
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[clonedKeyframe.actorID].AddPawnKeyFrame(clonedKeyframe.keyframeID);
|
||||
}
|
||||
|
||||
if (originalWindowSize != Workspace.StageWindowSize)
|
||||
{
|
||||
StretchKeyframes(originalWindowSize);
|
||||
ResizeStageWindowSize(originalWindowSize);
|
||||
}
|
||||
|
||||
Workspace.Instance.RecordEvent("Keyframe pasted");
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe()
|
||||
{
|
||||
foreach (int keyframeID in Workspace.keyframeID)
|
||||
{
|
||||
if (Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID) != null)
|
||||
{ RemovePawnKeyframe(clipID, keyframeID); }
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe(int actorID, int keyframeID, bool force = false)
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID];
|
||||
|
||||
if (keyframe == null || clip == null) return;
|
||||
|
||||
if (keyframe.atTick == Constants.minTick && force == false)
|
||||
{ Debug.LogWarning("Cannot delete key frame - the first key frame of an animation clip cannot be deleted"); return; }
|
||||
|
||||
if (clip.keyframes.Count <= 2 && force == false)
|
||||
{ Debug.LogWarning("Cannot delete key frame - an animation clip must have two or more keyframes"); return; }
|
||||
|
||||
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[actorID].RemovePawnKeyFrame(keyframe.keyframeID);
|
||||
|
||||
clip.keyframes.Remove(keyframe);
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
Workspace.Instance.RecordEvent("Keyframe deletion");
|
||||
}
|
||||
|
||||
public void ToggleAnimation()
|
||||
{
|
||||
isAnimating = !isAnimating;
|
||||
}
|
||||
|
||||
public void ToggleActorManipulationMode(int mode)
|
||||
{
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)mode;
|
||||
}
|
||||
|
||||
public void OnStageTimelineSliderChange()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
if (stageTick != (int)stageTimelineSlider.value)
|
||||
{
|
||||
stageTick = (int)stageTimelineSlider.value;
|
||||
animationClipTimeField.text = stageTick.ToString();
|
||||
if (Workspace.StageTick != (int)stageTimelineSlider.value)
|
||||
{
|
||||
Workspace.StageTick = (int)stageTimelineSlider.value;
|
||||
animationClipTimeField.text = Workspace.StageTick.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,8 +360,8 @@ namespace RimWorldAnimationStudio
|
|||
if (Workspace.animationDef == null) return;
|
||||
|
||||
int.TryParse(animationClipTimeField.text, out int newStageTick);
|
||||
stageTick = Mathf.Clamp(newStageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||
stageTimelineSlider.value = stageTick;
|
||||
Workspace.StageTick = Mathf.Clamp(newStageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||
stageTimelineSlider.value = Workspace.StageTick;
|
||||
}
|
||||
|
||||
public void OnAnimationClipLengthFieldChange()
|
||||
|
@ -591,55 +374,30 @@ namespace RimWorldAnimationStudio
|
|||
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
|
||||
|
||||
if (stretchKeyframesToggle.isOn)
|
||||
{ StretchKeyframes(newStageWindowSize); }
|
||||
{ Workspace.GetCurrentAnimationStage().StretchStageWindow(newStageWindowSize); }
|
||||
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < Workspace.animationDef.animationStages[Workspace.stageID].animationClips.Count; i++)
|
||||
for (int i = 0; i < Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips.Count; i++)
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[i];
|
||||
List<PawnKeyframe> keyframes = clip.keyframes.Where(x => x.atTick > newStageWindowSize)?.ToList();
|
||||
PawnAnimationClip clip = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[i];
|
||||
List<PawnKeyframe> keyframes = clip.Keyframes.Where(x => x.atTick > newStageWindowSize)?.ToList();
|
||||
|
||||
if (keyframes.NullOrEmpty())
|
||||
{ continue; }
|
||||
|
||||
foreach (PawnKeyframe keyframe in keyframes)
|
||||
{
|
||||
RemovePawnKeyframe(i, keyframe.keyframeID);
|
||||
clip.RemovePawnKeyframe(i, keyframe.keyframeID);
|
||||
|
||||
if (Workspace.animationDef.animationStages[Workspace.stageID].animationClips[i].keyframes.Count <= 2)
|
||||
if (Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[i].Keyframes.Count <= 2)
|
||||
{ break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResizeStageWindowSize(newStageWindowSize);
|
||||
Workspace.Instance.RecordEvent("Stage length");
|
||||
}
|
||||
|
||||
public void StretchKeyframes(int newStageWindowSize)
|
||||
{
|
||||
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
|
||||
|
||||
foreach (PawnAnimationClip clip in Workspace.animationDef.animationStages[Workspace.stageID].animationClips)
|
||||
{
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
{
|
||||
keyframe.tickDuration = Mathf.RoundToInt(keyframe.tickDuration * scale);
|
||||
keyframe.atTick = null;
|
||||
}
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
}
|
||||
}
|
||||
|
||||
public void ResizeStageWindowSize(int newStageWindowSize)
|
||||
{
|
||||
animationClipLengthField.text = newStageWindowSize.ToString();
|
||||
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].stageWindowSize = newStageWindowSize;
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks = newStageWindowSize * int.Parse(cyclesNormalField.text);
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick = newStageWindowSize * int.Parse(cyclesFastField.text);
|
||||
Workspace.GetCurrentAnimationStage().ResizeStageWindow(newStageWindowSize);
|
||||
Workspace.RecordEvent("Stage length");
|
||||
}
|
||||
|
||||
public void OnCycleNormalFieldChange()
|
||||
|
@ -651,14 +409,14 @@ namespace RimWorldAnimationStudio
|
|||
cycles = cycles <= 0 ? 1 : cycles;
|
||||
cyclesNormalField.text = cycles.ToString();
|
||||
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks = cycles * Workspace.StageWindowSize;
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].isLooping = cycles > 1;
|
||||
Workspace.animationDef.AnimationStages[Workspace.StageID].PlayTimeTicks = cycles * Workspace.StageWindowSize;
|
||||
Workspace.animationDef.AnimationStages[Workspace.StageID].IsLooping = cycles > 1;
|
||||
|
||||
foreach(AnimationTimeline animationTimeline in animationTimelines.GetComponentsInChildren<AnimationTimeline>())
|
||||
{ animationTimeline.InitiateUpdateOfGhostFrames(); }
|
||||
}
|
||||
|
||||
Workspace.Instance.RecordEvent("Cycle count (normal)");
|
||||
Workspace.RecordEvent("Cycle count (normal)");
|
||||
}
|
||||
|
||||
public void OnCycleFastFieldChange()
|
||||
|
@ -673,10 +431,10 @@ namespace RimWorldAnimationStudio
|
|||
if (fastCycles > cycles) fastCycles = cycles;
|
||||
cyclesFastField.text = fastCycles.ToString();
|
||||
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick = fastCycles * Workspace.StageWindowSize;
|
||||
Workspace.animationDef.AnimationStages[Workspace.StageID].PlayTimeTicksQuick = fastCycles * Workspace.StageWindowSize;
|
||||
}
|
||||
|
||||
Workspace.Instance.RecordEvent("Cycle count (fast)");
|
||||
Workspace.RecordEvent("Cycle count (fast)");
|
||||
}
|
||||
|
||||
public void OnPlayBackSpeedChange()
|
||||
|
@ -686,41 +444,5 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
playBackSpeedField.text = playBackSpeed.ToString();
|
||||
}
|
||||
|
||||
private int lastactorCount = 0;
|
||||
private int lastStageID = 0;
|
||||
private int lastStageCount = 0;
|
||||
private int lastStageWindowSize = 0;
|
||||
|
||||
public bool AnimationTimelinesNeedUpdate()
|
||||
{
|
||||
if (Workspace.animationDef == null) return false;
|
||||
|
||||
bool update = isTimelineDirty;
|
||||
|
||||
if (lastStageID != Workspace.stageID)
|
||||
{ update = true; }
|
||||
|
||||
if (lastStageCount != Workspace.animationDef.animationStages.Count)
|
||||
{ update = true; }
|
||||
|
||||
if (lastactorCount != Workspace.animationDef.actors.Count)
|
||||
{ update = true; }
|
||||
|
||||
if (lastStageWindowSize != Workspace.StageWindowSize)
|
||||
{ update = true; }
|
||||
|
||||
if (update)
|
||||
{
|
||||
lastStageID = Workspace.stageID;
|
||||
lastStageCount = Workspace.animationDef.animationStages.Count;
|
||||
lastactorCount = Workspace.animationDef.actors.Count;
|
||||
lastStageWindowSize = Workspace.StageWindowSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void Start()
|
||||
{
|
||||
LoadAlienRaceDefs();
|
||||
LoadPawnRaceDefs();
|
||||
LoadCustomArrays();
|
||||
}
|
||||
|
||||
|
@ -40,10 +40,10 @@ namespace RimWorldAnimationStudio
|
|||
if (paths == null || paths.Any() == false)
|
||||
{ Debug.LogWarning("Selected file was null or invalid"); return; }
|
||||
|
||||
Defs defs = null;
|
||||
AnimationDefs defs = null;
|
||||
|
||||
try
|
||||
{ defs = XmlUtility.ReadXML<Defs>(paths[0]); }
|
||||
{ defs = XmlUtility.ReadXML<AnimationDefs>(paths[0]); }
|
||||
|
||||
catch
|
||||
{ Debug.LogError("Could not read .xml file '" + paths[0] + "' - this file either uses a schema which is outdated, incorrect, or contains empty fields"); return; }
|
||||
|
@ -65,38 +65,39 @@ namespace RimWorldAnimationStudio
|
|||
UpdateCustomArrays(animationDef);
|
||||
RunPostLoadOperations(animationDef);
|
||||
|
||||
Debug.Log("Loaded AnimationDef: " + animationDef.defName);
|
||||
Debug.Log("Loaded AnimationDef: " + animationDef.DefName);
|
||||
|
||||
Workspace.animationDef = animationDef;
|
||||
animationDef.Initialize();
|
||||
|
||||
AnimationController.Instance.Reset();
|
||||
Workspace.Instance.Reset();
|
||||
Workspace.Instance.RecordEvent("AnimationDef loaded");
|
||||
Workspace.Reset();
|
||||
|
||||
EventsManager.OnAnimationDefChanged();
|
||||
Workspace.RecordEvent("AnimationDef loaded");
|
||||
}
|
||||
|
||||
public void RunPostLoadOperations(AnimationDef animationDef)
|
||||
{
|
||||
if (animationDef.animationTimeTicksQuick <= 0)
|
||||
{
|
||||
if (animationDef.animationStages.Count > 1)
|
||||
if (animationDef.AnimationStages.Count > 1)
|
||||
{
|
||||
for (int i = 0; i < animationDef.animationStages.Count; i++)
|
||||
for (int i = 0; i < animationDef.AnimationStages.Count; i++)
|
||||
{
|
||||
if (i == 0) continue;
|
||||
animationDef.animationStages[i].playTimeTicksQuick = animationDef.animationStages[i].playTimeTicks;
|
||||
animationDef.AnimationStages[i].PlayTimeTicksQuick = animationDef.AnimationStages[i].PlayTimeTicks;
|
||||
}
|
||||
}
|
||||
|
||||
else if (animationDef.animationStages.Count == 0)
|
||||
{ animationDef.animationStages[0].playTimeTicksQuick = animationDef.animationStages[0].playTimeTicks; }
|
||||
else if (animationDef.AnimationStages.Count == 1)
|
||||
{ animationDef.AnimationStages[0].PlayTimeTicksQuick = animationDef.AnimationStages[0].PlayTimeTicks; }
|
||||
}
|
||||
|
||||
foreach (AnimationStage stage in animationDef.animationStages)
|
||||
foreach (AnimationStage stage in animationDef.AnimationStages)
|
||||
{
|
||||
stage.OnPostLoad();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void TryToSaveAnimation()
|
||||
|
@ -118,7 +119,7 @@ namespace RimWorldAnimationStudio
|
|||
if (Workspace.animationDef == null)
|
||||
{ return; }
|
||||
|
||||
string defName = Workspace.animationDef.defName != null && Workspace.animationDef.defName != "" ? Workspace.animationDef.defName : "newAnimationDef";
|
||||
string defName = Workspace.animationDef.DefName != null && Workspace.animationDef.DefName != "" ? Workspace.animationDef.DefName : "newAnimationDef";
|
||||
string path = StandaloneFileBrowser.SaveFilePanel("Save AnimationDef File", "", defName, "xml");
|
||||
|
||||
if (path != null && path != "")
|
||||
|
@ -130,9 +131,9 @@ namespace RimWorldAnimationStudio
|
|||
AnimationDef animationDef = Workspace.animationDef.Copy();
|
||||
RunPreSaveOperations(animationDef);
|
||||
|
||||
Debug.Log("Saving AnimationDef: " + Workspace.animationDef.defName);
|
||||
Debug.Log("Saving AnimationDef: " + Workspace.animationDef.DefName);
|
||||
|
||||
Defs defs = new Defs();
|
||||
AnimationDefs defs = new AnimationDefs();
|
||||
defs.animationDefs.Add(animationDef);
|
||||
|
||||
XmlUtility.WriteXML(defs, path);
|
||||
|
@ -142,21 +143,21 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void RunPreSaveOperations(AnimationDef animationDef)
|
||||
{
|
||||
animationDef.ValidateData();
|
||||
animationDef.OnPreSave();
|
||||
|
||||
foreach (Actor actor in animationDef.actors)
|
||||
{ actor.ValidateData(); }
|
||||
foreach (Actor actor in animationDef.Actors)
|
||||
{ actor.OnPreSave(); }
|
||||
|
||||
foreach (AnimationStage stage in animationDef.animationStages)
|
||||
foreach (AnimationStage stage in animationDef.AnimationStages)
|
||||
{
|
||||
stage.ValidateData();
|
||||
stage.OnPreSave();
|
||||
|
||||
foreach (PawnAnimationClip clip in stage.animationClips)
|
||||
foreach (PawnAnimationClip clip in stage.AnimationClips)
|
||||
{
|
||||
clip.ValidateData();
|
||||
clip.OnPreSave();
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
{ keyframe.ValidateData(); }
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{ keyframe.OnPreSave(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +174,7 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
var path = Path.Combine(Application.streamingAssetsPath, "AnimationDefs/newAnimationDef.xml");
|
||||
|
||||
Defs defs = XmlUtility.ReadXML<Defs>(path);
|
||||
AnimationDefs defs = XmlUtility.ReadXML<AnimationDefs>(path);
|
||||
|
||||
if (defs?.animationDefs == null)
|
||||
{ Debug.LogError("Default animation def file contains no animation data"); return; }
|
||||
|
@ -224,37 +225,37 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void UpdateCustomArrays(AnimationDef animationDef)
|
||||
{
|
||||
CustomTags.bodyParts.AddRangeDistinct(animationDef.actors.SelectMany(x => x.requiredGenitals).Except(Tags.bodyParts));
|
||||
CustomTags.bodyDefTypes.AddRangeDistinct(animationDef.actors.SelectMany(x => x.bodyDefTypes).Except(Tags.bodyDefTypes));
|
||||
CustomTags.sexTypes.AddRangeDistinct(animationDef.sexTypes.Except(Tags.sexTypes));
|
||||
CustomTags.interactionDefTypes.AddRangeDistinct(animationDef.interactionDefTypes.Except(Tags.interactionDefTypes));
|
||||
CustomTags.soundDefs.AddRangeDistinct(animationDef.animationStages.SelectMany(x => x.animationClips.SelectMany(y => y.keyframes.Select(z => z.soundEffect))).Except(Tags.soundDefs));
|
||||
CustomTags.bodyParts.AddRangeDistinct(animationDef.Actors.SelectMany(x => x.RequiredGenitals).Except(DefaultTags.bodyParts));
|
||||
CustomTags.bodyDefTypes.AddRangeDistinct(animationDef.Actors.SelectMany(x => x.BodyDefTypes).Except(DefaultTags.bodyDefTypes));
|
||||
CustomTags.sexTypes.AddRangeDistinct(animationDef.SexTypes.Except(DefaultTags.sexTypes));
|
||||
CustomTags.interactionDefTypes.AddRangeDistinct(animationDef.InteractionDefTypes.Except(DefaultTags.interactionDefTypes));
|
||||
CustomTags.soundDefs.AddRangeDistinct(animationDef.AnimationStages.SelectMany(x => x.AnimationClips.SelectMany(y => y.Keyframes.Select(z => z.SoundEffect))).Except(DefaultTags.soundDefs));
|
||||
|
||||
SaveCustomArrays();
|
||||
}
|
||||
|
||||
public void LoadAlienRaceDefs()
|
||||
public void LoadPawnRaceDefs()
|
||||
{
|
||||
string path;
|
||||
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml"); }
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml"); }
|
||||
|
||||
else
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "alienRaceDefs.xml"); }
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "pawnRaceDefs.xml"); }
|
||||
|
||||
if (File.Exists(path) == false)
|
||||
{ SaveAlienRaceDefs(); return; }
|
||||
{ SavePawnRaceDefs(); return; }
|
||||
|
||||
AlienRaceDefs.allDefs = XmlUtility.ReadXML<List<AlienRaceDef>>(path);
|
||||
AlienRaceDefs.OnLoad();
|
||||
PawnRaceDefs.allDefs = XmlUtility.ReadXML<List<PawnRaceDef>>(path);
|
||||
PawnRaceDefs.OnLoad();
|
||||
}
|
||||
|
||||
public void SaveAlienRaceDefs()
|
||||
public void SavePawnRaceDefs()
|
||||
{
|
||||
var path = Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml");
|
||||
var path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml");
|
||||
|
||||
XmlUtility.WriteXML(AlienRaceDefs.allDefs, path);
|
||||
XmlUtility.WriteXML(PawnRaceDefs.allDefs, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
private float curZoom;
|
||||
private bool mouseDragActive = false;
|
||||
private Vector3 mouseDragOrigin;
|
||||
|
|
|
@ -192,13 +192,13 @@ namespace RimWorldAnimationStudio
|
|||
public void UndoAction()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.Instance.Undo();
|
||||
Workspace.Undo();
|
||||
}
|
||||
|
||||
public void RedoAction()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.Instance.Redo();
|
||||
Workspace.Redo();
|
||||
}
|
||||
|
||||
public void ToggleAnimationPreview()
|
||||
|
@ -210,43 +210,40 @@ namespace RimWorldAnimationStudio
|
|||
public void AddKeyframe()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.AddPawnKeyframe();
|
||||
Workspace.GetCurrentPawnAnimationClip().AddPawnKeyframe();
|
||||
}
|
||||
|
||||
public void CopyKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.CopyPawnKeyframes();
|
||||
Workspace.GetCurrentPawnAnimationClip().CopyPawnKeyframes();
|
||||
}
|
||||
|
||||
public void PasteKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.PastePawnKeyframes();
|
||||
Workspace.GetCurrentPawnAnimationClip().PastePawnKeyframes();
|
||||
}
|
||||
|
||||
public void DeleteKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.RemovePawnKeyframe();
|
||||
Workspace.GetCurrentPawnAnimationClip().RemovePawnKeyframe();
|
||||
}
|
||||
|
||||
public void ActorMovementMode()
|
||||
{
|
||||
//if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.ToggleActorManipulationMode(0);
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)0;
|
||||
}
|
||||
|
||||
public void ActorRotateMode()
|
||||
{
|
||||
//if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.ToggleActorManipulationMode(1);
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)1;
|
||||
}
|
||||
|
||||
public void ActorFacingMode()
|
||||
{
|
||||
//if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.ToggleActorManipulationMode(2);
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)2;
|
||||
}
|
||||
|
||||
public void AdjustActorUpward()
|
||||
|
@ -301,7 +298,7 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
ActorBody actorBody = AnimationController.Instance.actorBodies.GetChild(Workspace.actorID).GetComponent<ActorBody>();
|
||||
ActorBody actorBody = AnimationController.Instance.actorBodies.GetChild(Workspace.ActorID).GetComponent<ActorBody>();
|
||||
List<ActorBodyPart> actorBodyParts = actorBody.GetComponentsInChildren<ActorBodyPart>().Where(x => x.gameObject.activeInHierarchy)?.ToList();
|
||||
|
||||
if (actorBodyParts.NullOrEmpty()) return;
|
||||
|
@ -332,7 +329,7 @@ namespace RimWorldAnimationStudio
|
|||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.selectedBodyPart = null;
|
||||
Workspace.actorID = Mathf.Clamp(Workspace.actorID - 1, 0, Workspace.animationDef.actors.Count - 1);
|
||||
Workspace.ActorID = Mathf.Clamp(Workspace.ActorID - 1, 0, Workspace.animationDef.Actors.Count - 1);
|
||||
}
|
||||
|
||||
public void ToNextActor()
|
||||
|
@ -340,67 +337,67 @@ namespace RimWorldAnimationStudio
|
|||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.selectedBodyPart = null;
|
||||
Workspace.actorID = Mathf.Clamp(Workspace.actorID + 1, 0, Workspace.animationDef.actors.Count - 1);
|
||||
Workspace.ActorID = Mathf.Clamp(Workspace.ActorID + 1, 0, Workspace.animationDef.Actors.Count - 1);
|
||||
}
|
||||
|
||||
public void ToPreviousTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick - 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
Workspace.StageTick = Mathf.Clamp(Workspace.StageTick - 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
}
|
||||
|
||||
public void ToNextTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick + 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
Workspace.StageTick = Mathf.Clamp(Workspace.StageTick + 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
}
|
||||
|
||||
public void ToFirstTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.stageTick = Constants.minTick;
|
||||
Workspace.StageTick = Constants.minTick;
|
||||
}
|
||||
|
||||
public void ToLastTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
AnimationController.Instance.stageTick = Workspace.StageWindowSize;
|
||||
Workspace.StageTick = Workspace.StageWindowSize;
|
||||
}
|
||||
|
||||
public void ToPreviousKey()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPreviousKeyframe(Workspace.actorID);
|
||||
if (keyframe != null) AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
||||
PawnKeyframe keyframe = Workspace.GetPreviousKeyframe(Workspace.ActorID);
|
||||
if (keyframe != null) Workspace.StageTick = keyframe.atTick.Value;
|
||||
}
|
||||
|
||||
public void ToNextKey()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetNextKeyframe(Workspace.actorID);
|
||||
if (keyframe != null) AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
||||
PawnKeyframe keyframe = Workspace.GetNextKeyframe(Workspace.ActorID);
|
||||
if (keyframe != null) Workspace.StageTick = keyframe.atTick.Value;
|
||||
}
|
||||
|
||||
public void ToPreviousStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
int prevStageID = Workspace.stageID;
|
||||
Workspace.stageID = Mathf.Clamp(Workspace.stageID - 1, 0, Workspace.animationDef.animationStages.Count - 1);
|
||||
int prevStageID = Workspace.StageID;
|
||||
Workspace.StageID = Mathf.Clamp(Workspace.StageID - 1, 0, Workspace.animationDef.AnimationStages.Count - 1);
|
||||
|
||||
if (Workspace.stageID != prevStageID)
|
||||
{ Workspace.Instance.RecordEvent("Stage selected"); }
|
||||
if (Workspace.StageID != prevStageID)
|
||||
{ Workspace.RecordEvent("Stage selected"); }
|
||||
}
|
||||
|
||||
public void ToNextStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
int prevStageID = Workspace.stageID;
|
||||
Workspace.stageID = Mathf.Clamp(Workspace.stageID + 1, 0, Workspace.animationDef.animationStages.Count - 1);
|
||||
int prevStageID = Workspace.StageID;
|
||||
Workspace.StageID = Mathf.Clamp(Workspace.StageID + 1, 0, Workspace.animationDef.AnimationStages.Count - 1);
|
||||
|
||||
if (Workspace.stageID != prevStageID)
|
||||
{ Workspace.Instance.RecordEvent("Stage selected"); }
|
||||
if (Workspace.StageID != prevStageID)
|
||||
{ Workspace.RecordEvent("Stage selected"); }
|
||||
}
|
||||
|
||||
public void CenterView()
|
||||
|
@ -424,5 +421,19 @@ namespace RimWorldAnimationStudio
|
|||
if (Uri.IsWellFormedUriString(Constants.projectWiki, UriKind.RelativeOrAbsolute))
|
||||
{ Application.OpenURL(Constants.projectWiki); }
|
||||
}
|
||||
|
||||
public void AddActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.AddActor();
|
||||
}
|
||||
|
||||
public void RemoveActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.RemoveActor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
public StageCard stageCardPrefab;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onStageCountChanged.AddListener(delegate { Initialize(); });
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
foreach(AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{ MakeStageCard(stage.stageName); }
|
||||
|
||||
int stageCount = Workspace.animationDef.animationStages.Count;
|
||||
int stageCount = Workspace.animationDef.AnimationStages.Count;
|
||||
int childCount = GetComponentsInChildren<StageCard>().Count();
|
||||
|
||||
for (int i = 0; i < Mathf.Max(stageCount, childCount); i++)
|
||||
|
@ -30,102 +32,12 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
// Update values
|
||||
if (i < stageCount)
|
||||
{ stageCard.Initialize(Workspace.animationDef.animationStages[i].stageName); }
|
||||
{ stageCard.Initialize(Workspace.animationDef.AnimationStages[i].StageName); }
|
||||
|
||||
// Remove excess objects as required
|
||||
else
|
||||
{ Destroy(stageCard.gameObject); }
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach(StageCard stageCard in GetComponentsInChildren<StageCard>())
|
||||
{ Destroy(stageCard.gameObject); }
|
||||
}
|
||||
|
||||
public StageCard MakeStageCard(string stageName = null)
|
||||
{
|
||||
StageCard stageCard = Instantiate(stageCardPrefab, transform);
|
||||
|
||||
if (stageName != null)
|
||||
{ stageCard.Initialize(stageName); }
|
||||
|
||||
return stageCard;
|
||||
}
|
||||
|
||||
public void OnNewStage()
|
||||
{
|
||||
if (AddAnimationStage())
|
||||
{ MakeStageCard("NewStage"); }
|
||||
}
|
||||
|
||||
public bool AddAnimationStage()
|
||||
{
|
||||
AnimationStage stage = new AnimationStage();
|
||||
Workspace.Instance.RecordEvent("Stage addition");
|
||||
|
||||
return stage.MakeNew();
|
||||
}
|
||||
|
||||
public void OnCloneStage()
|
||||
{
|
||||
if (CloneAnimationStage())
|
||||
{
|
||||
StageCard stageCard = MakeStageCard(Workspace.animationDef.animationStages[Workspace.stageID + 1].stageName);
|
||||
stageCard.transform.SetSiblingIndex(Workspace.stageID + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CloneAnimationStage()
|
||||
{
|
||||
AnimationStage stage = Workspace.animationDef.animationStages[Workspace.stageID].Copy();
|
||||
stage.Initialize();
|
||||
stage.stageName += " (Clone)";
|
||||
|
||||
Workspace.animationDef.animationStages.Insert(Workspace.stageID + 1, stage);
|
||||
|
||||
Workspace.Instance.RecordEvent("Stage clone");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool MoveAnimationStage(int startIndex, int delta)
|
||||
{
|
||||
if (startIndex + delta < 0 || startIndex + delta >= Workspace.animationDef.animationStages.Count)
|
||||
{ return false; }
|
||||
|
||||
AnimationStage stage = Workspace.animationDef.animationStages[startIndex];
|
||||
|
||||
Workspace.animationDef.animationStages[startIndex] = Workspace.animationDef.animationStages[startIndex + delta];
|
||||
Workspace.animationDef.animationStages[startIndex + delta] = stage;
|
||||
Workspace.stageID = startIndex + delta;
|
||||
|
||||
Workspace.Instance.RecordEvent("Stage move");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnRemoveStage()
|
||||
{
|
||||
if (RemoveAnimationStage())
|
||||
{ Destroy(transform.GetChild(Workspace.stageID).gameObject); }
|
||||
}
|
||||
|
||||
public bool RemoveAnimationStage()
|
||||
{
|
||||
if (Workspace.animationDef.animationStages.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("Cannot delete animation stage - the animation must contain at least one animation stage.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Workspace.animationDef.animationStages.RemoveAt(Workspace.stageID);
|
||||
Workspace.stageID = Workspace.stageID >= Workspace.animationDef.animationStages.Count ? Workspace.stageID = Workspace.animationDef.animationStages.Count - 1 : Workspace.stageID;
|
||||
|
||||
Workspace.Instance.RecordEvent("Stage deletion");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue