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 |