Bug fixes plus extra features

- Insert adds a new keyframe to the selected timeline
- New stages have frames cloned from the last frame of current stage
- Existing key are now replaced when another key is dropped on them
- Fixed bug where starting a new animation could result in errors
This commit is contained in:
AbstractConcept 2022-10-18 21:57:43 -05:00
parent ca22fa0c18
commit 2989d9a72c
137 changed files with 527 additions and 668 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,116 @@
fileFormatVersion: 2
guid: 656b64fca82a9e14bbafce96bf8b5cbf
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: -1
mipBias: -100
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 0
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -121,5 +121,12 @@ namespace RimWorldAnimationStudio
return true; return true;
} }
public int GetActorID()
{
if (Workspace.animationDef == null) return -1;
return Workspace.animationDef.actors.IndexOf(this);
}
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Xml; using System.Xml;
using System.Xml.Serialization; using System.Xml.Serialization;
@ -89,17 +90,46 @@ namespace RimWorldAnimationStudio
public override void ValidateData() { } public override void ValidateData() { }
public bool MakeNew() public int GetOwningActorID()
{ {
PawnKeyframe keyframeA = new PawnKeyframe(); if (Workspace.animationDef == null) return -1;
keyframeA.tickDuration = Constants.defaultAnimationClipLength - 1;
keyframes.Add(keyframeA);
PawnKeyframe keyframeB = new PawnKeyframe(); return Workspace.animationDef.animationStages[Workspace.stageID].animationClips.IndexOf(this);
keyframes.Add(keyframeB); }
public bool MakeNew(int actorID = -1)
{
PawnKeyframe lastkeyframe = null;
if (actorID >= 0)
{ lastkeyframe = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID]?.keyframes?.Last(); }
if (lastkeyframe != null)
{
PawnKeyframe keyframeA = lastkeyframe.Copy();
keyframeA.atTick = null;
keyframeA.tickDuration = Constants.defaultAnimationClipLength - 1;
keyframeA.GenerateKeyframeID(actorID);
keyframes.Add(keyframeA);
PawnKeyframe keyframeB = lastkeyframe.Copy();
keyframeB.atTick = null;
keyframeB.tickDuration = 1;
keyframeB.GenerateKeyframeID(actorID);
keyframes.Add(keyframeB);
}
else
{
PawnKeyframe keyframeA = new PawnKeyframe();
keyframeA.tickDuration = Constants.defaultAnimationClipLength - 1;
keyframes.Add(keyframeA);
PawnKeyframe keyframeB = new PawnKeyframe();
keyframes.Add(keyframeB);
}
BuildSimpleCurves(); BuildSimpleCurves();
return true; return true;
} }
} }

View File

@ -36,23 +36,31 @@ namespace RimWorldAnimationStudio
{ clip.keyframes = clip.keyframes.OrderBy(x => x.atTick).ToList(); } { clip.keyframes = clip.keyframes.OrderBy(x => x.atTick).ToList(); }
} }
public int GetStageID()
{
if (Workspace.animationDef == null) return -1;
return Workspace.animationDef.animationStages.IndexOf(this);
}
public bool MakeNew() public bool MakeNew()
{ {
if (Workspace.animationDef == null) if (Workspace.animationDef == null)
{ Debug.LogWarning("Cannot make new animation stage - there is no AnimationDef"); return false; } { Debug.LogWarning("Cannot make new animation stage - there is no AnimationDef"); return false; }
foreach(Actor actor in Workspace.animationDef.actors) Workspace.animationDef.animationStages.Add(this);
foreach (Actor actor in Workspace.animationDef.actors)
{ {
PawnAnimationClip clip = new PawnAnimationClip(); PawnAnimationClip clip = new PawnAnimationClip();
if (clip.MakeNew()) if (clip.MakeNew(actor.GetActorID()))
{ animationClips.Add(clip); } { animationClips.Add(clip); }
} }
Initialize(); Initialize();
playTimeTicksQuick = playTimeTicks; playTimeTicksQuick = playTimeTicks;
Workspace.animationDef.animationStages.Add(this);
return true; return true;
} }
} }

View File

