UniversalViewer/Assets/KF3/Scripts/Containers/KF3SceneContainer.cs

185 lines
5.8 KiB
C#
Raw Normal View History

using KF3.Containers;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class KF3SceneContainer : SceneContainer
{
public string BackgroundName = "";
public Dictionary<string, GameObject> Backgrounds = new Dictionary<string, GameObject>();
public string StageName = "";
public Dictionary<string, GameObject> Stages = new Dictionary<string, GameObject>();
public List<GameObject> InstantiatedObjects = new List<GameObject>();
public List<FrameContent> Frames = new List<FrameContent>();
public UIKF3SceneSettings Settings;
protected KF3ModelViewerMain Main => KF3ModelViewerMain.Instance;
public override void Init(ModelViewerMain main1)
{
var main = main1 as KF3ModelViewerMain;
base.Init(main);
Settings = UIKF3SceneSettings.Create(this);
InstantiatedObjects.Add(Settings.gameObject);
if (main.UI != null)
{
KF3ModelViewerInterface.SetDropdownData(Settings.StageDropdown, KF3ModelViewerMain.Instance.Assets.Stages.Select(s => s.DisplayName).ToList(), true);
KF3ModelViewerInterface.SetDropdownData(Settings.BackgroundDropdown, KF3ModelViewerMain.Instance.Assets.Skies.Select(s => s.DisplayName).ToList(), true);
}
}
public void SetBackground(string newBackground)
{
if (newBackground == BackgroundName) return;
var currentBackground = BackgroundName;
if (newBackground != "")
{
if (!Backgrounds.ContainsKey(newBackground))
{
Backgrounds[newBackground] = null;
KF3ModelViewerMain.Instance.StartCoroutine(Main.Builder.SpawnAsset(newBackground, bg =>
{
Backgrounds[newBackground] = bg;
InstantiatedObjects.Add(bg);
}));
}
else
{
Backgrounds[newBackground]?.SetActive(true);
}
}
if (currentBackground != "")
{
Backgrounds[currentBackground]?.SetActive(false);
var currentFrame = TimelineController.Instance.CurrentFrame;
bool containsCurrent = Frames.Where(f => (f.ObjectData as SceneKeyframe).Background == currentBackground && f.FrameNum != currentFrame).Any();
if (!containsCurrent)
{
KF3ModelViewerMain.DisposeOf(Backgrounds[currentBackground]);
Backgrounds.Remove(currentBackground);
}
}
BackgroundName = newBackground;
}
public void SetStage(string newStage)
{
if (newStage == StageName) return;
var currentStage = StageName;
if (newStage != "")
{
if (!Stages.ContainsKey(newStage))
{
Stages[newStage] = null;
KF3ModelViewerMain.Instance.StartCoroutine(Main.Builder.SpawnAsset(newStage, bg =>
{
Stages[newStage] = bg;
InstantiatedObjects.Add(bg);
}));
}
else
{
Stages[newStage]?.SetActive(true);
}
}
if (currentStage != "")
{
Stages[currentStage]?.SetActive(false);
var currentFrame = TimelineController.Instance.CurrentFrame;
bool containsCurrent = Frames.Where(f => (f.ObjectData as SceneKeyframe).Stage == currentStage && f.FrameNum != currentFrame).Any();
if (!containsCurrent)
{
KF3ModelViewerMain.DisposeOf(Stages[currentStage]);
Stages.Remove(currentStage);
}
}
StageName = newStage;
}
public KeyframeData SerializeFrame()
{
return new SceneKeyframe(this);
}
public override SceneSerializable Serialize()
{
return new KF3SceneSerializable(this);
}
public void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
{
var frame = (frame1 as SceneKeyframe).Lerp(frame2, amount) as SceneKeyframe;
SetBackground(frame.Background);
SetStage(frame.Stage);
}
public void GetClosestFrames(int frame, out FrameContent previousFrame, out FrameContent nextFrame)
{
previousFrame = null;
nextFrame = null;
var frames = Frames.OrderBy(f => f.FrameNum).ToArray();
for (int i = 0; i < Frames.Count; i++)
{
if (Frames[i].FrameNum < frame)
{
previousFrame = nextFrame = frames[i];
}
else if (Frames[i].FrameNum == frame)
{
previousFrame = nextFrame = frames[i];
break;
}
else if (Frames[i].FrameNum > frame)
{
if (previousFrame == null) previousFrame = frames[i];
nextFrame = frames[i];
break;
}
}
}
public virtual void SetKeyframe(int frameNum = -1)
{
if (frameNum == -1) frameNum = TimelineController.Instance.CurrentFrame;
GetClosestFrames(frameNum, out var previousFrame, out var nextFrame);
FrameContent currentFrame = null;
if (previousFrame == null || previousFrame.FrameNum != frameNum)
{
currentFrame = new FrameContent(frameNum);
Frames.Add(currentFrame);
Frames = Frames.OrderBy(f => f.FrameNum).ToList();
}
else if (previousFrame.FrameNum == frameNum) currentFrame = previousFrame;
else if (nextFrame.FrameNum == frameNum) currentFrame = nextFrame;
currentFrame.SetObjectData(SerializeFrame());
TimelineController.UpdateTimeline();
}
public void SetDefaultFrame()
{
Frames = new List<FrameContent>()
{
new FrameContent(0).SetObjectData(SerializeFrame())
};
}
}