Jelajahi Sumber

Separate camera and environment management

habeebweeb 4 tahun lalu
induk
melakukan
41cc1d20a2

+ 7 - 7
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/CameraPane.cs

@@ -5,16 +5,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     public class CameraPane : BasePane
     {
-        private readonly EnvironmentManager environmentManager;
+        private readonly CameraManager cameraManager;
         private readonly SelectionGrid cameraGrid;
         private readonly Slider zRotationSlider;
         private readonly Slider fovSlider;
         private string header;
 
-        public CameraPane(EnvironmentManager environmentManager)
+        public CameraPane(CameraManager cameraManager)
         {
-            this.environmentManager = environmentManager;
-            this.environmentManager.CameraChange += (s, a) => UpdatePane();
+            this.cameraManager = cameraManager;
+            this.cameraManager.CameraChange += (s, a) => UpdatePane();
 
             Camera camera = CameraUtility.MainCamera.camera;
             Vector3 eulerAngles = camera.transform.eulerAngles;
@@ -42,12 +42,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 camera.fieldOfView = fovSlider.Value;
             };
             cameraGrid = new SelectionGrid(
-                Enumerable.Range(1, environmentManager.CameraCount).Select(x => x.ToString()).ToArray()
+                Enumerable.Range(1, cameraManager.CameraCount).Select(x => x.ToString()).ToArray()
             );
             cameraGrid.ControlEvent += (s, a) =>
             {
                 if (updating) return;
-                environmentManager.CurrentCameraIndex = cameraGrid.SelectedItemIndex;
+                cameraManager.CurrentCameraIndex = cameraGrid.SelectedItemIndex;
             };
 
             header = Translation.Get("cameraPane", "header");
@@ -78,7 +78,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             zRotationSlider.Value = camera.transform.eulerAngles.z;
             fovSlider.Value = camera.fieldOfView;
 
-            cameraGrid.SelectedItemIndex = environmentManager.CurrentCameraIndex;
+            cameraGrid.SelectedItemIndex = cameraManager.CurrentCameraIndex;
 
             updating = false;
         }

+ 2 - 2
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/MainWindowPanes/BGWindowPane.cs

