SHOW:
|
|
- or go back to the newest paste.
| 1 | #if HAVE_SLATE | |
| 2 | ||
| 3 | using System; | |
| 4 | using System.Collections.Generic; | |
| 5 | ||
| 6 | using UnityEngine; | |
| 7 | ||
| 8 | using Slate; | |
| 9 | ||
| 10 | using Framework.Camera; | |
| 11 | using Framework.Support; | |
| 12 | ||
| 13 | namespace Framework.Cinematics {
| |
| 14 | ||
| 15 | /// <summary>Helper methods for dealing with cutscenes</summary> | |
| 16 | public static class CutsceneHelper {
| |
| 17 | ||
| 18 | #region class CameraParenter | |
| 19 | ||
| 20 | /// <summary>Temporarily changes the parent of a game object</summary> | |
| 21 | private class CameraParenter : IDisposable {
| |
| 22 | ||
| 23 | /// <summary>Initializes a new instance that does nothing</summary> | |
| 24 | public CameraParenter() {
| |
| 25 | this.onCutsceneStoppedDelegate = new Action<Cutscene>(onCutsceneStopped); | |
| 26 | } | |
| 27 | ||
| 28 | /// <summary> | |
| 29 | /// Assigns a new parent to the camera and remembers the previous one | |
| 30 | /// </summary> | |
| 31 | /// <param name="newParentGameObject">New parent for the camera</param> | |
| 32 | /// <param name="cameraGameObject">Camera that will be reparented</param> | |
| 33 | public CameraParenter( | |
| 34 | GameObject newParentGameObject, GameObject cameraGameObject | |
| 35 | ) : this() {
| |
| 36 | Initialize(newParentGameObject, cameraGameObject); | |
| 37 | } | |
| 38 | ||
| 39 | /// <summary> | |
| 40 | /// Assigns a new parent to the camera and remembers the previous one | |
| 41 | /// </summary> | |
| 42 | /// <param name="newParentGameObject">New parent for the camera</param> | |
| 43 | /// <param name="cameraGameObject">Camera that will be reparented</param> | |
| 44 | public void Initialize( | |
| 45 | GameObject newParentGameObject, GameObject cameraGameObject | |
| 46 | ) {
| |
| 47 | this.cameraGameObject = cameraGameObject; | |
| 48 | ||
| 49 | Transform cameraTransform = cameraGameObject.transform; | |
| 50 | this.previousPosition = cameraTransform.localPosition; | |
| 51 | this.previousOrientation = cameraTransform.localRotation; | |
| 52 | ||
| 53 | Transform parentTransform = cameraTransform.parent; | |
| 54 | if(parentTransform == null) {
| |
| 55 | this.previousParentGameObject = null; | |
| 56 | } else {
| |
| 57 | this.previousParentGameObject = parentTransform.gameObject; | |
| 58 | } | |
| 59 | ||
| 60 | GameObjectHelper.SetAsChild(newParentGameObject, cameraGameObject); | |
| 61 | cameraTransform.localPosition = Vector3.zero; | |
| 62 | cameraTransform.localRotation = Quaternion.identity; | |
| 63 | } | |
| 64 | ||
| 65 | /// <summary>Restores the original parent of the camera</summary> | |
| 66 | public void Dispose() {
| |
| 67 | WatchCutsceneForRecycling(null); | |
| 68 | ||
| 69 | if(this.cameraGameObject != null) {
| |
| 70 | GameObjectHelper.SetAsChild(this.previousParentGameObject, this.cameraGameObject); | |
| 71 | ||
| 72 | Transform cameraTransform = this.cameraGameObject.transform; | |
| 73 | cameraTransform.localPosition = this.previousPosition; | |
| 74 | cameraTransform.localRotation = this.previousOrientation; | |
| 75 | ||
| 76 | this.cameraGameObject = null; | |
| 77 | } | |
| 78 | } | |
| 79 | ||
| 80 | /// <summary>Sets the parenter up for recycling after a cutscene finishes</summary> | |
| 81 | /// <param name="cutscene">Cutscene that will be watched for completion</param> | |
| 82 | public void WatchCutsceneForRecycling(Cutscene cutscene) {
| |
| 83 | if(this.cutsceneForUnsubscribe != null) {
| |
| 84 | Cutscene.OnCutsceneStopped -= this.onCutsceneStoppedDelegate; | |
| 85 | this.cutsceneForUnsubscribe = null; | |
| 86 | } | |
| 87 | if(cutscene != null) {
| |
| 88 | Cutscene.OnCutsceneStopped += this.onCutsceneStoppedDelegate; | |
| 89 | this.cutsceneForUnsubscribe = cutscene; | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | /// <summary>Recycles the parenter when the cutscene stops playing</summary> | |
| 94 | /// <param name="cutscene">Cutscene that has stopped playing</param> | |
| 95 | private void onCutsceneStopped(Cutscene cutscene) {
| |
| 96 | if(ReferenceEquals(this.cutsceneForUnsubscribe, cutscene)) {
| |
| 97 | Dispose(); | |
| 98 | ||
| 99 | CutsceneHelper.recyclableCameraParenters.Add(this); | |
| 100 | } | |
| 101 | } | |
| 102 | ||
| 103 | /// <summary>Game object that will be reparented</summary> | |
| 104 | private GameObject cameraGameObject; | |
| 105 | /// <summary>Game object that was the camera's previous parent</summary> | |
| 106 | private GameObject previousParentGameObject; | |
| 107 | /// <summary>Previous position of the camera</summary> | |
| 108 | private Vector3 previousPosition; | |
| 109 | /// <summary>Previous orientation of the camera</summary> | |
| 110 | private Quaternion previousOrientation; | |
| 111 | ||
| 112 | /// <summary>Cutscene this camera parenter is watching for completion</summary> | |
| 113 | private Cutscene cutsceneForUnsubscribe; | |
| 114 | /// <summary>Delegate for the onCutsceneStopped() method</summary> | |
| 115 | private Action<Cutscene> onCutsceneStoppedDelegate; | |
| 116 | ||
| 117 | } | |
| 118 | ||
| 119 | #endregion // class CameraParenter | |
| 120 | ||
| 121 | /// <summary>Starts playing a cutscene using the specified camera</summary> | |
| 122 | /// <param name="cutscene">Cutscene that will be played</param> | |
| 123 | /// <param name="camera">Camera on which the cutscene will be played</param> | |
| 124 | /// <param name="callback">Callback to invoke when the cutscene ends</param> | |
| 125 | public static void PlayCutsceneOnCamera( | |
| 126 | Cutscene cutscene, UnityEngine.Camera camera, System.Action callback = null | |
| 127 | ) {
| |
| 128 | ||
| 129 | // Stop the DirectorCamera from messing with our camera settings | |
| 130 | DirectorCamera.setMainWhenActive = false; | |
| 131 | - | DirectorCamera.matchMainCamera = False; |
| 131 | + | DirectorCamera.matchMainCamera = false; |
| 132 | DirectorCamera.autoHandleActiveState = false; | |
| 133 | DirectorCamera.dontDestroyOnLoad = false; | |
| 134 | ||
| 135 | // Parent our render camera to the director camera root | |
| 136 | CameraParenter parenter = recycleOrCreateCameraParenter(); | |
| 137 | parenter.Initialize(DirectorCamera.current.gameObject, camera.gameObject); | |
| 138 | ||
| 139 | // Set up the parenter to recycle (and unparent) when the cutscene ends, | |
| 140 | // then play the cutscene (in this order in case of a zero-length cutscene) | |
| 141 | parenter.WatchCutsceneForRecycling(cutscene); | |
| 142 | ||
| 143 | // Start the cutscene. This will disable the active camera, but we'll undo | |
| 144 | // that little mishap right away | |
| 145 | cutscene.Play(0.0f, callback); | |
| 146 | ||
| 147 | // Switch to our own render camera | |
| 148 | CameraHelper.ActivateCamera(camera); | |
| 149 | } | |
| 150 | ||
| 151 | /// <summary>Starts playing a cutscene using the director camera</summary> | |
| 152 | /// <param name="cutscene">Cutscene that will be played</param> | |
| 153 | /// <param name="camera">Camera that will be active when the cutscene starts</param> | |
| 154 | /// <param name="callback">Callback to invoke when the cutscene ends</param> | |
| 155 | public static void PlayCutsceneOnDirectorCamera( | |
| 156 | Cutscene cutscene, UnityEngine.Camera camera, System.Action callback = null | |
| 157 | ) {
| |
| 158 | ||
| 159 | // In this mode, we want the DirectorCamera to copy the camera's settings | |
| 160 | - | // In this case, we want the director camera to take over all camera settings |
| 160 | + | |
| 161 | DirectorCamera.matchMainCamera = true; | |
| 162 | DirectorCamera.autoHandleActiveState = true; | |
| 163 | DirectorCamera.dontDestroyOnLoad = false; | |
| 164 | ||
| 165 | // Active the camera from which the DirectorCamera should copy its settings | |
| 166 | CameraHelper.ActivateCamera(camera); | |
| 167 | ||
| 168 | // Start the cutscene | |
| 169 | cutscene.Play(0.0f, callback); | |
| 170 | ||
| 171 | } | |
| 172 | ||
| 173 | /// <summary> | |
| 174 | /// Returns a recycled instance of a camera parenter or creates a new one | |
| 175 | /// </summary> | |
| 176 | /// <returns>An unused instance of a camera parenter</returns> | |
| 177 | private static CameraParenter recycleOrCreateCameraParenter() {
| |
| 178 | if(recyclableCameraParenters == null) {
| |
| 179 | recyclableCameraParenters = new List<CameraParenter>(); | |
| 180 | return new CameraParenter(); | |
| 181 | } | |
| 182 | ||
| 183 | int parenterCount = recyclableCameraParenters.Count; | |
| 184 | if(parenterCount == 0) {
| |
| 185 | return new CameraParenter(); | |
| 186 | } | |
| 187 | ||
| 188 | CameraParenter parenter = recyclableCameraParenters[parenterCount - 1]; | |
| 189 | recyclableCameraParenters.RemoveAt(parenterCount - 1); | |
| 190 | return parenter; | |
| 191 | } | |
| 192 | ||
| 193 | /// <summary>Camera parenters that are ready for reuse</summary> | |
| 194 | private static IList<CameraParenter> recyclableCameraParenters; | |
| 195 | ||
| 196 | } | |
| 197 | ||
| 198 | } // namespace Framework.Cinematics | |
| 199 | ||
| 200 | #endif // HAVE_SLATE |