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

@ -88,7 +88,7 @@
<Compile Include="Assets\Scripts\GUI\Actors\ActorBody.cs" />
<Compile Include="Assets\Scripts\GUI\Actors\ActorBodyPart.cs" />
<Compile Include="Assets\Scripts\GUI\AddSoundDefButton.cs" />
<Compile Include="Assets\Scripts\GUI\AnimationLengthDisplay.cs" />
<Compile Include="Assets\Scripts\GUI\AnimationLengthsCard.cs" />
<Compile Include="Assets\Scripts\GUI\AnimationTimeline.cs" />
<Compile Include="Assets\Scripts\GUI\Cards\ActorAddonKeyframeCard.cs" />
<Compile Include="Assets\Scripts\GUI\Cards\ActorCard.cs" />
@ -132,6 +132,7 @@
<Compile Include="Assets\Scripts\Managers\AnimationController.cs" />
<Compile Include="Assets\Scripts\Managers\ApplicationManager.cs" />
<Compile Include="Assets\Scripts\Managers\CameraController.cs" />
<Compile Include="Assets\Scripts\Managers\EventsManager.cs" />
<Compile Include="Assets\Scripts\Managers\InputManager.cs" />
<Compile Include="Assets\Scripts\Managers\StageCardManager.cs" />
<Compile Include="Assets\Scripts\Math\CurvePoint.cs" />
@ -141,7 +142,6 @@
<Compile Include="Assets\Scripts\Strings\NumberValidator.cs" />
<Compile Include="Assets\Scripts\Utilities\PawnUtility.cs" />
<Compile Include="Assets\Scripts\Utilities\XmlUtility.cs" />
<Compile Include="Assets\Scripts\Workspace\EventsManager.cs" />
<Compile Include="Assets\Scripts\Workspace\HistoricRecord.cs" />
<Compile Include="Assets\Scripts\Workspace\Workspace.cs" />
<Compile Include="Assets\StandaloneFileBrowser\IStandaloneFileBrowser.cs" />

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;

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<ArrayOfAlienRaceDef>
<AlienRaceDef>
<ArrayOfPawnRaceDef>
<PawnRaceDef>
<defName>Human</defName>
<isHumanoid>true</isHumanoid>
<scale>1</scale>
@ -90,8 +90,8 @@
<path>Textures\Humanlike\Heads\Head2.png</path>
</southGraphic>
</headGraphics>
</AlienRaceDef>
<AlienRaceDef>
</PawnRaceDef>
<PawnRaceDef>
<defName>Wolf_Timber</defName>
<isHumanoid>false</isHumanoid>
<scale>1.3333</scale>
@ -145,8 +145,8 @@
<eastGraphic />
<southGraphic />
</headGraphics>
</AlienRaceDef>
<AlienRaceDef>
</PawnRaceDef>
<PawnRaceDef>
<defName>Horse</defName>
<isHumanoid>false</isHumanoid>
<scale>0.70</scale>
@ -200,5 +200,5 @@
<eastGraphic />
<southGraphic />
</headGraphics>
</AlienRaceDef>
</ArrayOfAlienRaceDef>
</PawnRaceDef>
</ArrayOfPawnRaceDef>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More