@ -31,10 +31,8 @@ namespace RimWorldAnimationStudio
public void LogMessage(string logString, string stackTrace, LogType type) public void LogMessage(string logString, string stackTrace, LogType type)
{ {
if (currentMessages > maxMessages) if (currentMessages > maxMessages) return;
{ return; } currentMessages++;
currentMessages++;
currentMessage.text = logString; currentMessage.text = logString;

View File

@ -17,7 +17,7 @@ namespace RimWorldAnimationStudio
public void Start() public void Start()
{ {
keybindLabel = GetComponent<Text>(); keybindLabel = GetComponent<Text>();
keybindLabel.text = KeybindConfig.Instance.GetKeybindLabel(command); keybindLabel.text = KeybindConfig.GetKeybindLabel(command);
} }
} }
} }

View File

@ -117,7 +117,7 @@ namespace RimWorldAnimationStudio
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false) if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
{ Workspace.keyframeID = new List<int> { keyframeID }; } { Workspace.keyframeID = new List<int> { keyframeID }; }
List<PawnKeyframe> selectedKeyframes = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID).Except(new List<PawnKeyframe>() { keyframe })?.ToList(); List<PawnKeyframe> selectedKeyframes = Workspace.Instance.GetPawnKeyframesByID(Workspace.keyframeID).Except(new List<PawnKeyframe>() { keyframe })?.ToList();
// Link other slected keyframes to the movement of this one // Link other slected keyframes to the movement of this one
if (selectedKeyframes.NotNullOrEmpty()) if (selectedKeyframes.NotNullOrEmpty())
@ -170,12 +170,39 @@ namespace RimWorldAnimationStudio
if (keyframe.atTick == Constants.minTick) if (keyframe.atTick == Constants.minTick)
{ value = Constants.minTick; return; } { value = Constants.minTick; return; }
foreach (Selectable linkedSlider in Selectable.allSelectablesArray) List<PawnKeyframe> keyframesToCheck = Workspace.Instance.GetPawnKeyframesAtTick(actorID, keyframe.atTick.Value);
if (keyframesToCheck.NotNullOrEmpty())
{ {
if (linkedSlider is KeyframeSlider) foreach (PawnKeyframe _keyframe in keyframesToCheck)
{ {
(linkedSlider as KeyframeSlider).linkedSlider = null; if (_keyframe != keyframe)
(linkedSlider as KeyframeSlider).pivotKeyframe = null; { AnimationController.Instance.RemovePawnKeyframe(actorID, _keyframe.keyframeID); }
}
}
foreach (Selectable selectable in Selectable.allSelectablesArray)
{
if (selectable is KeyframeSlider)
{
KeyframeSlider linkedSlider = selectable.GetComponent<KeyframeSlider>();
PawnKeyframe linkedKeyframe = linkedSlider.keyframe;
if (linkedSlider.linkedSlider != null)
{
keyframesToCheck = Workspace.Instance.GetPawnKeyframesAtTick(actorID, linkedKeyframe.atTick.Value);
if (keyframesToCheck.NotNullOrEmpty() && keyframesToCheck.Count > 1)
{
foreach (PawnKeyframe _keyframe in keyframesToCheck)
{
if (_keyframe.keyframeID != linkedKeyframe.keyframeID)
{ AnimationController.Instance.RemovePawnKeyframe(actorID, _keyframe.keyframeID); Debug.Log("delete"); }
}
}
}
linkedSlider.linkedSlider = null;
linkedSlider.pivotKeyframe = null;
} }
} }

View File

@ -8,26 +8,30 @@ using UnityEngine;
namespace RimWorldAnimationStudio namespace RimWorldAnimationStudio
{ {
public class KeybindConfig : Singleton<KeybindConfig> public class KeybindConfig
{ {
private static List<Keybind> keybinds = new List<Keybind>(); private static List<Keybind> keybinds = new List<Keybind>();
private static bool initialized = false;
public void Awake() public static void Initialize()
{ {
string path = Path.Combine(Application.streamingAssetsPath, "keybindConfig.xml"); string path = Path.Combine(Application.streamingAssetsPath, "keybindConfig.xml");
keybinds = XmlUtility.ReadXML<List<Keybind>>(path); keybinds = XmlUtility.ReadXML<List<Keybind>>(path);
initialized = true;
} }
public List<Keybind> GetAllKeybinds() public static List<Keybind> GetAllKeybinds()
{ {
if (initialized == false)
{ Initialize(); }
return keybinds; return keybinds;
} }
public string GetKeybindLabel(string command) public static string GetKeybindLabel(string command)
{ {
string label = ""; string label = "";
Keybind keybind = keybinds.FirstOrDefault(x => x.command == command); Keybind keybind = GetAllKeybinds()?.FirstOrDefault(x => x.command == command);
if (keybind == null) return label; if (keybind == null) return label;

View File

@ -44,7 +44,7 @@ namespace RimWorldAnimationStudio
private float playBackSpeed = 1f; private float playBackSpeed = 1f;
public void MakeDirty() public void MakeDirty()
{ isDirty = true; } { isDirty = true; isTimelineDirty = true; }
public void MakeTimelineDirty() public void MakeTimelineDirty()
{ isTimelineDirty = true; } { isTimelineDirty = true; }
@ -255,10 +255,11 @@ namespace RimWorldAnimationStudio
public void Reset() public void Reset()
{ {
Workspace.stageID = 0;
isAnimating = false; isAnimating = false;
timeSinceLastUpdate = 0; timeSinceLastUpdate = 0;
cycleIndex = 0; cycleIndex = 0;
MakeDirty();
} }
public void InitializeAnimationTimeline() public void InitializeAnimationTimeline()
@ -377,7 +378,7 @@ namespace RimWorldAnimationStudio
public void ClonePawnKeyframe() public void ClonePawnKeyframe()
{ {
List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID); List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframesByID(Workspace.keyframeID);
foreach (PawnKeyframe keyframe in keyframesToClone) foreach (PawnKeyframe keyframe in keyframesToClone)
{ {
@ -413,7 +414,7 @@ namespace RimWorldAnimationStudio
{ {
Workspace.copiedKeyframes.Clear(); Workspace.copiedKeyframes.Clear();
List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID); List<PawnKeyframe> keyframesToClone = Workspace.Instance.GetPawnKeyframesByID(Workspace.keyframeID);
foreach (PawnKeyframe keyframe in keyframesToClone) foreach (PawnKeyframe keyframe in keyframesToClone)
{ Workspace.copiedKeyframes.Add(keyframe.Copy()); } { Workspace.copiedKeyframes.Add(keyframe.Copy()); }

View File

@ -70,10 +70,9 @@ namespace RimWorldAnimationStudio
Workspace.animationDef = animationDef; Workspace.animationDef = animationDef;
animationDef.Initialize(); animationDef.Initialize();
Workspace.Instance.ClearHistory(); AnimationController.Instance.Reset();
Workspace.Instance.Reset();
Workspace.Instance.RecordEvent("AnimationDef loaded"); Workspace.Instance.RecordEvent("AnimationDef loaded");
AnimationController.Instance.MakeDirty();
} }
public void RunPostLoadOperations(AnimationDef animationDef) public void RunPostLoadOperations(AnimationDef animationDef)

View File

@ -61,7 +61,7 @@ namespace RimWorldAnimationStudio
bool canRepeatThisUpdate = CanRepeatThisUpdate(); bool canRepeatThisUpdate = CanRepeatThisUpdate();
// Check keybinds // Check keybinds
foreach (Keybind keybind in KeybindConfig.Instance.GetAllKeybinds()) foreach (Keybind keybind in KeybindConfig.GetAllKeybinds())
{ {
if (IsModifierKeyHeld() && keybind.keyModifiers.NullOrEmpty()) goto nextKeybind; if (IsModifierKeyHeld() && keybind.keyModifiers.NullOrEmpty()) goto nextKeybind;
@ -207,6 +207,12 @@ namespace RimWorldAnimationStudio
AnimationController.Instance.ToggleAnimation(); AnimationController.Instance.ToggleAnimation();
} }
public void AddKeyframe()
{
if (Workspace.animationDef == null) return;
AnimationController.Instance.AddPawnKeyframe();
}
public void CopyKeyframes() public void CopyKeyframes()
{ {
if (Workspace.animationDef == null) return; if (Workspace.animationDef == null) return;

View File

@ -14,6 +14,8 @@ namespace RimWorldAnimationStudio
public string message = "Undefined"; public string message = "Undefined";
public string executedCommand; public string executedCommand;
public float delay = 0f; public float delay = 0f;
public Vector2 offset = new Vector2(5f, -15f);
public bool flipX = false;
private GameObject tooltip; private GameObject tooltip;
private Text tooltipText; private Text tooltipText;
@ -33,12 +35,13 @@ namespace RimWorldAnimationStudio
if (isDisplayed == false) if (isDisplayed == false)
{ {
tooltip.GetComponent<RectTransform>().pivot = flipX ? new Vector2(1, 1) : new Vector2(0, 1);
tooltipText.text = message; tooltipText.text = message;
if (executedCommand != null && executedCommand != "") if (executedCommand != null && executedCommand != "")
{ tooltipText.text += " (" + KeybindConfig.Instance.GetKeybindLabel(executedCommand) + ")"; } { tooltipText.text += " (" + KeybindConfig.GetKeybindLabel(executedCommand) + ")"; }
tooltip.transform.position = (Vector2)transform.position + new Vector2(5f, -15f); tooltip.transform.position = (Vector2)transform.position + offset;
tooltip.gameObject.SetActive(true); tooltip.gameObject.SetActive(true);
LayoutRebuilder.ForceRebuildLayoutImmediate(tooltip.GetComponent<RectTransform>()); LayoutRebuilder.ForceRebuildLayoutImmediate(tooltip.GetComponent<RectTransform>());

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace RimWorldAnimationStudio namespace RimWorldAnimationStudio
{ {
[Serializable] [Serializable]
public class HistoricRecord public class WorkspaceRecord
{ {
public int recordID = 0; public int recordID = 0;
public string eventDesc; public string eventDesc;

View File

@ -14,7 +14,7 @@ namespace RimWorldAnimationStudio
public static List<int> keyframeID = new List<int>(); public static List<int> keyframeID = new List<int>();
[SerializeField] private List<HistoricRecord> workspaceHistory = new List<HistoricRecord>(); [SerializeField] private List<WorkspaceRecord> workspaceHistory = new List<WorkspaceRecord>();
[SerializeField] private int maxHistoryDepth = 100; [SerializeField] private int maxHistoryDepth = 100;
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan; public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
@ -53,6 +53,11 @@ namespace RimWorldAnimationStudio
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick); return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
} }
public List<PawnKeyframe> GetPawnKeyframesAtTick(int actorID, int atTick)
{
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.Where(x => x.atTick == atTick)?.ToList();
}
public PawnAnimationClip GetCurrentPawnAnimationClip() public PawnAnimationClip GetCurrentPawnAnimationClip()
{ {
return animationDef.animationStages[stageID].animationClips[actorID]; return animationDef.animationStages[stageID].animationClips[actorID];
@ -74,7 +79,7 @@ namespace RimWorldAnimationStudio
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID); return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
} }
public List<PawnKeyframe> GetPawnKeyframes(List<int> keyframeIDs) public List<PawnKeyframe> GetPawnKeyframesByID(List<int> keyframeIDs)
{ {
List<PawnKeyframe> pawnKeyframes = new List<PawnKeyframe>(); List<PawnKeyframe> pawnKeyframes = new List<PawnKeyframe>();
@ -203,12 +208,23 @@ namespace RimWorldAnimationStudio
} }
[SerializeField] [SerializeField]
public LinkedList<HistoricRecord> pastSnapshots = new LinkedList<HistoricRecord>(); public LinkedList<WorkspaceRecord> pastSnapshots = new LinkedList<WorkspaceRecord>();
public LinkedList<HistoricRecord> futureSnapshots = new LinkedList<HistoricRecord>(); public LinkedList<WorkspaceRecord> futureSnapshots = new LinkedList<WorkspaceRecord>();
public void Reset()
{
actorID = 0;
stageID = 0;
keyframeID.Clear();
selectedBodyPart = null;
ClearHistory();
}
public void MakeHistoricRecord(string eventDesc) public void MakeHistoricRecord(string eventDesc)
{ {
HistoricRecord record = new HistoricRecord(); WorkspaceRecord record = new WorkspaceRecord();
record.recordID = pastSnapshots.Count; record.recordID = pastSnapshots.Count;
record.eventDesc = eventDesc; record.eventDesc = eventDesc;
record.animationDef = animationDef.Copy(); record.animationDef = animationDef.Copy();
@ -221,7 +237,7 @@ namespace RimWorldAnimationStudio
{ pastSnapshots.RemoveFirst(); } { pastSnapshots.RemoveFirst(); }
} }
public void RestoreToHistoricRecord(HistoricRecord record) public void RestoreToHistoricRecord(WorkspaceRecord record)
{ {
animationDef = record.animationDef.Copy(); animationDef = record.animationDef.Copy();
stageID = record.stageID; stageID = record.stageID;
@ -232,8 +248,8 @@ namespace RimWorldAnimationStudio
public void Undo() public void Undo()
{ {
HistoricRecord recordToRead = pastSnapshots.Last?.Previous?.Value; WorkspaceRecord recordToRead = pastSnapshots.Last?.Previous?.Value;
HistoricRecord recordToStore = pastSnapshots.Last?.Value; WorkspaceRecord recordToStore = pastSnapshots.Last?.Value;
if (recordToRead == null || recordToStore == null) return; if (recordToRead == null || recordToStore == null) return;
@ -246,7 +262,7 @@ namespace RimWorldAnimationStudio
public void Redo() public void Redo()
{ {
HistoricRecord recordToReadAndStore = futureSnapshots.Last?.Value; WorkspaceRecord recordToReadAndStore = futureSnapshots.Last?.Value;
if (recordToReadAndStore == null) return; if (recordToReadAndStore == null) return;

View File

@ -131,6 +131,16 @@
</mac> </mac>
</Keybind> </Keybind>
<Keybind>
<command>AddKeyframe</command>
<win>
<keyCode>Insert</keyCode>
</win>
<mac>
<keyCode>Insert</keyCode>
</mac>
</Keybind>
<Keybind> <Keybind>
<command>CopyKeyframes</command> <command>CopyKeyframes</command>
<win> <win>
@ -162,34 +172,34 @@
<keyCode>X</keyCode> <keyCode>X</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>DeleteKeyframes</command> <command>DeleteKeyframes</command>
<win> <win>
<keyCode>Backspace</keyCode> <keyCode>Delete</keyCode>
</win> </win>
<mac> <mac>
<keyCode>Backspace</keyCode> <keyCode>Delete</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>DeleteKeyframes</command> <command>DeleteKeyframes</command>
<win> <win>
<keyCode>Delete</keyCode> <keyCode>Backspace</keyCode>
</win> </win>
<mac> <mac>
<keyCode>Delete</keyCode> <keyCode>Backspace</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>ActorMovementMode</command> <command>ActorMovementMode</command>
<win> <win>
<keyCode>M</keyCode> <keyCode>E</keyCode>
</win> </win>
<mac> <mac>
<keyCode>M</keyCode> <keyCode>E</keyCode>
</mac> </mac>
</Keybind> </Keybind>

View File

@ -131,6 +131,16 @@
</mac> </mac>
</Keybind> </Keybind>
<Keybind>
<command>AddKeyframe</command>
<win>
<keyCode>Insert</keyCode>
</win>
<mac>
<keyCode>Insert</keyCode>
</mac>
</Keybind>
<Keybind> <Keybind>
<command>CopyKeyframes</command> <command>CopyKeyframes</command>
<win> <win>
@ -162,34 +172,34 @@
<keyCode>X</keyCode> <keyCode>X</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>DeleteKeyframes</command> <command>DeleteKeyframes</command>
<win> <win>
<keyCode>Backspace</keyCode> <keyCode>Delete</keyCode>
</win> </win>
<mac> <mac>
<keyCode>Backspace</keyCode> <keyCode>Delete</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>DeleteKeyframes</command> <command>DeleteKeyframes</command>
<win> <win>
<keyCode>Delete</keyCode> <keyCode>Backspace</keyCode>
</win> </win>
<mac> <mac>
<keyCode>Delete</keyCode> <keyCode>Backspace</keyCode>
</mac> </mac>
</Keybind> </Keybind>
<Keybind> <Keybind>
<command>ActorMovementMode</command> <command>ActorMovementMode</command>
<win> <win>
<keyCode>M</keyCode> <keyCode>E</keyCode>
</win> </win>
<mac> <mac>
<keyCode>M</keyCode> <keyCode>E</keyCode>
</mac> </mac>
</Keybind> </Keybind>

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.

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

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.

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.

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.

Binary file not shown.

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