@@ -14,14 +14,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public BGWindowPane(
             EnvironmentManager environmentManager, LightManager lightManager, EffectManager effectManager,
-            SceneWindow sceneWindow
+            SceneWindow sceneWindow, CameraManager cameraManager
         )
         {
             sceneManagerButton = new Button(Translation.Get("backgroundWindow", "manageScenesButton"));
             sceneManagerButton.ControlEvent += (s, a) => sceneWindow.Visible = !sceneWindow.Visible;
 
             backgroundSelectorPane = AddPane(new BackgroundSelectorPane(environmentManager));
-            cameraPane = AddPane(new CameraPane(environmentManager));
+            cameraPane = AddPane(new CameraPane(cameraManager));
             dragPointPane = AddPane(new DragPointPane());
             lightsPane = AddPane(new LightsPane(lightManager));
 

+ 211 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/CameraManager.cs

@@ -0,0 +1,211 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine;
+using Object = UnityEngine.Object;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    using Input = InputManager;
+    using UInput = Input;
+    public class CameraManager : IManager, ISerializable
+    {
+        public const string header = "CAMERA";
+        private static readonly CameraMain mainCamera = CameraUtility.MainCamera;
+        private static readonly UltimateOrbitCamera ultimateOrbitCamera = CameraUtility.UOCamera;
+        private GameObject cameraObject;
+        private Camera subCamera;
+        private float defaultCameraMoveSpeed;
+        private float defaultCameraZoomSpeed;
+        private const float cameraFastMoveSpeed = 0.1f;
+        private const float cameraFastZoomSpeed = 3f;
+        private CameraInfo tempCameraInfo = new CameraInfo();
+        private const KeyCode AlphaOne = KeyCode.Alpha1;
+        public int CameraCount => cameraInfos.Length;
+        public EventHandler CameraChange;
+
+        private int currentCameraIndex;
+        public int CurrentCameraIndex
+        {
+            get => currentCameraIndex;
+            set
+            {
+                cameraInfos[currentCameraIndex].UpdateInfo(mainCamera);
+                currentCameraIndex = value;
+                LoadCameraInfo(cameraInfos[currentCameraIndex]);
+            }
+        }
+        private CameraInfo[] cameraInfos;
+
+        static CameraManager()
+        {
+            Input.Register(MpsKey.CameraLayer, KeyCode.Q, "Camera control layer");
+            Input.Register(MpsKey.CameraSave, KeyCode.S, "Save camera transform");
+            Input.Register(MpsKey.CameraLoad, KeyCode.A, "Load camera transform");
+            Input.Register(MpsKey.CameraReset, KeyCode.R, "Reset camera transform");
+        }
+
+        public CameraManager()
+        {
+            cameraInfos = new CameraInfo[5];
+            for (var i = 0; i < cameraInfos.Length; i++) cameraInfos[i] = new CameraInfo();
+            Activate();
+        }
+
+        public void Serialize(BinaryWriter binaryWriter) => Serialize(binaryWriter, false);
+
+        public void Serialize(BinaryWriter binaryWriter, bool kankyo)
+        {
+            binaryWriter.Write(header);
+
+            binaryWriter.Write(kankyo);
+
+            binaryWriter.WriteVector3(mainCamera.GetTargetPos());
+            binaryWriter.Write(mainCamera.GetDistance());
+            binaryWriter.WriteQuaternion(mainCamera.transform.rotation);
+
+            CameraUtility.StopAll();
+        }
+
+        public void Deserialize(BinaryReader binaryReader)
+        {
+            var kankyo = binaryReader.ReadBoolean();
+
+            Vector3 cameraPosition = binaryReader.ReadVector3();
+            var cameraDistance = binaryReader.ReadSingle();
+            Quaternion cameraRotation = binaryReader.ReadQuaternion();
+
+            if (kankyo) return;
+
+            mainCamera.SetTargetPos(cameraPosition);
+            mainCamera.SetDistance(cameraDistance);
+            mainCamera.transform.rotation = cameraRotation;
+            CameraUtility.StopAll();
+        }
+
+        public void Activate()
+        {
+            cameraObject = new GameObject("subCamera");
+            subCamera = cameraObject.AddComponent<Camera>();
+            subCamera.CopyFrom(mainCamera.camera);
+            subCamera.clearFlags = CameraClearFlags.Depth;
+            subCamera.cullingMask = 256;
+            subCamera.depth = 1f;
+            subCamera.transform.parent = mainCamera.transform;
+
+            cameraObject.SetActive(true);
+
+            ultimateOrbitCamera.enabled = true;
+
+            defaultCameraMoveSpeed = ultimateOrbitCamera.moveSpeed;
+            defaultCameraZoomSpeed = ultimateOrbitCamera.zoomSpeed;
+
+            if (!MeidoPhotoStudio.EditMode) ResetCamera();
+
+            currentCameraIndex = 0;
+
+            tempCameraInfo.Reset();
+
+            for (var i = 0; i < CameraCount; i++) cameraInfos[i].Reset();
+        }
+
+        public void Deactivate()
+        {
+            Object.Destroy(cameraObject);
+            Object.Destroy(subCamera);
+
+            mainCamera.camera.backgroundColor = Color.black;
+
+            ultimateOrbitCamera.moveSpeed = defaultCameraMoveSpeed;
+            ultimateOrbitCamera.zoomSpeed = defaultCameraZoomSpeed;
+
+            if (MeidoPhotoStudio.EditMode) return;
+
+            mainCamera.Reset(CameraMain.CameraType.Target, true);
+            mainCamera.SetTargetPos(new Vector3(0.5609447f, 1.380762f, -1.382336f));
+            mainCamera.SetDistance(1.6f);
+            mainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f));
+        }
+
+        public void Update()
+        {
+            if (Input.GetKey(MpsKey.CameraLayer))
+            {
+                if (Input.GetKeyDown(MpsKey.CameraSave)) SaveTempCamera();
+                else if (Input.GetKeyDown(MpsKey.CameraLoad)) LoadCameraInfo(tempCameraInfo);
+                else if (Input.GetKeyDown(MpsKey.CameraReset)) ResetCamera();
+
+                for (var i = 0; i < CameraCount; i++)
+                {
+                    if (i != CurrentCameraIndex && UInput.GetKeyDown(AlphaOne + i)) CurrentCameraIndex = i;
+                }
+            }
+
+            var shift = Input.Shift;
+            ultimateOrbitCamera.moveSpeed = shift ? cameraFastMoveSpeed : defaultCameraMoveSpeed;
+            ultimateOrbitCamera.zoomSpeed = shift ? cameraFastZoomSpeed : defaultCameraZoomSpeed;
+        }
+
+        private void SaveTempCamera()
+        {
+            tempCameraInfo.UpdateInfo(mainCamera);
+            CameraUtility.StopAll();
+        }
+
+        public void LoadCameraInfo(CameraInfo info)
+        {
+            info.Apply(mainCamera);
+            CameraUtility.StopAll();
+            CameraChange?.Invoke(this, EventArgs.Empty);
+        }
+
+        private void ResetCamera()
+        {
+            mainCamera.Reset(CameraMain.CameraType.Target, true);
+            mainCamera.SetTargetPos(new Vector3(0f, 0.9f, 0f));
+            mainCamera.SetDistance(3f);
+            CameraChange?.Invoke(this, EventArgs.Empty);
+        }
+    }
+
+    public class CameraInfo
+    {
+        public Vector3 TargetPos { get; set; }
+        public Quaternion Angle { get; set; }
+        public float Distance { get; set; }
+        public float FOV { get; set; }
+
+        public CameraInfo() => Reset();
+
+        public static CameraInfo FromCamera(CameraMain mainCamera)
+        {
+            var info = new CameraInfo();
+            info.UpdateInfo(mainCamera);
+            return info;
+        }
+
+        public void Reset()
+        {
+            TargetPos = new Vector3(0f, 0.9f, 0f);
+            Angle = Quaternion.Euler(10f, 180f, 0f);
+            Distance = 3f;
+            FOV = 35f;
+        }
+
+        public void UpdateInfo(CameraMain camera)
+        {
+            TargetPos = camera.GetTargetPos();
+            Angle = camera.transform.rotation;
+            Distance = camera.GetDistance();
+            FOV = camera.camera.fieldOfView;
+        }
+
+        public void Apply(CameraMain camera)
+        {
+            camera.SetTargetPos(TargetPos);
+            camera.SetDistance(Distance);
+            camera.transform.rotation = Angle;
+            camera.camera.fieldOfView = FOV;
+        }
+    }
+}

