using KF3.Containers; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; public class KF3SceneContainer : SceneContainer { public string BackgroundName = ""; public Dictionary Backgrounds = new Dictionary(); public string StageName = ""; public Dictionary Stages = new Dictionary(); public List InstantiatedObjects = new List(); public List Frames = new List(); 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() { new FrameContent(0).SetObjectData(SerializeFrame()) }; } }