mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
v 1.0.0
This commit is contained in:
parent
0828ecd037
commit
2998865184
9821 changed files with 90 additions and 90 deletions
250
Source/Assets/Scripts/Managers/AnimationController.cs
Normal file
250
Source/Assets/Scripts/Managers/AnimationController.cs
Normal file
|
@ -0,0 +1,250 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class AnimationController : Singleton<AnimationController>
|
||||
{
|
||||
[Header("Object references")]
|
||||
public Transform animationTimelines;
|
||||
public Transform actorBodies;
|
||||
public Dropdown stageLoopDropdown;
|
||||
|
||||
[Header("Prefabs")]
|
||||
public ActorBody actorBodyPrefab;
|
||||
public GameObject animationTimelinePrefab;
|
||||
|
||||
// Private timing variables
|
||||
private float timeSinceLastUpdate = 0;
|
||||
private int loopCount = 0;
|
||||
private float playBackSpeed = 1f;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate{ Initialize(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { Initialize(); });
|
||||
EventsManager.onActorCountChanged.AddListener(delegate { Initialize(); });
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
// Update stage tick / loop count if animating
|
||||
if (Workspace.IsAnimating)
|
||||
{
|
||||
timeSinceLastUpdate += Time.deltaTime;
|
||||
|
||||
if (timeSinceLastUpdate < 1 / (playBackSpeed * 60f))
|
||||
{ return; }
|
||||
|
||||
timeSinceLastUpdate -= 1 / (playBackSpeed * 60f);
|
||||
Workspace.StageTick += 1;
|
||||
|
||||
if (Workspace.StageTick >= Workspace.StageWindowSize)
|
||||
{
|
||||
switch (stageLoopDropdown.value)
|
||||
{
|
||||
case 1: Workspace.StageTick = Constants.minTick; break;
|
||||
case 2: UpdateLoopCount(Workspace.GetCurrentAnimationStage().StageLoopsNormal); break;
|
||||
case 3: UpdateLoopCount(Workspace.GetCurrentAnimationStage().StageLoopsQuick); break;
|
||||
default: Workspace.IsAnimating = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update animation preview
|
||||
UpdateAnimationPreview();
|
||||
}
|
||||
|
||||
public void UpdateLoopCount(int stageLoops)
|
||||
{
|
||||
loopCount++;
|
||||
Workspace.StageTick = Constants.minTick;
|
||||
|
||||
if (loopCount >= stageLoops)
|
||||
{
|
||||
if (Workspace.StageID >= Workspace.animationDef.AnimationStages.Count - 1)
|
||||
{ Workspace.IsAnimating = false; }
|
||||
|
||||
else
|
||||
{
|
||||
Workspace.StageID++;
|
||||
loopCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAnimationPreview()
|
||||
{
|
||||
if (Workspace.animationDef == null || Workspace.StageID >= Workspace.animationDef?.AnimationStages.Count) return;
|
||||
|
||||
List<ActorBody> actorBodiesList = actorBodies.GetComponentsInChildren<ActorBody>().ToList();
|
||||
|
||||
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
|
||||
{
|
||||
// Get the current actor
|
||||
Actor actor = Workspace.GetActor(actorID);
|
||||
|
||||
// Get their animation clip and rebuild it to ensure it is up to date
|
||||
PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
|
||||
clip.BuildSimpleCurves();
|
||||
|
||||
// Get flags
|
||||
bool quiver = Workspace.IsAnimating && Workspace.GetCurrentOrPreviousKeyframe(actorID).Quiver == true;
|
||||
bool requiresGenitals = actor.RequiredGenitals.Any(x => x == "Penis") || actor.IsFucking;
|
||||
|
||||
// Get clip percentage
|
||||
float clipPercent = (float)(Workspace.StageTick % clip.duration) / clip.duration;
|
||||
if (Workspace.StageTick > Constants.minTick && Workspace.StageTick == clip.duration) clipPercent = 1f;
|
||||
|
||||
if (Workspace.GetCurrentAnimationStage().IsLooping == false)
|
||||
{ clipPercent = (float)Workspace.StageTick / clip.duration; }
|
||||
|
||||
// Get the actors race and body type
|
||||
PawnRaceDef pawnRaceDef = actor.GetPawnRaceDef();
|
||||
string bodyType = pawnRaceDef.isHumanoid ? actor.bodyType : "None";
|
||||
|
||||
// Evalute the actor's basic offsets and facing
|
||||
ActorPosition actorPosition = actor.GetCurrentPosition();
|
||||
|
||||
float bodyPosX = actorPosition.bodyOffsetX;
|
||||
float bodyPosZ = actorPosition.bodyOffsetZ;
|
||||
float bodyAngle = actorPosition.bodyAngle + (quiver ? UnityEngine.Random.value * 2f - 1f : 0f);
|
||||
float headBob = actorPosition.headBob;
|
||||
float headAngle = actorPosition.headAngle;
|
||||
float genitalAngle = actorPosition.genitalAngle;
|
||||
|
||||
int bodyFacing = actorPosition.bodyFacing;
|
||||
int headFacing = actorPosition.headFacing;
|
||||
|
||||
// Convert values to world coordinates
|
||||
Vector3 bodyPos = new Vector3(bodyPosX, bodyPosZ, 0f);
|
||||
Vector3 headPos = new Vector3(0f, headBob, 0f) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
|
||||
Vector3 appendagePos = PawnUtility.GroinOffsetAt(bodyType, bodyFacing);
|
||||
|
||||
// Update actorbody
|
||||
ActorBody actorBody = actorBodiesList[actorID];
|
||||
ActorBodyPart actorBodypart;
|
||||
|
||||
actorBody.transform.localScale = new Vector3(pawnRaceDef.scale, pawnRaceDef.scale, pawnRaceDef.scale);
|
||||
|
||||
// Body
|
||||
actorBody.transform.position = bodyPos + actor.GetFinalTransformOffset();
|
||||
actorBody.transform.eulerAngles = new Vector3(0, 0, -bodyAngle);
|
||||
|
||||
actorBody.bodyRenderer.sortingLayerName = clip.Layer;
|
||||
actorBody.bodyRenderer.sprite = pawnRaceDef.GetBodyTypeGraphic((CardinalDirection)bodyFacing, bodyType);
|
||||
actorBody.bodyRenderer.flipX = bodyFacing == 3;
|
||||
|
||||
actorBody.bodyRenderer.gameObject.SetActive(actorBody.bodyRenderer.sprite != null);
|
||||
|
||||
// Head
|
||||
actorBodypart = actorBody.GetActorBodyPart("head");
|
||||
|
||||
actorBodypart.transform.localPosition = headPos;
|
||||
actorBodypart.transform.eulerAngles = new Vector3(0, 0, -headAngle);
|
||||
|
||||
actorBodypart.bodyPartRenderer.sortingLayerName = clip.Layer;
|
||||
actorBodypart.bodyPartRenderer.sortingOrder = bodyFacing == 0 ? -1 : 1;
|
||||
actorBodypart.bodyPartRenderer.sprite = pawnRaceDef.isHumanoid ? pawnRaceDef.GetHeadGraphic((CardinalDirection)headFacing) : null;
|
||||
actorBodypart.bodyPartRenderer.flipX = headFacing == 3;
|
||||
|
||||
actorBodypart.gameObject.SetActive(actorBodypart.bodyPartRenderer.sprite != null);
|
||||
|
||||
// Appendage
|
||||
actorBodypart = actorBody.GetActorBodyPart("appendage");
|
||||
|
||||
actorBodypart.transform.localPosition = new Vector3(appendagePos.x, appendagePos.z, 0f);
|
||||
actorBodypart.transform.eulerAngles = new Vector3(0, 0, -genitalAngle);
|
||||
|
||||
actorBodypart.bodyPartRenderer.sortingLayerName = clip.Layer;
|
||||
actorBodypart.bodyPartRenderer.sprite = requiresGenitals && pawnRaceDef.isHumanoid ? Resources.Load<Sprite>("Textures/Humanlike/Appendages/Appendage" + bodyFacing) : null;
|
||||
//actorBody.appendageRenderer.flipX = bodyFacing == 3;
|
||||
|
||||
actorBodypart.gameObject.SetActive(actorBodypart.bodyPartRenderer.sprite != null);
|
||||
|
||||
// Add-ons
|
||||
foreach (ActorAddon addon in clip.Addons)
|
||||
{
|
||||
actorBodypart = actorBody.GetActorBodyPart(addon.AddonName);
|
||||
if (actorBodypart == null) continue;
|
||||
|
||||
ActorBody anchoringActorBody = actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
|
||||
Vector3 anchor = PawnUtility.GetBodyPartAnchor(anchoringActorBody, addon.anchorName);
|
||||
|
||||
actorBodypart.transform.position = anchor + new Vector3(addon.PosX.Evaluate(clipPercent), addon.PosZ.Evaluate(clipPercent), 0);
|
||||
actorBodypart.transform.eulerAngles = new Vector3(0, 0, -addon.Rotation.Evaluate(clipPercent));
|
||||
|
||||
actorBodypart.bodyPartRenderer.sortingLayerName = addon.Layer;
|
||||
//actorBodypart.bodyPartRenderer.sprite
|
||||
|
||||
actorBodypart.gameObject.SetActive(addon.Render);
|
||||
}
|
||||
|
||||
// Play sounds
|
||||
if (Workspace.IsAnimating)
|
||||
{
|
||||
PawnKeyframe keyframe = clip.keyframes.FirstOrDefault(x => x.atTick == (int)(clip.duration * clipPercent));
|
||||
|
||||
if (keyframe != null && string.IsNullOrEmpty(keyframe.soundEffect) == false)
|
||||
{ actorBody.GetComponent<AudioController>().PlaySound(keyframe.soundEffect); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Debug.Log("Initializing animation preview");
|
||||
|
||||
int actorCount = Workspace.animationDef.Actors.Count;
|
||||
int childCount = animationTimelines.GetComponentsInChildren<AnimationTimeline>().Count();
|
||||
|
||||
for (int actorID = 0; actorID < Mathf.Max(actorCount, childCount); actorID++)
|
||||
{
|
||||
// Add new actors as required
|
||||
if (actorID >= childCount)
|
||||
{
|
||||
Instantiate(animationTimelinePrefab, animationTimelines);
|
||||
Instantiate(actorBodyPrefab, actorBodies.transform);
|
||||
}
|
||||
|
||||
// Get objects to update
|
||||
AnimationTimeline animationTimeline = animationTimelines.GetComponentsInChildren<AnimationTimeline>()[actorID];
|
||||
ActorBody actorBody = actorBodies.GetComponentsInChildren<ActorBody>()[actorID];
|
||||
|
||||
// Update values
|
||||
if (actorID < actorCount)
|
||||
{
|
||||
animationTimeline.Initialize(actorID);
|
||||
actorBody.Initialize(actorID);
|
||||
}
|
||||
|
||||
// Remove excess objects as required
|
||||
else
|
||||
{
|
||||
Destroy(animationTimeline.transform.parent.gameObject);
|
||||
Destroy(actorBody.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
EventsManager.OnAnimationTimelinesChanged();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Workspace.IsAnimating = false;
|
||||
timeSinceLastUpdate = 0;
|
||||
loopCount = 0;
|
||||
|
||||
foreach (Transform child in transform)
|
||||
{ child.gameObject.SetActive(true); }
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/AnimationController.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/AnimationController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5ce34f72fe7ef0c41a7bc163fce97970
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
344
Source/Assets/Scripts/Managers/ApplicationManager.cs
Normal file
344
Source/Assets/Scripts/Managers/ApplicationManager.cs
Normal file
|
@ -0,0 +1,344 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Networking;
|
||||
using SFB;
|
||||
using System.Collections;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class ApplicationManager : Singleton<ApplicationManager>
|
||||
{
|
||||
public DialogBox exitDialog;
|
||||
public DialogBox newAnimationDialog;
|
||||
public SelectAnimationDialog selectAnimationDialog;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
LoadPawnRaceDefs();
|
||||
LoadActorAddonDefs();
|
||||
LoadSoundDefs();
|
||||
LoadAudioClips();
|
||||
LoadCustomArrays();
|
||||
}
|
||||
|
||||
public void TryToCloseApplication()
|
||||
{
|
||||
exitDialog.Pop();
|
||||
}
|
||||
|
||||
public void CloseApplication()
|
||||
{
|
||||
Debug.Log("Exiting application");
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
public void TryToLoadAnimation()
|
||||
{
|
||||
var paths = StandaloneFileBrowser.OpenFilePanel("Open AnimationDef File", "", "xml", false);
|
||||
|
||||
if (paths == null || paths.Any() == false)
|
||||
{ Debug.LogWarning("Selected file was null or invalid"); return; }
|
||||
|
||||
AnimationDefs defs = XmlUtility.ReadXML<AnimationDefs>(paths[0]);
|
||||
|
||||
try
|
||||
{ defs = XmlUtility.ReadXML<AnimationDefs>(paths[0]); }
|
||||
|
||||
catch
|
||||
{ Debug.LogError("Could not read .xml file '" + paths[0] + "' - this file either uses a schema which is outdated, incorrect, or contains empty fields"); return; }
|
||||
|
||||
if (defs?.animationDefs == null)
|
||||
{ Debug.LogError("Selected file contains no animation data"); return; }
|
||||
|
||||
if (defs.animationDefs.Count == 1)
|
||||
{ LoadAnimation(defs.animationDefs[0]); return; }
|
||||
|
||||
Workspace.animationSavePath = paths[0];
|
||||
|
||||
selectAnimationDialog.Initialize(defs);
|
||||
selectAnimationDialog.Pop();
|
||||
}
|
||||
|
||||
public void LoadAnimation(AnimationDef animationDef)
|
||||
{
|
||||
Workspace.Reset();
|
||||
|
||||
Workspace.animationDef = animationDef;
|
||||
UpdateCustomArrays(animationDef);
|
||||
RunPostLoadOperations(animationDef);
|
||||
|
||||
animationDef.Initialize();
|
||||
|
||||
Debug.Log("Loaded AnimationDef: " + animationDef.DefName);
|
||||
|
||||
AnimationController.Instance.Reset();
|
||||
AnimationController.Instance.Initialize();
|
||||
|
||||
EventsManager.OnAnimationChanged();
|
||||
Workspace.RecordEvent("AnimationDef loaded");
|
||||
|
||||
Workspace.ActorID = 0;
|
||||
EventsManager.OnActorIDChanged();
|
||||
}
|
||||
|
||||
public void RunPostLoadOperations(AnimationDef animationDef)
|
||||
{
|
||||
if (animationDef.animationTimeTicksQuick <= 0)
|
||||
{
|
||||
if (animationDef.AnimationStages.Count > 1)
|
||||
{
|
||||
for (int i = 0; i < animationDef.AnimationStages.Count; i++)
|
||||
{
|
||||
if (i == 0) continue;
|
||||
animationDef.AnimationStages[i].PlayTimeTicksQuick = animationDef.AnimationStages[i].PlayTimeTicks;
|
||||
}
|
||||
}
|
||||
|
||||
else if (animationDef.AnimationStages.Count == 1)
|
||||
{ animationDef.AnimationStages[0].PlayTimeTicksQuick = animationDef.AnimationStages[0].PlayTimeTicks; }
|
||||
}
|
||||
|
||||
foreach (AnimationStage stage in animationDef.AnimationStages)
|
||||
{ stage.OnPostLoad(); }
|
||||
}
|
||||
|
||||
public void TryToSaveAnimation()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{ return; }
|
||||
|
||||
string path = Workspace.animationSavePath;
|
||||
|
||||
if (path != null && path != "" && File.Exists(path))
|
||||
{ SaveAnimation(path); }
|
||||
|
||||
else
|
||||
{ TryToSaveAnimationAs(); }
|
||||
}
|
||||
|
||||
public void TryToSaveAnimationAs()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{ return; }
|
||||
|
||||
string defName = Workspace.animationDef.DefName != null && Workspace.animationDef.DefName != "" ? Workspace.animationDef.DefName : "newAnimationDef";
|
||||
string path = StandaloneFileBrowser.SaveFilePanel("Save AnimationDef File", "", defName, "xml");
|
||||
|
||||
if (path != null && path != "")
|
||||
{ SaveAnimation(path); }
|
||||
}
|
||||
|
||||
public void SaveAnimation(string path)
|
||||
{
|
||||
AnimationDef animationDef = Workspace.animationDef.Copy();
|
||||
RunPreSaveOperations(animationDef);
|
||||
|
||||
Debug.Log("Saving AnimationDef: " + Workspace.animationDef.DefName);
|
||||
|
||||
AnimationDefs defs = new AnimationDefs();
|
||||
defs.animationDefs.Add(animationDef);
|
||||
|
||||
XmlUtility.WriteXML(defs, path);
|
||||
|
||||
Workspace.animationSavePath = path;
|
||||
}
|
||||
|
||||
public void RunPreSaveOperations(AnimationDef animationDef)
|
||||
{
|
||||
animationDef.OnPreSave();
|
||||
|
||||
foreach (Actor actor in animationDef.Actors)
|
||||
{ actor.OnPreSave(); }
|
||||
|
||||
foreach (AnimationStage stage in animationDef.AnimationStages)
|
||||
{
|
||||
stage.OnPreSave();
|
||||
|
||||
foreach (PawnAnimationClip clip in stage.AnimationClips)
|
||||
{
|
||||
clip.OnPreSave();
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{ keyframe.OnPreSave(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TryToMakeNewAnimation()
|
||||
{
|
||||
if (Workspace.animationDef == null)
|
||||
{ NewAnimation(); return; }
|
||||
|
||||
newAnimationDialog.Pop();
|
||||
}
|
||||
|
||||
public void NewAnimation()
|
||||
{
|
||||
var path = Path.Combine(Application.streamingAssetsPath, "AnimationDefs/newAnimationDef.xml");
|
||||
|
||||
AnimationDefs defs = XmlUtility.ReadXML<AnimationDefs>(path);
|
||||
|
||||
if (defs?.animationDefs == null)
|
||||
{ Debug.LogError("Default animation def file contains no animation data"); return; }
|
||||
|
||||
LoadAnimation(defs.animationDefs[0]);
|
||||
|
||||
Workspace.animationSavePath = null;
|
||||
}
|
||||
|
||||
public void SaveCustomArrays()
|
||||
{
|
||||
var path = Path.Combine(Application.persistentDataPath, "customTags.xml");
|
||||
|
||||
CustomTagsHelper helper = new CustomTagsHelper();
|
||||
|
||||
helper.defNames = CustomTags.defNames;
|
||||
helper.bodyParts = CustomTags.bodyParts;
|
||||
helper.bodyDefTypes = CustomTags.bodyDefTypes;
|
||||
helper.sexTypes = CustomTags.sexTypes;
|
||||
helper.interactionDefTypes = CustomTags.interactionDefTypes;
|
||||
helper.soundDefs = CustomTags.soundDefs;
|
||||
|
||||
XmlUtility.WriteXML(helper, path);
|
||||
}
|
||||
|
||||
public void LoadCustomArrays()
|
||||
{
|
||||
string path;
|
||||
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "customTags.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "customTags.xml"); }
|
||||
|
||||
else
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "customTags.xml"); }
|
||||
|
||||
if (File.Exists(path) == false)
|
||||
{ SaveCustomArrays(); return; }
|
||||
|
||||
CustomTagsHelper helper = XmlUtility.ReadXML<CustomTagsHelper>(path);
|
||||
|
||||
CustomTags.defNames = helper.defNames;
|
||||
CustomTags.bodyParts = helper.bodyParts;
|
||||
CustomTags.bodyDefTypes = helper.bodyDefTypes;
|
||||
CustomTags.sexTypes = helper.sexTypes;
|
||||
CustomTags.interactionDefTypes = helper.interactionDefTypes;
|
||||
CustomTags.soundDefs = helper.soundDefs;
|
||||
}
|
||||
|
||||
public void UpdateCustomArrays(AnimationDef animationDef)
|
||||
{
|
||||
CustomTags.bodyParts.AddRangeDistinct(animationDef.Actors.SelectMany(x => x.RequiredGenitals).Except(DefaultTags.bodyParts));
|
||||
CustomTags.bodyDefTypes.AddRangeDistinct(animationDef.Actors.SelectMany(x => x.BodyDefTypes).Except(DefaultTags.bodyDefTypes));
|
||||
CustomTags.sexTypes.AddRangeDistinct(animationDef.SexTypes.Except(DefaultTags.sexTypes));
|
||||
CustomTags.interactionDefTypes.AddRangeDistinct(animationDef.InteractionDefTypes.Except(DefaultTags.interactionDefTypes));
|
||||
CustomTags.soundDefs.AddRangeDistinct(animationDef.AnimationStages.SelectMany(x => x.AnimationClips.SelectMany(y => y.Keyframes.Select(z => z.SoundEffect))).Except(DefaultTags.soundDefs));
|
||||
|
||||
SaveCustomArrays();
|
||||
}
|
||||
|
||||
public void LoadPawnRaceDefs()
|
||||
{
|
||||
string path;
|
||||
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml"); }
|
||||
|
||||
else
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "pawnRaceDefs.xml"); }
|
||||
|
||||
PawnRaceDefs.allDefs = XmlUtility.ReadXML<List<PawnRaceDef>>(path);
|
||||
SavePawnRaceDefs();
|
||||
|
||||
PawnRaceDefs.OnLoad();
|
||||
}
|
||||
|
||||
public void SavePawnRaceDefs()
|
||||
{
|
||||
var path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml");
|
||||
|
||||
XmlUtility.WriteXML(PawnRaceDefs.allDefs, path);
|
||||
}
|
||||
|
||||
public void LoadActorAddonDefs()
|
||||
{
|
||||
string path;
|
||||
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "actorAddonDefs.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "actorAddonDefs.xml"); }
|
||||
|
||||
else
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "actorAddonDefs.xml"); }
|
||||
|
||||
ActorAddonDefs.allDefs = XmlUtility.ReadXML<List<ActorAddonDef>>(path);
|
||||
SaveActorAddonDefs();
|
||||
|
||||
ActorAddonDefs.OnLoad();
|
||||
}
|
||||
|
||||
public void SaveActorAddonDefs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void LoadSoundDefs()
|
||||
{
|
||||
string path;
|
||||
|
||||
if (File.Exists(Path.Combine(Application.persistentDataPath, "soundDefs.xml")))
|
||||
{ path = Path.Combine(Application.persistentDataPath, "soundDefs.xml"); }
|
||||
|
||||
else
|
||||
{ path = Path.Combine(Application.streamingAssetsPath, "soundDefs.xml"); }
|
||||
|
||||
SoundDefs.allDefs = XmlUtility.ReadXML<List<SoundDef>>(path);
|
||||
SaveSoundDefs();
|
||||
|
||||
SoundDefs.OnLoad();
|
||||
}
|
||||
|
||||
public void SaveSoundDefs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void LoadAudioClips()
|
||||
{
|
||||
StartCoroutine(LoadAudioClipsCoroutine());
|
||||
}
|
||||
|
||||
private IEnumerator LoadAudioClipsCoroutine()
|
||||
{
|
||||
foreach (SoundDef soundDef in SoundDefs.allDefs)
|
||||
{
|
||||
foreach (SubSoundDef subSoundDef in soundDef.subSounds)
|
||||
{
|
||||
foreach (AudioGrain audioGrain in subSoundDef.grains)
|
||||
{
|
||||
string fullPath = Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, "Sounds", audioGrain.clipPath)) + ".wav";
|
||||
|
||||
using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(fullPath, AudioType.WAV))
|
||||
{
|
||||
yield return www.SendWebRequest();
|
||||
|
||||
if (string.IsNullOrEmpty(www.error) == false)
|
||||
{
|
||||
Debug.Log("Could not load audio clip '" + fullPath + "' - .WAV audio clip was not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
|
||||
|
||||
SoundDefs.AddAudioClip(fullPath, audioClip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/ApplicationManager.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/ApplicationManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8c0c094e56b459d42850b3632db6c4ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
79
Source/Assets/Scripts/Managers/CameraController.cs
Normal file
79
Source/Assets/Scripts/Managers/CameraController.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class CameraController : MonoBehaviour
|
||||
{
|
||||
private Camera cam;
|
||||
|
||||
[Header("Scroll controls")]
|
||||
public float scrollSpeed = 100f;
|
||||
|
||||
[Header("Zoom controls")]
|
||||
public float zoom = -5f;
|
||||
public float minZoom = -3f;
|
||||
public float maxZoom = -15f;
|
||||
|
||||
[Header("Max bounds")]
|
||||
public float maxBoundsXAxis = 30;
|
||||
public float maxBoundsYAxis = 30;
|
||||
|
||||
private float x;
|
||||
private float y;
|
||||
private float curZoom;
|
||||
private bool mouseDragActive = false;
|
||||
private Vector3 mouseDragOrigin;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
x = transform.position.x;
|
||||
y = transform.position.y;
|
||||
|
||||
curZoom = zoom;
|
||||
|
||||
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
|
||||
cam = this.GetComponent<Camera>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetMouseButton(2))
|
||||
{ StartMouseDrag(); }
|
||||
|
||||
else if (Input.GetMouseButtonUp(2))
|
||||
{ ResetMouseDrag(); }
|
||||
|
||||
curZoom += Input.GetAxis("Mouse ScrollWheel") * scrollSpeed * 0.1f;
|
||||
curZoom = Mathf.Clamp(curZoom, maxZoom, minZoom);
|
||||
cam.orthographicSize = Mathf.Abs(curZoom);
|
||||
}
|
||||
|
||||
public void StartMouseDrag()
|
||||
{
|
||||
Vector3 delta = cam.ScreenToWorldPoint(Input.mousePosition) - cam.transform.position;
|
||||
|
||||
if (mouseDragActive == false)
|
||||
{
|
||||
mouseDragActive = true;
|
||||
mouseDragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
|
||||
}
|
||||
|
||||
cam.transform.position = mouseDragOrigin - delta;
|
||||
}
|
||||
|
||||
public void ResetMouseDrag()
|
||||
{
|
||||
mouseDragActive = false;
|
||||
}
|
||||
|
||||
public void ResetCamera()
|
||||
{
|
||||
cam.transform.position = new Vector3(0, 0, -10);
|
||||
curZoom = zoom;
|
||||
|
||||
mouseDragActive = false;
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/CameraController.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/CameraController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 192ae5e804d239d42891ba0bdc42e8b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
68
Source/Assets/Scripts/Managers/EventsManager.cs
Normal file
68
Source/Assets/Scripts/Managers/EventsManager.cs
Normal file
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public static class EventsManager
|
||||
{
|
||||
// Event classes
|
||||
public class WorkspaceIntEvent : UnityEvent<int> { }
|
||||
public class ActorEvent : UnityEvent<Actor> { }
|
||||
public class AnimationStageEvent : UnityEvent<AnimationStage> { }
|
||||
public class PawnAnimationClipEvent : UnityEvent<PawnAnimationClip> { }
|
||||
public class PawnKeyframeEvent : UnityEvent<PawnKeyframe> { }
|
||||
public class ActorAddonEvent : UnityEvent<ActorAddon> { }
|
||||
public class AddonKeyframeEvent : UnityEvent<AddonKeyframe> { }
|
||||
public class ActorBodyEvent : UnityEvent<ActorBody> { }
|
||||
public class ActorBodyPartEvent : UnityEvent<ActorBodyPart> { }
|
||||
|
||||
// Event list
|
||||
public static UnityEvent onAnimationTimelinesChanged = new UnityEvent();
|
||||
public static UnityEvent onAnimationToggled = new UnityEvent();
|
||||
public static UnityEvent onAnimationChanged = new UnityEvent();
|
||||
public static UnityEvent onAnimationDefChanged = new UnityEvent();
|
||||
public static WorkspaceIntEvent onActorIDChanged = new WorkspaceIntEvent();
|
||||
public static WorkspaceIntEvent onStageIDChanged = new WorkspaceIntEvent();
|
||||
public static WorkspaceIntEvent onStageTickChanged = new WorkspaceIntEvent();
|
||||
public static WorkspaceIntEvent onStageCountChanged = new WorkspaceIntEvent();
|
||||
public static WorkspaceIntEvent onActorCountChanged = new WorkspaceIntEvent();
|
||||
public static WorkspaceIntEvent onKeyframeCountChanged = new WorkspaceIntEvent();
|
||||
public static ActorEvent onActorChanged = new ActorEvent();
|
||||
public static AnimationStageEvent onAnimationStageChanged = new AnimationStageEvent();
|
||||
public static AnimationStageEvent onStageWindowSizeChanged = new AnimationStageEvent();
|
||||
public static PawnAnimationClipEvent onPawnAnimationClipChanged = new PawnAnimationClipEvent();
|
||||
public static PawnKeyframeEvent onPawnKeyframeChanged = new PawnKeyframeEvent();
|
||||
public static ActorAddonEvent onActorAddonChanged = new ActorAddonEvent();
|
||||
public static AddonKeyframeEvent onAddonKeyframeChanged = new AddonKeyframeEvent();
|
||||
public static UnityEvent onDefNamesChanged = new UnityEvent();
|
||||
public static ActorBodyEvent onActorBodySelected = new ActorBodyEvent();
|
||||
public static ActorBodyPartEvent onActorBodyPartSelected = new ActorBodyPartEvent();
|
||||
|
||||
// Event invoking
|
||||
public static void OnAnimationTimelinesChanged() { onAnimationTimelinesChanged.Invoke(); }
|
||||
public static void OnAnimationToggled() { onAnimationToggled.Invoke(); }
|
||||
public static void OnAnimationChanged() { onAnimationChanged.Invoke(); }
|
||||
public static void OnAnimationDefChanged() { onAnimationDefChanged.Invoke(); }
|
||||
public static void OnActorIDChanged() { onActorIDChanged.Invoke(Workspace.ActorID); }
|
||||
public static void OnStageIDChanged() { onStageIDChanged.Invoke(Workspace.ActorID); }
|
||||
public static void OnStageTickChanged() { onStageTickChanged.Invoke(Workspace.StageTick); }
|
||||
public static void OnStageCountChanged() { onStageCountChanged.Invoke(Workspace.animationDef.AnimationStages.Count); }
|
||||
public static void OnActorCountChanged() { onActorCountChanged.Invoke(Workspace.animationDef.Actors.Count); }
|
||||
public static void OnKeyframeCountChanged(PawnAnimationClip clip) { onKeyframeCountChanged.Invoke(clip.Keyframes.Count); }
|
||||
public static void OnActorChanged(Actor actor) { onActorChanged.Invoke(actor); }
|
||||
public static void OnAnimationStageChanged(AnimationStage stage) { onAnimationStageChanged.Invoke(stage); }
|
||||
public static void OnStageWindowSizeChanged(AnimationStage stage) { onStageWindowSizeChanged.Invoke(stage); }
|
||||
public static void OnPawnAnimationClipChanged(PawnAnimationClip clip) { onPawnAnimationClipChanged.Invoke(clip); }
|
||||
public static void OnPawnKeyframeChanged(PawnKeyframe keyframe) { onPawnKeyframeChanged.Invoke(keyframe); }
|
||||
public static void OnActorAddonChanged(ActorAddon actorAddon) { onActorAddonChanged.Invoke(actorAddon); }
|
||||
public static void OnAddonKeyframeChanged(AddonKeyframe addonKeyframe) { onAddonKeyframeChanged.Invoke(addonKeyframe); }
|
||||
public static void OnDefNamesChanged() { onDefNamesChanged.Invoke(); }
|
||||
public static void OnActorBodySelected(ActorBody actorBody) { onActorBodySelected.Invoke(actorBody); }
|
||||
public static void OnActorBodyPartSelected(ActorBodyPart bodyPart) { onActorBodyPartSelected.Invoke(bodyPart); }
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/EventsManager.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/EventsManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b4b96f2652caaa44985765ae416ac6ea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
478
Source/Assets/Scripts/Managers/InputManager.cs
Normal file
478
Source/Assets/Scripts/Managers/InputManager.cs
Normal file
|
@ -0,0 +1,478 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class InputManager : Singleton<InputManager>
|
||||
{
|
||||
public Transform dialogBoxes;
|
||||
public GameObject keyframeSelector;
|
||||
|
||||
private float lastUpdate = -1f;
|
||||
private float largeStep = 0.1f;
|
||||
private float smallStep = 0.03f;
|
||||
|
||||
private bool isDragging;
|
||||
private Vector2 v0;
|
||||
|
||||
public bool CanRepeatThisUpdate()
|
||||
{
|
||||
if (Time.unscaledTime > lastUpdate + Constants.actionRepeatSpeed)
|
||||
{
|
||||
lastUpdate = Time.unscaledTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsModifierKeyHeld()
|
||||
{
|
||||
if (Input.GetKey(KeyCode.LeftShift)) return true;
|
||||
if (Input.GetKey(KeyCode.LeftControl)) return true;
|
||||
if (Input.GetKey(KeyCode.LeftAlt)) return true;
|
||||
if (Input.GetKey(KeyCode.LeftCommand)) return true;
|
||||
if (Input.GetKey(KeyCode.RightShift)) return true;
|
||||
if (Input.GetKey(KeyCode.RightControl)) return true;
|
||||
if (Input.GetKey(KeyCode.RightAlt)) return true;
|
||||
if (Input.GetKey(KeyCode.RightCommand)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsDialogBoxIsActive()
|
||||
{
|
||||
foreach (Transform child in dialogBoxes)
|
||||
{ if (child.gameObject.activeSelf) return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (IsDialogBoxIsActive()) return;
|
||||
if (EventSystem.current.currentSelectedGameObject != null && EventSystem.current.currentSelectedGameObject.GetComponent<InputField>()?.isFocused == true) return;
|
||||
bool canRepeatThisUpdate = CanRepeatThisUpdate();
|
||||
|
||||
// Check keybinds
|
||||
foreach (Keybind keybind in KeybindConfig.GetAllKeybinds())
|
||||
{
|
||||
if (IsModifierKeyHeld() && keybind.keyModifiers.NullOrEmpty()) goto nextKeybind;
|
||||
|
||||
foreach (KeyCode modKeyCode in keybind.keyModifiers)
|
||||
{ if (Input.GetKey(modKeyCode) == false) goto nextKeybind; }
|
||||
|
||||
if (keybind.repeatable && canRepeatThisUpdate)
|
||||
{ if (Input.GetKey(keybind.keyCode) == false) goto nextKeybind; }
|
||||
|
||||
else
|
||||
{ if (Input.GetKeyDown(keybind.keyCode) == false) goto nextKeybind; }
|
||||
|
||||
//Debug.Log(keybind.command);
|
||||
Invoke(keybind.command, 0f); return;
|
||||
|
||||
nextKeybind:;
|
||||
}
|
||||
|
||||
// Drag selection
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{ StartKeyframeSelectionDrag(); }
|
||||
|
||||
else if (Input.GetMouseButtonUp(0))
|
||||
{ EndKeyframeSelectionDrag(); }
|
||||
|
||||
else if (isDragging)
|
||||
{ UpdateKeyframeSelector(); }
|
||||
|
||||
else
|
||||
{ HideKeyframeSelector(); }
|
||||
}
|
||||
|
||||
public void StartKeyframeSelectionDrag()
|
||||
{
|
||||
PointerEventData pointer = new PointerEventData(EventSystem.current);
|
||||
pointer.position = Input.mousePosition;
|
||||
|
||||
List<RaycastResult> raycastResults = new List<RaycastResult>();
|
||||
EventSystem.current.RaycastAll(pointer, raycastResults);
|
||||
|
||||
if (raycastResults.Count > 0)
|
||||
{
|
||||
foreach (var go in raycastResults)
|
||||
{
|
||||
//Debug.Log(go.gameObject);
|
||||
if (go.gameObject?.GetComponent<Button>() != null) return;
|
||||
if (go.gameObject?.GetComponent<IDragHandler>() != null) return;
|
||||
if (go.gameObject?.GetComponentInParent<IDragHandler>() != null) return;
|
||||
}
|
||||
}
|
||||
|
||||
v0 = (Vector2)Input.mousePosition;
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
public void EndKeyframeSelectionDrag()
|
||||
{
|
||||
if (isDragging == false) return;
|
||||
isDragging = false;
|
||||
|
||||
Vector2 v1 = (Vector2)Input.mousePosition;
|
||||
List<int> keyframeIDs = new List<int>();
|
||||
IEnumerable<KeyframeSlider> sliders = Selectable.allSelectablesArray.Select(x => x.GetComponent<KeyframeSlider>());
|
||||
|
||||
foreach (KeyframeSlider slider in sliders)
|
||||
{
|
||||
Transform handle = slider?.transform?.FindDeepChild("Handle");
|
||||
if (handle == null) continue;
|
||||
|
||||
Vector2 vi = (Vector2)handle.GetComponent<RectTransform>().position;
|
||||
|
||||
if (vi.x < Mathf.Min(v0.x, v1.x)) continue;
|
||||
if (vi.x > Mathf.Max(v0.x, v1.x)) continue;
|
||||
if (vi.y < Mathf.Min(v0.y, v1.y)) continue;
|
||||
if (vi.y > Mathf.Max(v0.y, v1.y)) continue;
|
||||
|
||||
keyframeIDs.Add(slider.keyframeID);
|
||||
}
|
||||
|
||||
if (keyframeIDs.NotNullOrEmpty())
|
||||
{ Workspace.keyframeID = keyframeIDs; }
|
||||
}
|
||||
|
||||
public void UpdateKeyframeSelector()
|
||||
{
|
||||
Vector2 v1 = (Vector2)Input.mousePosition;
|
||||
Vector2 pos = new Vector2(Mathf.Min(v0.x, v1.x), Mathf.Min(v0.y, v1.y));
|
||||
Vector2 dim = new Vector2(Mathf.Abs(v1.x - v0.x), Mathf.Abs(v1.y - v0.y));
|
||||
|
||||
keyframeSelector.GetComponent<RectTransform>().anchoredPosition = pos;
|
||||
keyframeSelector.GetComponent<RectTransform>().sizeDelta = dim;
|
||||
|
||||
if (keyframeSelector.activeSelf == false)
|
||||
{ keyframeSelector.SetActive(true); }
|
||||
}
|
||||
|
||||
public void HideKeyframeSelector()
|
||||
{
|
||||
if (keyframeSelector.activeSelf)
|
||||
{ keyframeSelector.SetActive(false); }
|
||||
}
|
||||
|
||||
public void QuitApplication()
|
||||
{
|
||||
ApplicationManager.Instance.TryToCloseApplication();
|
||||
}
|
||||
|
||||
public void NewAnimation()
|
||||
{
|
||||
ApplicationManager.Instance.TryToMakeNewAnimation();
|
||||
}
|
||||
|
||||
public void SaveAnimation()
|
||||
{
|
||||
ApplicationManager.Instance.TryToSaveAnimation();
|
||||
}
|
||||
|
||||
public void SaveAnimationAs()
|
||||
{
|
||||
ApplicationManager.Instance.TryToSaveAnimationAs();
|
||||
}
|
||||
|
||||
public void LoadAnimation()
|
||||
{
|
||||
ApplicationManager.Instance.TryToLoadAnimation();
|
||||
}
|
||||
|
||||
public void UndoAction()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.Undo();
|
||||
}
|
||||
|
||||
public void RedoAction()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.Redo();
|
||||
}
|
||||
|
||||
public void ToggleAnimationPreview()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.IsAnimating = !Workspace.IsAnimating;
|
||||
}
|
||||
|
||||
public void AddKeyframe()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.GetCurrentPawnAnimationClip().AddPawnKeyframe();
|
||||
}
|
||||
|
||||
public void CopyKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.GetCurrentPawnAnimationClip().CopyPawnKeyframes();
|
||||
}
|
||||
|
||||
public void PasteKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.GetCurrentPawnAnimationClip().PastePawnKeyframes();
|
||||
}
|
||||
|
||||
public void DeleteKeyframes()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
foreach (int keyframeID in Workspace.keyframeID)
|
||||
{ Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID).RemovePawnKeyframe(keyframeID); }
|
||||
}
|
||||
|
||||
public void ActorMovementMode()
|
||||
{
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)0;
|
||||
}
|
||||
|
||||
public void ActorRotateMode()
|
||||
{
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)1;
|
||||
}
|
||||
|
||||
public void ActorFacingMode()
|
||||
{
|
||||
Workspace.actorManipulationMode = (ActorManipulationMode)2;
|
||||
}
|
||||
|
||||
public void AdjustActorUpward()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.up * largeStep);
|
||||
}
|
||||
|
||||
public void AdjustActorDownward()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.down * largeStep);
|
||||
}
|
||||
|
||||
public void AdjustActorLeftward()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.left * largeStep);
|
||||
}
|
||||
|
||||
public void AdjustActorRightward()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.right * largeStep);
|
||||
}
|
||||
|
||||
public void AdjustActorUpwardSmall()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.up * smallStep);
|
||||
}
|
||||
|
||||
public void AdjustActorDownwardSmall()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.down * smallStep);
|
||||
}
|
||||
|
||||
public void AdjustActorLeftwardSmall()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.left * smallStep);
|
||||
}
|
||||
|
||||
public void AdjustActorRightwardSmall()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
keyframe.AdjustActor(Vector2.right * smallStep);
|
||||
}
|
||||
|
||||
public void CycleActorBodyPartSelecion()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
ActorBody actorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren<ActorBody>().FirstOrDefault(x => x.actorID == Workspace.ActorID);
|
||||
List<ActorBodyPart> actorBodyParts = actorBody?.GetComponentsInChildren<ActorBodyPart>()?.Where(x => x.gameObject.activeInHierarchy)?.ToList();
|
||||
|
||||
if (actorBodyParts.NullOrEmpty()) return;
|
||||
|
||||
if (Workspace.selectedBodyPart == null)
|
||||
{ actorBodyParts[0].Activate(); return; }
|
||||
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < actorBodyParts.Count; i++)
|
||||
{
|
||||
ActorBodyPart part = actorBodyParts[i];
|
||||
|
||||
if (part == Workspace.selectedBodyPart)
|
||||
{
|
||||
if (i < actorBodyParts.Count - 1)
|
||||
{ actorBodyParts[i + 1].Activate(); return; }
|
||||
|
||||
else
|
||||
{ actorBody.Activate(); return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ToPreviousActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.selectedBodyPart = null;
|
||||
Workspace.ActorID = Mathf.Clamp(Workspace.ActorID - 1, 0, Workspace.animationDef.Actors.Count - 1);
|
||||
}
|
||||
|
||||
public void ToNextActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.selectedBodyPart = null;
|
||||
Workspace.ActorID = Mathf.Clamp(Workspace.ActorID + 1, 0, Workspace.animationDef.Actors.Count - 1);
|
||||
}
|
||||
|
||||
public void ToPreviousTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.StageTick = Mathf.Clamp(Workspace.StageTick - 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
}
|
||||
|
||||
public void ToNextTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.StageTick = Mathf.Clamp(Workspace.StageTick + 1, Constants.minTick, Workspace.StageWindowSize);
|
||||
}
|
||||
|
||||
public void ToFirstTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.StageTick = Constants.minTick;
|
||||
}
|
||||
|
||||
public void ToLastTick()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
Workspace.StageTick = Workspace.StageWindowSize;
|
||||
}
|
||||
|
||||
public void ToPreviousKey()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
PawnKeyframe keyframe = Workspace.GetPreviousKeyframe(Workspace.ActorID);
|
||||
if (keyframe != null) Workspace.StageTick = keyframe.atTick.Value;
|
||||
}
|
||||
|
||||
public void ToNextKey()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
PawnKeyframe keyframe = Workspace.GetNextKeyframe(Workspace.ActorID);
|
||||
if (keyframe != null) Workspace.StageTick = keyframe.atTick.Value;
|
||||
}
|
||||
|
||||
public void ToPreviousStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
int prevStageID = Workspace.StageID;
|
||||
Workspace.StageID = Mathf.Clamp(Workspace.StageID - 1, 0, Workspace.animationDef.AnimationStages.Count - 1);
|
||||
|
||||
if (Workspace.StageID != prevStageID)
|
||||
{ Workspace.RecordEvent("Stage selected"); }
|
||||
}
|
||||
|
||||
public void ToNextStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
int prevStageID = Workspace.StageID;
|
||||
Workspace.StageID = Mathf.Clamp(Workspace.StageID + 1, 0, Workspace.animationDef.AnimationStages.Count - 1);
|
||||
|
||||
if (Workspace.StageID != prevStageID)
|
||||
{ Workspace.RecordEvent("Stage selected"); }
|
||||
}
|
||||
|
||||
public void CenterView()
|
||||
{
|
||||
Camera.main.GetComponent<CameraController>().ResetCamera();
|
||||
}
|
||||
|
||||
public void StretchKeyframesToggle()
|
||||
{
|
||||
Workspace.stretchKeyframes = !Workspace.stretchKeyframes;
|
||||
}
|
||||
|
||||
public void OpenProjectHome()
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(Constants.projectHome, UriKind.RelativeOrAbsolute))
|
||||
{ Application.OpenURL(Constants.projectHome); }
|
||||
}
|
||||
|
||||
public void OpenProjectWiki()
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(Constants.projectWiki, UriKind.RelativeOrAbsolute))
|
||||
{ Application.OpenURL(Constants.projectWiki); }
|
||||
}
|
||||
|
||||
public void AddActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.AddActor();
|
||||
}
|
||||
|
||||
public void RemoveActor()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.RemoveActor();
|
||||
}
|
||||
|
||||
public void AddStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.AddAnimationStage();
|
||||
}
|
||||
|
||||
public void CloneStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.CloneAnimationStage();
|
||||
}
|
||||
|
||||
public void RemoveStage()
|
||||
{
|
||||
if (Workspace.animationDef == null) return;
|
||||
|
||||
Workspace.animationDef.RemoveAnimationStage();
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/InputManager.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/InputManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 120c040fa90da65478716f3ccda1248f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
47
Source/Assets/Scripts/Managers/StageCardManager.cs
Normal file
47
Source/Assets/Scripts/Managers/StageCardManager.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageCardManager : Singleton<StageCardManager>
|
||||
{
|
||||
public StageCard stageCardPrefab;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EventsManager.onAnimationChanged.AddListener(delegate { Initialize(); });
|
||||
EventsManager.onStageIDChanged.AddListener(delegate { Initialize(); });
|
||||
EventsManager.onStageCountChanged.AddListener(delegate { Initialize(); });
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
int stageCount = Workspace.animationDef.AnimationStages.Count;
|
||||
int childCount = GetComponentsInChildren<StageCard>().Count();
|
||||
|
||||
for (int i = 0; i < Mathf.Max(stageCount, childCount); i++)
|
||||
{
|
||||
// Add new stage cards as required
|
||||
if (i >= childCount)
|
||||
{ Instantiate(stageCardPrefab, transform); }
|
||||
|
||||
// Get objects to update
|
||||
StageCard stageCard = GetComponentsInChildren<StageCard>()[i];
|
||||
|
||||
// Update values
|
||||
if (i < stageCount)
|
||||
{ stageCard.Initialize(Workspace.animationDef.AnimationStages[i].StageName); }
|
||||
|
||||
// Remove excess objects as required
|
||||
else
|
||||
{ Destroy(stageCard.gameObject); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Source/Assets/Scripts/Managers/StageCardManager.cs.meta
Normal file
11
Source/Assets/Scripts/Managers/StageCardManager.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7ecd16bf04b637f4c96d6ae733205d3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue