CinemachineMenu.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. #if !UNITY_2019_3_OR_NEWER
  2. #define CINEMACHINE_PHYSICS
  3. #define CINEMACHINE_PHYSICS_2D
  4. #endif
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System;
  8. using System.IO;
  9. namespace Cinemachine.Editor
  10. {
  11. internal static class CinemachineMenu
  12. {
  13. public const string kCinemachineRootMenu = "Assets/Create/Cinemachine/";
  14. [MenuItem(kCinemachineRootMenu + "BlenderSettings")]
  15. private static void CreateBlenderSettingAsset()
  16. {
  17. ScriptableObjectUtility.Create<CinemachineBlenderSettings>();
  18. }
  19. [MenuItem(kCinemachineRootMenu + "NoiseSettings")]
  20. private static void CreateNoiseSettingAsset()
  21. {
  22. ScriptableObjectUtility.Create<NoiseSettings>();
  23. }
  24. [MenuItem(kCinemachineRootMenu + "Fixed Signal Definition")]
  25. private static void CreateFixedSignalDefinition()
  26. {
  27. ScriptableObjectUtility.Create<CinemachineFixedSignal>();
  28. }
  29. [MenuItem("Cinemachine/Create Virtual Camera", false, 1)]
  30. public static CinemachineVirtualCamera CreateVirtualCamera()
  31. {
  32. return InternalCreateVirtualCamera(
  33. "CM vcam", true, typeof(CinemachineComposer), typeof(CinemachineTransposer));
  34. }
  35. [MenuItem("Cinemachine/Create FreeLook Camera", false, 1)]
  36. private static void CreateFreeLookCamera()
  37. {
  38. CreateCameraBrainIfAbsent();
  39. GameObject go = InspectorUtility.CreateGameObject(
  40. GenerateUniqueObjectName(typeof(CinemachineFreeLook), "CM FreeLook"),
  41. typeof(CinemachineFreeLook));
  42. if (SceneView.lastActiveSceneView != null)
  43. go.transform.position = SceneView.lastActiveSceneView.pivot;
  44. Selection.activeGameObject = go;
  45. }
  46. [MenuItem("Cinemachine/Create Blend List Camera", false, 1)]
  47. private static void CreateBlendListCamera()
  48. {
  49. CreateCameraBrainIfAbsent();
  50. GameObject go = InspectorUtility.CreateGameObject(
  51. GenerateUniqueObjectName(typeof(CinemachineBlendListCamera), "CM BlendListCamera"),
  52. typeof(CinemachineBlendListCamera));
  53. if (SceneView.lastActiveSceneView != null)
  54. go.transform.position = SceneView.lastActiveSceneView.pivot;
  55. Undo.RegisterCreatedObjectUndo(go, "create Blend List camera");
  56. var vcam = go.GetComponent<CinemachineBlendListCamera>();
  57. Selection.activeGameObject = go;
  58. // Give it a couple of children
  59. var child1 = CreateDefaultVirtualCamera();
  60. Undo.SetTransformParent(child1.transform, go.transform, "create BlendListCam child");
  61. var child2 = CreateDefaultVirtualCamera();
  62. child2.m_Lens.FieldOfView = 10;
  63. Undo.SetTransformParent(child2.transform, go.transform, "create BlendListCam child");
  64. // Set up initial instruction set
  65. vcam.m_Instructions = new CinemachineBlendListCamera.Instruction[2];
  66. vcam.m_Instructions[0].m_VirtualCamera = child1;
  67. vcam.m_Instructions[0].m_Hold = 1f;
  68. vcam.m_Instructions[1].m_VirtualCamera = child2;
  69. vcam.m_Instructions[1].m_Blend.m_Style = CinemachineBlendDefinition.Style.EaseInOut;
  70. vcam.m_Instructions[1].m_Blend.m_Time = 2f;
  71. }
  72. [MenuItem("Cinemachine/Create State-Driven Camera", false, 1)]
  73. private static void CreateStateDivenCamera()
  74. {
  75. CreateCameraBrainIfAbsent();
  76. GameObject go = InspectorUtility.CreateGameObject(
  77. GenerateUniqueObjectName(typeof(CinemachineStateDrivenCamera), "CM StateDrivenCamera"),
  78. typeof(CinemachineStateDrivenCamera));
  79. if (SceneView.lastActiveSceneView != null)
  80. go.transform.position = SceneView.lastActiveSceneView.pivot;
  81. Undo.RegisterCreatedObjectUndo(go, "create state driven camera");
  82. Selection.activeGameObject = go;
  83. // Give it a child
  84. Undo.SetTransformParent(CreateDefaultVirtualCamera().transform, go.transform, "create state driven camera");
  85. }
  86. #if CINEMACHINE_PHYSICS
  87. [MenuItem("Cinemachine/Create ClearShot Camera", false, 1)]
  88. private static void CreateClearShotVirtualCamera()
  89. {
  90. CreateCameraBrainIfAbsent();
  91. GameObject go = InspectorUtility.CreateGameObject(
  92. GenerateUniqueObjectName(typeof(CinemachineClearShot), "CM ClearShot"),
  93. typeof(CinemachineClearShot));
  94. if (SceneView.lastActiveSceneView != null)
  95. go.transform.position = SceneView.lastActiveSceneView.pivot;
  96. Undo.RegisterCreatedObjectUndo(go, "create ClearShot camera");
  97. Selection.activeGameObject = go;
  98. // Give it a child
  99. var child = CreateDefaultVirtualCamera();
  100. Undo.SetTransformParent(child.transform, go.transform, "create ClearShot camera");
  101. var collider = Undo.AddComponent<CinemachineCollider>(child.gameObject);
  102. collider.m_AvoidObstacles = false;
  103. Undo.RecordObject(collider, "create ClearShot camera");
  104. }
  105. #endif
  106. [MenuItem("Cinemachine/Create Dolly Camera with Track", false, 1)]
  107. private static void CreateDollyCameraWithPath()
  108. {
  109. CinemachineVirtualCamera vcam = InternalCreateVirtualCamera(
  110. "CM vcam", true, typeof(CinemachineComposer), typeof(CinemachineTrackedDolly));
  111. GameObject go = InspectorUtility.CreateGameObject(
  112. GenerateUniqueObjectName(typeof(CinemachineSmoothPath), "DollyTrack"),
  113. typeof(CinemachineSmoothPath));
  114. if (SceneView.lastActiveSceneView != null)
  115. go.transform.position = SceneView.lastActiveSceneView.pivot;
  116. Undo.RegisterCreatedObjectUndo(go, "create track");
  117. CinemachineSmoothPath path = go.GetComponent<CinemachineSmoothPath>();
  118. var dolly = vcam.GetCinemachineComponent<CinemachineTrackedDolly>();
  119. Undo.RecordObject(dolly, "create track");
  120. dolly.m_Path = path;
  121. }
  122. [MenuItem("Cinemachine/Create Dolly Track with Cart", false, 1)]
  123. private static void CreateDollyTrackWithCart()
  124. {
  125. GameObject go = InspectorUtility.CreateGameObject(
  126. GenerateUniqueObjectName(typeof(CinemachineSmoothPath), "DollyTrack"),
  127. typeof(CinemachineSmoothPath));
  128. if (SceneView.lastActiveSceneView != null)
  129. go.transform.position = SceneView.lastActiveSceneView.pivot;
  130. Undo.RegisterCreatedObjectUndo(go, "create track");
  131. CinemachineSmoothPath path = go.GetComponent<CinemachineSmoothPath>();
  132. Selection.activeGameObject = go;
  133. go = InspectorUtility.CreateGameObject(
  134. GenerateUniqueObjectName(typeof(CinemachineDollyCart), "DollyCart"),
  135. typeof(CinemachineDollyCart));
  136. if (SceneView.lastActiveSceneView != null)
  137. go.transform.position = SceneView.lastActiveSceneView.pivot;
  138. Undo.RegisterCreatedObjectUndo(go, "create cart");
  139. CinemachineDollyCart cart = go.GetComponent<CinemachineDollyCart>();
  140. Undo.RecordObject(cart, "create track");
  141. cart.m_Path = path;
  142. }
  143. [MenuItem("Cinemachine/Create Target Group Camera", false, 1)]
  144. private static void CreateTargetGroupCamera()
  145. {
  146. CinemachineVirtualCamera vcam = InternalCreateVirtualCamera(
  147. "CM vcam", true, typeof(CinemachineGroupComposer), typeof(CinemachineTransposer));
  148. GameObject go = InspectorUtility.CreateGameObject(
  149. GenerateUniqueObjectName(typeof(CinemachineTargetGroup), "TargetGroup"),
  150. typeof(CinemachineTargetGroup));
  151. if (SceneView.lastActiveSceneView != null)
  152. go.transform.position = SceneView.lastActiveSceneView.pivot;
  153. Undo.RegisterCreatedObjectUndo(go, "create target group");
  154. vcam.LookAt = go.transform;
  155. vcam.Follow = go.transform;
  156. }
  157. [MenuItem("Cinemachine/Create Mixing Camera", false, 1)]
  158. private static void CreateMixingCamera()
  159. {
  160. CreateCameraBrainIfAbsent();
  161. GameObject go = InspectorUtility.CreateGameObject(
  162. GenerateUniqueObjectName(typeof(CinemachineMixingCamera), "CM MixingCamera"),
  163. typeof(CinemachineMixingCamera));
  164. if (SceneView.lastActiveSceneView != null)
  165. go.transform.position = SceneView.lastActiveSceneView.pivot;
  166. Undo.RegisterCreatedObjectUndo(go, "create MixingCamera camera");
  167. Selection.activeGameObject = go;
  168. // Give it a couple of children
  169. Undo.SetTransformParent(CreateDefaultVirtualCamera().transform, go.transform, "create MixedCamera child");
  170. Undo.SetTransformParent(CreateDefaultVirtualCamera().transform, go.transform, "create MixingCamera child");
  171. }
  172. [MenuItem("Cinemachine/Create 2D Camera", false, 1)]
  173. private static void Create2DCamera()
  174. {
  175. InternalCreateVirtualCamera("CM vcam", true, typeof(CinemachineFramingTransposer));
  176. }
  177. #if !UNITY_2019_1_OR_NEWER
  178. [MenuItem("Cinemachine/Import Post Processing V2 Adapter Asset Package")]
  179. private static void ImportPostProcessingV2Package()
  180. {
  181. var message = "In Cinemachine 2.4.0 and up, the PostProcessing adapter is built-in, and "
  182. + "can be auto-enabled by Unity 2019 and up.\n\n"
  183. + "Unity 2018.4 is unable to auto-detect the presence of PostProcessing, so you must "
  184. + "manually add a define to your player settings to enable the code.\n\n"
  185. + "To enable support for PostProcessing v2, please do the following:\n\n"
  186. + "1. Delete the CinemachinePostProcessing folder from your assets, if it's present\n\n"
  187. + "2. Open the Player Settings tab in Project Settings\n\n"
  188. + "3. Add this define: CINEMACHINE_POST_PROCESSING_V2";
  189. EditorUtility.DisplayDialog("Cinemachine Adapter Code for PostProcessing V2", message, "OK");
  190. }
  191. [MenuItem("Cinemachine/Import CinemachineExamples Asset Package")]
  192. private static void ImportExamplePackage()
  193. {
  194. string pkgFile = ScriptableObjectUtility.CinemachineInstallPath
  195. + "/Extras~/CinemachineExamples.unitypackage";
  196. if (!System.IO.File.Exists(pkgFile))
  197. Debug.LogError("Missing file " + pkgFile);
  198. else
  199. AssetDatabase.ImportPackage(pkgFile, true);
  200. }
  201. #endif
  202. /// <summary>
  203. /// Create a default Virtual Camera, with standard components
  204. /// </summary>
  205. public static CinemachineVirtualCamera CreateDefaultVirtualCamera()
  206. {
  207. return InternalCreateVirtualCamera(
  208. "CM vcam", false, typeof(CinemachineComposer), typeof(CinemachineTransposer));
  209. }
  210. /// <summary>
  211. /// Create a static Virtual Camera, with no procedural components
  212. /// </summary>
  213. public static CinemachineVirtualCamera CreateStaticVirtualCamera()
  214. {
  215. return InternalCreateVirtualCamera("CM vcam", false);
  216. }
  217. /// <summary>
  218. /// Create a Virtual Camera, with components
  219. /// </summary>
  220. static CinemachineVirtualCamera InternalCreateVirtualCamera(
  221. string name, bool selectIt, params Type[] components)
  222. {
  223. // Create a new virtual camera
  224. var brain = CreateCameraBrainIfAbsent();
  225. GameObject go = InspectorUtility.CreateGameObject(
  226. GenerateUniqueObjectName(typeof(CinemachineVirtualCamera), name),
  227. typeof(CinemachineVirtualCamera));
  228. CinemachineVirtualCamera vcam = go.GetComponent<CinemachineVirtualCamera>();
  229. SetVcamFromSceneView(vcam);
  230. Undo.RegisterCreatedObjectUndo(go, "create " + name);
  231. GameObject componentOwner = vcam.GetComponentOwner().gameObject;
  232. foreach (Type t in components)
  233. Undo.AddComponent(componentOwner, t);
  234. vcam.InvalidateComponentPipeline();
  235. if (brain != null && brain.OutputCamera != null)
  236. vcam.m_Lens = LensSettings.FromCamera(brain.OutputCamera);
  237. if (selectIt)
  238. Selection.activeObject = go;
  239. return vcam;
  240. }
  241. public static void SetVcamFromSceneView(CinemachineVirtualCamera vcam)
  242. {
  243. if (SceneView.lastActiveSceneView != null)
  244. {
  245. vcam.transform.position = SceneView.lastActiveSceneView.camera.transform.position;
  246. vcam.transform.rotation = SceneView.lastActiveSceneView.camera.transform.rotation;
  247. var lens = LensSettings.FromCamera(SceneView.lastActiveSceneView.camera);
  248. // Don't grab these
  249. lens.NearClipPlane = LensSettings.Default.NearClipPlane;
  250. lens.FarClipPlane = LensSettings.Default.FarClipPlane;
  251. vcam.m_Lens = lens;
  252. }
  253. }
  254. /// <summary>
  255. /// If there is no CinemachineBrain in the scene, try to create one on the main camera
  256. /// </summary>
  257. public static CinemachineBrain CreateCameraBrainIfAbsent()
  258. {
  259. CinemachineBrain[] brains = UnityEngine.Object.FindObjectsOfType(
  260. typeof(CinemachineBrain)) as CinemachineBrain[];
  261. CinemachineBrain brain = (brains != null && brains.Length > 0) ? brains[0] : null;
  262. if (brain == null)
  263. {
  264. Camera cam = Camera.main;
  265. if (cam == null)
  266. {
  267. Camera[] cams = UnityEngine.Object.FindObjectsOfType(
  268. typeof(Camera)) as Camera[];
  269. if (cams != null && cams.Length > 0)
  270. cam = cams[0];
  271. }
  272. if (cam != null)
  273. {
  274. brain = Undo.AddComponent<CinemachineBrain>(cam.gameObject);
  275. }
  276. }
  277. return brain;
  278. }
  279. /// <summary>
  280. /// Generate a unique name with the given prefix by adding a suffix to it
  281. /// </summary>
  282. public static string GenerateUniqueObjectName(Type type, string prefix)
  283. {
  284. int count = 0;
  285. UnityEngine.Object[] all = Resources.FindObjectsOfTypeAll(type);
  286. foreach (UnityEngine.Object o in all)
  287. {
  288. if (o != null && o.name.StartsWith(prefix))
  289. {
  290. string suffix = o.name.Substring(prefix.Length);
  291. int i;
  292. if (Int32.TryParse(suffix, out i) && i > count)
  293. count = i;
  294. }
  295. }
  296. return prefix + (count + 1);
  297. }
  298. }
  299. }