using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine.Events; public class ModelViewerMain : MonoBehaviour { protected static ModelViewerMain _mainInstance; [Header("Required")] public CameraContainer MainCameraOrbit; public CameraContainer WorkCameraOrbit; [Header("Runtime")] public OperationMode Mode; public SceneContainer CurrentScene; public ObjectContainer SelectedObject; public List SelectedObjects = new List(); public static UnityEvent OnObjectDeleteEvent = new UnityEvent(); protected float[] _backupTimes = new float[] { 15 * 60, 5 * 60, 60 }; protected float[] _backupTimers; public enum OperationMode { Single, Multiple } public static ModelViewerMain GetInstance() { return _mainInstance; } public static T GetInstance() where T : ModelViewerMain { return _mainInstance as T; } protected virtual void Awake() { ModelViewerSettings.Load(); _backupTimers = _backupTimes.ToArray(); if(CurrentScene == null) { Debug.LogError("Custom model viewer should create a new scene in Awake()"); CurrentScene = SceneContainer.Create(this); } _mainInstance = this; } public CameraOrbit GetCamera() { return MainCameraOrbit.Camera; } public CameraContainer GetCameraHandler() { if (!MainCameraOrbit.LineRenderer.enabled) return MainCameraOrbit; else return WorkCameraOrbit; } public static void RegisterObject(ObjectContainer container) { if (!GetInstance().CurrentScene.AllObjects.Contains(container)) { GetInstance().CurrentScene.AllObjects.Add(container); } var selector = UITimelineObjectEntry.Create(container); container.InstantiatedObjects.Add(selector.gameObject); } public static void UnregisterObject(ObjectContainer container) { var instance = GetInstance(); instance.CurrentScene.AllObjects.Remove(container); instance.SelectionRemove(container); if (instance.SelectedObject == container) { instance.SelectObject(null); } } public T GetSelectedObject() where T: ObjectContainer { return SelectedObject as T; } public T GetCurrentScene() where T : SceneContainer { return CurrentScene as T; } public void SelectObject(ObjectContainer container) { if (SelectedObject == container) return; SelectedObject?.Deselect(); SelectedObject = container; SelectedObject?.Select(); TimelineController.UpdateTimeline(); } public void SelectionAdd(ObjectContainer container) { if (container == null) return; if (SelectedObjects.Count == 0) { SelectedObjects.Add(container); SelectObject(container); } else if(container != null && !SelectedObjects.Contains(container)) { SelectedObjects.Add(container); } } public void SelectionRemove(ObjectContainer container) { if (container == null) return; bool wasSelected = container == SelectedObject; if (container != null && SelectedObjects.Contains(container)) { SelectedObjects.Remove(container); if (wasSelected) { if(SelectedObjects.Count > 0) { SelectObject(SelectedObjects[0]); } else { SelectObject(null); } } } } public virtual void SelectionClear() { SelectedObjects.Clear(); } public void PrepareForLoad() { if (Mode == OperationMode.Single) { EmptySceneDefault(); } } /// Replace with custom type if game requires it public virtual void EmptySceneDefault() { EmptyScene(); } public void EmptyScene() where T : SceneContainer, new() { CurrentScene?.Destroy(); CurrentScene = SceneContainer.Create(this); ModelViewerMain.GetInstance().SelectionClear(); TimelineController.UpdateTimeline(); } public SceneSerializable SaveScene() { return CurrentScene.Serialize(); } public virtual IEnumerator LoadScene(SceneSerializable bc) { EmptySceneDefault(); ObjectContainerSerializable cameraFrameData = null; foreach (var c in bc.Objects) { if (c.GUID == "cameraOrbit") { cameraFrameData = c; } else { yield return ModelBuilder.GetInstance().SpawnSerializedCoroutine(c); } } //deserialize camera last yield return 0; MainCameraOrbit.DeserializeFrames(cameraFrameData); bc.Timeline.Deserialize(TimelineController.Instance); TimelineController.SetCurrentFrame(TimelineController.Instance.CurrentFrame); //CurrentScene.AllObjects[1].PastePose(CurrentScene.AllObjects[1].Frames[0].ObjectData, PoseLoadOptions.All()); } protected void AutoSaveUpdate() { bool skip = false; for (int i = 0; i < _backupTimes.Length; i++) { _backupTimers[i] -= Time.deltaTime; if (skip) { _backupTimers[i] = _backupTimes[i]; } else if (_backupTimers[i] <= 0) { _backupTimers[i] = _backupTimes[i]; var scene = SaveScene(); scene.Filename = $"AutoBackup_{_backupTimes[i]}"; UISceneContainer.CreateNew(scene, true).Save(true); skip = true; } } } }