+ 38 - 184
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using UnityEngine;
@@ -7,12 +7,9 @@ using Object = UnityEngine.Object;
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     using Input = InputManager;
-    using UInput = Input;
     public class EnvironmentManager : IManager, ISerializable
     {
         private static readonly BgMgr bgMgr = GameMain.Instance.BgMgr;
-        private static readonly CameraMain mainCamera = CameraUtility.MainCamera;
-        private static readonly UltimateOrbitCamera ultimateOrbitCamera = CameraUtility.UOCamera;
         public const string header = "ENVIRONMENT";
         public const string defaultBg = "Theater";
         private const string myRoomPrefix = "マイルーム:";
@@ -40,12 +37,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         }
         private static event EventHandler CubeActiveChange;
         private static event EventHandler CubeSmallChange;
-        private GameObject cameraObject;
-        private Camera subCamera;
-        private GameObject bgObject;
         private Transform bg;
+        private GameObject bgObject;
         private DragPointBG bgDragPoint;
-        private string currentBGAsset = defaultBg;
+        public string CurrentBgAsset { get; private set; } = defaultBg;
         private bool bgVisible = true;
         public bool BGVisible
         {
@@ -56,35 +51,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 bgObject.SetActive(bgVisible);
             }
         }
-        private float defaultCameraMoveSpeed;
-        private float defaultCameraZoomSpeed;
-        private const float cameraFastMoveSpeed = 0.1f;
-        private const float cameraFastZoomSpeed = 3f;
-        private CameraInfo tempCameraInfo;
-        private int currentCameraIndex;
-        private const KeyCode AlphaOne = KeyCode.Alpha1;
-        public int CameraCount => cameraInfos.Length;
-        public EventHandler CameraChange;
-
-        public int CurrentCameraIndex
-        {
-            get => currentCameraIndex;
-            set
-            {
-                cameraInfos[currentCameraIndex] = mainCamera.GetInfo();
-                currentCameraIndex = value;
-                LoadCameraInfo(cameraInfos[currentCameraIndex]);
-            }
-        }
-        private CameraInfo[] cameraInfos;
-
-        static EnvironmentManager()
-        {
-            Input.Register(MpsKey.CameraLayer, KeyCode.Q, "Camera control layer");
-            Input.Register(MpsKey.CameraSave, KeyCode.S, "Save camera transform");
-            Input.Register(MpsKey.CameraLoad, KeyCode.A, "Load camera transform");
-            Input.Register(MpsKey.CameraReset, KeyCode.R, "Reset camera transform");
-        }
 
         public EnvironmentManager()
         {
@@ -92,62 +58,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             Activate();
         }
 
