View difference between Paste ID: NTQ3gXtP and 4B3LHdCi
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