CameraManager.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using Object = UnityEngine.Object;
  6. namespace COM3D2.MeidoPhotoStudio.Plugin
  7. {
  8. using Input = InputManager;
  9. using UInput = Input;
  10. public class CameraManager : IManager, ISerializable
  11. {
  12. public const string header = "CAMERA";
  13. private static readonly CameraMain mainCamera = CameraUtility.MainCamera;
  14. private static readonly UltimateOrbitCamera ultimateOrbitCamera = CameraUtility.UOCamera;
  15. private GameObject cameraObject;
  16. private Camera subCamera;
  17. private float defaultCameraMoveSpeed;
  18. private float defaultCameraZoomSpeed;
  19. private const float cameraFastMoveSpeed = 0.1f;
  20. private const float cameraFastZoomSpeed = 3f;
  21. private CameraInfo tempCameraInfo = new CameraInfo();
  22. private const KeyCode AlphaOne = KeyCode.Alpha1;
  23. public int CameraCount => cameraInfos.Length;
  24. public EventHandler CameraChange;
  25. private int currentCameraIndex;
  26. public int CurrentCameraIndex
  27. {
  28. get => currentCameraIndex;
  29. set
  30. {
  31. cameraInfos[currentCameraIndex].UpdateInfo(mainCamera);
  32. currentCameraIndex = value;
  33. LoadCameraInfo(cameraInfos[currentCameraIndex]);
  34. }
  35. }
  36. private CameraInfo[] cameraInfos;
  37. static CameraManager()
  38. {
  39. Input.Register(MpsKey.CameraLayer, KeyCode.Q, "Camera control layer");
  40. Input.Register(MpsKey.CameraSave, KeyCode.S, "Save camera transform");
  41. Input.Register(MpsKey.CameraLoad, KeyCode.A, "Load camera transform");
  42. Input.Register(MpsKey.CameraReset, KeyCode.R, "Reset camera transform");
  43. }
  44. public CameraManager()
  45. {
  46. cameraInfos = new CameraInfo[5];
  47. for (var i = 0; i < cameraInfos.Length; i++) cameraInfos[i] = new CameraInfo();
  48. Activate();
  49. }
  50. public void Serialize(BinaryWriter binaryWriter) => Serialize(binaryWriter, false);
  51. public void Serialize(BinaryWriter binaryWriter, bool kankyo)
  52. {
  53. binaryWriter.Write(header);
  54. binaryWriter.Write(kankyo);
  55. binaryWriter.WriteVector3(mainCamera.GetTargetPos());
  56. binaryWriter.Write(mainCamera.GetDistance());
  57. binaryWriter.WriteQuaternion(mainCamera.transform.rotation);
  58. CameraUtility.StopAll();
  59. }
  60. public void Deserialize(BinaryReader binaryReader)
  61. {
  62. var kankyo = binaryReader.ReadBoolean();
  63. Vector3 cameraPosition = binaryReader.ReadVector3();
  64. var cameraDistance = binaryReader.ReadSingle();
  65. Quaternion cameraRotation = binaryReader.ReadQuaternion();
  66. if (kankyo) return;
  67. mainCamera.SetTargetPos(cameraPosition);
  68. mainCamera.SetDistance(cameraDistance);
  69. mainCamera.transform.rotation = cameraRotation;
  70. CameraUtility.StopAll();
  71. }
  72. public void Activate()
  73. {
  74. cameraObject = new GameObject("subCamera");
  75. subCamera = cameraObject.AddComponent<Camera>();
  76. subCamera.CopyFrom(mainCamera.camera);
  77. subCamera.clearFlags = CameraClearFlags.Depth;
  78. subCamera.cullingMask = 256;
  79. subCamera.depth = 1f;
  80. subCamera.transform.parent = mainCamera.transform;
  81. cameraObject.SetActive(true);
  82. ultimateOrbitCamera.enabled = true;
  83. defaultCameraMoveSpeed = ultimateOrbitCamera.moveSpeed;
  84. defaultCameraZoomSpeed = ultimateOrbitCamera.zoomSpeed;
  85. if (!MeidoPhotoStudio.EditMode) ResetCamera();
  86. currentCameraIndex = 0;
  87. tempCameraInfo.Reset();
  88. for (var i = 0; i < CameraCount; i++) cameraInfos[i].Reset();
  89. }
  90. public void Deactivate()
  91. {
  92. Object.Destroy(cameraObject);
  93. Object.Destroy(subCamera);
  94. mainCamera.camera.backgroundColor = Color.black;
  95. ultimateOrbitCamera.moveSpeed = defaultCameraMoveSpeed;
  96. ultimateOrbitCamera.zoomSpeed = defaultCameraZoomSpeed;
  97. if (MeidoPhotoStudio.EditMode) return;
  98. mainCamera.Reset(CameraMain.CameraType.Target, true);
  99. mainCamera.SetTargetPos(new Vector3(0.5609447f, 1.380762f, -1.382336f));
  100. mainCamera.SetDistance(1.6f);
  101. mainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f));
  102. }
  103. public void Update()
  104. {
  105. if (Input.GetKey(MpsKey.CameraLayer))
  106. {
  107. if (Input.GetKeyDown(MpsKey.CameraSave)) SaveTempCamera();
  108. else if (Input.GetKeyDown(MpsKey.CameraLoad)) LoadCameraInfo(tempCameraInfo);
  109. else if (Input.GetKeyDown(MpsKey.CameraReset)) ResetCamera();
  110. for (var i = 0; i < CameraCount; i++)
  111. {
  112. if (i != CurrentCameraIndex && UInput.GetKeyDown(AlphaOne + i)) CurrentCameraIndex = i;
  113. }
  114. }
  115. var shift = Input.Shift;
  116. ultimateOrbitCamera.moveSpeed = shift ? cameraFastMoveSpeed : defaultCameraMoveSpeed;
  117. ultimateOrbitCamera.zoomSpeed = shift ? cameraFastZoomSpeed : defaultCameraZoomSpeed;
  118. }
  119. private void SaveTempCamera()
  120. {
  121. tempCameraInfo.UpdateInfo(mainCamera);
  122. CameraUtility.StopAll();
  123. }
  124. public void LoadCameraInfo(CameraInfo info)
  125. {
  126. info.Apply(mainCamera);
  127. CameraUtility.StopAll();
  128. CameraChange?.Invoke(this, EventArgs.Empty);
  129. }
  130. private void ResetCamera()
  131. {
  132. mainCamera.Reset(CameraMain.CameraType.Target, true);
  133. mainCamera.SetTargetPos(new Vector3(0f, 0.9f, 0f));
  134. mainCamera.SetDistance(3f);
  135. CameraChange?.Invoke(this, EventArgs.Empty);
  136. }
  137. }
  138. public class CameraInfo
  139. {
  140. public Vector3 TargetPos { get; set; }
  141. public Quaternion Angle { get; set; }
  142. public float Distance { get; set; }
  143. public float FOV { get; set; }
  144. public CameraInfo() => Reset();
  145. public static CameraInfo FromCamera(CameraMain mainCamera)
  146. {
  147. var info = new CameraInfo();
  148. info.UpdateInfo(mainCamera);
  149. return info;
  150. }
  151. public void Reset()
  152. {
  153. TargetPos = new Vector3(0f, 0.9f, 0f);
  154. Angle = Quaternion.Euler(10f, 180f, 0f);
  155. Distance = 3f;
  156. FOV = 35f;
  157. }
  158. public void UpdateInfo(CameraMain camera)
  159. {
  160. TargetPos = camera.GetTargetPos();
  161. Angle = camera.transform.rotation;
  162. Distance = camera.GetDistance();
  163. FOV = camera.camera.fieldOfView;
  164. }
  165. public void Apply(CameraMain camera)
  166. {
  167. camera.SetTargetPos(TargetPos);
  168. camera.SetDistance(Distance);
  169. camera.transform.rotation = Angle;
  170. camera.camera.fieldOfView = FOV;
  171. }
  172. }
  173. }