-        public void Serialize(BinaryWriter binaryWriter) => Serialize(binaryWriter, false);
-
-        public void Serialize(BinaryWriter binaryWriter, bool kankyo)
-        {
-            binaryWriter.Write(header);
-            binaryWriter.Write(currentBGAsset);
-            binaryWriter.WriteVector3(bg.position);
-            binaryWriter.WriteQuaternion(bg.rotation);
-            binaryWriter.WriteVector3(bg.localScale);
-
-            binaryWriter.Write(kankyo);
-
-            binaryWriter.WriteVector3(mainCamera.GetTargetPos());
-            binaryWriter.Write(mainCamera.GetDistance());
-            binaryWriter.WriteQuaternion(mainCamera.transform.rotation);
-
-            CameraUtility.StopAll();
-        }
-
-        public void Deserialize(BinaryReader binaryReader)
-        {
-            var bgAsset = binaryReader.ReadString();
-            var isCreative = Utility.IsGuidString(bgAsset);
-            List<string> bgList = isCreative
-                ? Constants.MyRoomCustomBGList.ConvertAll(kvp => kvp.Key)
-                : Constants.BGList;
-
-            var assetIndex = bgList.FindIndex(
-                asset => asset.Equals(bgAsset, StringComparison.InvariantCultureIgnoreCase)
-            );
-            if (assetIndex < 0)
-            {
-                Utility.LogWarning($"Could not load BG '{bgAsset}'");
-                isCreative = false;
-                bgAsset = defaultBg;
-            }
-            else bgAsset = bgList[assetIndex];
-
-            ChangeBackground(bgAsset, isCreative);
-            bg.position = binaryReader.ReadVector3();
-            bg.rotation = binaryReader.ReadQuaternion();
-            bg.localScale = binaryReader.ReadVector3();
-
-            var kankyo = binaryReader.ReadBoolean();
-
-            Vector3 cameraPosition = binaryReader.ReadVector3();
-            var cameraDistance = binaryReader.ReadSingle();
-            Quaternion cameraRotation = binaryReader.ReadQuaternion();
-
-            if (kankyo) return;
-
-            mainCamera.SetTargetPos(cameraPosition);
-            mainCamera.SetDistance(cameraDistance);
-            mainCamera.transform.rotation = cameraRotation;
-            CameraUtility.StopAll();
-        }
+        public void Update() { }
 
         public void Activate()
         {
@@ -156,37 +67,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             bgObject = bgMgr.Parent;
 
-            cameraObject = new GameObject("subCamera");
-            subCamera = cameraObject.AddComponent<Camera>();
-            subCamera.CopyFrom(mainCamera.camera);
-            subCamera.clearFlags = CameraClearFlags.Depth;
-            subCamera.cullingMask = 256;
-            subCamera.depth = 1f;
-            subCamera.transform.parent = mainCamera.transform;
-
-            cameraObject.SetActive(true);
-
             bgObject.SetActive(true);
-
-            ultimateOrbitCamera.enabled = true;
-
-            defaultCameraMoveSpeed = ultimateOrbitCamera.moveSpeed;
-            defaultCameraZoomSpeed = ultimateOrbitCamera.zoomSpeed;
-
-            if (!MeidoPhotoStudio.EditMode)
-            {
-                ResetCamera();
-                ChangeBackground(defaultBg);
-            }
-            else UpdateBG();
-
-            SaveTempCamera();
-
-            CameraInfo initalInfo = mainCamera.GetInfo();
-
-            cameraInfos = new CameraInfo[5];
-
-            for (var i = 0; i < CameraCount; i++) cameraInfos[i] = initalInfo;
+            
+            if (MeidoPhotoStudio.EditMode) UpdateBG();
+            else ChangeBackground(defaultBg);
 
             CubeSmallChange += OnCubeSmall;
             CubeActiveChange += OnCubeActive;
@@ -198,26 +82,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             BgMgrPatcher.ChangeBgEnd -= OnChangeEnd;
 
             DestroyDragPoint();
-            Object.Destroy(cameraObject);
-            Object.Destroy(subCamera);
-
             BGVisible = true;
-            mainCamera.camera.backgroundColor = Color.black;
-
-            ultimateOrbitCamera.moveSpeed = defaultCameraMoveSpeed;
-            ultimateOrbitCamera.zoomSpeed = defaultCameraZoomSpeed;
 
             if (MeidoPhotoStudio.EditMode) bgMgr.ChangeBg(defaultBg);
             else
             {
                 var isNight = GameMain.Instance.CharacterMgr.status.GetFlag("時間帯") == 3;
-
                 bgMgr.ChangeBg(isNight ? "ShinShitsumu_ChairRot_Night" : "ShinShitsumu_ChairRot");
-
-                mainCamera.Reset(CameraMain.CameraType.Target, true);
-                mainCamera.SetTargetPos(new Vector3(0.5609447f, 1.380762f, -1.382336f));
-                mainCamera.SetDistance(1.6f);
-                mainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f));
             }
 
             if (bgMgr.BgObject) bgMgr.BgObject.transform.localScale = Vector3.one;
