Code refactor

This commit is contained in:
AbstractConcept 2022-10-28 19:52:58 -05:00
parent a55ba7b95b
commit 5ca7e486f8
243 changed files with 1065 additions and 625 deletions

View file

@ -181,7 +181,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.5, g: 0, b: 0, a: 0.5019608}
m_Color: {r: 0.5, g: 0, b: 0, a: 1}
m_RaycastTarget: 0
m_Maskable: 1
m_OnCullStateChanged:

File diff suppressed because it is too large Load diff

View file

@ -98,6 +98,8 @@ namespace RimWorldAnimationStudio
clip.BuildSimpleCurves();
}
EventsManager.OnStageWindowSizeChanged(this);
}
public void ResizeStageWindow(int newStageWindowSize)
@ -105,6 +107,8 @@ namespace RimWorldAnimationStudio
Workspace.GetCurrentAnimationStage().stageWindowSize = newStageWindowSize;
Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * StageLoopsNormal;
Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * StageLoopsQuick;
EventsManager.OnStageWindowSizeChanged(this);
}
public void AddAnimationClip(int actorID = -1)

View file

@ -193,30 +193,27 @@ namespace RimWorldAnimationStudio
public void AddPawnKeyframe()
{
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
List<PawnKeyframe> keyframes = clip?.Keyframes;
if (clip == null || keyframes == null)
if (Keyframes == null)
{ Debug.LogWarning("Cannot add pawn keyframe - the AnimationDef is invalid"); return; }
if (keyframes.FirstOrDefault(x => x.atTick == Workspace.StageTick) != null)
if (Keyframes.FirstOrDefault(x => x.atTick == Workspace.StageTick) != null)
{ Debug.LogWarning("Cannot add pawn keyframe - a keyframe already exists at this tick"); return; }
float clipPercent = (float)(Workspace.StageTick % clip.duration) / clip.duration;
float clipPercent = (float)(Workspace.StageTick % duration) / 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 = (int)clip.HeadFacing.Evaluate(clipPercent);
keyframe.BodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
keyframe.GenitalAngle = clip.GenitalAngle.Evaluate(clipPercent);
keyframe.BodyAngle = BodyAngle.Evaluate(clipPercent);
keyframe.HeadAngle = HeadAngle.Evaluate(clipPercent);
keyframe.HeadBob = HeadBob.Evaluate(clipPercent);
keyframe.BodyOffsetX = BodyOffsetX.Evaluate(clipPercent);
keyframe.BodyOffsetZ = BodyOffsetZ.Evaluate(clipPercent);
keyframe.HeadFacing = (int)HeadFacing.Evaluate(clipPercent);
keyframe.BodyFacing = (int)BodyFacing.Evaluate(clipPercent);
keyframe.GenitalAngle = GenitalAngle.Evaluate(clipPercent);
keyframe.atTick = Workspace.StageTick;
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick);
PawnKeyframe nextKeyframe = Keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick);
if (nextKeyframe != null)
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), keyframe); }
@ -224,41 +221,10 @@ namespace RimWorldAnimationStudio
else
{ keyframes.Add(keyframe); }
clip.BuildSimpleCurves();
BuildSimpleCurves();
Workspace.RecordEvent("Keyframe addition");
}
public void ClonePawnKeyframe()
{
List<PawnKeyframe> keyframesToClone = Workspace.GetPawnKeyframesByID(Workspace.keyframeID);
foreach (PawnKeyframe keyframe in keyframesToClone)
{
PawnAnimationClip clip = Workspace.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID);
if (clip == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - no clip owns this keyframe"); continue; }
if (clip.Keyframes.FirstOrDefault(x => x.atTick == Workspace.StageTick) != null)
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
PawnKeyframe cloneFrame = keyframe.Copy();
cloneFrame.GenerateKeyframeID(clip.GetOwningActorID());
cloneFrame.atTick = Workspace.StageTick;
PawnKeyframe nextKeyframe = clip.Keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick);
if (nextKeyframe != null)
{ clip.Keyframes.Insert(clip.Keyframes.IndexOf(nextKeyframe), cloneFrame); }
else
{ clip.Keyframes.Add(cloneFrame); }
clip.BuildSimpleCurves();
}
Workspace.RecordEvent("Keyframe clone");
EventsManager.OnKeyframeCountChanged(this);
Workspace.RecordEvent("Keyframe addition");
}
public void CopyPawnKeyframes()
@ -319,6 +285,8 @@ namespace RimWorldAnimationStudio
{ clip.Keyframes.Add(clonedKeyframe); }
clip.BuildSimpleCurves();
EventsManager.OnKeyframeCountChanged(clip);
}
if (originalWindowSize != Workspace.StageWindowSize)
@ -344,6 +312,7 @@ namespace RimWorldAnimationStudio
Keyframes.Remove(keyframe);
BuildSimpleCurves();
EventsManager.OnKeyframeCountChanged(this);
Workspace.RecordEvent("Keyframe deletion");
}
@ -360,7 +329,10 @@ namespace RimWorldAnimationStudio
// Pre-save / post-load
public void OnPreSave()
{
foreach (ActorAddon addon in Addons)
var temp = Addons.Copy();
Addons.Clear();
foreach (ActorAddon addon in temp)
{
if (addon.Render)
{ addons.Add(addon); }

View file

@ -210,14 +210,18 @@ namespace RimWorldAnimationStudio
{
SoundEffect = DefaultTags.soundDefs.Concat(CustomTags.soundDefs).Contains(SoundEffect) ? SoundEffect : null;
addonKeyframes.Clear();
foreach (AddonKeyframe addonKeyframe in AddonKeyframes)
if (addonKeyframes.NotNullOrEmpty())
{
ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID).GetActorAddon(addonKeyframe.AddonName);
var temp = AddonKeyframes.Copy();
addonKeyframes.Clear();
if (addon.Render)
{ addonKeyframes.Add(addonKeyframe.Copy()); }
foreach (AddonKeyframe addonKeyframe in temp)
{
ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID).GetActorAddon(addonKeyframe.AddonName);
if (addon.Render)
{ addonKeyframes.Add(addonKeyframe.Copy()); }
}
}
}

