mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Code refactor
This commit is contained in:
parent
cd4711a8e5
commit
757badf4f6
517 changed files with 2534 additions and 2221 deletions
54
Assets/Scripts/Workspace/EventsManager.cs
Normal file
54
Assets/Scripts/Workspace/EventsManager.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
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> { }
|
||||
|
||||
// Event list
|
||||
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 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();
|
||||
|
||||
// Event invoking
|
||||
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 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(); }
|
||||
}
|
||||
}
|
11
Assets/Scripts/Workspace/EventsManager.cs.meta
Normal file
11
Assets/Scripts/Workspace/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:
|
|
@ -4,28 +4,55 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
public class Workspace : Singleton<Workspace>
|
||||
public static class Workspace
|
||||
{
|
||||
// Animation def
|
||||
public static AnimationDef animationDef;
|
||||
public static int stageID = 0;
|
||||
|
||||
public static List<int> keyframeID = new List<int>();
|
||||
|
||||
[SerializeField] private List<WorkspaceRecord> workspaceHistory = new List<WorkspaceRecord>();
|
||||
[SerializeField] private int maxHistoryDepth = 100;
|
||||
// Animation indices set / get
|
||||
public static int StageID
|
||||
{
|
||||
get { return Mathf.Clamp(stageID, 0, animationDef.AnimationStages.Count - 1); }
|
||||
set
|
||||
{
|
||||
bool triggerEvent = stageID != value;
|
||||
stageID = value;
|
||||
|
||||
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
|
||||
public static ActorBodyPart selectedBodyPart;
|
||||
if (triggerEvent)
|
||||
{
|
||||
StageTick = Constants.minTick;
|
||||
EventsManager.OnStageIDChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PawnKeyframe> copiedKeyframes = new List<PawnKeyframe>();
|
||||
public static int ActorID
|
||||
{
|
||||
get { return Mathf.Clamp(actorID, 0, animationDef.Actors.Count - 1); }
|
||||
set
|
||||
{
|
||||
bool triggerEvent = actorID != value;
|
||||
actorID = value;
|
||||
|
||||
public static string animationSavePath;
|
||||
if (triggerEvent) { EventsManager.OnActorIDChanged(); }
|
||||
}
|
||||
}
|
||||
|
||||
private static int _actorID = 0;
|
||||
public static int actorID { get { return Mathf.Clamp(_actorID, 0, animationDef.actors.Count - 1); } set { _actorID = value; } }
|
||||
public static int StageTick
|
||||
{
|
||||
get { return Mathf.Clamp(stageTick, Constants.minTick, StageWindowSize); }
|
||||
set
|
||||
{
|
||||
bool triggerEvent = stageTick != value;
|
||||
stageTick = value;
|
||||
|
||||
if (triggerEvent) { EventsManager.OnStageTickChanged(); }
|
||||
}
|
||||
}
|
||||
|
||||
public static int StageWindowSize
|
||||
{
|
||||
|
@ -34,58 +61,103 @@ namespace RimWorldAnimationStudio
|
|||
if (animationDef == null)
|
||||
{ return -1; }
|
||||
|
||||
if (animationDef.animationStages[stageID].stageWindowSize < 0)
|
||||
{ animationDef.animationStages[stageID].stageWindowSize = animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); }
|
||||
if (animationDef.AnimationStages[StageID].stageWindowSize < 0)
|
||||
{ animationDef.AnimationStages[StageID].stageWindowSize = animationDef.AnimationStages[StageID].AnimationClips.Select(x => x.duration).Max(); }
|
||||
|
||||
return animationDef.animationStages[stageID].stageWindowSize;
|
||||
return animationDef.AnimationStages[StageID].stageWindowSize;
|
||||
}
|
||||
}
|
||||
|
||||
public PawnKeyframe GetCurrentPawnKeyframe(bool makeKeyframe = false)
|
||||
// Selected keyframes and copied keyframe data
|
||||
public static List<int> keyframeID = new List<int>();
|
||||
public static List<PawnKeyframe> copiedKeyframes = new List<PawnKeyframe>();
|
||||
|
||||
// Actor manipulation
|
||||
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
|
||||
public static ActorBodyPart selectedBodyPart;
|
||||
|
||||
// Current save path
|
||||
public static string animationSavePath;
|
||||
|
||||
// Stage loop counts and stretching
|
||||
public static int stageLoopsNormal = 1;
|
||||
public static int stageLoopsQuick = 1;
|
||||
public static bool stretchKeyframes;
|
||||
|
||||
// Animation indices
|
||||
private static int stageID = 0;
|
||||
private static int actorID = 0;
|
||||
private static int stageTick = Constants.minTick;
|
||||
|
||||
// Workspace history
|
||||
private static LinkedList<WorkspaceRecord> pastSnapshots = new LinkedList<WorkspaceRecord>();
|
||||
private static LinkedList<WorkspaceRecord> futureSnapshots = new LinkedList<WorkspaceRecord>();
|
||||
private static int maxHistoryDepth = 100;
|
||||
|
||||
public static Actor GetCurrentActor()
|
||||
{
|
||||
int stageTick = AnimationController.Instance.stageTick;
|
||||
PawnKeyframe keyframe = animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
|
||||
return animationDef?.Actors[ActorID];
|
||||
}
|
||||
|
||||
public static AnimationStage GetCurrentAnimationStage()
|
||||
{
|
||||
return animationDef?.AnimationStages[StageID];
|
||||
}
|
||||
|
||||
public static PawnAnimationClip GetCurrentPawnAnimationClip()
|
||||
{
|
||||
return animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID];
|
||||
}
|
||||
|
||||
public static PawnKeyframe GetCurrentPawnKeyframe(bool makeKeyframe = false)
|
||||
{
|
||||
PawnKeyframe keyframe = animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID]?.Keyframes.FirstOrDefault(x => x.atTick == StageTick);
|
||||
|
||||
if (keyframe != null || makeKeyframe == false)
|
||||
{ return keyframe; }
|
||||
|
||||
AnimationController.Instance.AddPawnKeyframe();
|
||||
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick);
|
||||
GetCurrentPawnAnimationClip().AddPawnKeyframe();
|
||||
return animationDef?.AnimationStages[StageID]?.AnimationClips[ActorID]?.Keyframes.FirstOrDefault(x => x.atTick == StageTick);
|
||||
}
|
||||
|
||||
public List<PawnKeyframe> GetPawnKeyframesAtTick(int actorID, int atTick)
|
||||
public static Actor GetActor(int actorID)
|
||||
{
|
||||
return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.Where(x => x.atTick == atTick)?.ToList();
|
||||
return animationDef?.Actors[actorID];
|
||||
}
|
||||
|
||||
public PawnAnimationClip GetCurrentPawnAnimationClip()
|
||||
public static AnimationStage GetAnimationStage(int stageID)
|
||||
{
|
||||
return animationDef.animationStages[stageID].animationClips[actorID];
|
||||
return animationDef?.AnimationStages[stageID];
|
||||
}
|
||||
|
||||
public PawnAnimationClip GetPawnAnimationClip(int actorID)
|
||||
public static PawnAnimationClip GetPawnAnimationClip(int actorID)
|
||||
{
|
||||
return animationDef.animationStages[stageID].animationClips[actorID];
|
||||
return animationDef?.AnimationStages[StageID]?.AnimationClips[actorID];
|
||||
}
|
||||
|
||||
public PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID)
|
||||
public static PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID)
|
||||
{
|
||||
if (stageID < 0) return null;
|
||||
if (StageID < 0) return null;
|
||||
if (actorID < 0) return null;
|
||||
|
||||
if (stageID >= animationDef.animationStages.Count) return null;
|
||||
if (actorID >= animationDef.animationStages[stageID].animationClips.Count) return null;
|
||||
if (StageID >= animationDef.AnimationStages.Count) return null;
|
||||
if (actorID >= animationDef.AnimationStages[StageID].AnimationClips.Count) return null;
|
||||
|
||||
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
|
||||
return animationDef.AnimationStages[StageID].AnimationClips[actorID].Keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
|
||||
}
|
||||
|
||||
public List<PawnKeyframe> GetPawnKeyframesByID(List<int> keyframeIDs)
|
||||
public static List<PawnKeyframe> GetAllPawnKeyframesAtTick(int actorID, int atTick)
|
||||
{
|
||||
return animationDef?.AnimationStages[StageID]?.AnimationClips[actorID]?.Keyframes.Where(x => x.atTick == atTick)?.ToList();
|
||||
}
|
||||
|
||||
public static List<PawnKeyframe> GetPawnKeyframesByID(List<int> keyframeIDs)
|
||||
{
|
||||
List<PawnKeyframe> pawnKeyframes = new List<PawnKeyframe>();
|
||||
|
||||
foreach (PawnAnimationClip clip in animationDef.animationStages[stageID].animationClips)
|
||||
foreach (PawnAnimationClip clip in animationDef.AnimationStages[StageID].AnimationClips)
|
||||
{
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{
|
||||
if (keyframeIDs.Contains(keyframe.keyframeID))
|
||||
{ pawnKeyframes.Add(keyframe); }
|
||||
|
@ -95,15 +167,15 @@ namespace RimWorldAnimationStudio
|
|||
return pawnKeyframes;
|
||||
}
|
||||
|
||||
public PawnAnimationClip GetAnimationClipThatOwnsKeyframe(int keyframeID, out int clipID)
|
||||
public static PawnAnimationClip GetAnimationClipThatOwnsKeyframe(int keyframeID, out int clipID)
|
||||
{
|
||||
clipID = -1;
|
||||
|
||||
for (int i = 0; i < animationDef.animationStages[stageID].animationClips.Count; i++)
|
||||
for (int i = 0; i < animationDef.AnimationStages[StageID].AnimationClips.Count; i++)
|
||||
{
|
||||
PawnAnimationClip clip = animationDef.animationStages[stageID].animationClips[i];
|
||||
PawnAnimationClip clip = animationDef.AnimationStages[StageID].AnimationClips[i];
|
||||
|
||||
if (clip.keyframes.Any(x => x.keyframeID == keyframeID))
|
||||
if (clip.Keyframes.Any(x => x.keyframeID == keyframeID))
|
||||
{
|
||||
clipID = i;
|
||||
return clip;
|
||||
|
@ -113,19 +185,19 @@ namespace RimWorldAnimationStudio
|
|||
return null;
|
||||
}
|
||||
|
||||
public bool DoesPawnKeyframeExistAtTick(int stageID, int actorID, int atTick)
|
||||
public static bool DoesPawnKeyframeExistAtTick(int stageID, int actorID, int atTick)
|
||||
{
|
||||
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.Any(x => x.atTick == atTick);
|
||||
return animationDef.AnimationStages[stageID].AnimationClips[actorID].Keyframes.Any(x => x.atTick == atTick);
|
||||
}
|
||||
|
||||
public PawnKeyframe GetNextKeyframe(int actorID)
|
||||
public static PawnKeyframe GetNextKeyframe(int actorID)
|
||||
{
|
||||
PawnKeyframe pawnKeyframe = null;
|
||||
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
|
||||
|
||||
int stageTick = AnimationController.Instance.stageTick;
|
||||
int stageTick = Workspace.StageTick;
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{
|
||||
if (keyframe.atTick > stageTick)
|
||||
{ pawnKeyframe = keyframe; break; }
|
||||
|
@ -134,14 +206,14 @@ namespace RimWorldAnimationStudio
|
|||
return pawnKeyframe;
|
||||
}
|
||||
|
||||
public PawnKeyframe GetPreviousKeyframe(int actorID)
|
||||
public static PawnKeyframe GetPreviousKeyframe(int actorID)
|
||||
{
|
||||
PawnKeyframe pawnKeyframe = null;
|
||||
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
|
||||
|
||||
int stageTick = AnimationController.Instance.stageTick;
|
||||
int stageTick = Workspace.StageTick;
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{
|
||||
if (keyframe.atTick < stageTick)
|
||||
{ pawnKeyframe = keyframe; }
|
||||
|
@ -150,14 +222,14 @@ namespace RimWorldAnimationStudio
|
|||
return pawnKeyframe;
|
||||
}
|
||||
|
||||
public PawnKeyframe GetCurrentOrPreviousKeyframe(int actorID)
|
||||
public static PawnKeyframe GetCurrentOrPreviousKeyframe(int actorID)
|
||||
{
|
||||
PawnKeyframe pawnKeyframe = null;
|
||||
PawnAnimationClip clip = GetPawnAnimationClip(actorID);
|
||||
|
||||
int stageTick = AnimationController.Instance.stageTick;
|
||||
int stageTick = Workspace.StageTick;
|
||||
|
||||
foreach (PawnKeyframe keyframe in clip.keyframes)
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{
|
||||
if (keyframe.atTick <= stageTick)
|
||||
{ pawnKeyframe = keyframe; }
|
||||
|
@ -172,12 +244,12 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
if (excludedActorID >= 0)
|
||||
{
|
||||
keyframesToCheck = animationDef.animationStages[stageID].animationClips.Where(x =>
|
||||
animationDef.animationStages[stageID].animationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.keyframes)?.ToList();
|
||||
keyframesToCheck = animationDef.AnimationStages[StageID].AnimationClips.Where(x =>
|
||||
animationDef.AnimationStages[StageID].AnimationClips.IndexOf(x) != excludedActorID).SelectMany(x => x.Keyframes)?.ToList();
|
||||
}
|
||||
|
||||
else
|
||||
{ keyframesToCheck = animationDef.animationStages[stageID].animationClips.SelectMany(x => x.keyframes)?.ToList(); }
|
||||
{ keyframesToCheck = animationDef.AnimationStages[StageID].AnimationClips.SelectMany(x => x.Keyframes)?.ToList(); }
|
||||
|
||||
keyframesToCheck = keyframesToCheck.Where(x => Mathf.Abs(atTick - x.atTick.Value) <= searchDistance)?.ToList();
|
||||
|
||||
|
@ -199,36 +271,32 @@ namespace RimWorldAnimationStudio
|
|||
return bestAtTick;
|
||||
}
|
||||
|
||||
public int GetEarliestAtTickInCopiedKeyframes(int actorID)
|
||||
public static int GetEarliestAtTickInCopiedKeyframes(int actorID)
|
||||
{
|
||||
IEnumerable<Keyframe> keyframes = copiedKeyframes.Where(x => x.actorID == actorID);
|
||||
IEnumerable<PawnKeyframe> keyframes = copiedKeyframes.Where(x => x.actorID == actorID);
|
||||
if (keyframes == null || keyframes.Any() == false) return -1;
|
||||
|
||||
return keyframes.Min(x => x.atTick).Value;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
public LinkedList<WorkspaceRecord> pastSnapshots = new LinkedList<WorkspaceRecord>();
|
||||
public LinkedList<WorkspaceRecord> futureSnapshots = new LinkedList<WorkspaceRecord>();
|
||||
|
||||
|
||||
public void Reset()
|
||||
public static void Reset()
|
||||
{
|
||||
actorID = 0;
|
||||
stageID = 0;
|
||||
ActorID = 0;
|
||||
StageID = 0;
|
||||
keyframeID.Clear();
|
||||
selectedBodyPart = null;
|
||||
animationSavePath = null;
|
||||
|
||||
ClearHistory();
|
||||
}
|
||||
|
||||
public void MakeHistoricRecord(string eventDesc)
|
||||
public static void MakeHistoricRecord(string eventDesc)
|
||||
{
|
||||
WorkspaceRecord record = new WorkspaceRecord();
|
||||
record.recordID = pastSnapshots.Count;
|
||||
record.eventDesc = eventDesc;
|
||||
record.animationDef = animationDef.Copy();
|
||||
record.stageID = stageID;
|
||||
record.stageID = StageID;
|
||||
|
||||
futureSnapshots.Clear();
|
||||
pastSnapshots.AddLast(record);
|
||||
|
@ -237,16 +305,16 @@ namespace RimWorldAnimationStudio
|
|||
{ pastSnapshots.RemoveFirst(); }
|
||||
}
|
||||
|
||||
public void RestoreToHistoricRecord(WorkspaceRecord record)
|
||||
public static void RestoreToHistoricRecord(WorkspaceRecord record)
|
||||
{
|
||||
animationDef = record.animationDef.Copy();
|
||||
stageID = record.stageID;
|
||||
StageID = record.stageID;
|
||||
|
||||
AnimationController.Instance.MakeTimelineDirty();
|
||||
StageCardManager.Instance.Initialize();
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
public static void Undo()
|
||||
{
|
||||
WorkspaceRecord recordToRead = pastSnapshots.Last?.Previous?.Value;
|
||||
WorkspaceRecord recordToStore = pastSnapshots.Last?.Value;
|
||||
|
@ -258,9 +326,11 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
RestoreToHistoricRecord(recordToRead);
|
||||
Debug.Log("Undoing : " + recordToStore.eventDesc);
|
||||
|
||||
EventsManager.OnAnimationDefChanged();
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
public static void Redo()
|
||||
{
|
||||
WorkspaceRecord recordToReadAndStore = futureSnapshots.Last?.Value;
|
||||
|
||||
|
@ -271,15 +341,17 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
RestoreToHistoricRecord(recordToReadAndStore);
|
||||
Debug.Log("Redoing : " + recordToReadAndStore.eventDesc);
|
||||
|
||||
EventsManager.OnAnimationDefChanged();
|
||||
}
|
||||
|
||||
public void ClearHistory()
|
||||
public static void ClearHistory()
|
||||
{
|
||||
pastSnapshots.Clear();
|
||||
futureSnapshots.Clear();
|
||||
}
|
||||
|
||||
public void RecordEvent(string eventDesc)
|
||||
public static void RecordEvent(string eventDesc)
|
||||
{
|
||||
//Debug.Log("Recording event: " + eventDesc + " (record ID: " + pastSnapshots.Count + ")");
|
||||
MakeHistoricRecord(eventDesc);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue