UniversalViewer/Assets/Scripts/ModelViewerBase/ModelViewerMain.cs

231 lines
6.0 KiB
C#

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<ObjectContainer> SelectedObjects = new List<ObjectContainer>();
public static UnityEvent<ObjectContainer> OnObjectDeleteEvent = new UnityEvent<ObjectContainer>();
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<T>() 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<SceneContainer>(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<T>() where T: ObjectContainer
{
return SelectedObject as T;
}
public T GetCurrentScene<T>() 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();
}
}
/// <summary> Replace with custom type if game requires it </summary>
public virtual void EmptySceneDefault()
{
EmptyScene<SceneContainer>();
}
public void EmptyScene<T>() where T : SceneContainer, new()
{
CurrentScene?.Destroy();
CurrentScene = SceneContainer.Create<T>(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;
}
}
}
}