View file

@ -17,6 +17,9 @@ namespace RimWorldAnimationStudio
{
EventsManager.onActorBodyPartSelected.AddListener(delegate(ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
EventsManager.onActorBodySelected.AddListener(delegate(ActorBody actorBody) { OnActorBodySelected(actorBody); });
if (Workspace.ActorID == actorID)
{ Activate(); }
}
public void OnActorBodySelected(ActorBody actorBody)

View file

@ -18,6 +18,9 @@ namespace RimWorldAnimationStudio
{
EventsManager.onActorBodyPartSelected.AddListener(delegate (ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
EventsManager.onActorBodySelected.AddListener(delegate (ActorBody actorBody) { OnActorBodySelected(actorBody); });
if (Workspace.ActorID == parent.actorID)
{ parent.Activate(); }
}
public void OnActorAddonChange(ActorAddon actorAddon)

View file

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class AnimationLengthDisplay : MonoBehaviour
{
public Text stageLengthNormalText;
public Text animationLengthNormalText;
public Text stageLengthQuickText;
public Text animationLengthQuickText;
public void Start()
{
}
public void UpdateGUI()
{
stageLengthNormalText.text = "Stage length (normal): " + Workspace.GetCurrentAnimationStage().PlayTimeTicks + " (" + Workspace.GetCurrentAnimationStage().PlayTimeTicks / 60f + " s)";
animationLengthNormalText.text = "Animation length (normal): " + Workspace.animationDef.animationTimeTicks + " (" + Workspace.animationDef.animationTimeTicks / 60f + " s)";
stageLengthQuickText.text = "Stage length (quickie): " + Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick + " (" + Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick / 60f + " s)";
animationLengthQuickText.text = "Animation length (quickie): " + Workspace.animationDef.animationTimeTicksQuick + " (" + Workspace.animationDef.animationTimeTicksQuick / 60f + " s)";
LayoutRebuilder.ForceRebuildLayoutImmediate(stageLengthQuickText.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(animationLengthQuickText.GetComponent<RectTransform>());
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class AnimationLengthsCard : MonoBehaviour
{
public Text stageLengthNormalText;
public Text stageLengthQuickText;
public Text animationLengthNormalText;
public Text animationLengthQuickText;
public float spacing = 10f;
private RectTransform rect;
private void Start()
{
rect = GetComponent<RectTransform>();
}
public void Update()
{
LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
rect.localPosition = new Vector3(rect.localPosition.x, spacing + transform.parent.GetComponent<RectTransform>().sizeDelta.y, rect.localPosition.z);
stageLengthNormalText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicks + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicks / 60f) + " s)";
animationLengthNormalText.text = Workspace.animationDef.animationTimeTicks + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicks / 60f) + " s)";
stageLengthQuickText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick / 60f) + " s)";
animationLengthQuickText.text = Workspace.animationDef.animationTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicksQuick / 60f) + " s)";
}
}
}

View file

@ -11,45 +11,50 @@ namespace RimWorldAnimationStudio
{
public class AnimationTimeline : MonoBehaviour, IPointerClickHandler
{
public int actorID;
public int actorID = -1;
public KeyframeSlider keyframeSliderPrefab;
private Transform anchorTransform;
private void Start()
{
EventsManager.onAnimationTimelinesChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onKeyframeCountChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onActorIDChanged.AddListener(delegate { UpdateTimelineSelection(); });
UpdateTimelineSelection();
UpdateGUI();
}
public void Initialize(int actorID)
{
anchorTransform = transform.parent;
this.actorID = actorID;
UpdateGUI();
}
public void UpdateGUI()
{
if (actorID < 0) return;
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
if (clip == null) return;
clip.BuildSimpleCurves();
foreach (KeyframeSlider slider in GetComponentsInChildren<KeyframeSlider>())
{ RemovePawnKeyFrame(slider.keyframeID);}
{ RemovePawnKeyFrame(slider.keyframeID); }
foreach (PawnKeyframe keyframe in clip.Keyframes)
{ AddPawnKeyFrame(keyframe.keyframeID); }
/*int keyframeCount = clip.keyframes.Count;
int childCount = GetComponentsInChildren<KeyframeSlider>().Count();
InitiateUpdateOfGhostFrames();
}
for (int i = 0; i < Mathf.Max(keyframeCount, childCount); i++)
{
// Add new keyframe sliders as required
if (i >= childCount)
{ AddPawnKeyFrame(clip.keyframes[i].keyframeID); }
// Get objects to update
KeyframeSlider keyframeSlider = GetComponentsInChildren<KeyframeSlider>()[i];
// Update values
if (i < keyframeCount)
{ keyframeSlider.Initialize(this, actorID, clip.keyframes[i].keyframeID); }
// Remove excess objects as required
else
{ RemovePawnKeyFrame(GetComponentsInChildren<KeyframeSlider>()[i].keyframeID); }
}*/
public void UpdateTimelineSelection()
{
GetComponent<Image>().color = (Workspace.ActorID == actorID ? Constants.ColorGoldYellow : Constants.ColorMidGrey);
}
public void AddPawnKeyFrame(int keyframeID)
@ -64,19 +69,8 @@ namespace RimWorldAnimationStudio
Destroy(keyframeSlider?.gameObject);
}
public void Update()
{
if (Workspace.ActorID == actorID)
{ GetComponent<Image>().color = Constants.ColorGoldYellow; }
else
{ GetComponent<Image>().color = Constants.ColorMidGrey; }
}
public void InitiateUpdateOfGhostFrames()
{
//if (AnimationController.Instance.IsTimelineDirty()) return;
BroadcastMessage("UpdateGhostFrames");
}

View file

@ -48,8 +48,9 @@ namespace RimWorldAnimationStudio
keyframe.GenitalAngle = float.Parse(appendageRotationField.text);
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
Workspace.RecordEvent("Actor position / orientation");
UpdateGUI();
}
public void UpdateGUI()

View file

@ -8,67 +8,52 @@ namespace RimWorldAnimationStudio
{
public class AnimationControlCard : MonoBehaviour
{
public Dropdown stageLoopDropdown;
public InputField animationClipTimeField;
public InputField animationClipLengthField;
public Toggle stretchKeyframesToggle;
public InputField currentTimeField;
public InputField stageWindowLengthField;
public InputField playBackSpeedField;
public Button playToggleButton;
public Slider stageTimelineSlider;
private void Start()
{
EventsManager.onStageTickChanged.AddListener(delegate
{
animationClipTimeField.SetTextWithoutNotify(Workspace.StageTick.ToString());
stageTimelineSlider.SetValueWithoutNotify(Workspace.StageTick);
});
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onAnimationToggled.AddListener(delegate { playToggleButton.image.color = Workspace.IsAnimating ? Constants.ColorGoldYellow : Constants.ColorWhite; });
EventsManager.onAnimationToggled.AddListener(delegate
{
playToggleButton.image.color = Workspace.isAnimating ? Constants.ColorGoldYellow : Constants.ColorWhite;
});
stageTimelineSlider.onValueChanged.AddListener(delegate { OnStageTimelineSliderChange(); });
currentTimeField.onEndEdit.AddListener(delegate { OnCurrentTimeFieldChange(); });
stageWindowLengthField.onEndEdit.AddListener(delegate { OnStageWindowLengthFieldChange(); });
playBackSpeedField.onEndEdit.AddListener(delegate { OnPlayBackSpeedChange(); });
animationClipLengthField.text = Workspace.StageWindowSize.ToString();
stageTimelineSlider.maxValue = Workspace.StageWindowSize;
}
public void ToggleAnimation(bool forceOff = false)
{
Workspace.isAnimating = !Workspace.isAnimating;
if (forceOff) Workspace.isAnimating = false;
UpdateGUI();
}
public void OnStageTimelineSliderChange()
{
if (Workspace.animationDef == null) return;
if (Workspace.StageTick != (int)stageTimelineSlider.value)
{
Workspace.StageTick = (int)stageTimelineSlider.value;
animationClipTimeField.text = Workspace.StageTick.ToString();
}
Workspace.StageTick = (int)stageTimelineSlider.value;
}
public void OnAnimationClipTimeFieldChange()
public void OnPlayBackSpeedChange()
{
if (Workspace.animationDef == null) return;
int.TryParse(animationClipTimeField.text, out int newStageTick);
Workspace.StageTick = Mathf.Clamp(newStageTick, Constants.minTick, Workspace.StageWindowSize);
stageTimelineSlider.value = Workspace.StageTick;
Workspace.PlayBackSpeed = float.Parse(playBackSpeedField.text);
}
public void OnAnimationClipLengthFieldChange()
public void OnCurrentTimeFieldChange()
{
if (Workspace.animationDef == null) return;
Workspace.StageTick = Mathf.Clamp(int.Parse(currentTimeField.text), Constants.minTick, Workspace.StageWindowSize);
int.TryParse(animationClipLengthField.text, out int newStageWindowSize);
UpdateGUI();
}
public void OnStageWindowLengthFieldChange()
{
int.TryParse(stageWindowLengthField.text, out int newStageWindowSize);
newStageWindowSize = Mathf.Clamp(newStageWindowSize, Constants.minAnimationClipLength, Constants.maxAnimationClipLength);
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
if (stretchKeyframesToggle.isOn)
if (Workspace.stretchKeyframes)
{ Workspace.GetCurrentAnimationStage().StretchStageWindow(newStageWindowSize); }
else
@ -92,11 +77,16 @@ namespace RimWorldAnimationStudio
Workspace.GetCurrentAnimationStage().ResizeStageWindow(newStageWindowSize);
Workspace.RecordEvent("Stage length");
UpdateGUI();
}
public void OnPlayBackSpeedChange()
public void UpdateGUI()
{
Workspace.PlayBackSpeed = float.Parse(playBackSpeedField.text);
stageTimelineSlider.maxValue = Workspace.StageWindowSize;
stageTimelineSlider.SetValueWithoutNotify(Workspace.StageTick);
currentTimeField.SetTextWithoutNotify(Workspace.StageTick.ToString());
stageWindowLengthField.SetTextWithoutNotify(Workspace.StageWindowSize.ToString());
playBackSpeedField.SetTextWithoutNotify(Workspace.PlayBackSpeed.ToString());
}
}

View file

@ -15,14 +15,13 @@ namespace RimWorldAnimationStudio
public void Start()
{
EventsManager.onAnimationChanged.AddListener(delegate { UpdateInputFields(); });
EventsManager.onStageIDChanged.AddListener(delegate { UpdateInputFields(); });
EventsManager.onAnimationStageChanged.AddListener(delegate { UpdateInputFields(); });
EventsManager.onAnimationTimelinesChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onStageWindowSizeChanged.AddListener(delegate { UpdateGUI(); });
stageLoopsNormalField.onEndEdit.AddListener(delegate { OnStageLoopsNormalFieldChange(); });
stageLoopsQuickField.onEndEdit.AddListener(delegate { OnStageLoopsFastFieldChange(); });
UpdateInputFields();
UpdateGUI();
}
public void OnStageLoopsNormalFieldChange()
@ -33,8 +32,6 @@ namespace RimWorldAnimationStudio
EventsManager.OnAnimationStageChanged(Workspace.GetCurrentAnimationStage());
Workspace.RecordEvent("Cycle count (normal)");
UpdateInputFields();
}
public void OnStageLoopsFastFieldChange()
@ -45,11 +42,9 @@ namespace RimWorldAnimationStudio
EventsManager.OnAnimationStageChanged(Workspace.GetCurrentAnimationStage());
Workspace.RecordEvent("Cycle count (fast)");
UpdateInputFields();
}
public void UpdateInputFields()
public void UpdateGUI()
{
stageLoopsNormalField.SetTextWithoutNotify(Workspace.GetCurrentAnimationStage().StageLoopsNormal.ToString());
stageLoopsQuickField.SetTextWithoutNotify(Workspace.GetCurrentAnimationStage().StageLoopsQuick.ToString());

View file

@ -10,6 +10,28 @@ namespace RimWorldAnimationStudio
{
public class SelectActorAddonsDialog : DialogBox
{
public class AddonDef
{
public string addonName;
public Toggle toggle;
public Dropdown anchor;
public InputField anchoringPawn;
public Dropdown layer;
public GameObject controls;
public AddonDef(string addonName, Toggle toggle, Dropdown anchor, InputField anchoringPawn, Dropdown layer, GameObject controls)
{
this.addonName = addonName;
this.toggle = toggle;
this.anchor = anchor;
this.anchoringPawn = anchoringPawn;
this.layer = layer;
this.controls = controls;
}
}
private List<AddonDef> addonDefs = new List<AddonDef>();
public Toggle handLeftToggle;
public Toggle handRightToggle;
public Toggle sexToyToggle;
@ -30,92 +52,70 @@ namespace RimWorldAnimationStudio
public GameObject handRightControls;
public GameObject sexToyControls;
private PawnAnimationClip clip { get { return Workspace.GetCurrentPawnAnimationClip(); } }
private void Start()
{
EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
InitializeAddonDefs();
UpdateGUI();
}
// temp code
public void InitializeAddonDefs()
{
if (addonDefs.NotNullOrEmpty()) return;
addonDefs.Add(new AddonDef("left hand", handLeftToggle, handLeftAnchor, handLeftAnchoringPawn, handLeftLayer, handLeftControls));
addonDefs.Add(new AddonDef("right hand", handRightToggle, handRightAnchor, handRightAnchoringPawn, handRightLayer, handRightControls));
addonDefs.Add(new AddonDef("dildo", sexToyToggle, sexToyAnchor, sexToyAnchoringPawn, sexToyLayer, sexToyControls));
}
public override void Initialize(bool addedNewTag = false)
{
InitializeAddonDefs();
}
public void UpdateGUI()
{
if (Workspace.animationDef == null) return;
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
if (clip?.GetActorAddon("left hand") != null)
Debug.Log("Actor: " + clip.GetOwningActorID());
foreach (AddonDef addonDef in addonDefs)
{
switch (clip.GetActorAddon("left hand").AnchorName)
if (clip?.GetActorAddon(addonDef.addonName) != null)
{
case "torso": handLeftAnchor.value = 1; break;
case "head": handLeftAnchor.value = 2; break;
case "groin": handLeftAnchor.value = 3; break;
case "left breast": handLeftAnchor.value = 4; break;
case "right breast": handLeftAnchor.value = 5; break;
default: handLeftAnchor.value = 0; break;
switch (clip.GetActorAddon(addonDef.addonName).AnchorName)
{
case "torso": addonDef.anchor.SetValueWithoutNotify(1); break;
case "head": addonDef.anchor.SetValueWithoutNotify(2); break;
case "groin": addonDef.anchor.SetValueWithoutNotify(3); break;
case "left breast": addonDef.anchor.SetValueWithoutNotify(4); break;
case "right breast": addonDef.anchor.SetValueWithoutNotify(5); break;
default: addonDef.anchor.SetValueWithoutNotify(0); break;
}
addonDef.layer.SetValueWithoutNotify(addonDef.layer.options.IndexOf(addonDef.layer.options.First(x => x.text == clip.GetActorAddon(addonDef.addonName).Layer)));
addonDef.anchoringPawn.SetTextWithoutNotify(clip.GetActorAddon(addonDef.addonName).AnchoringActor.ToString());
addonDef.toggle.SetIsOnWithoutNotify(clip.IsActorAddonVisible(addonDef.addonName));
}
}
if (clip?.GetActorAddon("right hand") != null)
{
switch (clip.GetActorAddon("right hand").AnchorName)
{
case "torso": handRightAnchor.value = 1; break;
case "head": handRightAnchor.value = 2; break;
case "groin": handRightAnchor.value = 3; break;
case "left breast": handRightAnchor.value = 4; break;
case "right breast": handRightAnchor.value = 5; break;
default: handRightAnchor.value = 0; break;
}
}
if (clip?.GetActorAddon("dildo") != null)
{
switch (clip.GetActorAddon("dildo").AnchorName)
{
case "torso": sexToyAnchor.value = 1; break;
case "head": sexToyAnchor.value = 2; break;
case "groin": sexToyAnchor.value = 3; break;
case "left breast": sexToyAnchor.value = 4; break;
case "right breast": sexToyAnchor.value = 5; break;
default: sexToyAnchor.value = 0; break;
}
}
if (clip?.GetActorAddon("left hand") != null)
{
handLeftLayer.value = handLeftLayer.options.IndexOf(handLeftLayer.options.First(x => x.text == clip.GetActorAddon("left hand").Layer));
handLeftAnchoringPawn.text = clip.GetActorAddon("left hand").AnchoringActor.ToString();
}
if (clip?.GetActorAddon("right hand") != null)
{
handRightLayer.value = handRightLayer.options.IndexOf(handRightLayer.options.First(x => x.text == clip.GetActorAddon("right hand").Layer));
handRightAnchoringPawn.text = clip.GetActorAddon("right hand").AnchoringActor.ToString();
}
if (clip?.GetActorAddon("dildo") != null)
{
sexToyLayer.value = sexToyLayer.options.IndexOf(sexToyLayer.options.First(x => x.text == clip.GetActorAddon("dildo").Layer));
sexToyAnchoringPawn.text = clip.GetActorAddon("dildo").AnchoringActor.ToString();
}
handLeftToggle.isOn = clip.IsActorAddonVisible("left hand");
handRightToggle.isOn = clip.IsActorAddonVisible("right hand");
sexToyToggle.isOn = clip.IsActorAddonVisible("dildo");
//handLeftControls.SetActive(handLeftToggle.isOn);
//handRightControls.SetActive(handRightToggle.isOn);
//sexToyControls.SetActive(sexToyToggle.isOn);
}
public void OnToggleChanged()
{
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
clip.ShowOrHideActorAddon("left hand", handLeftToggle.isOn);
clip.ShowOrHideActorAddon("right hand", handRightToggle.isOn);
clip.ShowOrHideActorAddon("dildo", sexToyToggle.isOn);
//Initialize();
UpdateGUI();
}
public void OnValueChanged()
{
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
if (clip?.GetActorAddon("left hand") != null)
{
switch (handLeftAnchor.value)
@ -155,13 +155,11 @@ namespace RimWorldAnimationStudio
}
}
//Initialize();
UpdateGUI();
}
public void OnLayerChanged()
{
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
if (clip?.GetActorAddon("left hand") != null)
{ clip.GetActorAddon("left hand").Layer = handLeftLayer.options[handLeftLayer.value].text; }
@ -171,13 +169,11 @@ namespace RimWorldAnimationStudio
if (clip?.GetActorAddon("dildo") != null)
{ clip.GetActorAddon("dildo").Layer = sexToyLayer.options[sexToyLayer.value].text; }
//Initialize();
UpdateGUI();
}
public void OnAnchoringPawnChanged()
{
PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
if (clip?.GetActorAddon("left hand") != null)
{
int i = int.Parse(handLeftAnchoringPawn.text);
@ -210,6 +206,8 @@ namespace RimWorldAnimationStudio
clip.GetActorAddon("dildo").AnchoringActor = i;
sexToyAnchoringPawn.SetTextWithoutNotify(i.ToString());
}
UpdateGUI();
}
}
}

View file

@ -11,6 +11,7 @@ namespace RimWorldAnimationStudio
{
public class KeyframeSlider : Slider, IPointerClickHandler, IBeginDragHandler, IEndDragHandler
{
public int keyframeID;
public AnimationTimeline timeline;
public Transform ghostSliders;
public Slider ghostSliderPrefab;
@ -18,33 +19,32 @@ namespace RimWorldAnimationStudio
public GameObject soundIcon;
public int maxGhosts = 4;
public int actorID;
public int keyframeID;
private PawnAnimationClip clip;
private PawnKeyframe keyframe;
private float dragTimeStart = -1f;
private int dragTickStart = -1;
public KeyframeSlider linkedSlider;
public PawnKeyframe pivotKeyframe;
public int linkedOffset;
private PawnAnimationClip clip { get { return Workspace.GetPawnAnimationClip(actorID); } }
private PawnKeyframe keyframe { get { return Workspace.GetPawnKeyframe(keyframeID); } }
private int actorID;
private float dragTimeStart = -1f;
private int dragTickStart = -1;
protected override void Start()
{
base.Start();
onValueChanged.AddListener(delegate (float value) { OnValueChanged(); });
}
public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID)
{
this.timeline = timeline;
this.clip = Workspace.GetPawnAnimationClip(actorID);
this.keyframe = Workspace.GetPawnKeyframe(keyframeID);
this.actorID = actorID;
this.keyframeID = keyframeID;
PawnKeyframe keyframe = Workspace.GetPawnKeyframe(keyframeID);
maxValue = Workspace.StageWindowSize;
value = keyframe.atTick.Value;
onValueChanged.AddListener(delegate (float value) { OnValueChanged(); });
}
public void OnValueChanged()
@ -119,7 +119,7 @@ namespace RimWorldAnimationStudio
List<PawnKeyframe> selectedKeyframes = Workspace.GetPawnKeyframesByID(Workspace.keyframeID).Except(new List<PawnKeyframe>() { keyframe })?.ToList();
// Link other slected keyframes to the movement of this one
// Link other selected keyframes to the movement of this one
if (selectedKeyframes.NotNullOrEmpty())
{
pivotKeyframe = keyframe.atTick <= selectedKeyframes.Min(x => x.atTick) ?
@ -215,6 +215,8 @@ namespace RimWorldAnimationStudio
{
base.Update();
if (keyframe == null) return;
// Update outdated values
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
{ linkedSlider = null; }

View file

@ -10,6 +10,7 @@ namespace RimWorldAnimationStudio
{
public class LinearScale : Singleton<LinearScale>
{
public Transform animationTimelines;
public int targetDivisions = 30;
public List<int> divisionBands = new List<int>() { 5, 10, 25, 50, 100, 250, 500, 1000 };
public GameObject linearScaleTickPrefab;
@ -19,13 +20,18 @@ namespace RimWorldAnimationStudio
public void Start()
{
EventsManager.onAnimationChanged.AddListener(delegate { UpdateLinearScale(); });
EventsManager.onStageIDChanged.AddListener(delegate { UpdateLinearScale(); });
EventsManager.onStageWindowSizeChanged.AddListener(delegate { UpdateLinearScale(); });
UpdateLinearScale();
}
public void UpdateLinearScale()
{
if (Workspace.animationDef == null) return;
LayoutRebuilder.ForceRebuildLayoutImmediate(animationTimelines.GetComponent<RectTransform>());
minDiff = -1f;
foreach (int division in divisionBands)

View file

@ -16,7 +16,7 @@ namespace RimWorldAnimationStudio
private void Update()
{
inputfield.interactable = AnimationController.Instance.isAnimating == false;
inputfield.interactable = Workspace.IsAnimating == false;
}
}
}

View file

@ -12,7 +12,7 @@ namespace RimWorldAnimationStudio
private List<Text> buttonText;
private List<Color> buttonTextColor = new List<Color>();
public void Start()
private void Start()
{
button = GetComponent<Button>();
buttonText = GetComponentsInChildren<Text>()?.ToList();
@ -24,7 +24,7 @@ namespace RimWorldAnimationStudio
}
}
public void Update()
private void Update()
{
button.interactable = Workspace.animationDef != null;

View file

@ -11,9 +11,6 @@ namespace RimWorldAnimationStudio
{
public class AnimationController : Singleton<AnimationController>
{
[Header("Animation settings")]
public bool isAnimating = false;
[Header("Object references")]
public Transform animationTimelines;
public Transform actorBodies;
@ -40,7 +37,7 @@ namespace RimWorldAnimationStudio
if (Workspace.animationDef == null) return;
// Update stage tick / loop count if animating
if (isAnimating)
if (Workspace.IsAnimating)
{
timeSinceLastUpdate += Time.deltaTime;
@ -50,54 +47,54 @@ namespace RimWorldAnimationStudio
timeSinceLastUpdate -= 1 / (playBackSpeed * 60f);
Workspace.StageTick += 1;
if (Workspace.StageTick > Workspace.StageWindowSize)
if (Workspace.StageTick >= Workspace.StageWindowSize)
{
switch (stageLoopDropdown.value)
{
case 1: Workspace.StageTick = Constants.minTick; break;
case 2: UpdateLoopCount(Workspace.GetCurrentAnimationStage().StageLoopsNormal); break;
case 3: UpdateLoopCount(Workspace.GetCurrentAnimationStage().StageLoopsQuick); break;
default: break;
default: Workspace.IsAnimating = false; break;
}
}
}
// Update animation preview
UpdateAnimationPReview();
UpdateAnimationPreview();
}
public void UpdateLoopCount(int stageLoops)
{
++loopCount;
loopCount++;
Workspace.StageTick = Constants.minTick;
if (loopCount >= stageLoops)
{
++Workspace.StageID;
loopCount = 0;
}
if (Workspace.StageID >= Workspace.animationDef.AnimationStages.Count - 1)
{ Workspace.IsAnimating = false; }
if (Workspace.StageID >= Workspace.animationDef.AnimationStages.Count - 1)
{
Workspace.StageTick = Workspace.StageWindowSize;
Workspace.isAnimating = false;
else
{
Workspace.StageID++;
loopCount = 0;
}
}
}
public void UpdateAnimationPReview()
public void UpdateAnimationPreview()
{
if (Workspace.animationDef == null || Workspace.StageID >= Workspace.animationDef?.AnimationStages.Count) return;
List<ActorBody> actorBodiesList = actorBodies.GetComponentsInChildren<ActorBody>().ToList();
for (int actorID = 0; actorID < actorBodiesList.Count; actorID++)
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
{
// Get the current actor and their animation clip
Actor actor = Workspace.GetActor(actorID);
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
// Get flags
bool quiver = isAnimating && Workspace.GetCurrentOrPreviousKeyframe(actorID).Quiver == true;
bool quiver = Workspace.IsAnimating && Workspace.GetCurrentOrPreviousKeyframe(actorID).Quiver == true;
bool requiresGenitals = actor.RequiredGenitals.Any(x => x == "Penis") || actor.IsFucking;
// Get clip percentage
@ -193,9 +190,6 @@ namespace RimWorldAnimationStudio
{
Debug.Log("Initializing animation preview");
foreach (Transform child in transform)
{ child.gameObject.SetActive(true); }
int actorCount = Workspace.animationDef.Actors.Count;
int childCount = animationTimelines.GetComponentsInChildren<AnimationTimeline>().Count();
@ -227,15 +221,17 @@ namespace RimWorldAnimationStudio
}
}
foreach (AnimationTimeline timeline in animationTimelines.GetComponentsInChildren<AnimationTimeline>())
{ timeline.InitiateUpdateOfGhostFrames(); }
EventsManager.OnAnimationTimelinesChanged();
}
public void Reset()
{
Workspace.isAnimating = false;
Workspace.IsAnimating = false;
timeSinceLastUpdate = 0;
loopCount = 0;
foreach (Transform child in transform)
{ child.gameObject.SetActive(true); }
}
}
}

View file

@ -64,17 +64,21 @@ namespace RimWorldAnimationStudio
{
UpdateCustomArrays(animationDef);
RunPostLoadOperations(animationDef);
animationDef.Initialize();
Debug.Log("Loaded AnimationDef: " + animationDef.DefName);
Workspace.Reset();
Workspace.animationDef = animationDef;
animationDef.Initialize();
AnimationController.Instance.Reset();
Workspace.Reset();
AnimationController.Instance.Initialize();
EventsManager.OnAnimationChanged();
Workspace.RecordEvent("AnimationDef loaded");
Workspace.ActorID = 0;
EventsManager.OnActorIDChanged();
}
public void RunPostLoadOperations(AnimationDef animationDef)

View file

@ -22,6 +22,7 @@ namespace RimWorldAnimationStudio
public class ActorBodyPartEvent : UnityEvent<ActorBodyPart> { }
// Event list
public static UnityEvent onAnimationTimelinesChanged = new UnityEvent();
public static UnityEvent onAnimationToggled = new UnityEvent();
public static UnityEvent onAnimationChanged = new UnityEvent();
public static UnityEvent onAnimationDefChanged = new UnityEvent();
@ -43,6 +44,7 @@ namespace RimWorldAnimationStudio
public static ActorBodyPartEvent onActorBodyPartSelected = new ActorBodyPartEvent();
// Event invoking
public static void OnAnimationTimelinesChanged() { onAnimationTimelinesChanged.Invoke(); }
public static void OnAnimationToggled() { onAnimationToggled.Invoke(); }
public static void OnAnimationChanged() { onAnimationChanged.Invoke(); }
public static void OnAnimationDefChanged() { onAnimationDefChanged.Invoke(); }

View file

@ -204,7 +204,7 @@ namespace RimWorldAnimationStudio
public void ToggleAnimationPreview()
{
if (Workspace.animationDef == null) return;
Workspace.isAnimating = !Workspace.isAnimating;
Workspace.IsAnimating = !Workspace.IsAnimating;
}
public void AddKeyframe()

View file

@ -77,11 +77,21 @@ namespace RimWorldAnimationStudio
// Stage controls
private static float playBackSpeed = 1f;
public static bool isAnimating;
private static bool isAnimating;
public static bool stretchKeyframes;
// Stage controls set / get
public static float PlayBackSpeed { get { return playBackSpeed; } set { Mathf.Clamp(Workspace.playBackSpeed, 0.01f, 10f); } }
public static float PlayBackSpeed
{
get { return playBackSpeed; }
set { Mathf.Clamp(Workspace.playBackSpeed, 0.01f, 10f); }
}
public static bool IsAnimating
{
get { return isAnimating; }
set { isAnimating = value; EventsManager.OnAnimationToggled(); }
}
// Animation indices
private static int stageID = 0;