@@ -226,23 +97,38 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             CubeActiveChange -= OnCubeActive;
         }
 
-        public void Update()
+        public void Serialize(BinaryWriter binaryWriter)
         {
-            if (Input.GetKey(MpsKey.CameraLayer))
-            {
-                if (Input.GetKeyDown(MpsKey.CameraSave)) SaveTempCamera();
-                else if (Input.GetKeyDown(MpsKey.CameraLoad)) LoadCameraInfo(tempCameraInfo);
-                else if (Input.GetKeyDown(MpsKey.CameraReset)) ResetCamera();
+            binaryWriter.Write(header);
+            binaryWriter.Write(CurrentBgAsset);
+            binaryWriter.WriteVector3(bg.position);
+            binaryWriter.WriteQuaternion(bg.rotation);
+            binaryWriter.WriteVector3(bg.localScale);
+        }
+        
+        public void Deserialize(BinaryReader binaryReader) 
+        { 
+            var bgAsset = binaryReader.ReadString();
+            var isCreative = Utility.IsGuidString(bgAsset);
+            List<string> bgList = isCreative
+                ? Constants.MyRoomCustomBGList.ConvertAll(kvp => kvp.Key)
+                : Constants.BGList;
 
-                for (var i = 0; i < CameraCount; i++)
-                {
-                    if (i != CurrentCameraIndex && UInput.GetKeyDown(AlphaOne + i)) CurrentCameraIndex = i;
-                }
+            var assetIndex = bgList.FindIndex(
+                asset => asset.Equals(bgAsset, StringComparison.InvariantCultureIgnoreCase)
+            );
+            if (assetIndex < 0)
+            {
+                Utility.LogWarning($"Could not load BG '{bgAsset}'");
+                isCreative = false;
+                bgAsset = defaultBg;
             }
+            else bgAsset = bgList[assetIndex];
 
-            var shift = Input.Shift;
-            ultimateOrbitCamera.moveSpeed = shift ? cameraFastMoveSpeed : defaultCameraMoveSpeed;
-            ultimateOrbitCamera.zoomSpeed = shift ? cameraFastZoomSpeed : defaultCameraZoomSpeed;
+            ChangeBackground(bgAsset, isCreative);
+            bg.position = binaryReader.ReadVector3();
+            bg.rotation = binaryReader.ReadQuaternion();
+            bg.localScale = binaryReader.ReadVector3();
         }
 
         public void ChangeBackground(string assetName, bool creative = false)
@@ -269,9 +155,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             if (!bgMgr.BgObject) return;
 
-            currentBGAsset = bgMgr.GetBGName();
-            if (currentBGAsset.StartsWith(myRoomPrefix))
-                currentBGAsset = currentBGAsset.Replace(myRoomPrefix, string.Empty);
+            CurrentBgAsset = bgMgr.GetBGName();
+            if (CurrentBgAsset.StartsWith(myRoomPrefix))
+                CurrentBgAsset = CurrentBgAsset.Replace(myRoomPrefix, string.Empty);
             bg = bgMgr.BgObject.transform;
             AttachDragPoint(bg);
         }
@@ -281,22 +167,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             if (bgDragPoint) Object.Destroy(bgDragPoint.gameObject);
         }
 
-        private void SaveTempCamera() => tempCameraInfo = mainCamera.GetInfo(true);
-
-        public void LoadCameraInfo(CameraInfo info)
-        {
-            mainCamera.ApplyInfo(info, true);
-            CameraChange?.Invoke(this, EventArgs.Empty);
-        }
-
-        private void ResetCamera()
-        {
-            mainCamera.Reset(CameraMain.CameraType.Target, true);
-            mainCamera.SetTargetPos(new Vector3(0f, 0.9f, 0f));
-            mainCamera.SetDistance(3f);
-            CameraChange?.Invoke(this, EventArgs.Empty);
-        }
-
         private void OnCubeSmall(object sender, EventArgs args)
         {
             bgDragPoint.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
@@ -307,20 +177,4 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             bgDragPoint.gameObject.SetActive(CubeActive);
         }
     }
-
-    public readonly struct CameraInfo
-    {
-        public Vector3 TargetPos { get; }
-        public Quaternion Angle { get; }
-        public float Distance { get; }
-        public float FOV { get; }
-
-        public CameraInfo(CameraMain camera)
-        {
-            TargetPos = camera.GetTargetPos();
-            Angle = camera.transform.rotation;
-            Distance = camera.GetDistance();
-            FOV = camera.camera.fieldOfView;
-        }
-    }
 }

+ 15 - 5
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MeidoPhotoStudio.cs

@@ -32,6 +32,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private LightManager lightManager;
         private PropManager propManager;
         private EffectManager effectManager;
