2022-09-13 05:36:34 +00:00
|
|
|
|
using System;
|
2022-09-14 05:25:58 +00:00
|
|
|
|
using System.Text;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Xml.Serialization;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using SFB;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
|
|
|
namespace RimWorldAnimationStudio
|
|
|
|
|
{
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public class AnimationController : Singleton<AnimationController>
|
2022-09-13 05:36:34 +00:00
|
|
|
|
{
|
|
|
|
|
public bool isAnimating = false;
|
|
|
|
|
public bool isLooping = true;
|
|
|
|
|
public int stageTick = 0;
|
|
|
|
|
|
|
|
|
|
public bool autoAdvanceToNextStage = false;
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public Slider stageTimelineSlider;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public GameObject actorBodyPrefab;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
public List<ActorBody> actorBodies = new List<ActorBody>();
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public Text stageTickText;
|
|
|
|
|
public Text stageLengthText;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-14 05:25:58 +00:00
|
|
|
|
public Transform actorCards;
|
|
|
|
|
public GameObject actorCardPrefab;
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public Dropdown stageLoopDropdown;
|
|
|
|
|
public InputField stageIDField;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
private float currentTime = 0;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
public void Update()
|
2022-09-13 05:36:34 +00:00
|
|
|
|
{
|
2022-09-15 05:17:44 +00:00
|
|
|
|
// No animation, exit
|
|
|
|
|
if (Workspace.animationDef == null) { return; }
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
// Dirty animation, reset
|
|
|
|
|
if (Workspace.animationDef != null && Workspace.isDirty)
|
|
|
|
|
{ Initialize(); return; }
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
// Not animating, update preview
|
2022-09-14 05:25:58 +00:00
|
|
|
|
if (isAnimating == false) { UpdateAnimation(); return; }
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
// Animating, update stage tick before updating preview
|
2022-09-13 05:36:34 +00:00
|
|
|
|
currentTime += Time.deltaTime;
|
|
|
|
|
|
|
|
|
|
if (currentTime < 1f/60f)
|
|
|
|
|
{ return; }
|
|
|
|
|
|
|
|
|
|
currentTime -= 1f/60f;
|
|
|
|
|
stageTick += 1;
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
int stageLenght = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks;
|
|
|
|
|
|
|
|
|
|
if (stageTick > stageLenght)
|
2022-09-13 05:36:34 +00:00
|
|
|
|
{
|
2022-09-15 05:17:44 +00:00
|
|
|
|
if (stageLoopDropdown.value == 1)
|
2022-09-13 05:36:34 +00:00
|
|
|
|
{ stageTick = 1; }
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
else if (stageLoopDropdown.value == 2 && Workspace.stageID < Workspace.animationDef.animationStages.Count - 1)
|
|
|
|
|
{
|
|
|
|
|
stageTick = 1;
|
|
|
|
|
Workspace.stageID++;
|
|
|
|
|
stageIDField.text = Workspace.stageID.ToString();
|
|
|
|
|
}
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
|
|
|
|
else
|
2022-09-15 05:17:44 +00:00
|
|
|
|
{ stageTick = stageLenght; }
|
2022-09-13 05:36:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
stageTimelineSlider.maxValue = stageLenght;
|
|
|
|
|
stageTimelineSlider.value = stageTick;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
UpdateAnimation();
|
2022-09-13 05:36:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateAnimation()
|
|
|
|
|
{
|
2022-09-15 05:17:44 +00:00
|
|
|
|
if (stageTickText != null)
|
|
|
|
|
{ stageTickText.text = stageTick.ToString(); }
|
|
|
|
|
if (stageLengthText != null)
|
|
|
|
|
{ stageLengthText.text = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks.ToString(); }
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
|
|
|
|
for (int actorID = 0; actorID < actorBodies.Count; actorID++)
|
|
|
|
|
{
|
|
|
|
|
ActorBody actorBody = actorBodies[actorID];
|
2022-09-14 05:25:58 +00:00
|
|
|
|
string bodyType = actorCards.transform.GetChild(actorID).GetComponent<ActorCard>().bodyType; //bodyTypeDropdowns[actorID].options[bodyTypeDropdowns[actorID].value].text;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID];
|
2022-09-13 05:36:34 +00:00
|
|
|
|
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
|
|
|
|
|
|
|
|
|
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
|
2022-09-15 05:17:44 +00:00
|
|
|
|
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
|
2022-09-13 05:36:34 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
int bodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
|
|
|
|
|
int headFacing = (int)clip.HeadFacing.Evaluate(clipPercent);
|
|
|
|
|
|
|
|
|
|
Vector3 headBob = new Vector3(0, 0, clip.HeadBob.Evaluate(clipPercent)) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
|
|
|
|
|
|
|
|
|
|
Vector3 bodyPos = new Vector3(deltaPos.x, deltaPos.z, 0);
|
|
|
|
|
Vector3 headPos = new Vector3(headBob.x, headBob.z, 0);
|
|
|
|
|
|
|
|
|
|
actorBody.transform.position = bodyPos;
|
|
|
|
|
actorBody.transform.eulerAngles = new Vector3(0, 0, bodyAngle);
|
|
|
|
|
|
|
|
|
|
actorBody.headRenderer.transform.localPosition = headPos;
|
|
|
|
|
actorBody.headRenderer.transform.eulerAngles = new Vector3(0, 0, headAngle);
|
|
|
|
|
|
|
|
|
|
actorBody.bodyRenderer.sprite = Resources.Load<Sprite>("Textures/Humanlike/Bodies/" + bodyType + bodyFacing);
|
|
|
|
|
actorBody.headRenderer.sprite = Resources.Load<Sprite>("Textures/Humanlike/Heads/Head" + headFacing);
|
|
|
|
|
|
2022-09-15 05:17:44 +00:00
|
|
|
|
actorBody.bodyRenderer.sortingLayerName = clip.layer;
|
|
|
|
|
actorBody.headRenderer.sortingLayerName = clip.layer;
|
2022-09-13 05:36:34 +00:00
|
|
|
|
actorBody.headRenderer.sortingOrder = headFacing == 2 ? 1 : -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-15 05:17:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
|
|
|
|
|
{
|
|
|
|
|
GameObject actorBodyObject = Instantiate(actorBodyPrefab, transform);
|
|
|
|
|
actorBodies.Add(actorBodyObject.GetComponent<ActorBody>());
|
|
|
|
|
|
|
|
|
|
GameObject actorCardObject = Instantiate(actorCardPrefab, actorCards);
|
|
|
|
|
actorCardObject.GetComponent<ActorCard>().Initialize(Workspace.animationDef.actors[actorID]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Workspace.isDirty = false;
|
|
|
|
|
|
|
|
|
|
UpdateAnimation();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
Workspace.stageID = 0;
|
|
|
|
|
stageTick = 0;
|
|
|
|
|
isAnimating = false;
|
|
|
|
|
|
|
|
|
|
foreach (ActorBody actorBody in actorBodies)
|
|
|
|
|
{ Destroy(actorBody.gameObject); }
|
|
|
|
|
|
|
|
|
|
foreach (Transform actorCard in actorCards)
|
|
|
|
|
{ Destroy(actorCard.gameObject); }
|
|
|
|
|
|
|
|
|
|
actorBodies.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ToggleAnimation()
|
|
|
|
|
{
|
|
|
|
|
isAnimating = !isAnimating;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ToggleAnimationLoop()
|
|
|
|
|
{
|
|
|
|
|
isLooping = !isLooping;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateFromStageTimelineSlider()
|
|
|
|
|
{
|
|
|
|
|
if (Workspace.animationDef == null)
|
|
|
|
|
{ return; }
|
|
|
|
|
|
|
|
|
|
int stageLenght = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks;
|
|
|
|
|
|
|
|
|
|
if (stageLenght != (int)stageTimelineSlider.value)
|
|
|
|
|
{ stageTick = (int)stageTimelineSlider.value; }
|
|
|
|
|
}
|
2022-09-13 05:36:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|