mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Improved adding and removal of anim events
This commit is contained in:
parent
f0d46df3d6
commit
8523abf957
276 changed files with 1401 additions and 5422 deletions
|
@ -33,5 +33,26 @@ namespace RimWorldAnimationStudio
|
|||
public bool ShouldSerializecontrolGenitalAngle() { return controlGenitalAngle != null; }
|
||||
public bool ShouldSerializeisFucking() { return isFucking != null; }
|
||||
public bool ShouldSerializeisFucked() { return isFucked != null; }
|
||||
|
||||
public bool MakeNew()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{ Debug.LogWarning("Cannot make new actor - there is no AnimationDef"); return false; }
|
||||
|
||||
Workspace.animationDef.actors.Add(this);
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{
|
||||
PawnAnimationClip clip = new PawnAnimationClip();
|
||||
|
||||
if (clip.MakeNew())
|
||||
{
|
||||
stage.animationClips.Add(clip);
|
||||
stage.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace RimWorldAnimationStudio
|
|||
BodyFacing.Clear();
|
||||
HeadBob.Clear();
|
||||
GenitalAngle.Clear();
|
||||
SoundEffects.Clear();
|
||||
|
||||
int duration = 0;
|
||||
|
||||
|
@ -60,9 +59,6 @@ namespace RimWorldAnimationStudio
|
|||
if (keyframe.genitalAngle.HasValue)
|
||||
{ GenitalAngle.Add((float)keyframe.atTick / (float)duration, keyframe.genitalAngle.Value, true); }
|
||||
|
||||
if (keyframe.soundEffect != null)
|
||||
{ SoundEffects.Add((int)keyframe.atTick, keyframe.soundEffect); }
|
||||
|
||||
if (i + 1 < keyframes.Count)
|
||||
{ keyframes[i].tickDuration = keyframes[i + 1].atTick.Value - keyframes[i].atTick.Value; }
|
||||
}
|
||||
|
@ -78,10 +74,7 @@ namespace RimWorldAnimationStudio
|
|||
HeadBob.Add((float)keyframePosition / (float)duration, keyframe.headBob, true);
|
||||
|
||||
if (keyframe.genitalAngle.HasValue)
|
||||
GenitalAngle.Add((float)keyframePosition / (float)duration, keyframe.genitalAngle.Value, true);
|
||||
|
||||
if (keyframe.soundEffect != null)
|
||||
{ SoundEffects.Add(keyframePosition, keyframe.soundEffect); }
|
||||
{ GenitalAngle.Add((float)keyframePosition / (float)duration, keyframe.genitalAngle.Value, true); }
|
||||
|
||||
if (keyframe.tickDuration != 1 && keyframe.quiver.HasValue)
|
||||
{
|
||||
|
@ -96,5 +89,19 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
keyframes[keyframes.Count - 1].tickDuration = 1;
|
||||
}
|
||||
|
||||
public bool MakeNew()
|
||||
{
|
||||
PawnKeyframe keyframeA = new PawnKeyframe();
|
||||
keyframeA.tickDuration = 60;
|
||||
keyframes.Add(keyframeA);
|
||||
|
||||
PawnKeyframe keyframeB = new PawnKeyframe();
|
||||
keyframes.Add(keyframeB);
|
||||
|
||||
BuildSimpleCurves();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationStage
|
||||
{
|
||||
public string stageName = "default";
|
||||
public string stageName = "NewStage";
|
||||
public int stageIndex = 0;
|
||||
public int playTimeTicks = 0;
|
||||
public int playTimeTicksQuick = -1;
|
||||
public bool isLooping = true;
|
||||
public bool isLooping = false;
|
||||
|
||||
[XmlArray("animationClips"), XmlArrayItem("li")]
|
||||
public List<PawnAnimationClip> animationClips = new List<PawnAnimationClip>();
|
||||
|
@ -26,5 +27,25 @@ namespace RimWorldAnimationStudio
|
|||
{ playTimeTicks = clip.duration; }
|
||||
}
|
||||
}
|
||||
|
||||
public bool MakeNew()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{ Debug.LogWarning("Cannot make new animation stage - there is no AnimationDef"); return false; }
|
||||
|
||||
foreach(Actor actor in Workspace.animationDef.actors)
|
||||
{
|
||||
PawnAnimationClip clip = new PawnAnimationClip();
|
||||
|
||||
if (clip.MakeNew())
|
||||
{ animationClips.Add(clip); }
|
||||
}
|
||||
|
||||
Initialize();
|
||||
|
||||
Workspace.animationDef.animationStages.Add(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace RimWorldAnimationStudio
|
|||
public class ActorBody : MonoBehaviour, IPointerClickHandler, IDragHandler
|
||||
{
|
||||
public int actorID;
|
||||
public string bodyType = "Male";
|
||||
|
||||
public SpriteRenderer bodyRenderer;
|
||||
public SpriteRenderer headRenderer;
|
||||
|
@ -22,8 +23,51 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBody>() == null)
|
||||
{ return; }
|
||||
|
||||
foreach (ActorBody actorBody in AnimationController.Instance.actorBodies)
|
||||
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Activate();
|
||||
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe();
|
||||
|
||||
if (Workspace.Instance.GetCurrentPawnKeyframe() == null)
|
||||
{ Debug.LogWarning("Cannot alter actor - no keyframe data available"); return; }
|
||||
|
||||
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
keyframe.bodyOffsetX = mousePosition.x;
|
||||
keyframe.bodyOffsetZ = mousePosition.y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
keyframe.bodyAngle = angle;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
int facing = -Mathf.RoundToInt(angle / 90f );
|
||||
facing = facing < 0 ? facing + 4 : facing;
|
||||
|
||||
keyframe.bodyFacing = facing;
|
||||
}
|
||||
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Workspace.actorID = actorID;
|
||||
|
||||
foreach (ActorBody actorBody in AnimationController.Instance.GetComponentsInChildren<ActorBody>())
|
||||
{
|
||||
if (actorBody == this)
|
||||
{ continue; }
|
||||
|
@ -34,40 +78,6 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
bodyRenderer.color = new Color(0f, 1f, 0f);
|
||||
headRenderer.color = new Color(0f, 1f, 0f);
|
||||
|
||||
Workspace.actorID = actorID;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
|
||||
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
|
||||
{
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == Workspace.keyframeID).bodyOffsetX = mousePosition.x;
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == Workspace.keyframeID).bodyOffsetZ = mousePosition.y;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == Workspace.keyframeID).bodyAngle = angle;
|
||||
}
|
||||
|
||||
else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
|
||||
{
|
||||
float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
|
||||
int facing = -Mathf.RoundToInt(angle / 90f );
|
||||
facing = facing < 0 ? facing + 4 : facing;
|
||||
|
||||
Debug.Log(facing.ToString());
|
||||
|
||||
Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == Workspace.keyframeID).bodyFacing = facing;
|
||||
}
|
||||
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,17 +16,13 @@ namespace RimWorldAnimationStudio
|
|||
if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>() == null)
|
||||
{ return; }
|
||||
|
||||
foreach (ActorBody actorBody in AnimationController.Instance.actorBodies)
|
||||
{
|
||||
actorBody.bodyRenderer.color = new Color(1f, 1f, 1f);
|
||||
actorBody.headRenderer.color = new Color(1f, 1f, 1f);
|
||||
}
|
||||
|
||||
bodyPartRenderer.color = new Color(0f, 1f, 0f);
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
Activate();
|
||||
|
||||
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
PawnKeyframe keyframe = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[parent.actorID].keyframes.FirstOrDefault(x => x.keyframeID == Workspace.keyframeID);
|
||||
|
||||
|
@ -63,5 +59,18 @@ namespace RimWorldAnimationStudio
|
|||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(parent.actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
Workspace.actorID = parent.actorID;
|
||||
|
||||
foreach (ActorBody actorBody in AnimationController.Instance.GetComponentsInChildren<ActorBody>())
|
||||
{
|
||||
actorBody.bodyRenderer.color = new Color(1f, 1f, 1f);
|
||||
actorBody.headRenderer.color = new Color(1f, 1f, 1f);
|
||||
}
|
||||
|
||||
bodyPartRenderer.color = new Color(0f, 1f, 0f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,22 +13,11 @@ namespace RimWorldAnimationStudio
|
|||
public InputField bodyOffsetZField;
|
||||
public Toggle initiatorToggle;
|
||||
|
||||
private Actor actor;
|
||||
|
||||
public string bodyType
|
||||
{
|
||||
get
|
||||
{
|
||||
string _bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text;
|
||||
if (_bodyType == "") return "Male";
|
||||
|
||||
return _bodyType;
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(Actor actor)
|
||||
public void Initialize()
|
||||
{
|
||||
this.actor = actor;
|
||||
Actor actor = Workspace.animationDef.actors[Workspace.actorID];
|
||||
string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text;
|
||||
bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType;
|
||||
|
||||
initiatorToggle.isOn = actor.initiator;
|
||||
bodyOffsetXField.text = actor.bodyTypeOffset.GetOffset(bodyType).x.ToString();
|
||||
|
@ -37,18 +26,23 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void UpdateAnimationDef()
|
||||
{
|
||||
Actor actor = Workspace.animationDef.actors[Workspace.actorID];
|
||||
|
||||
string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text;
|
||||
bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType;
|
||||
Debug.Log(bodyType);
|
||||
AnimationController.Instance.transform.GetChild(Workspace.actorID).GetComponent<ActorBody>().bodyType = bodyType;
|
||||
|
||||
float.TryParse(bodyOffsetXField.text, out float x);
|
||||
float.TryParse(bodyOffsetZField.text, out float z);
|
||||
|
||||
actor.bodyTypeOffset.SetOffset(bodyType, new Vector2(x, z));
|
||||
actor.initiator = initiatorToggle.isOn;
|
||||
|
||||
if (actor.isFucking == null)
|
||||
{ }
|
||||
actor.initiator = initiatorToggle.isOn;
|
||||
}
|
||||
|
||||
public void OpenSelectBodyPartsDialog()
|
||||
{
|
||||
Actor actor = Workspace.animationDef.actors[Workspace.actorID];
|
||||
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectBodyPartsDialog)) as SelectBodyPartsDialog[];
|
||||
|
||||
if (dialog != null)
|
||||
|
@ -57,6 +51,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void OpenSelectDefNamesDialog()
|
||||
{
|
||||
Actor actor = Workspace.animationDef.actors[Workspace.actorID];
|
||||
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectDefNamesDialog)) as SelectDefNamesDialog[];
|
||||
|
||||
if (dialog != null)
|
||||
|
@ -65,6 +60,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void OpenSelectBodyDefTypesDialog()
|
||||
{
|
||||
Actor actor = Workspace.animationDef.actors[Workspace.actorID];
|
||||
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectBodyDefTypesDialog)) as SelectBodyDefTypesDialog[];
|
||||
|
||||
if (dialog != null)
|
|
@ -20,8 +20,11 @@ namespace RimWorldAnimationStudio
|
|||
if ((Workspace.animationDef == null || AnimationController.Instance.stageTick == lastTick) && isDirty == false)
|
||||
{ return; }
|
||||
|
||||
ActorBody actorBody = AnimationController.Instance.actorBodies[Workspace.actorID];
|
||||
string bodyType = AnimationController.Instance.actorCards.transform.GetChild(Workspace.actorID).GetComponent<ActorCard>().bodyType;
|
||||
if (Workspace.actorID >= AnimationController.Instance.transform.childCount)
|
||||
{ return; }
|
||||
|
||||
ActorBody actorBody = AnimationController.Instance.transform.GetChild(Workspace.actorID).GetComponent<ActorBody>();
|
||||
string bodyType = actorBody.bodyType;
|
||||
|
||||
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[Workspace.actorID];
|
||||
float clipPercent = (float)(AnimationController.Instance.stageTick % clip.duration) / clip.duration;
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
this.actorID = actorID;
|
||||
|
||||
Reset();
|
||||
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
|
||||
if (clip == null || clip.keyframes.NullOrEmpty())
|
||||
|
@ -35,22 +37,22 @@ namespace RimWorldAnimationStudio
|
|||
}
|
||||
}
|
||||
|
||||
public void AddKeyFrame(int atTick)
|
||||
public void Reset()
|
||||
{
|
||||
|
||||
foreach(KeyframeSlider keyframeSlider in GetComponentsInChildren<KeyframeSlider>())
|
||||
{ Destroy(keyframeSlider.gameObject); }
|
||||
}
|
||||
|
||||
public bool CanAddKeyFrameAtTick(int atTick)
|
||||
public void AddPawnKeyFrame(int keyframeID)
|
||||
{
|
||||
foreach (Transform child in transform)
|
||||
{
|
||||
KeyframeSlider keyframeSlider = child.GetComponent<KeyframeSlider>();
|
||||
KeyframeSlider keyframeSlider = Instantiate(keyframeSliderPrefab, transform);
|
||||
keyframeSlider.Initialize(this, actorID, keyframeID);
|
||||
}
|
||||
|
||||
if (keyframeSlider != null && Workspace.Instance.GetPawnKeyframe(keyframeSlider.actorID, keyframeSlider.keyframeID).atTick == atTick)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
public void RemovePawnKeyFrame(int keyframeID)
|
||||
{
|
||||
KeyframeSlider keyframeSlider = GetComponentsInChildren<KeyframeSlider>().FirstOrDefault(x => x.keyframeID == keyframeID);
|
||||
Destroy(keyframeSlider?.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,6 @@ namespace RimWorldAnimationStudio
|
|||
public class KeyframeSlider : Slider, IPointerClickHandler, IBeginDragHandler, IEndDragHandler
|
||||
{
|
||||
public AnimationTimeline timeline;
|
||||
//public AnimationClip clip;
|
||||
//public Keyframe keyframe;
|
||||
|
||||
public Transform ghostSliders;
|
||||
public Slider ghostSliderPrefab;
|
||||
public int maxGhosts = 4;
|
||||
|
@ -22,18 +19,22 @@ namespace RimWorldAnimationStudio
|
|||
public int actorID;
|
||||
public int keyframeID;
|
||||
|
||||
private PawnAnimationClip clip;
|
||||
private PawnKeyframe keyframe;
|
||||
|
||||
public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID)
|
||||
{
|
||||
this.timeline = timeline;
|
||||
//this.clip = clip;
|
||||
//this.keyframe = keyframe;
|
||||
this.clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
this.keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
|
||||
this.actorID = actorID;
|
||||
this.keyframeID = keyframeID;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
Debug.Log(keyframe.atTick);
|
||||
value = (float)keyframe.atTick / Workspace.animationClipWindowSize;
|
||||
maxValue = Workspace.animationClipWindowSize;
|
||||
value = keyframe.atTick.Value;
|
||||
|
||||
OnValueChanged();
|
||||
|
||||
onValueChanged.AddListener(delegate (float value) { OnValueChanged(); });
|
||||
|
@ -41,12 +42,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void OnValueChanged()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
|
||||
int newTick = Mathf.RoundToInt(value * Workspace.animationClipWindowSize);
|
||||
|
||||
keyframe.atTick = newTick;
|
||||
keyframe.atTick = (int)value;
|
||||
|
||||
UpdateGhostFrames();
|
||||
|
||||
|
@ -58,9 +54,6 @@ namespace RimWorldAnimationStudio
|
|||
// Ghost sliders are non-interactable slider handle
|
||||
public void UpdateGhostFrames()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
|
||||
if (maxGhosts == 0)
|
||||
{ return; }
|
||||
|
||||
|
@ -79,7 +72,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
Slider ghostSlider = ghostSliderObject.GetComponent<Slider>();
|
||||
Debug.Log(ghostSlider);
|
||||
ghostSlider.value = (float)((i + 1) * clip.duration + keyframe.atTick) / Workspace.animationClipWindowSize;
|
||||
ghostSlider.value = (int)((i + 1) * clip.duration + keyframe.atTick);
|
||||
|
||||
float mult = 1f - Mathf.Pow((float)i / maxGhosts, 2);
|
||||
ghostSlider.transform.FindDeepChild("Handle").GetComponent<Image>().color = new Color(0, 0.5f, 0.5f, 0.5f * mult);
|
||||
|
@ -92,8 +85,6 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public int GetGhostFramesRequired()
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
|
||||
|
||||
if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false)
|
||||
{ return 0; }
|
||||
|
||||
|
@ -105,31 +96,48 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID);
|
||||
|
||||
foreach (KeyframeSlider keyframeSlider in timeline.transform.GetComponentsInChildren<KeyframeSlider>())
|
||||
{
|
||||
if (keyframeSlider == this)
|
||||
{ continue; }
|
||||
|
||||
keyframeSlider.transform.FindDeepChild("Handle").GetComponent<Image>().color = new Color(1f, 1f, 1f);
|
||||
}
|
||||
|
||||
transform.FindDeepChild("Handle").GetComponent<Image>().color = new Color(0f, 1f, 0f);
|
||||
|
||||
AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
||||
|
||||
Workspace.keyframeID = keyframeID;
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
Activate();
|
||||
|
||||
if (keyframe.atTick == 1)
|
||||
{ return; }
|
||||
|
||||
interactable = true;
|
||||
}
|
||||
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
base.OnDrag(eventData);
|
||||
|
||||
Activate();
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
interactable = false;
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
||||
|
||||
Workspace.keyframeID = keyframeID;
|
||||
|
||||
foreach (AnimationTimeline _timeline in AnimationController.Instance.animationTimelines.GetComponentsInChildren<AnimationTimeline>())
|
||||
{
|
||||
foreach (KeyframeSlider keyframeSlider in _timeline.GetComponentsInChildren<KeyframeSlider>())
|
||||
{
|
||||
if (keyframeSlider.keyframe.atTick.Value == keyframe.atTick.Value)
|
||||
{ keyframeSlider.transform.FindDeepChild("Handle").GetComponent<Image>().color = new Color(0f, 1f, 0f); }
|
||||
|
||||
else
|
||||
{ keyframeSlider.transform.FindDeepChild("Handle").GetComponent<Image>().color = new Color(1f, 1f, 1f); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,20 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageCard : MonoBehaviour
|
||||
public class StageCard : MonoBehaviour, IPointerClickHandler
|
||||
{
|
||||
private Text stageName;
|
||||
private InputField stageNameField;
|
||||
private Image banner;
|
||||
private Toggle toggle;
|
||||
|
||||
public void OnNameChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnSelectStage()
|
||||
{
|
||||
if (GetComponent<Toggle>().isOn && Workspace.stageID != transform.GetSiblingIndex())
|
||||
{ Workspace.stageID = transform.GetSiblingIndex(); }
|
||||
stageName.text = stageNameField.text;
|
||||
stageNameField.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void OnMoveStage(int delta)
|
||||
|
@ -32,30 +29,39 @@ namespace RimWorldAnimationStudio
|
|||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
public void Initialize(string stageName)
|
||||
{
|
||||
banner = transform.Find("Banner").GetComponent<Image>();
|
||||
toggle = GetComponent<Toggle>();
|
||||
toggle.group = StageCardManager.Instance.GetComponent<ToggleGroup>();
|
||||
this.stageName = transform.Find("StageName").GetComponent<Text>();
|
||||
this.stageNameField = transform.Find("StageNameField").GetComponent<InputField>();
|
||||
this.banner = transform.Find("Banner").GetComponent<Image>();
|
||||
|
||||
this.stageName.text = stageName;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Workspace.stageID == transform.GetSiblingIndex())
|
||||
{
|
||||
banner.gameObject.SetActive(true);
|
||||
|
||||
if (toggle.isOn == false)
|
||||
{ toggle.isOn = true; }
|
||||
}
|
||||
{ banner.gameObject.SetActive(true); }
|
||||
|
||||
else
|
||||
{
|
||||
banner.gameObject.SetActive(false);
|
||||
|
||||
if (toggle.isOn)
|
||||
{ toggle.isOn = false; }
|
||||
stageNameField.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
if (eventData.clickCount >= 2)
|
||||
{
|
||||
stageNameField.text = stageName.text;
|
||||
stageNameField.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
Workspace.stageID = transform.GetSiblingIndex();
|
||||
|
||||
AnimationController.Instance.ResetAnimationTimeline();
|
||||
AnimationController.Instance.InitializeAnimationTimeline();
|
||||
}
|
||||
}
|
||||
}
|
8
Assets/Scripts/Managers.meta
Normal file
8
Assets/Scripts/Managers.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5d9672c420dae5b4095d933223c39cd5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -12,35 +12,28 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
public class AnimationController : Singleton<AnimationController>
|
||||
{
|
||||
[Header("Animation settings")]
|
||||
public bool isAnimating = false;
|
||||
public bool isLooping = true;
|
||||
public int stageTick = 0;
|
||||
|
||||
public bool autoAdvanceToNextStage = false;
|
||||
public int stageTick = 1;
|
||||
|
||||
[Header("Object references")]
|
||||
public Slider stageTimelineSlider;
|
||||
|
||||
public GameObject actorBodyPrefab;
|
||||
public List<ActorBody> actorBodies = new List<ActorBody>();
|
||||
|
||||
public Text stageTickText;
|
||||
public Text stageLengthText;
|
||||
|
||||
public Transform actorCards;
|
||||
public GameObject actorCardPrefab;
|
||||
|
||||
public Dropdown stageLoopDropdown;
|
||||
public InputField stageIDField;
|
||||
|
||||
public Transform animationTimelines;
|
||||
public AnimationTimeline animationTimelinePrefab;
|
||||
|
||||
private float currentTime = 0;
|
||||
private int cycleIndex = 0;
|
||||
|
||||
public InputField cyclesNormalField;
|
||||
public InputField cyclesFastField;
|
||||
public Text stageTickText;
|
||||
public Text stageLengthText;
|
||||
public ActorCard actorCard;
|
||||
public Transform animationTimelines;
|
||||
|
||||
[Header("Prefabs")]
|
||||
public ActorBody actorBodyPrefab;
|
||||
public AnimationTimeline animationTimelinePrefab;
|
||||
|
||||
// Private timing variables
|
||||
private float timeSinceLastUpdate = 0;
|
||||
private int cycleIndex = 0;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// No animation, exit
|
||||
|
@ -50,61 +43,65 @@ namespace RimWorldAnimationStudio
|
|||
if (Workspace.animationDef != null && Workspace.isDirty)
|
||||
{ Initialize(); return; }
|
||||
|
||||
// Not animating, update preview
|
||||
if (isAnimating == false) { UpdateAnimation(); return; }
|
||||
// Update tick if animating
|
||||
if (isAnimating)
|
||||
{
|
||||
timeSinceLastUpdate += Time.deltaTime;
|
||||
|
||||
// Animating, update stage tick before updating preview
|
||||
currentTime += Time.deltaTime;
|
||||
if (timeSinceLastUpdate < 1f / 60f)
|
||||
{ return; }
|
||||
|
||||
if (currentTime < 1f/60f)
|
||||
{ return; }
|
||||
timeSinceLastUpdate -= 1f / 60f;
|
||||
stageTick += 1;
|
||||
|
||||
currentTime -= 1f/60f;
|
||||
stageTick += 1;
|
||||
|
||||
if (stageTick > Workspace.animationClipWindowSize)
|
||||
{
|
||||
if (stageLoopDropdown.value == 1)
|
||||
{ stageTick = 1; }
|
||||
|
||||
else if (stageLoopDropdown.value == 2 && Workspace.stageID < Workspace.animationDef.animationStages.Count - 1)
|
||||
if (stageTick > Workspace.animationClipWindowSize)
|
||||
{
|
||||
++cycleIndex;
|
||||
stageTick = 1;
|
||||
if (stageLoopDropdown.value == 1)
|
||||
{ stageTick = 1; }
|
||||
|
||||
if (cycleIndex > int.Parse(cyclesNormalField.text))
|
||||
else if (stageLoopDropdown.value == 2 && Workspace.stageID < Workspace.animationDef.animationStages.Count - 1)
|
||||
{
|
||||
++Workspace.stageID;
|
||||
stageIDField.text = Workspace.stageID.ToString();
|
||||
cycleIndex = 0;
|
||||
}
|
||||
}
|
||||
++cycleIndex;
|
||||
stageTick = 1;
|
||||
|
||||
else
|
||||
{ stageTick = Workspace.animationClipWindowSize; }
|
||||
if (cycleIndex > int.Parse(cyclesNormalField.text))
|
||||
{
|
||||
++Workspace.stageID;
|
||||
cycleIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{ stageTick = Workspace.animationClipWindowSize; }
|
||||
}
|
||||
}
|
||||
|
||||
// Update stage timeline
|
||||
stageTimelineSlider.maxValue = Workspace.animationClipWindowSize;
|
||||
stageTimelineSlider.value = stageTick;
|
||||
stageTickText.text = stageTick.ToString();
|
||||
stageLengthText.text = Workspace.animationClipWindowSize.ToString();
|
||||
|
||||
// Update animation
|
||||
UpdateAnimation();
|
||||
}
|
||||
|
||||
public void UpdateAnimation()
|
||||
{
|
||||
if (stageTickText != null)
|
||||
{ stageTickText.text = stageTick.ToString(); }
|
||||
if (stageLengthText != null)
|
||||
{ stageLengthText.text = Workspace.animationClipWindowSize.ToString(); }
|
||||
List<ActorBody> actorBodies = GetComponentsInChildren<ActorBody>().ToList();
|
||||
|
||||
for (int actorID = 0; actorID < actorBodies.Count; actorID++)
|
||||
{
|
||||
ActorBody actorBody = actorBodies[actorID];
|
||||
string bodyType = actorCards.transform.GetChild(actorID).GetComponent<ActorCard>().bodyType;
|
||||
PawnAnimationClip clip = Workspace.animationDef?.animationStages[Workspace.stageID]?.animationClips[actorID];
|
||||
|
||||
if (clip == null)
|
||||
{ continue; }
|
||||
|
||||
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID];
|
||||
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
||||
|
||||
ActorBody actorBody = actorBodies[actorID];
|
||||
string bodyType = actorBody.bodyType;
|
||||
|
||||
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
|
||||
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
|
||||
|
||||
|
@ -140,75 +137,64 @@ namespace RimWorldAnimationStudio
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void UpdateStageID()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{
|
||||
stageIDField.text = "0";
|
||||
return;
|
||||
}
|
||||
|
||||
int.TryParse(stageIDField.text, out int i);
|
||||
Workspace.stageID = Mathf.Clamp(i, 0, Workspace.animationDef.animationStages.Count - 1);
|
||||
stageTick = 0;
|
||||
|
||||
stageIDField.text = Workspace.stageID.ToString();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Debug.Log("Initializing animation preview");
|
||||
|
||||
Reset();
|
||||
|
||||
Workspace.animationClipWindowSize = Workspace.animationDef.animationStages[Workspace.stageID].animationClips.Select(x => x.duration).Max();
|
||||
stageTimelineSlider.maxValue = Workspace.animationClipWindowSize;
|
||||
InitializeAnimationTimeline();
|
||||
StageCardManager.Instance.Initialize();
|
||||
|
||||
Workspace.isDirty = false;
|
||||
}
|
||||
|
||||
public void InitializeAnimationTimeline()
|
||||
{
|
||||
Workspace.animationClipWindowSize = Workspace.animationDef.animationStages[Workspace.stageID].animationClips.Select(x => x.duration).Max();
|
||||
|
||||
cyclesNormalField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks / Workspace.animationClipWindowSize), 1).ToString();
|
||||
cyclesFastField.text = Mathf.Max(Mathf.CeilToInt((float)Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicksQuick / Workspace.animationClipWindowSize), 1).ToString();
|
||||
|
||||
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
|
||||
{
|
||||
GameObject actorBodyObject = Instantiate(actorBodyPrefab, transform);
|
||||
actorBodies.Add(actorBodyObject.GetComponent<ActorBody>());
|
||||
actorBodyObject.GetComponent<ActorBody>().Initialize(actorID);
|
||||
|
||||
GameObject actorCardObject = Instantiate(actorCardPrefab, actorCards);
|
||||
actorCardObject.GetComponent<ActorCard>().Initialize(Workspace.animationDef.actors[actorID]);
|
||||
ActorBody actorBody = Instantiate(actorBodyPrefab, transform);
|
||||
actorBody.Initialize(actorID);
|
||||
|
||||
AnimationTimeline animationTimeline = Instantiate(animationTimelinePrefab, animationTimelines);
|
||||
animationTimeline.Initialize(actorID);
|
||||
}
|
||||
|
||||
StageCardManager.Instance.Initialize();
|
||||
|
||||
Workspace.isDirty = false;
|
||||
|
||||
UpdateAnimation();
|
||||
stageTimelineSlider.maxValue = Workspace.animationClipWindowSize;
|
||||
stageTimelineSlider.value = 1;
|
||||
stageTick = 1;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Workspace.stageID = 0;
|
||||
stageTick = 0;
|
||||
|
||||
ResetAnimationTimeline();
|
||||
StageCardManager.Instance.Reset();
|
||||
}
|
||||
|
||||
public void ResetAnimationTimeline()
|
||||
{
|
||||
isAnimating = false;
|
||||
timeSinceLastUpdate = 0;
|
||||
cycleIndex = 0;
|
||||
|
||||
foreach (ActorBody actorBody in actorBodies)
|
||||
foreach (ActorBody actorBody in GetComponentsInChildren<ActorBody>())
|
||||
{ Destroy(actorBody.gameObject); }
|
||||
|
||||
foreach (Transform actorCard in actorCards)
|
||||
{ Destroy(actorCard.gameObject); }
|
||||
|
||||
foreach (Transform animationTimeline in animationTimelines)
|
||||
{ Destroy(animationTimeline.gameObject); }
|
||||
|
||||
actorBodies.Clear();
|
||||
}
|
||||
|
||||
public bool AddAnimationStage()
|
||||
{
|
||||
return true;
|
||||
AnimationStage stage = new AnimationStage();
|
||||
|
||||
return stage.MakeNew();
|
||||
}
|
||||
|
||||
public bool CloneAnimationStage()
|
||||
|
@ -248,17 +234,20 @@ namespace RimWorldAnimationStudio
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool AddActor()
|
||||
public void AddActor()
|
||||
{
|
||||
return true;
|
||||
Actor actor = new Actor();
|
||||
|
||||
if (actor.MakeNew())
|
||||
{ Initialize(); }
|
||||
}
|
||||
|
||||
public bool RemoveActor()
|
||||
public void RemoveActor()
|
||||
{
|
||||
if (Workspace.animationDef.actors.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("Cannot delete actor - the animation must contain at least one actor.");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
|
@ -267,21 +256,66 @@ namespace RimWorldAnimationStudio
|
|||
Workspace.animationDef.actors.RemoveAt(Workspace.actorID);
|
||||
Workspace.actorID = Workspace.actorID >= Workspace.animationDef.actors.Count ? Workspace.actorID = Workspace.animationDef.actors.Count - 1 : Workspace.actorID;
|
||||
|
||||
return true;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
|
||||
public void AddPawnKeyframe()
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
|
||||
List<PawnKeyframe> keyframes = clip?.keyframes;
|
||||
|
||||
if (clip == null || keyframes == null)
|
||||
{ Debug.LogWarning("Cannot add pawn keyframe - the AnimationDef is invalid"); return; }
|
||||
|
||||
if (keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
|
||||
{ Debug.LogWarning("Cannot add pawn keyframe - a keyframe already exists at this tick"); return; }
|
||||
|
||||
float clipPercent = (float)(stageTick % clip.duration) / clip.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 = clip.HeadFacing.Evaluate(clipPercent);
|
||||
keyframe.bodyFacing = clip.BodyFacing.Evaluate(clipPercent);
|
||||
keyframe.genitalAngle = clip.GenitalAngle.Evaluate(clipPercent);
|
||||
|
||||
keyframe.atTick = stageTick;
|
||||
|
||||
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > stageTick);
|
||||
|
||||
if (nextKeyframe != null)
|
||||
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), keyframe); }
|
||||
|
||||
else
|
||||
{ keyframes.Add(keyframe); }
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
animationTimelines.GetChild(Workspace.actorID).GetComponent<AnimationTimeline>().AddPawnKeyFrame(keyframe.keyframeID);
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe()
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(false);
|
||||
|
||||
if (keyframe != null)
|
||||
{
|
||||
animationTimelines.GetChild(Workspace.actorID).GetComponent<AnimationTimeline>().RemovePawnKeyFrame(keyframe.keyframeID);
|
||||
|
||||
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
|
||||
clip.keyframes.Remove(keyframe);
|
||||
clip.BuildSimpleCurves();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleAnimation()
|
||||
{
|
||||
isAnimating = !isAnimating;
|
||||
}
|
||||
|
||||
public void ToggleAnimationLoop()
|
||||
{
|
||||
isLooping = !isLooping;
|
||||
}
|
||||
|
||||
public void UpdateFromStageTimelineSlider()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
|
@ -49,9 +49,6 @@ namespace RimWorldAnimationStudio
|
|||
curZoom += Input.GetAxis("Mouse ScrollWheel") * scrollSpeed * 0.1f;
|
||||
curZoom = Mathf.Clamp(curZoom, maxZoom, minZoom);
|
||||
|
||||
x = transform.position.x + Input.GetAxis("Horizontal") * scrollSpeed * Time.deltaTime;
|
||||
y = transform.position.y + Input.GetAxis("Vertical") * scrollSpeed * Time.deltaTime;
|
||||
|
||||
Vector3 cameraPosition = Vector3.Lerp(transform.position, new Vector3(x, y, -10), 0.2f);
|
||||
transform.position = cameraPosition;
|
||||
cam.orthographicSize = Mathf.Abs(curZoom);
|
|
@ -12,9 +12,13 @@ namespace RimWorldAnimationStudio
|
|||
public void Initialize()
|
||||
{
|
||||
foreach(AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{
|
||||
MakeStageCard(stage.stageName);
|
||||
}
|
||||
{ MakeStageCard(stage.stageName); }
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach(StageCard stageCard in GetComponentsInChildren<StageCard>())
|
||||
{ Destroy(stageCard.gameObject); }
|
||||
}
|
||||
|
||||
public StageCard MakeStageCard(string stageName = null)
|
||||
|
@ -22,14 +26,15 @@ namespace RimWorldAnimationStudio
|
|||
StageCard stageCard = Instantiate(stageCardPrefab, transform);
|
||||
|
||||
if (stageName != null)
|
||||
{ stageCard.transform.Find("StageNameField").GetComponent<InputField>().text = stageName; }
|
||||
{ stageCard.Initialize(stageName); }
|
||||
|
||||
return stageCard;
|
||||
}
|
||||
|
||||
public void OnNewStage()
|
||||
{
|
||||
MakeStageCard();
|
||||
if (AnimationController.Instance.AddAnimationStage())
|
||||
{ MakeStageCard("NewStage"); }
|
||||
}
|
||||
|
||||
public void OnCloneStage()
|
8
Assets/Scripts/Math.meta
Normal file
8
Assets/Scripts/Math.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8ac88bae1e709d142bde52c3a5f17a9b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Math/Constants.meta
Normal file
8
Assets/Scripts/Math/Constants.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0288c6c177cf10045b08f5d2b9ad52c4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,35 +0,0 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class Tag : MonoBehaviour
|
||||
{
|
||||
public string tagName = "New Tag";
|
||||
public Text tagText;
|
||||
public GameObject tagPrefab;
|
||||
|
||||
public void Initialize(string tagName)
|
||||
{
|
||||
this.tagName = tagName;
|
||||
tagText.text = tagName;
|
||||
}
|
||||
|
||||
public void AddTag()
|
||||
{
|
||||
GameObject newTag = Instantiate(tagPrefab, transform.parent);
|
||||
newTag.GetComponent<Tag>().Initialize(tagText.text);
|
||||
|
||||
tagText.text = tagName;
|
||||
transform.SetAsLastSibling();
|
||||
}
|
||||
|
||||
public void DeleteTag()
|
||||
{
|
||||
//SendMessageUpwards("DeleteTag", this);
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e3306014932bdc74ca0fe3ff85867c58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Utilities.meta
Normal file
8
Assets/Scripts/Utilities.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ecaf47cada431924c86ace2e8056da7e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/Workspace.meta
Normal file
8
Assets/Scripts/Workspace.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c7b8488a225a00944963946ebfa7a654
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -28,12 +28,22 @@ namespace RimWorldAnimationStudio
|
|||
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
|
||||
public static int animationClipWindowSize = 600;
|
||||
|
||||
|
||||
public PawnKeyframe GetCurrentPawnKeyframe(bool makeNewIfNull = true)
|
||||
{
|
||||
int stageTick = AnimationController.Instance.stageTick;
|
||||
PawnKeyframe keyframe = animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
|
||||
|
||||
//public int? GetCurrentKeyframe()
|
||||
//{
|
||||
// return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.keyframeID == keyframeID)?.keyframeID;
|
||||
//}
|
||||
if (keyframe != null || makeNewIfNull == false)
|
||||
{ return keyframe; }
|
||||
|
||||
AnimationController.Instance.AddPawnKeyframe();
|
||||
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
|
||||
}
|
||||
|
||||
public PawnAnimationClip GetCurrentPawnAnimationClip()
|
||||
{
|
||||
return animationDef.animationStages[stageID].animationClips[actorID];
|
||||
}
|
||||
|
||||
public PawnAnimationClip GetPawnAnimationClip(int actorID)
|
||||
{
|
Loading…
Add table
Add a link
Reference in a new issue