mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Key snapping
This commit is contained in:
parent
5436410162
commit
f275ed90ae
101 changed files with 253 additions and 117 deletions
|
@ -911,7 +911,7 @@ MonoBehaviour:
|
|||
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_CustomCaretColor: 0
|
||||
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
|
||||
m_Text: 1
|
||||
m_Text: 0
|
||||
m_CaretBlinkRate: 0.85
|
||||
m_CaretWidth: 1
|
||||
m_ReadOnly: 0
|
||||
|
@ -1649,8 +1649,8 @@ RectTransform:
|
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 439, y: -7.5}
|
||||
m_SizeDelta: {x: 878, y: 15}
|
||||
m_AnchoredPosition: {x: 305.5, y: -7.5}
|
||||
m_SizeDelta: {x: 611, y: 15}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &138865805
|
||||
MonoBehaviour:
|
||||
|
@ -16133,6 +16133,7 @@ GameObject:
|
|||
m_Component:
|
||||
- component: {fileID: 1289465654}
|
||||
- component: {fileID: 1289465655}
|
||||
- component: {fileID: 1289465656}
|
||||
m_Layer: 5
|
||||
m_Name: AnimTimelineSlider
|
||||
m_TagString: Untagged
|
||||
|
@ -16225,6 +16226,18 @@ MonoBehaviour:
|
|||
m_StringArgument:
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!114 &1289465656
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1289465653}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9b19816966eab6a4eba748f04532fb61, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &1293104865
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -19044,7 +19057,7 @@ MonoBehaviour:
|
|||
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_CustomCaretColor: 0
|
||||
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
|
||||
m_Text: 1
|
||||
m_Text: 0
|
||||
m_CaretBlinkRate: 0.85
|
||||
m_CaretWidth: 1
|
||||
m_ReadOnly: 0
|
||||
|
|
|
@ -128,6 +128,15 @@ namespace RimWorldAnimationStudio
|
|||
interactable = true;
|
||||
base.OnDrag(eventData);
|
||||
|
||||
int targetTick = Workspace.FindClosestKeyFrameAtTick(keyframe.atTick.Value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f), actorID);
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftShift) && Workspace.Instance.DoesPawnKeyframeExistAtTick(Workspace.stageID, actorID, targetTick) == false)
|
||||
{ value = (float)targetTick; }
|
||||
|
||||
// Prevent frames from being moved to tick 1
|
||||
if (value == 1)
|
||||
{ value = 2; }
|
||||
|
||||
//AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
||||
Workspace.actorID = actorID;
|
||||
}
|
||||
|
|
|
@ -95,8 +95,8 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
else
|
||||
{
|
||||
stageTick = Workspace.StageWindowSize;
|
||||
isAnimating = false;
|
||||
//stageTick = Workspace.StageWindowSize;
|
||||
//isAnimating = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
{ return; }
|
||||
|
||||
if (actorID >= Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips.Count)
|
||||
{ /*Debug.Log("Waiting for animation clip data to initialize...");*/ return; }
|
||||
{ return; }
|
||||
|
||||
Actor actor = Workspace.animationDef.actors[actorID];
|
||||
PawnAnimationClip clip = Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips[actorID];
|
||||
|
@ -146,6 +146,9 @@ namespace RimWorldAnimationStudio
|
|||
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
||||
if (stageTick == clip.duration) clipPercent = 1f;
|
||||
|
||||
if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false)
|
||||
{ clipPercent = (float)stageTick / clip.duration; }
|
||||
|
||||
AlienRaceDef alienRaceDef = actor.GetAlienRaceDef();
|
||||
ActorBody actorBody = _actorBodies[actorID];
|
||||
string bodyType = alienRaceDef.isHumanoid ? actor.bodyType : "None";
|
||||
|
@ -155,15 +158,6 @@ namespace RimWorldAnimationStudio
|
|||
float bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
|
||||
float headAngle = clip.HeadAngle.Evaluate(clipPercent);
|
||||
|
||||
/*if (bodyAngle < 0) bodyAngle = 360 - ((-1f * bodyAngle) % 360);
|
||||
if (bodyAngle > 360) bodyAngle %= 360;
|
||||
|
||||
if (headAngle < 0) headAngle = 360 - ((-1f * headAngle) % 360);
|
||||
if (headAngle > 360) headAngle %= 360;
|
||||
|
||||
bodyAngle = bodyAngle > 180 ? 180 - bodyAngle : bodyAngle;
|
||||
headAngle = headAngle > 180 ? 180 - headAngle : headAngle;*/
|
||||
|
||||
int bodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
|
||||
int headFacing = (int)clip.HeadFacing.Evaluate(clipPercent);
|
||||
|
||||
|
@ -233,7 +227,9 @@ namespace RimWorldAnimationStudio
|
|||
public void InitializeAnimationTimeline()
|
||||
{
|
||||
cyclesNormalField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks / Workspace.StageWindowSize), 1).ToString();
|
||||
cyclesFastField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick / Workspace.StageWindowSize), 1).ToString();
|
||||
cyclesFastField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick / Workspace.StageWindowSize), 0).ToString();
|
||||
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].isLooping = int.Parse(cyclesNormalField.text) > 1 ? true : false;
|
||||
|
||||
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
|
||||
{
|
||||
|
|
26
Assets/Scripts/SnapToKeyframe.cs
Normal file
26
Assets/Scripts/SnapToKeyframe.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class SnapToKeyframe : MonoBehaviour, IDragHandler
|
||||
{
|
||||
private Slider slider;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
slider = GetComponent<Slider>();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
int targetTick = Workspace.FindClosestKeyFrameAtTick((int)slider.value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f));
|
||||
|
||||
if (Input.GetKey(KeyCode.LeftShift))
|
||||
{ slider.value = (float)targetTick; }
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/SnapToKeyframe.cs.meta
Normal file
11
Assets/Scripts/SnapToKeyframe.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9b19816966eab6a4eba748f04532fb61
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -103,7 +103,77 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public bool DoesPawnKeyframeExistAtTick(int stageID, int actorID, int atTick)
|
||||
{
|
||||
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.Any(x => x.atTick == atTick);
|
||||
}
|
||||
|
||||
public static void FindAdjacentKeyframes(int atTick, out PawnKeyframe prevKeyframe, out PawnKeyframe nextKeyframe, int actorID = -1, int excludedActorID = -1, bool ignoreSelf = true, int searchDistance = int.MaxValue)
|
||||
{
|
||||
prevKeyframe = null;
|
||||
nextKeyframe = null;
|
||||
|
||||
List<PawnKeyframe> keyframesToCheck;
|
||||
|
||||
if (actorID >= 0)
|
||||
{ keyframesToCheck = animationDef.animationStages[stageID].animationClips[actorID].keyframes; }
|
||||
|
||||
else
|
||||
{
|
||||
keyframesToCheck = animationDef.animationStages[stageID].animationClips.Where(x =>
|
||||
animationDef.animationStages[stageID].animationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.keyframes)?.ToList();
|
||||
}
|
||||
|
||||
foreach (PawnKeyframe keyframe in keyframesToCheck)
|
||||
{
|
||||
if (keyframe.atTick <= atTick && atTick - keyframe.atTick <= searchDistance)
|
||||
{
|
||||
if (keyframe.atTick != atTick || ignoreSelf)
|
||||
{ prevKeyframe = keyframe; }
|
||||
|
||||
else
|
||||
{ prevKeyframe = null; }
|
||||
}
|
||||
|
||||
if (nextKeyframe == null && keyframe.atTick > atTick && keyframe.atTick - atTick <= searchDistance)
|
||||
{ nextKeyframe = keyframe; }
|
||||
}
|
||||
}
|
||||
|
||||
public static int FindClosestKeyFrameAtTick(int atTick, int searchDistance = int.MaxValue, int excludedActorID = -1)
|
||||
{
|
||||
List<PawnKeyframe> keyframesToCheck;
|
||||
|
||||
if (excludedActorID >= 0)
|
||||
{
|
||||
keyframesToCheck = animationDef.animationStages[stageID].animationClips.Where(x =>
|
||||
animationDef.animationStages[stageID].animationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.keyframes)?.ToList();
|
||||
}
|
||||
|
||||
else
|
||||
{ keyframesToCheck = animationDef.animationStages[stageID].animationClips.SelectMany(x => x.keyframes)?.ToList(); }
|
||||
|
||||
keyframesToCheck = keyframesToCheck.Where(x => Mathf.Abs(atTick - x.atTick.Value) <= searchDistance)?.ToList();
|
||||
|
||||
if (keyframesToCheck.NullOrEmpty())
|
||||
{ return atTick; }
|
||||
|
||||
int minDist = int.MaxValue;
|
||||
int bestAtTick = -1;
|
||||
|
||||
foreach (PawnKeyframe keyframe_ in keyframesToCheck)
|
||||
{
|
||||
if (Mathf.Abs(keyframe_.atTick.Value - atTick) < minDist)
|
||||
{
|
||||
minDist = Mathf.Abs(keyframe_.atTick.Value - atTick);
|
||||
bestAtTick = keyframe_.atTick.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return bestAtTick;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
public LinkedList<HistoricRecord> pastSnapshots = new LinkedList<HistoricRecord>();
|
||||
public LinkedList<HistoricRecord> futureSnapshots = new LinkedList<HistoricRecord>();
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<stageName>NewStage</stageName>
|
||||
<stageIndex>0</stageIndex>
|
||||
<playTimeTicks>600</playTimeTicks>
|
||||
<playTimeTicksQuick>-1</playTimeTicksQuick>
|
||||
<playTimeTicksQuick>600</playTimeTicksQuick>
|
||||
<isLooping>false</isLooping>
|
||||
<animationClips>
|
||||
<li Class="Rimworld_Animations.PawnAnimationClip">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue