mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Stage cards and basic stage management
This commit is contained in:
parent
1dd7781179
commit
f0d46df3d6
200 changed files with 2829 additions and 81 deletions
|
@ -181,6 +181,8 @@ namespace RimWorldAnimationStudio
|
|||
animationTimeline.Initialize(actorID);
|
||||
}
|
||||
|
||||
StageCardManager.Instance.Initialize();
|
||||
|
||||
Workspace.isDirty = false;
|
||||
|
||||
UpdateAnimation();
|
||||
|
@ -204,6 +206,72 @@ namespace RimWorldAnimationStudio
|
|||
actorBodies.Clear();
|
||||
}
|
||||
|
||||
public bool AddAnimationStage()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CloneAnimationStage()
|
||||
{
|
||||
AnimationStage stage = Workspace.animationDef.animationStages[Workspace.stageID].Copy();
|
||||
stage.Initialize();
|
||||
stage.stageName += " (Clone)";
|
||||
|
||||
Workspace.animationDef.animationStages.Insert(Workspace.stageID + 1, stage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool MoveAnimationStage(int startIndex, int delta)
|
||||
{
|
||||
if (startIndex + delta < 0 || startIndex + delta >= Workspace.animationDef.animationStages.Count)
|
||||
{ return false; }
|
||||
|
||||
AnimationStage stage = Workspace.animationDef.animationStages[startIndex];
|
||||
Workspace.animationDef.animationStages[startIndex] = Workspace.animationDef.animationStages[startIndex + delta];
|
||||
Workspace.animationDef.animationStages[startIndex + delta] = stage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveAnimationStage()
|
||||
{
|
||||
if (Workspace.animationDef.animationStages.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("Cannot delete animation stage - the animation must contain at least one animation stage.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Workspace.animationDef.animationStages.RemoveAt(Workspace.stageID);
|
||||
Workspace.stageID = Workspace.stageID >= Workspace.animationDef.animationStages.Count ? Workspace.stageID = Workspace.animationDef.animationStages.Count - 1 : Workspace.stageID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddActor()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveActor()
|
||||
{
|
||||
if (Workspace.animationDef.actors.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("Cannot delete actor - the animation must contain at least one actor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{ stage.animationClips.RemoveAt(Workspace.actorID); }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ToggleAnimation()
|
||||
{
|
||||
isAnimating = !isAnimating;
|
||||
|
|
61
Assets/Scripts/GUI/StageCard.cs
Normal file
61
Assets/Scripts/GUI/StageCard.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageCard : MonoBehaviour
|
||||
{
|
||||
private Image banner;
|
||||
private Toggle toggle;
|
||||
|
||||
public void OnNameChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnSelectStage()
|
||||
{
|
||||
if (GetComponent<Toggle>().isOn && Workspace.stageID != transform.GetSiblingIndex())
|
||||
{ Workspace.stageID = transform.GetSiblingIndex(); }
|
||||
}
|
||||
|
||||
public void OnMoveStage(int delta)
|
||||
{
|
||||
if (AnimationController.Instance.MoveAnimationStage(transform.GetSiblingIndex(), delta))
|
||||
{
|
||||
int siblingCount = transform.parent.childCount;
|
||||
int index = Mathf.Clamp(transform.GetSiblingIndex() + delta, 0, siblingCount - 1);
|
||||
|
||||
transform.SetSiblingIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
banner = transform.Find("Banner").GetComponent<Image>();
|
||||
toggle = GetComponent<Toggle>();
|
||||
toggle.group = StageCardManager.Instance.GetComponent<ToggleGroup>();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Workspace.stageID == transform.GetSiblingIndex())
|
||||
{
|
||||
banner.gameObject.SetActive(true);
|
||||
|
||||
if (toggle.isOn == false)
|
||||
{ toggle.isOn = true; }
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
banner.gameObject.SetActive(false);
|
||||
|
||||
if (toggle.isOn)
|
||||
{ toggle.isOn = false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/GUI/StageCard.cs.meta
Normal file
11
Assets/Scripts/GUI/StageCard.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 20b2be62d5fdc4b4992cede005ec2aee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
131
Assets/Scripts/ObjectExtensions.cs
Normal file
131
Assets/Scripts/ObjectExtensions.cs
Normal file
|
@ -0,0 +1,131 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.ArrayExtensions;
|
||||
|
||||
namespace System
|
||||
{
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
public static bool IsPrimitive(this Type type)
|
||||
{
|
||||
if (type == typeof(String)) return true;
|
||||
return (type.IsValueType & type.IsPrimitive);
|
||||
}
|
||||
|
||||
public static Object Copy(this Object originalObject)
|
||||
{
|
||||
return InternalCopy(originalObject, new Dictionary<Object, Object>(new ReferenceEqualityComparer()));
|
||||
}
|
||||
|
||||
private static Object InternalCopy(Object originalObject, IDictionary<Object, Object> visited)
|
||||
{
|
||||
if (originalObject == null) return null;
|
||||
var typeToReflect = originalObject.GetType();
|
||||
if (IsPrimitive(typeToReflect)) return originalObject;
|
||||
if (visited.ContainsKey(originalObject)) return visited[originalObject];
|
||||
if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null;
|
||||
var cloneObject = CloneMethod.Invoke(originalObject, null);
|
||||
if (typeToReflect.IsArray)
|
||||
{
|
||||
var arrayType = typeToReflect.GetElementType();
|
||||
if (IsPrimitive(arrayType) == false)
|
||||
{
|
||||
Array clonedArray = (Array)cloneObject;
|
||||
clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
|
||||
}
|
||||
|
||||
}
|
||||
visited.Add(originalObject, cloneObject);
|
||||
CopyFields(originalObject, visited, cloneObject, typeToReflect);
|
||||
RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect);
|
||||
return cloneObject;
|
||||
}
|
||||
|
||||
private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary<object, object> visited, object cloneObject, Type typeToReflect)
|
||||
{
|
||||
if (typeToReflect.BaseType != null)
|
||||
{
|
||||
RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
|
||||
CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, info => info.IsPrivate);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyFields(object originalObject, IDictionary<object, object> visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy, Func<FieldInfo, bool> filter = null)
|
||||
{
|
||||
foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags))
|
||||
{
|
||||
if (filter != null && filter(fieldInfo) == false) continue;
|
||||
if (IsPrimitive(fieldInfo.FieldType)) continue;
|
||||
var originalFieldValue = fieldInfo.GetValue(originalObject);
|
||||
var clonedFieldValue = InternalCopy(originalFieldValue, visited);
|
||||
fieldInfo.SetValue(cloneObject, clonedFieldValue);
|
||||
}
|
||||
}
|
||||
public static T Copy<T>(this T original)
|
||||
{
|
||||
return (T)Copy((Object)original);
|
||||
}
|
||||
}
|
||||
|
||||
public class ReferenceEqualityComparer : EqualityComparer<Object>
|
||||
{
|
||||
public override bool Equals(object x, object y)
|
||||
{
|
||||
return ReferenceEquals(x, y);
|
||||
}
|
||||
public override int GetHashCode(object obj)
|
||||
{
|
||||
if (obj == null) return 0;
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
namespace ArrayExtensions
|
||||
{
|
||||
public static class ArrayExtensions
|
||||
{
|
||||
public static void ForEach(this Array array, Action<Array, int[]> action)
|
||||
{
|
||||
if (array.LongLength == 0) return;
|
||||
ArrayTraverse walker = new ArrayTraverse(array);
|
||||
do action(array, walker.Position);
|
||||
while (walker.Step());
|
||||
}
|
||||
}
|
||||
|
||||
internal class ArrayTraverse
|
||||
{
|
||||
public int[] Position;
|
||||
private int[] maxLengths;
|
||||
|
||||
public ArrayTraverse(Array array)
|
||||
{
|
||||
maxLengths = new int[array.Rank];
|
||||
for (int i = 0; i < array.Rank; ++i)
|
||||
{
|
||||
maxLengths[i] = array.GetLength(i) - 1;
|
||||
}
|
||||
Position = new int[array.Rank];
|
||||
}
|
||||
|
||||
public bool Step()
|
||||
{
|
||||
for (int i = 0; i < Position.Length; ++i)
|
||||
{
|
||||
if (Position[i] < maxLengths[i])
|
||||
{
|
||||
Position[i]++;
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
Position[j] = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/ObjectExtensions.cs.meta
Normal file
11
Assets/Scripts/ObjectExtensions.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f7f234a811195334b8390740155d41dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
50
Assets/Scripts/StageCardManager.cs
Normal file
50
Assets/Scripts/StageCardManager.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class StageCardManager : Singleton<StageCardManager>
|
||||
{
|
||||
public StageCard stageCardPrefab;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
foreach(AnimationStage stage in Workspace.animationDef.animationStages)
|
||||
{
|
||||
MakeStageCard(stage.stageName);
|
||||
}
|
||||
}
|
||||
|
||||
public StageCard MakeStageCard(string stageName = null)
|
||||
{
|
||||
StageCard stageCard = Instantiate(stageCardPrefab, transform);
|
||||
|
||||
if (stageName != null)
|
||||
{ stageCard.transform.Find("StageNameField").GetComponent<InputField>().text = stageName; }
|
||||
|
||||
return stageCard;
|
||||
}
|
||||
|
||||
public void OnNewStage()
|
||||
{
|
||||
MakeStageCard();
|
||||
}
|
||||
|
||||
public void OnCloneStage()
|
||||
{
|
||||
if (AnimationController.Instance.CloneAnimationStage())
|
||||
{
|
||||
StageCard stageCard = MakeStageCard(Workspace.animationDef.animationStages[Workspace.stageID + 1].stageName);
|
||||
stageCard.transform.SetSiblingIndex(Workspace.stageID + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDeleteStage()
|
||||
{
|
||||
if (AnimationController.Instance.RemoveAnimationStage())
|
||||
{ Destroy(transform.GetChild(Workspace.stageID).gameObject); }
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/StageCardManager.cs.meta
Normal file
11
Assets/Scripts/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