Basic keybinds plus multi key selection

This commit is contained in:
AbstractConcept 2022-10-02 17:39:03 -05:00
parent 518a912ef1
commit 842c954455
89 changed files with 977 additions and 164 deletions

View file

@ -95,7 +95,12 @@ namespace RimWorldAnimationStudio
public void OnPointerClick(PointerEventData eventData)
{
Workspace.actorID = actorID;
Workspace.keyframeID = keyframeID;
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand))
{ Workspace.keyframeID.Add(keyframeID); }
else
{ Workspace.keyframeID = new List<int> { keyframeID }; }
if (eventData.clickCount >= 2)
{ AnimationController.Instance.stageTick = keyframe.atTick.Value; }
@ -107,7 +112,8 @@ namespace RimWorldAnimationStudio
{
//AnimationController.Instance.stageTick = keyframe.atTick.Value;
Workspace.actorID = actorID;
Workspace.keyframeID = keyframeID;
Workspace.keyframeID = new List<int> { keyframeID };
dragTimeStart = Time.unscaledTime;
}
@ -132,17 +138,17 @@ namespace RimWorldAnimationStudio
{ value = 1; return; }
interactable = false;
Workspace.Instance.RecordEvent("Keyframe tick");
Workspace.Instance.RecordEvent("Keyframe move");
}
protected override void Update()
{
base.Update();
if (keyframe.atTick.HasValue && Workspace.keyframeID == keyframeID && AnimationController.Instance.stageTick == keyframe.atTick.Value)
if (keyframe.atTick.HasValue && Workspace.keyframeID.Contains(keyframeID) && AnimationController.Instance.stageTick == keyframe.atTick.Value)
{ handleImage.color = Constants.ColorPurple; }
else if (Workspace.keyframeID == keyframeID)
else if (Workspace.keyframeID.Contains(keyframeID))
{ handleImage.color = Constants.ColorCyan; }
else if (keyframe.atTick.HasValue && AnimationController.Instance.stageTick == keyframe.atTick.Value)

View file

@ -132,10 +132,10 @@ namespace RimWorldAnimationStudio
for (int actorID = 0; actorID < _actorBodies.Count; actorID++)
{
if (Workspace.stageID >= Workspace.animationDef?.animationStages.Count)
{ Debug.Log("Waiting for animation stage data to initialize..."); return; }
{ /*Debug.Log("Waiting for animation stage data to initialize...");*/ return; }
if (actorID >= Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips.Count)
{ Debug.Log("Waiting for animation clip data to initialize..."); return; }
{ /*Debug.Log("Waiting for animation clip data to initialize...");*/ return; }
Actor actor = Workspace.animationDef.actors[actorID];
PawnAnimationClip clip = Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips[actorID];
@ -340,39 +340,45 @@ namespace RimWorldAnimationStudio
public void ClonePawnKeyframe()
{
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
List<PawnKeyframe> keyframes = clip?.keyframes;
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(Workspace.actorID, Workspace.keyframeID);
List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID);
if (clip == null || keyframes == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - the AnimationDef is invalid"); return; }
foreach (PawnKeyframe keyframe in keyframesToClone)
{
PawnAnimationClip clip = Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID);
if (keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
if (clip == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - no clip owns this keyframe"); continue; }
if (keyframe == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - no keyframe has been selected for cloning"); return; }
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();
cloneFrame.atTick = stageTick;
PawnKeyframe cloneFrame = keyframe.Copy();
cloneFrame.GenerateKeyframeID();
cloneFrame.atTick = stageTick;
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > stageTick);
PawnKeyframe nextKeyframe = clip.keyframes.FirstOrDefault(x => x.atTick > stageTick);
if (nextKeyframe != null)
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), cloneFrame); }
if (nextKeyframe != null)
{ clip.keyframes.Insert(clip.keyframes.IndexOf(nextKeyframe), cloneFrame); }
else
{ keyframes.Add(cloneFrame); }
else
{ clip.keyframes.Add(cloneFrame); }
clip.BuildSimpleCurves();
clip.BuildSimpleCurves();
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[Workspace.actorID].AddPawnKeyFrame(cloneFrame.keyframeID);
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[clipID].AddPawnKeyFrame(cloneFrame.keyframeID);
}
Workspace.Instance.RecordEvent("Keyframe clone");
}
public void RemovePawnKeyframe()
{
RemovePawnKeyframe(Workspace.actorID, Workspace.keyframeID);
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)
@ -388,7 +394,7 @@ namespace RimWorldAnimationStudio
if (clip.keyframes.Count <= 2)
{ Debug.LogWarning("Cannot delete key frame - an animation clip must have two or more keyframes"); return; }
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[Workspace.actorID].RemovePawnKeyFrame(keyframe.keyframeID);
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[actorID].RemovePawnKeyFrame(keyframe.keyframeID);
clip.keyframes.Remove(keyframe);
clip.BuildSimpleCurves();

View file