+        private CameraManager cameraManager;
         private static Constants.Scene currentScene;
         private bool initialized;
         private bool active;
@@ -86,7 +87,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 binaryWriter.Write(kankyo ? kankyoMagic : meidoManager.ActiveMeidoList.Count);
 
                 effectManager.Serialize(binaryWriter);
-                environmentManager.Serialize(binaryWriter, kankyo);
+                environmentManager.Serialize(binaryWriter);
                 lightManager.Serialize(binaryWriter);
 
                 if (!kankyo)
@@ -173,9 +174,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                         return;
                     }
 
-                    if (binaryReader.ReadInt32() > sceneVersion)
+                    var version = binaryReader.ReadInt32();
+
+                    if (version > sceneVersion)
                     {
-                        Utility.LogWarning($"'{filePath}' is made in a newer version of {pluginName}");
+                        Utility.LogWarning($"'{filePath}' is newer than the current version"
+                        + $"Scene's version: {version}, current version: {sceneVersion}");
                         return;
                     }
 
@@ -191,6 +195,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                             case EnvironmentManager.header:
                                 environmentManager.Deserialize(binaryReader);
                                 break;
+                            case CameraManager.header:
+                                environmentManager.Deserialize(binaryReader);
+                                break;
                             case MeidoManager.header:
                                 meidoManager.Deserialize(binaryReader);
                                 break;
@@ -250,7 +257,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     }
 
                     meidoManager.Update();
-                    environmentManager.Update();
+                    cameraManager.Update();
                     windowManager.Update();
                     effectManager.Update();
                     sceneManager.Update();
@@ -395,6 +402,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             lightManager = new LightManager();
             propManager = new PropManager(meidoManager);
             sceneManager = new SceneManager(this);
+            cameraManager = new CameraManager();
 
             effectManager = new EffectManager();
             effectManager.AddManager<BloomEffectManager>();
@@ -419,7 +427,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     [Constants.Window.Pose] = new PoseWindowPane(meidoManager, maidSwitcherPane),
                     [Constants.Window.Face] = new FaceWindowPane(meidoManager, maidSwitcherPane),
                     [Constants.Window.BG] = new BGWindowPane(
-                        environmentManager, lightManager, effectManager, sceneWindow
+                        environmentManager, lightManager, effectManager, sceneWindow, cameraManager
                     ),
                     [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
                     [Constants.Window.Settings] = new SettingsWindowPane()
@@ -438,6 +446,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 meidoManager.Activate();
                 environmentManager.Activate();
+                cameraManager.Activate();
                 propManager.Activate();
                 lightManager.Activate();
                 effectManager.Activate();
@@ -471,6 +480,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
                 meidoManager.Deactivate();
                 environmentManager.Deactivate();
+                cameraManager.Deactivate();
                 propManager.Deactivate();
                 lightManager.Deactivate();
                 effectManager.Deactivate();

+ 1 - 16
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Utility.cs

@@ -237,22 +237,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public static CameraMain MainCamera => GameMain.Instance.MainCamera;
         public static UltimateOrbitCamera UOCamera { get; } =
             GameMain.Instance.MainCamera.GetComponent<UltimateOrbitCamera>();
-
-        public static void ApplyInfo(this CameraMain camera, CameraInfo info, bool stop = false)
-        {
-            camera.SetTargetPos(info.TargetPos);
-            camera.SetDistance(info.Distance);
-            camera.transform.rotation = info.Angle;
-            camera.camera.fieldOfView = info.FOV;
-            if (stop) StopAll();
-        }
-
-        public static CameraInfo GetInfo(this CameraMain camera, bool stop = false)
-        {
-            if (stop) StopAll();
-            return new CameraInfo(camera);
-        }
-
+        
         public static void StopSpin()
         {
             Utility.SetFieldValue(UOCamera, "xVelocity", 0f);