@ -13,6 +13,7 @@ namespace RimWorldAnimationStudio
public class ApplicationManager : Singleton<ApplicationManager>
{
public DialogBox exitDialog;
public DialogBox newAnimationDialog;
public SelectAnimationDialog selectAnimationDialog;
public void Start()
@ -74,7 +75,7 @@ namespace RimWorldAnimationStudio
}
public void TrySaveAnimation()
public void TryToSaveAnimation()
{
if (Workspace.animationDef == null)
{ return; }
@ -121,6 +122,14 @@ namespace RimWorldAnimationStudio
}
}
public void TryToMakeNewAnimation()
{
if (Workspace.animationDef == null)
{ NewAnimation(); return; }
newAnimationDialog.Pop();
}
public void NewAnimation()
{
var path = Path.Combine(Application.streamingAssetsPath, "AnimationDefs/newAnimationDef.xml");

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace RimWorldAnimationStudio
{
public class InputManager : Singleton<InputManager>
{
public void Update()
{
if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.Z))
{ Workspace.Instance.Undo(); }
else if (Input.GetKey(KeyCode.LeftCommand) && Input.GetKeyDown(KeyCode.Z))
{ Workspace.Instance.Undo(); }
else if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.Y))
{ Workspace.Instance.Redo(); }
else if (Input.GetKey(KeyCode.LeftCommand) && Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Z))
{ Workspace.Instance.Redo(); }
else if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand)) && Input.GetKeyDown(KeyCode.C))
{ AnimationController.Instance.ClonePawnKeyframe(); }
else if (Input.GetKey(KeyCode.Backspace) || Input.GetKey(KeyCode.Delete))
{ AnimationController.Instance.RemovePawnKeyframe(); }
else if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand)) && Input.GetKeyDown(KeyCode.N))
{ ApplicationManager.Instance.TryToMakeNewAnimation(); }
else if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand)) && Input.GetKeyDown(KeyCode.S))
{ ApplicationManager.Instance.TryToSaveAnimation(); }
else if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand)) && Input.GetKeyDown(KeyCode.L))
{ ApplicationManager.Instance.TryToLoadAnimation(); }
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 120c040fa90da65478716f3ccda1248f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -13,14 +13,14 @@ namespace RimWorldAnimationStudio
{
public static T ReadXML<T>(string path)
{
Debug.Log("Reading data from " + path);
//Debug.Log("Reading data from " + path);
using (StreamReader stringReader = new StreamReader(path))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
var data = (T)serializer.Deserialize(stringReader);
Debug.Log("Read successful");
//Debug.Log("Read successful");
return data;
}
}
@ -30,7 +30,7 @@ namespace RimWorldAnimationStudio
if (obj == null || path == null || path == "")
{ return; }
Debug.Log("Saving data to " + path);
//Debug.Log("Saving data to " + path);
XmlSerializer writer = new XmlSerializer(typeof(T));
XmlSerializerNamespaces nameSpaces = new XmlSerializerNamespaces();
@ -40,7 +40,7 @@ namespace RimWorldAnimationStudio
writer.Serialize(file, obj, nameSpaces);
file.Close();
Debug.Log("Saving successful");
//Debug.Log("Saving successful");
}
}
}

View file

@ -12,7 +12,7 @@ namespace RimWorldAnimationStudio
public static AnimationDef animationDef;
public static int stageID = 0;
public static int keyframeID = 0;
public static List<int> keyframeID = new List<int>();
[SerializeField] private List<HistoricRecord> workspaceHistory = new List<HistoricRecord>();
[SerializeField] private int maxHistoryDepth = 100;
@ -61,9 +61,49 @@ namespace RimWorldAnimationStudio
public PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID)
{
if (stageID < 0) return null;
if (actorID < 0) return null;
if (stageID >= animationDef.animationStages.Count) return null;
if (actorID >= animationDef.animationStages[stageID].animationClips.Count) return null;
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
}
public List<PawnKeyframe> GetPawnKeyframes(List<int> keyframeIDs)
{
List<PawnKeyframe> pawnKeyframes = new List<PawnKeyframe>();
foreach (PawnAnimationClip clip in animationDef.animationStages[stageID].animationClips)
{
foreach (PawnKeyframe keyframe in clip.keyframes)
{
if (keyframeIDs.Contains(keyframe.keyframeID))
{ pawnKeyframes.Add(keyframe); }
}
}
return pawnKeyframes;
}
public PawnAnimationClip GetAnimationClipThatOwnsKeyframe(int keyframeID, out int clipID)
{
clipID = -1;
for (int i = 0; i < animationDef.animationStages[stageID].animationClips.Count; i++)
{
PawnAnimationClip clip = animationDef.animationStages[stageID].animationClips[i];
if (clip.keyframes.Any(x => x.keyframeID == keyframeID))
{
clipID = i;
return clip;
}
}
return null;
}
[SerializeField]
public LinkedList<HistoricRecord> pastSnapshots = new LinkedList<HistoricRecord>();
public LinkedList<HistoricRecord> futureSnapshots = new LinkedList<HistoricRecord>();