├── Cutscene Ed
├── Gizmos
│ └── Cutscene.png
├── Effects
│ ├── Filters
│ │ ├── CutsceneInvertFilter.cs
│ │ └── CutsceneBlurFilter.cs
│ ├── CutsceneEffect.cs
│ └── ImageEffects.cs
├── Editor
│ ├── CutsceneEditorGUILayout.cs
│ ├── ICutsceneGUI.cs
│ ├── CutsceneOptions.cs
│ ├── CutsceneSubtitleInspector.cs
│ ├── CutsceneTools.cs
│ ├── BugReporter.cs
│ ├── CutsceneNavigation.cs
│ ├── CutsceneTrackControls.cs
│ ├── CutscenePreview.cs
│ ├── CutsceneAddSubtitle.cs
│ ├── CutscenePlaybackControls.cs
│ ├── CutsceneAddAudio.cs
│ ├── CutsceneAddActor.cs
│ ├── CutsceneHotkeys.cs
│ ├── CutsceneInspector.cs
│ ├── CutsceneTrackInfo.cs
│ ├── CutsceneEffectsWindow.cs
│ ├── CutsceneTimeline.cs
│ ├── CutsceneTimecodeBar.cs
│ ├── CutsceneMediaWindow.cs
│ ├── CutsceneTracksView.cs
│ └── CutsceneEditor.cs
└── Scripts
│ ├── CutsceneShot.cs
│ ├── CutsceneAudio.cs
│ ├── CutsceneActor.cs
│ ├── CutsceneTrigger.cs
│ ├── CutsceneSubtitle.cs
│ ├── CutsceneMedia.cs
│ ├── EDebug.cs
│ ├── CutsceneClip.cs
│ ├── CutsceneTrack.cs
│ └── Cutscene.cs
├── Editor Default Resources
└── Cutscene Ed
│ ├── gui_pane.png
│ ├── icon_add.png
│ ├── icon_eye.png
│ ├── overlay.png
│ ├── resize.png
│ ├── clip_actor.png
│ ├── clip_audio.png
│ ├── clip_shot.png
│ ├── icon_lock.png
│ ├── media_shot.png
│ ├── tool_move.png
│ ├── tool_zoom.png
│ ├── track_lock.png
│ ├── clip_selected.png
│ ├── clip_subtitle.png
│ ├── gui_selection.png
│ ├── icon_addtrack.png
│ ├── icon_zoomout.png
│ ├── media_actor.png
│ ├── media_audio.png
│ ├── playback_back.png
│ ├── playback_in.png
│ ├── playback_out.png
│ ├── playback_play.png
│ ├── tool_scissors.png
│ ├── effects_filter.png
│ ├── media_subtitle.png
│ ├── playback_pause.png
│ ├── effects_transition.png
│ ├── gui_trackcontrols.png
│ ├── inpoint_indicator.png
│ ├── outpoint_indicator.png
│ ├── playback_forward.png
│ ├── position_indicator.png
│ ├── icon_zoomtotimeline.png
│ ├── cutscene_editor_style.guiskin
│ └── Icons.txt
└── README.md
/Cutscene Ed/Gizmos/Cutscene.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Cutscene Ed/Gizmos/Cutscene.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/gui_pane.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/gui_pane.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_add.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_eye.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/overlay.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/resize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/resize.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/clip_actor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/clip_actor.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/clip_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/clip_audio.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/clip_shot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/clip_shot.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_lock.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/media_shot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/media_shot.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/tool_move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/tool_move.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/tool_zoom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/tool_zoom.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/track_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/track_lock.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/clip_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/clip_selected.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/clip_subtitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/clip_subtitle.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/gui_selection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/gui_selection.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_addtrack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_addtrack.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_zoomout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_zoomout.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/media_actor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/media_actor.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/media_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/media_audio.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_back.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_in.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_out.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_out.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_play.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/tool_scissors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/tool_scissors.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/effects_filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/effects_filter.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/media_subtitle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/media_subtitle.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_pause.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/effects_transition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/effects_transition.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/gui_trackcontrols.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/gui_trackcontrols.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/inpoint_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/inpoint_indicator.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/outpoint_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/outpoint_indicator.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/playback_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/playback_forward.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/position_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/position_indicator.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/icon_zoomtotimeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/icon_zoomtotimeline.png
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/cutscene_editor_style.guiskin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mminer/silverscreen/HEAD/Editor Default Resources/Cutscene Ed/cutscene_editor_style.guiskin
--------------------------------------------------------------------------------
/Editor Default Resources/Cutscene Ed/Icons.txt:
--------------------------------------------------------------------------------
1 | Editor icons are courtesy of Fugue Icons, available online at http://www.pinvoke.com. They are licensed under the Creative Commons Attribution 3.0 license (http://creativecommons.org/licenses/by/3.0/).
--------------------------------------------------------------------------------
/Cutscene Ed/Effects/Filters/CutsceneInvertFilter.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | // Based off of InvertCamera.js by Joachim Ante
4 | // Retrieved from the Unify Community wiki (http://www.unifycommunity.com/wiki/index.php?title=InvertCamera)
5 |
6 | public class CutsceneInvertFilter : CutsceneEffect {
7 | [HideInInspector]
8 | public static new string name = "Invert";
9 |
10 | void OnPreCull () {
11 | camera.ResetWorldToCameraMatrix();
12 | camera.ResetProjectionMatrix();
13 | camera.projectionMatrix = camera.projectionMatrix * Matrix4x4.Scale(new Vector3(1, -1, 1));
14 | }
15 |
16 | void OnPreRender () {
17 | GL.SetRevertBackfacing(true);
18 | }
19 |
20 | void OnPostRender () {
21 | GL.SetRevertBackfacing(false);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneEditorGUILayout.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 |
4 | public delegate void GUIContents ();
5 |
6 | public static class CutsceneEditorGUILayout
7 | {
8 | public static Rect Horizontal (GUIContents contents, params GUILayoutOption[] options)
9 | {
10 | Rect rect = EditorGUILayout.BeginHorizontal(options);
11 | contents();
12 | EditorGUILayout.EndHorizontal();
13 |
14 | return rect;
15 | }
16 |
17 | public static Rect Horizontal (GUIContents contents, GUIStyle style, params GUILayoutOption[] options)
18 | {
19 | Rect rect = EditorGUILayout.BeginHorizontal(style, options);
20 | contents();
21 | EditorGUILayout.EndHorizontal();
22 |
23 | return rect;
24 | }
25 | }
26 |
27 | public static class CutsceneGUILayout
28 | {
29 | public static void Area (GUIContents contents, Rect screenRect)
30 | {
31 | GUILayout.BeginArea(screenRect);
32 | contents();
33 | GUILayout.EndArea();
34 | }
35 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneShot.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | [RequireComponent(typeof(Camera))]
26 | public class CutsceneShot : CutsceneMedia {}
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneAudio.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | [RequireComponent(typeof(AudioSource))]
26 | public class CutsceneAudio : CutsceneMedia {}
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneActor.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | public class CutsceneActor : CutsceneMedia
26 | {
27 | public AnimationClip anim;
28 | public GameObject go;
29 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Effects/CutsceneEffect.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | ///
26 | /// Base class for all cutscene effects.
27 | ///
28 | [ExecuteInEditMode]
29 | [RequireComponent(typeof(CutsceneShot))]
30 | public class CutsceneEffect : MonoBehaviour {}
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/ICutsceneGUI.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | interface ICutsceneGUI
26 | {
27 | ///
28 | /// Displays the GUI for this element.
29 | ///
30 | /// The bounding box this element is contained in.
31 | void OnGUI (Rect rect);
32 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneTrigger.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using System.Collections;
25 |
26 | public class CutsceneTrigger : MonoBehaviour
27 | {
28 | public Cutscene scene;
29 |
30 | void Update ()
31 | {
32 | //TEMP
33 | if (Input.GetKey("p")) {
34 | scene.PlayCutscene();
35 | }
36 | }
37 |
38 | void OnTriggerEnter (Collider collider)
39 | {
40 | scene.PlayCutscene();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneSubtitle.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | public class CutsceneSubtitle : CutsceneMedia
26 | {
27 | public string dialog;
28 |
29 | public new string name {
30 | get {
31 | int maxTitleLength = 25;
32 | string _name = dialog;
33 | if (_name.Length > maxTitleLength) {
34 | _name = _name.Substring(0, maxTitleLength) + " ...";
35 | }
36 | return _name;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Silver Screen
2 | =============
3 |
4 | Editor tools for creating cinematics using the Unity game engine.
5 |
6 | I haven't updated this in ages. If you're looking for a cutscene editor, there
7 | are numerous good options on the Asset Store that are more likely to work well
8 | with the latest version of Unity.
9 |
10 |
11 | Release History
12 | ---------------
13 |
14 | - 0.1
15 | - Initial release
16 | - Compatible with Unity 2.6
17 |
18 |
19 | License
20 | -------
21 |
22 | All code is released under the MIT license.
23 |
24 | > Copyright (c) 2010 Matthew Miner
25 | >
26 | > Permission is hereby granted, free of charge, to any person obtaining a copy
27 | > of this software and associated documentation files (the "Software"), to deal
28 | > in the Software without restriction, including without limitation the rights
29 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30 | > copies of the Software, and to permit persons to whom the Software is
31 | > furnished to do so, subject to the following conditions:
32 | >
33 | > The above copyright notice and this permission notice shall be included in
34 | > all copies or substantial portions of the Software.
35 | >
36 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42 | > THE SOFTWARE.
43 |
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneMedia.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | public abstract class CutsceneMedia : MonoBehaviour
26 | {
27 | public Cutscene.MediaType type {
28 | get {
29 | if (this.GetType() == typeof(CutsceneShot)) {
30 | return Cutscene.MediaType.Shots;
31 | } else if (this.GetType() == typeof(CutsceneActor)) {
32 | return Cutscene.MediaType.Actors;
33 | } else if (this.GetType() == typeof(CutsceneAudio)) {
34 | return Cutscene.MediaType.Audio;
35 | } else { // obj.GetType() == typeof(CutsceneSubtitle)
36 | return Cutscene.MediaType.Subtitles;
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneOptions.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | class CutsceneOptions : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | public CutsceneOptions (CutsceneEditor ed)
31 | {
32 | this.ed = ed;
33 | }
34 |
35 | ///
36 | /// Displays the options window.
37 | ///
38 | /// The options window's Rect.
39 | public void OnGUI (Rect rect)
40 | {
41 | GUILayout.BeginArea(rect);
42 |
43 | ed.scene.inPoint = GUILayout.HorizontalSlider(ed.scene.inPoint, 0, 100);
44 |
45 | GUILayout.EndArea();
46 | }
47 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneSubtitleInspector.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | ///
27 | /// A custom inspector for a subtitle.
28 | ///
29 | [CustomEditor (typeof(CutsceneSubtitle))]
30 | public class CutsceneSubtitleInspector : Editor
31 | {
32 | CutsceneSubtitle subtitle {
33 | get { return target as CutsceneSubtitle; }
34 | }
35 |
36 | public override void OnInspectorGUI ()
37 | {
38 | EditorGUILayout.BeginHorizontal();
39 |
40 | EditorGUILayout.PrefixLabel("Dialog");
41 | subtitle.dialog = EditorGUILayout.TextArea(subtitle.dialog);
42 |
43 | EditorGUILayout.EndHorizontal();
44 |
45 | if (GUI.changed) {
46 | EditorUtility.SetDirty(subtitle);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneTools.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | public enum Tool {
27 | MoveResize,
28 | Scissors,
29 | Zoom
30 | }
31 |
32 | class CutsceneTools : ICutsceneGUI
33 | {
34 | readonly CutsceneEditor ed;
35 |
36 | readonly GUIContent[] tools = {
37 | new GUIContent(EditorGUIUtility.LoadRequired("Cutscene Ed/tool_move.png") as Texture, "Move/Resize"),
38 | new GUIContent(EditorGUIUtility.LoadRequired("Cutscene Ed/tool_scissors.png") as Texture, "Scissors"),
39 | new GUIContent(EditorGUIUtility.LoadRequired("Cutscene Ed/tool_zoom.png") as Texture, "Zoom")
40 | };
41 |
42 | public CutsceneTools (CutsceneEditor ed)
43 | {
44 | this.ed = ed;
45 | }
46 |
47 | public void OnGUI (Rect rect)
48 | {
49 | CutsceneGUILayout.Area(delegate {
50 | CutsceneEditorGUILayout.Horizontal(delegate {
51 |
52 | GUILayout.FlexibleSpace();
53 | ed.currentTool = (Tool)GUILayout.Toolbar((int)ed.currentTool, tools);
54 |
55 | }, ed.style.GetStyle("Tools Bar"), GUILayout.Width(rect.width));
56 | }, rect);
57 | }
58 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/EDebug.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 |
25 | ///
26 | /// A simple class for toggle-able debug messages. Debug messages for editor tools are useful when developing the tool itself, but annoying for end users.
27 | ///
28 | public class EDebug
29 | {
30 | static bool debug = false;
31 |
32 | public static void Break ()
33 | {
34 | if (debug) Debug.Break();
35 | }
36 |
37 | public static void Log (object message)
38 | {
39 | if (debug) Debug.Log(message);
40 | }
41 |
42 | public static void Log (object message, Object context)
43 | {
44 | if (debug) Debug.Log(message, context);
45 | }
46 |
47 | public static void LogError (object message)
48 | {
49 | if (debug) Debug.LogError(message);
50 | }
51 |
52 | public static void LogError (object message, Object context)
53 | {
54 | if (debug) Debug.LogError(message, context);
55 | }
56 |
57 | public static void LogWarning (object message)
58 | {
59 | if (debug) Debug.LogWarning(message);
60 | }
61 |
62 | public static void LogWarning (object message, Object context)
63 | {
64 | if (debug) Debug.LogWarning(message, context);
65 | }
66 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/BugReporter.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | public class BugReporter : EditorWindow
27 | {
28 | string email = "";
29 | string details = "";
30 |
31 | readonly GUIContent emailLabel = new GUIContent("Your Email", "If we require additional information, we'll contact you at the supplied address (optional).");
32 | readonly GUIContent submitLabel = new GUIContent("Submit", "Send this bug report.");
33 |
34 | ///
35 | /// Adds "Bug Reporter" to the Window menu.
36 | ///
37 | [MenuItem("Window/Bug Reporter")]
38 | public static void OpenEditor ()
39 | {
40 | // Get existing open window or if none, make a new one
41 | GetWindow(true, "Bug Reporter").Show();
42 | }
43 |
44 | void OnGUI ()
45 | {
46 | GUILayout.Label("Please take a minute to tell us what happened in as much detail as possible. This makes it possible for us to fix the problem.");
47 |
48 | EditorGUILayout.Separator();
49 |
50 | email = EditorGUILayout.TextField(emailLabel, email);
51 |
52 | EditorGUILayout.Separator();
53 |
54 | GUILayout.Label("Problem Details:");
55 | details = EditorGUILayout.TextArea(details);
56 |
57 | EditorGUILayout.BeginHorizontal();
58 |
59 | GUILayout.FlexibleSpace();
60 |
61 | if (GUILayout.Button(submitLabel, GUILayout.ExpandWidth(false))) {
62 | // TODO Send bug report
63 | Debug.Log("Bug report sent.");
64 | }
65 | EditorGUILayout.EndHorizontal();
66 | }
67 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneNavigation.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | class CutsceneNavigation : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | readonly ICutsceneGUI playbackControls;
31 | readonly ICutsceneGUI timecodeBar;
32 |
33 | readonly GUIContent zoomButton = new GUIContent("", "Zoom timeline to entire scene.");
34 |
35 | public CutsceneNavigation (CutsceneEditor ed)
36 | {
37 | this.ed = ed;
38 | playbackControls = new CutscenePlaybackControls(ed);
39 | timecodeBar = new CutsceneTimecodeBar(ed);
40 | }
41 |
42 | public void OnGUI (Rect rect)
43 | {
44 | GUI.BeginGroup(rect);
45 |
46 | float zoomButtonWidth = GUI.skin.verticalScrollbar.fixedWidth;
47 | float timecodeBarWidth = ed.position.width - CutsceneTimeline.trackInfoWidth - zoomButtonWidth;
48 |
49 | // Playback controls
50 | Rect playbackControlsRect = new Rect(0, 0, CutsceneTimeline.trackInfoWidth, rect.height);
51 | playbackControls.OnGUI(playbackControlsRect);
52 |
53 | // Timecode bar
54 | Rect timecodeBarRect = new Rect(playbackControlsRect.xMax, 0, timecodeBarWidth, rect.height);
55 | timecodeBar.OnGUI(timecodeBarRect);
56 |
57 | // Zoom to view entire project
58 | Rect zoomButtonRect = new Rect(timecodeBarRect.xMax, 0, zoomButtonWidth, rect.height);
59 | if (GUI.Button(zoomButtonRect, zoomButton, EditorStyles.toolbarButton)) {
60 | ed.timelineZoom = ed.timelineMin;
61 | EDebug.Log("Cutscene Editor: zoomed timeline to entire scene");
62 | }
63 |
64 | GUI.EndGroup();
65 | }
66 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneTrackControls.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | class CutsceneTrackControls : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | readonly GUIContent newTrackLabel = new GUIContent(
31 | EditorGUIUtility.LoadRequired("Cutscene Ed/icon_addtrack.png") as Texture,
32 | "Add a new track."
33 | );
34 |
35 | public CutsceneTrackControls (CutsceneEditor ed)
36 | {
37 | this.ed = ed;
38 | }
39 |
40 | public void OnGUI (Rect rect)
41 | {
42 | // TODO Make this a style in the cutscene editor's GUISkin
43 | GUIStyle popupStyle = "MiniToolbarButton";
44 | popupStyle.padding = new RectOffset(0, 0, 2, 1); // Left, right, top, bottom
45 |
46 | GUI.BeginGroup(rect, GUI.skin.GetStyle("MiniToolbarButtonLeft"));
47 |
48 | // New track popdown
49 | Rect newTrackRect = new Rect(0, 0, 33, rect.height);
50 | GUI.Label(newTrackRect, newTrackLabel, popupStyle);
51 |
52 | if (Event.current.type == EventType.MouseDown && newTrackRect.Contains(Event.current.mousePosition)) {
53 | GUIUtility.hotControl = 0;
54 | EditorUtility.DisplayPopupMenu(newTrackRect, "Component/Cutscene/Track", null);
55 | Event.current.Use();
56 | }
57 |
58 | // Timeline zoom slider
59 | Rect timelineZoomRect = new Rect(newTrackRect.xMax + GUI.skin.horizontalSlider.margin.left, -1, rect.width - newTrackRect.xMax - GUI.skin.horizontalSlider.margin.horizontal, rect.height);
60 | ed.timelineZoom = GUI.HorizontalSlider(timelineZoomRect, ed.timelineZoom, ed.timelineMin, CutsceneTimeline.timelineZoomMax);
61 |
62 | GUI.EndGroup();
63 | }
64 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutscenePreview.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | class CutscenePreview : ICutsceneGUI
27 | {
28 | //readonly CutsceneEditor ed;
29 |
30 | public CutscenePreview (CutsceneEditor ed)
31 | {
32 | //this.ed = ed;
33 | }
34 |
35 | public void OnGUI (Rect rect)
36 | {
37 | //GUI.DrawTexture(rect, );
38 | Camera cam = GameObject.Find("Some Cam").GetComponent();
39 | EDebug.Log(cam.name);
40 |
41 | cam.targetTexture = new RenderTexture(128, 128, 32);
42 | cam.targetTexture.isPowerOfTwo = true;
43 | cam.targetTexture.Create();
44 |
45 |
46 |
47 | GUI.DrawTexture(rect, cam.targetTexture);
48 |
49 | cam.targetTexture.Release();
50 | cam.targetTexture = null;
51 |
52 | /*if (Event.current.type == EventType.repaint) {
53 | MovieTexture target = base.target as MovieTexture;
54 | float num = Mathf.Min(Mathf.Min((float)(r.width / ((float)target.width)), (float)(r.height / ((float)target.height))), 1f);
55 | Rect viewRect = new Rect(r.x, r.y, target.width * num, target.height * num);
56 | PreviewGUI.BeginScrollView(r, this.m_Pos, viewRect, "PreHorizontalScrollbar", "PreHorizontalScrollbarThumb");
57 | GUI.DrawTexture(viewRect, target, ScaleMode.StretchToFill, false);
58 | this.m_Pos = PreviewGUI.EndScrollView();
59 | if (target.isPlaying) {
60 | GUIView.current.Repaint();
61 | }
62 | if (Application.isPlaying) {
63 | if (target.isPlaying) {
64 | Rect position = new Rect(r.x, r.y + 10f, r.width, 20f);
65 | EditorGUI.DropShadowLabel(position, "Can't pause preview when in play mode");
66 | } else {
67 | Rect rect3 = new Rect(r.x, r.y + 10f, r.width, 20f);
68 | EditorGUI.DropShadowLabel(rect3, "Can't start preview when in play mode");
69 | }
70 | }
71 | }*/
72 | }
73 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneAddSubtitle.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | public class CutsceneAddSubtitle : ScriptableWizard {
27 | string dialog = "";
28 |
29 | ///
30 | /// Creates a wizard for adding a new subtitle.
31 | ///
32 | [MenuItem("Component/Cutscene/Add Media/Subtitle")]
33 | public static void CreateWizard ()
34 | {
35 | DisplayWizard("Add Subtitle", "Add");
36 | }
37 |
38 | ///
39 | /// Validates the menu item.
40 | ///
41 | /// The item will be disabled if no cutscene is selected.
42 | [MenuItem("Component/Cutscene/Add Media/Subtitle", true)]
43 | static bool ValidateCreateWizard ()
44 | {
45 | return CutsceneEditor.CutsceneSelected;
46 | }
47 |
48 | void OnGUI ()
49 | {
50 | OnWizardUpdate();
51 |
52 | EditorGUILayout.BeginHorizontal();
53 |
54 | GUIContent itemLabel = new GUIContent("Dialog", EditorGUIUtility.ObjectContent(null, typeof(TextAsset)).image);
55 | GUILayout.Label(itemLabel, GUILayout.ExpandWidth(false));
56 | dialog = EditorGUILayout.TextArea(dialog);
57 |
58 | EditorGUILayout.EndHorizontal();
59 |
60 | GUI.enabled = isValid;
61 | EditorGUILayout.BeginHorizontal();
62 |
63 | GUILayout.FlexibleSpace();
64 |
65 | if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) {
66 | OnWizardCreate();
67 | Close();
68 | }
69 |
70 | EditorGUILayout.EndHorizontal();
71 | GUI.enabled = true;
72 | }
73 |
74 | void OnWizardUpdate ()
75 | {
76 | helpString = "Type in some dialog to add.";
77 | // Only valid if some text has been entered in the text field
78 | isValid = dialog != "";
79 | }
80 |
81 | ///
82 | /// Adds the new subtitle to the cutscene.
83 | ///
84 | void OnWizardCreate ()
85 | {
86 | Selection.activeGameObject.GetComponent().NewSubtitle(dialog);
87 | }
88 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutscenePlaybackControls.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | class CutscenePlaybackControls : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | const int buttonWidth = 18;
31 |
32 | readonly GUIContent inPointLabel = new GUIContent(
33 | EditorGUIUtility.LoadRequired("Cutscene Ed/playback_in.png") as Texture,
34 | "Go to in point."
35 | );
36 | readonly GUIContent backLabel = new GUIContent(
37 | EditorGUIUtility.LoadRequired("Cutscene Ed/playback_back.png") as Texture,
38 | "Go back a second."
39 | );
40 | /*
41 | readonly GUIContent playLabel = new GUIContent(
42 | EditorGUIUtility.LoadRequired("Cutscene Ed/playback_play.png") as Texture,
43 | "Play."
44 | );
45 | */
46 | readonly GUIContent forwardLabel = new GUIContent(
47 | EditorGUIUtility.LoadRequired("Cutscene Ed/playback_forward.png") as Texture,
48 | "Go forward a second."
49 | );
50 | readonly GUIContent outPointLabel = new GUIContent(
51 | EditorGUIUtility.LoadRequired("Cutscene Ed/playback_out.png") as Texture,
52 | "Go to out point."
53 | );
54 |
55 | public CutscenePlaybackControls (CutsceneEditor ed)
56 | {
57 | this.ed = ed;
58 | }
59 |
60 | ///
61 | /// Displays playback controls.
62 | ///
63 | /// The playback controls' Rect.
64 | public void OnGUI (Rect rect)
65 | {
66 | GUI.BeginGroup(rect, EditorStyles.toolbar);
67 |
68 | // In point
69 | Rect inPointRect = new Rect(6, 0, buttonWidth, rect.height);
70 | if (GUI.Button(inPointRect, inPointLabel, EditorStyles.toolbarButton)) {
71 | ed.scene.playhead = ed.scene.inPoint;
72 | }
73 | // Back
74 | Rect backRect = new Rect(inPointRect.xMax, 0, buttonWidth, rect.height);
75 | if (GUI.Button(backRect, backLabel, EditorStyles.toolbarButton)) {
76 | ed.scene.playhead -= CutsceneTimeline.scrubSmallJump;
77 | }
78 | /* Feature not implemented yet:
79 | // Play
80 | Rect playRect = new Rect(backRect.xMax, 0, buttonWidth, rect.height);
81 | if (GUI.Button(playRect, playLabel, EditorStyles.toolbarButton)) {
82 | EDebug.Log("Cutscene Editor: previewing scene (feature not implemented)");
83 | };*/
84 | // Forward
85 | Rect forwardRect = new Rect(backRect.xMax, 0, buttonWidth, rect.height);
86 | if (GUI.Button(forwardRect, forwardLabel, EditorStyles.toolbarButton)) {
87 | ed.scene.playhead += CutsceneTimeline.scrubSmallJump;
88 | }
89 | // Out point
90 | Rect outPointRect = new Rect(forwardRect.xMax, 0, buttonWidth, rect.height);
91 | if (GUI.Button(outPointRect, outPointLabel, EditorStyles.toolbarButton)) {
92 | ed.scene.playhead = ed.scene.outPoint;
93 | }
94 |
95 | Rect floatRect = new Rect(outPointRect.xMax + 4, 2, 50, rect.height);
96 | ed.scene.playhead = EditorGUI.FloatField(floatRect, ed.scene.playhead, EditorStyles.toolbarTextField);
97 |
98 | GUI.EndGroup();
99 | }
100 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneAddAudio.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | class CutsceneAddAudio : ScriptableWizard
27 | {
28 | //GUISkin style = EditorGUIUtility.LoadRequired("Cutscene Ed/cutscene_editor_style.guiskin") as GUISkin;
29 |
30 | AudioClip[] audioClips;
31 | AudioClip selected;
32 |
33 | ///
34 | /// Creates a wizard for adding a new audio clip.
35 | ///
36 | [MenuItem("Component/Cutscene/Add Media/Audio")]
37 | public static void CreateWizard ()
38 | {
39 | DisplayWizard("Add Audio", "Add");
40 | }
41 |
42 | ///
43 | /// Validates the menu item.
44 | ///
45 | /// The item will be disabled if no cutscene is selected.
46 | [MenuItem("Component/Cutscene/Add Media/Audio", true)]
47 | static bool ValidateCreateWizard ()
48 | {
49 | return CutsceneEditor.CutsceneSelected;
50 | }
51 |
52 | void OnGUI ()
53 | {
54 | OnWizardUpdate();
55 |
56 | // Display temporary workaround info
57 | GUILayout.Label("To add an audio clip from the Project view, drag and drop it to the audio pane. This is a temporary workaround and will hopefully be fixed soon.");
58 |
59 | // TODO Make LoadAllAssetsAtPath work
60 | /*
61 | audioClips = (AudioClip[])AssetDatabase.LoadAllAssetsAtPath("Assets");
62 |
63 | Debug.Log("Objects length: " + audioClips.Length);
64 |
65 | EditorGUILayout.BeginVertical(style.GetStyle("List Container"));
66 |
67 | foreach (AudioClip aud in audioClips) {
68 | GUIStyle itemStyle = aud == selected ? style.GetStyle("Selected List Item") : GUIStyle.none;
69 |
70 | Rect rect = EditorGUILayout.BeginHorizontal(itemStyle);
71 |
72 | GUIContent itemLabel = new GUIContent(aud.name, EditorGUIUtility.ObjectContent(null, typeof(AudioClip)).image);
73 | GUILayout.Label(itemLabel);
74 |
75 | EditorGUILayout.EndHorizontal();
76 |
77 | // Select when clicked
78 | if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
79 | selected = aud;
80 | EditorGUIUtility.PingObject(aud);
81 | Event.current.Use();
82 | }
83 | }
84 |
85 | EditorGUILayout.EndVertical();
86 |
87 | GUI.enabled = isValid;
88 | EditorGUILayout.BeginHorizontal();
89 |
90 | GUILayout.FlexibleSpace();
91 |
92 | if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) {
93 | OnWizardCreate();
94 | Close();
95 | }
96 |
97 | EditorGUILayout.EndHorizontal();
98 | GUI.enabled = true;*/
99 | }
100 |
101 | void OnWizardUpdate ()
102 | {
103 | helpString = "Choose an audio clip to add.";
104 | // Only valid if an audio clip has been selected
105 | isValid = selected != null;
106 | }
107 |
108 | ///
109 | /// Adds a new audio clip to the cutscene.
110 | ///
111 | void OnWizardCreate ()
112 | {
113 | Selection.activeGameObject.GetComponent().NewAudio(selected);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneAddActor.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 | using System.Collections;
26 | using System.Collections.Generic;
27 |
28 | class CutsceneAddActor : ScriptableWizard
29 | {
30 | GUISkin style = EditorGUIUtility.LoadRequired("Cutscene Ed/cutscene_editor_style.guiskin") as GUISkin;
31 | AnimationClip selected;
32 | GameObject selectedGO;
33 |
34 | ///
35 | /// Creates a wizard for adding a new actor.
36 | ///
37 | [MenuItem("Component/Cutscene/Add Media/Actor")]
38 | public static void CreateWizard () {
39 | DisplayWizard("Add Actor", "Add");
40 | }
41 |
42 | ///
43 | /// Validates the menu item.
44 | ///
45 | /// The item will be disabled if no cutscene is selected.
46 | [MenuItem("Component/Cutscene/Add Media/Actor", true)]
47 | static bool ValidateCreateWizard () {
48 | return CutsceneEditor.CutsceneSelected;
49 | }
50 |
51 | void OnGUI ()
52 | {
53 | OnWizardUpdate();
54 |
55 | Object[] animations = FindObjectsOfType(typeof(Animation));
56 |
57 | EditorGUILayout.BeginVertical(style.GetStyle("List Container"));
58 |
59 | foreach (Animation anim in animations) {
60 | GUILayout.Label(anim.gameObject.name, EditorStyles.largeLabel);
61 |
62 | foreach (AnimationClip clip in AnimationUtility.GetAnimationClips(anim)) {
63 | GUIStyle itemStyle = GUIStyle.none;
64 | if (clip == selected) {
65 | itemStyle = style.GetStyle("Selected List Item");
66 | }
67 |
68 | Rect rect = EditorGUILayout.BeginHorizontal(itemStyle);
69 |
70 | GUIContent itemLabel = new GUIContent(clip.name, EditorGUIUtility.ObjectContent(null, typeof(Animation)).image);
71 | GUILayout.Label(itemLabel);
72 |
73 | EditorGUILayout.EndHorizontal();
74 |
75 | // Select when clicked
76 | if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
77 | selected = clip;
78 | selectedGO = anim.gameObject;
79 | EditorGUIUtility.PingObject(anim);
80 | Event.current.Use();
81 | Repaint();
82 | }
83 | }
84 | }
85 |
86 | EditorGUILayout.EndVertical();
87 |
88 | GUI.enabled = isValid;
89 | EditorGUILayout.BeginHorizontal();
90 |
91 | GUILayout.FlexibleSpace();
92 |
93 | if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) {
94 | OnWizardCreate();
95 | Close();
96 | }
97 |
98 | EditorGUILayout.EndHorizontal();
99 | GUI.enabled = true;
100 | }
101 |
102 | void OnWizardUpdate ()
103 | {
104 | helpString = "Choose an animation to add.";
105 | // Only valid if an animation has been selected
106 | isValid = selected != null;
107 | }
108 |
109 | ///
110 | /// Adds the new actor to the cutscene.
111 | ///
112 | void OnWizardCreate ()
113 | {
114 | Selection.activeGameObject.GetComponent().NewActor(selected, selectedGO);
115 | }
116 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneHotkeys.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | struct Hotkey
27 | {
28 | const string prefPrefix = "Cutscene Editor Hotkey ";
29 |
30 | string id;
31 | KeyCode defaultKey;
32 | bool assignable;
33 |
34 | public KeyCode key {
35 | get {
36 | if (assignable && EditorPrefs.HasKey(prefPrefix + id)) {
37 | return (KeyCode)EditorPrefs.GetInt(prefPrefix + id, (int)defaultKey);
38 | } else {
39 | return defaultKey;
40 | }
41 | }
42 | set {
43 | if (assignable) {
44 | EditorPrefs.SetInt(prefPrefix + id, (int)value);
45 | } else {
46 | EDebug.LogWarning("Cutscene Editor: Hotkey " + id + " cannot be reassigned");
47 | }
48 | }
49 | }
50 |
51 | public Hotkey (string id, KeyCode defaultKey, bool assignable)
52 | {
53 | this.id = id;
54 | this.defaultKey = defaultKey;
55 | this.assignable = assignable;
56 | }
57 |
58 | ///
59 | /// Resets the key to its default value.
60 | ///
61 | public void Reset ()
62 | {
63 | if (assignable) {
64 | key = defaultKey;
65 | }
66 | EDebug.Log("Cutscene Editor: Hotkey " + id + " reset to its default " + defaultKey);
67 | }
68 | }
69 |
70 | static class CutsceneHotkeys
71 | {
72 | // Assignable:
73 | public static Hotkey MoveResizeTool = new Hotkey("moveResizeTool", KeyCode.M, true);
74 | public static Hotkey ScissorsTool = new Hotkey("scissorsTool", KeyCode.S, true);
75 | public static Hotkey ZoomTool = new Hotkey("zoomTool", KeyCode.Z, true);
76 | public static Hotkey SetInPont = new Hotkey("setInPoint", KeyCode.I, true);
77 | public static Hotkey SetOutPoint = new Hotkey("setOutPoint", KeyCode.O, true);
78 |
79 | // Unassignable:
80 | public static readonly Hotkey SelectTrack1 = new Hotkey("selectTrack1", KeyCode.Alpha1, true);
81 | public static readonly Hotkey SelectTrack2 = new Hotkey("selectTrack2", KeyCode.Alpha2, true);
82 | public static readonly Hotkey SelectTrack3 = new Hotkey("selectTrack3", KeyCode.Alpha3, true);
83 | public static readonly Hotkey SelectTrack4 = new Hotkey("selectTrack4", KeyCode.Alpha4, true);
84 | public static readonly Hotkey SelectTrack5 = new Hotkey("selectTrack5", KeyCode.Alpha5, true);
85 | public static readonly Hotkey SelectTrack6 = new Hotkey("selectTrack6", KeyCode.Alpha6, true);
86 | public static readonly Hotkey SelectTrack7 = new Hotkey("selectTrack7", KeyCode.Alpha7, true);
87 | public static readonly Hotkey SelectTrack8 = new Hotkey("selectTrack8", KeyCode.Alpha8, true);
88 | public static readonly Hotkey SelectTrack9 = new Hotkey("selectTrack9", KeyCode.Alpha9, true);
89 |
90 | public static Hotkey[] assignable = new Hotkey[] {
91 | MoveResizeTool,
92 | ScissorsTool,
93 | ZoomTool,
94 | SetInPont,
95 | SetOutPoint
96 | };
97 |
98 | ///
99 | /// Resets all the assignable hotkeys to their default values.
100 | ///
101 | public static void ResetAll ()
102 | {
103 | foreach (Hotkey key in assignable) {
104 | key.Reset();
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneInspector.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | ///
27 | /// A custom inspector for a cutscene.
28 | ///
29 | [CustomEditor(typeof(Cutscene))]
30 | public class CutsceneInspector : Editor
31 | {
32 | Cutscene scene {
33 | get { return target as Cutscene; }
34 | }
35 |
36 | public override void OnInspectorGUI ()
37 | {
38 | /*
39 | GUILayout.Label("Timing", EditorStyles.boldLabel);
40 |
41 | GUIContent durationLabel = new GUIContent("Duration", "The entire length of the cutscene.");
42 | scene.duration = EditorGUILayout.FloatField(durationLabel, scene.duration);
43 |
44 | // Instead of trying to clamp the values of the in and out points by slider leftValue and rightValue of the slider, we leave it to the Cutscene class
45 | GUIContent inPointLabel = new GUIContent("In", "The point at which the cutscene starts.");
46 | scene.inPoint = EditorGUILayout.Slider(inPointLabel, scene.inPoint, 0f, scene.duration);
47 |
48 | GUIContent outPointLabel = new GUIContent("Out", "The point at which the cutscene ends.");
49 | scene.outPoint = EditorGUILayout.Slider(outPointLabel, scene.outPoint, 0f, scene.duration);
50 |
51 | GUILayout.Label("Options", EditorStyles.boldLabel);
52 |
53 | GUIContent stopPlayerLabel = new GUIContent("Stop Player", "Deactivate the player when the scene starts.");
54 | scene.stopPlayer = EditorGUILayout.Toggle(stopPlayerLabel, scene.stopPlayer);
55 |
56 | // Disable the player reference box if the stop player toggle in unchecked
57 | GUI.enabled = scene.stopPlayer ? true : false;
58 |
59 | GUIContent playerLabel = new GUIContent("Player", "The player to deactivate.");
60 | scene.player = EditorGUILayout.ObjectField(playerLabel, scene.player, typeof(GameObject)) as GameObject;
61 |
62 | GUI.enabled = true;
63 |
64 | EditorGUILayout.Separator();*/
65 |
66 | DrawDefaultInspector();
67 |
68 | if (GUILayout.Button("Edit")) {
69 | CutsceneEditor.OpenEditor();
70 | }
71 |
72 | if (GUI.changed) {
73 | EditorUtility.SetDirty(target);
74 | }
75 | }
76 |
77 | public void OnSceneGUI ()
78 | {
79 | Handles.BeginGUI();
80 |
81 | GUI.Box(new Rect(0, Screen.height - 300, 200, 30), "Cutscene Preview");
82 |
83 | //Rect camRect = GUILayoutUtility.GetRect(100, 100);
84 | if (scene != null) {
85 |
86 | Camera cam = null;
87 |
88 | foreach (CutsceneTrack track in scene.tracks) {
89 | if (track.type == Cutscene.MediaType.Shots) {
90 | CutsceneClip clip = track.ContainsClipAtTime(scene.playhead);
91 | if (clip != null) {
92 | cam = ((CutsceneShot)clip.master).camera;
93 | break;
94 | }
95 | }
96 | }
97 |
98 | if (cam != null) {
99 | DrawCamera(new Rect(0, 0, 200, 200), cam);
100 | }
101 | }
102 |
103 | Handles.EndGUI();
104 | }
105 |
106 | void DrawCamera (Rect previewRect, Camera camera)
107 | {
108 | if (Event.current.type == EventType.Repaint) {
109 | Rect cameraOriginalRect = camera.pixelRect;
110 | camera.pixelRect = previewRect;
111 | camera.Render();
112 | camera.pixelRect = cameraOriginalRect;
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneTrackInfo.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | class CutsceneTrackInfo : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | readonly GUIContent visibilityIcon = new GUIContent("",
31 | EditorGUIUtility.LoadRequired("Cutscene Ed/icon_eye.png") as Texture,
32 | "Toggle visibility."
33 | );
34 |
35 | readonly GUIContent lockIcon = new GUIContent("",
36 | EditorGUIUtility.LoadRequired("Cutscene Ed/icon_lock.png") as Texture,
37 | "Toggle track lock."
38 | );
39 |
40 | public CutsceneTrackInfo (CutsceneEditor ed) {
41 | this.ed = ed;
42 | }
43 |
44 | ///
45 | /// Displays the track info GUI.
46 | ///
47 | /// The track info's Rect.
48 | public void OnGUI (Rect rect)
49 | {
50 | ed.timelineScrollPos.y = EditorGUILayout.BeginScrollView(
51 | new Vector2(0, ed.timelineScrollPos.y),
52 | false, false,
53 | ed.style.horizontalScrollbar,
54 | ed.style.verticalScrollbar,
55 | GUIStyle.none,
56 | GUILayout.Width(CutsceneTimeline.trackInfoWidth), GUILayout.ExpandHeight(true)).y;
57 |
58 | foreach (CutsceneTrack track in ed.scene.tracks) {
59 | if (track == ed.selectedTrack) {
60 | GUI.SetNextControlName("track");
61 | }
62 |
63 | Rect infoRect = EditorGUILayout.BeginHorizontal(ed.style.GetStyle("Track Info"));
64 | track.enabled = GUILayout.Toggle(track.enabled, visibilityIcon, EditorStyles.miniButtonLeft, GUILayout.ExpandWidth(false));
65 | track.locked = GUILayout.Toggle(track.locked, lockIcon, EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false));
66 |
67 | GUILayout.Space(10);
68 |
69 | GUI.enabled = track.enabled;
70 |
71 | // Track name and icon
72 | GUIContent trackIcon = new GUIContent(ed.mediaIcons[(int)track.type]);
73 | GUILayout.Label(trackIcon, GUILayout.ExpandWidth(false));
74 | // Set a minimum width to keep the label from becoming uneditable
75 | Rect trackNameRect = GUILayoutUtility.GetRect(new GUIContent(track.name), EditorStyles.miniLabel, GUILayout.ExpandWidth(false), GUILayout.MinWidth(20));
76 | track.name = EditorGUI.TextField(trackNameRect, track.name, EditorStyles.miniLabel);
77 |
78 | GUI.enabled = true;
79 | EditorGUILayout.EndHorizontal();
80 |
81 | if (track == ed.selectedTrack) {
82 | GUI.FocusControl("track");
83 | }
84 |
85 | // Handle clicks
86 | Vector2 mousePos = Event.current.mousePosition;
87 | if (Event.current.type == EventType.MouseDown && infoRect.Contains(mousePos)) {
88 | switch (Event.current.button) {
89 | case 0: // Left mouse button
90 | ed.selectedTrack = track;
91 | break;
92 |
93 | case 1: // Right mouse button
94 | EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/CutsceneTrack/", new MenuCommand(track));
95 | break;
96 |
97 | default:
98 | break;
99 | }
100 |
101 | Event.current.Use();
102 | }
103 | }
104 |
105 | // Divider line
106 | Handles.color = Color.grey;
107 | Handles.DrawLine(new Vector3(67, 0), new Vector3(67, rect.yMax));
108 |
109 | EditorGUILayout.EndScrollView();
110 | }
111 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneClip.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using System;
25 |
26 | public class CutsceneClip : ScriptableObject
27 | {
28 | public CutsceneMedia master;
29 |
30 | public float timelineStart = 0f;
31 | public float inPoint = 0f;
32 | public float outPoint = 5f; // Default 5 seconds
33 |
34 | public float timelineEnd {
35 | get { return timelineStart + duration; }
36 | }
37 |
38 | float maxOutPoint {
39 | get {
40 | float max = Mathf.Infinity;
41 |
42 | if (master is CutsceneActor) {
43 | max = ((CutsceneActor)master).anim.length;
44 | } else if (master is CutsceneAudio) {
45 | max = ((CutsceneAudio)master).gameObject.audio.clip.length;
46 | }
47 |
48 | return max;
49 | }
50 | }
51 |
52 | public void SetTimelineStart (float value)
53 | {
54 | timelineStart = Mathf.Clamp(value, 0f, Mathf.Infinity);
55 | }
56 |
57 | public void SetInPoint (float value)
58 | {
59 | inPoint = Mathf.Clamp(value, 0f, outPoint);
60 | }
61 |
62 | public void SetOutPoint (float value)
63 | {
64 | outPoint = Mathf.Clamp(value, inPoint, maxOutPoint);
65 | }
66 |
67 | [HideInInspector]
68 | public bool setToDelete = false; // An ugly workaround used for deleting clips
69 |
70 | // Read only
71 | public float duration {
72 | get { return outPoint - inPoint; }
73 | }
74 | public string startFunction {
75 | get {
76 | // Determine which function to call based on the master object type
77 | if (master is CutsceneShot) {
78 | return "PlayShot";
79 | } else if (master is CutsceneActor) {
80 | return "PlayActor";
81 | } else if (master is CutsceneAudio) {
82 | return "PlayAudio";
83 | } else if (master is CutsceneSubtitle) {
84 | return "PlaySubtitle";
85 | } else {
86 | return "UnknownFunction";
87 | }
88 | }
89 | }
90 | public Cutscene.MediaType type {
91 | get {
92 | if (master is CutsceneShot) {
93 | return Cutscene.MediaType.Shots;
94 | } else if (master is CutsceneActor) {
95 | return Cutscene.MediaType.Actors;
96 | } else if (master is CutsceneAudio) {
97 | return Cutscene.MediaType.Audio;
98 | } else { // master is CutsceneSubtitles
99 | return Cutscene.MediaType.Subtitles;
100 | }
101 | }
102 | }
103 |
104 | public CutsceneClip (CutsceneMedia master)
105 | {
106 | this.master = master;
107 | if (master is CutsceneSubtitle) {
108 | name = ((CutsceneSubtitle)master).dialog;
109 | } else {
110 | name = master.name;
111 | }
112 |
113 | if (maxOutPoint != Mathf.Infinity) {
114 | outPoint = maxOutPoint;
115 | }
116 | }
117 |
118 | ///
119 | /// Gets a clone of the current clip.
120 | ///
121 | /// The clip copy.
122 | public CutsceneClip GetCopy ()
123 | {
124 | CutsceneClip copy = new CutsceneClip(master);
125 | copy.timelineStart = timelineStart;
126 | copy.SetInPoint(inPoint);
127 | copy.outPoint = outPoint;
128 |
129 | return copy;
130 | }
131 |
132 | ///
133 | /// Adds an effect to the clip.
134 | ///
135 | /// The transitions or filter.
136 | public void ApplyEffect (Type effect)
137 | {
138 | // Only add the effect if the master object is a camera shot
139 | if (master is CutsceneShot) {
140 | master.gameObject.AddComponent(effect);
141 | }
142 | }
143 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/CutsceneTrack.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using System.Collections.Generic;
25 | using System;
26 |
27 | public class CutsceneTrack : MonoBehaviour
28 | {
29 | public bool locked;
30 | [HideInInspector]
31 | public Cutscene.MediaType type = Cutscene.MediaType.Shots;
32 | public new string name = DefaultName(Cutscene.MediaType.Shots);
33 | public List clips = new List();
34 | [HideInInspector]
35 | public int id = 0;
36 |
37 | public AnimationClip track {
38 | get {
39 | AnimationClip _track = new AnimationClip();
40 |
41 | foreach (CutsceneClip clip in clips) {
42 | AnimationEvent start = new AnimationEvent();
43 | start.time = clip.timelineStart;
44 | start.functionName = clip.startFunction;
45 | start.objectReferenceParameter = clip;
46 | _track.AddEvent(start);
47 | }
48 |
49 | return _track;
50 | }
51 | }
52 |
53 | public static string DefaultName (Cutscene.MediaType type)
54 | {
55 | switch (type) {
56 | case Cutscene.MediaType.Shots:
57 | return "Shots";
58 | case Cutscene.MediaType.Actors:
59 | return "Actors";
60 | case Cutscene.MediaType.Audio:
61 | return "Audio";
62 | default: // Cutscene.MediaType.Subtitles
63 | return "Subtitles";
64 | }
65 | }
66 |
67 | ///
68 | /// Checks to see if there's a clip at the given time, ignoring the given clip.
69 | ///
70 | /// The time to check for.
71 | /// The CutsceneClip that is at the given time.
72 | public CutsceneClip ContainsClipAtTime (float time, CutsceneClip ignoreClip)
73 | {
74 | CutsceneClip contains = ContainsClipAtTime(time);
75 |
76 | if (contains != null && contains != ignoreClip) {
77 | return contains;
78 | } else {
79 | return null;
80 | }
81 | }
82 |
83 | ///
84 | /// Checks to see if there's a clip at the given time.
85 | ///
86 | /// The time to check for.
87 | /// The CutsceneClip that is at the given time.
88 | public CutsceneClip ContainsClipAtTime (float time)
89 | {
90 | foreach (CutsceneClip clip in clips) {
91 | if (time >= clip.timelineStart && time <= clip.timelineStart + clip.duration) {
92 | return clip;
93 | }
94 | }
95 |
96 | // The timeline doesn't contain a clip at the specified time
97 | return null;
98 | }
99 |
100 | public float GetTimeOfPreviousSplit (float time)
101 | {
102 | float splitTime = -1f;
103 |
104 | foreach (CutsceneClip clip in clips) {
105 | if (clip.timelineEnd < time && clip.timelineEnd > splitTime) {
106 | splitTime = clip.timelineEnd;
107 | } else if (clip.timelineStart < time && clip.timelineStart > splitTime) {
108 | splitTime = clip.timelineStart;
109 | }
110 | }
111 |
112 | // If splitTime is still -1, just return the original time
113 | return splitTime == -1f ? time : splitTime;
114 | }
115 |
116 | public float GetTimeOfNextSplit (float time)
117 | {
118 | float splitTime = Mathf.Infinity;
119 |
120 | foreach (CutsceneClip clip in clips) {
121 | if (clip.timelineStart > time && clip.timelineStart < splitTime) {
122 | splitTime = clip.timelineStart;
123 | } else if (clip.timelineEnd > time && clip.timelineEnd < splitTime) {
124 | splitTime = clip.timelineEnd;
125 | }
126 | }
127 |
128 | // If splitTime is still infinity, just return the original time
129 | return splitTime == Mathf.Infinity ? time : splitTime;
130 | }
131 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneEffectsWindow.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 | using System;
26 | using System.Collections.Generic;
27 |
28 | class CutsceneEffectsWindow : ICutsceneGUI
29 | {
30 | readonly CutsceneEditor ed;
31 |
32 | static Dictionary filters = new Dictionary
33 | {
34 | { CutsceneBlurFilter.name, typeof(CutsceneBlurFilter) },
35 | { CutsceneInvertFilter.name, typeof(CutsceneInvertFilter) }
36 | };
37 |
38 | static Dictionary transitions = new Dictionary {};
39 |
40 | static readonly GUIContent filtersLabel = new GUIContent("Filters", "Full screen filters.");
41 | static readonly GUIContent transitionsLabel = new GUIContent("Transitions", "Camera transitions.");
42 |
43 | readonly GUIContent[] effectsTabs = CutsceneEditor.HasPro ? new GUIContent[] { filtersLabel, transitionsLabel } : new GUIContent[] { transitionsLabel };
44 | Cutscene.EffectType currentEffectsTab = Cutscene.EffectType.Filters;
45 |
46 | Type selectedEffect;
47 |
48 | readonly Texture[] effectsIcons = {
49 | EditorGUIUtility.LoadRequired("Cutscene Ed/effects_filter.png") as Texture,
50 | EditorGUIUtility.LoadRequired("Cutscene Ed/effects_transition.png") as Texture
51 | };
52 |
53 | public CutsceneEffectsWindow (CutsceneEditor ed)
54 | {
55 | this.ed = ed;
56 | }
57 |
58 | ///
59 | /// Displays the effects pane's GUI.
60 | ///
61 | /// The effects pane's Rect.
62 | public void OnGUI (Rect rect)
63 | {
64 | GUILayout.BeginArea(rect, ed.style.GetStyle("Pane"));
65 |
66 | EditorGUILayout.BeginHorizontal();
67 |
68 | GUILayout.FlexibleSpace();
69 | currentEffectsTab = (Cutscene.EffectType)GUILayout.Toolbar((int)currentEffectsTab, effectsTabs, GUILayout.Width(CutsceneEditor.PaneTabsWidth(effectsTabs.Length)));
70 | GUILayout.FlexibleSpace();
71 |
72 | EditorGUILayout.EndHorizontal();
73 |
74 | EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
75 |
76 | GUI.enabled = ed.selectedClip != null && ed.selectedClip.type == Cutscene.MediaType.Shots && selectedEffect != null;
77 |
78 | GUIContent applyLabel = new GUIContent("Apply", "Apply the selected effect to the selected clip.");
79 | if (GUILayout.Button(applyLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
80 | if (ed.selectedClip != null) {
81 | ed.selectedClip.ApplyEffect(selectedEffect);
82 | }
83 | }
84 |
85 | GUI.enabled = true;
86 |
87 | EditorGUILayout.EndHorizontal();
88 |
89 | switch (currentEffectsTab) {
90 | case Cutscene.EffectType.Filters:
91 | foreach (KeyValuePair item in filters) {
92 |
93 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedEffect == item.Value ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
94 |
95 | GUIContent filterLabel = new GUIContent(item.Key, effectsIcons[(int)Cutscene.EffectType.Filters]);
96 | GUILayout.Label(filterLabel);
97 |
98 | EditorGUILayout.EndHorizontal();
99 |
100 | // Handle clicks
101 | if (Event.current.type == EventType.MouseDown && itemRect.Contains(Event.current.mousePosition)) {
102 | selectedEffect = item.Value;
103 | Event.current.Use();
104 | }
105 | }
106 | break;
107 |
108 | case Cutscene.EffectType.Transitions:
109 | foreach (KeyValuePair item in transitions) {
110 |
111 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedEffect == item.Value ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
112 | GUIContent transitionLabel = new GUIContent(item.Key, effectsIcons[(int)Cutscene.EffectType.Transitions]);
113 | GUILayout.Label(transitionLabel);
114 |
115 | EditorGUILayout.EndHorizontal();
116 |
117 | // Handle clicks
118 | if (Event.current.type == EventType.MouseDown && itemRect.Contains(Event.current.mousePosition)) {
119 | selectedEffect = item.Value;
120 | Event.current.Use();
121 | }
122 | }
123 | break;
124 |
125 | default:
126 | break;
127 | }
128 |
129 | GUILayout.EndArea();
130 | }
131 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Effects/Filters/CutsceneBlurFilter.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | // Based off of BlurEffect.cs from the Pro Standard Assets
5 |
6 | public class CutsceneBlurFilter : CutsceneEffect {
7 | [HideInInspector]
8 | public static new string name = "Blur";
9 |
10 | /// Blur iterations - larger number means more blur.
11 | public int iterations = 3;
12 |
13 | /// Blur spread for each iteration. Lower values
14 | /// give better looking blur, but require more iterations to
15 | /// get large blurs. Value is usually between 0.5 and 1.0.
16 | public float blurSpread = 0.6f;
17 |
18 |
19 | // --------------------------------------------------------
20 | // The blur iteration shader.
21 | // Basically it just takes 4 texture samples and averages them.
22 | // By applying it repeatedly and spreading out sample locations
23 | // we get a Gaussian blur approximation.
24 |
25 | static string blurMatString =
26 | @"Shader ""BlurConeTap"" {
27 | SubShader {
28 | Pass {
29 | ZTest Always Cull Off ZWrite Off Fog { Mode Off }
30 | SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant alpha}
31 | SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
32 | SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
33 | SetTexture [__RenderTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
34 | }
35 | }
36 | Fallback off
37 | }";
38 |
39 | static Material m_Material = null;
40 | protected static Material material {
41 | get {
42 | if (m_Material == null) {
43 | m_Material = new Material( blurMatString );
44 | m_Material.hideFlags = HideFlags.HideAndDontSave;
45 | m_Material.shader.hideFlags = HideFlags.HideAndDontSave;
46 | }
47 | return m_Material;
48 | }
49 | }
50 |
51 | protected void OnDisable() {
52 | if( m_Material ) {
53 | DestroyImmediate( m_Material.shader );
54 | DestroyImmediate( m_Material );
55 | }
56 | }
57 |
58 | // --------------------------------------------------------
59 |
60 | protected void Start() {
61 | // Disable if we don't support image effects
62 | if (!SystemInfo.supportsImageEffects) {
63 | enabled = false;
64 | return;
65 | }
66 | // Disable if the shader can't run on the users graphics card
67 | if (!material.shader.isSupported) {
68 | enabled = false;
69 | return;
70 | }
71 | }
72 |
73 | // Performs one blur iteration.
74 | public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration) {
75 | RenderTexture.active = dest;
76 | source.SetGlobalShaderProperty ("__RenderTex");
77 |
78 | float offsetX = (.5F+iteration*blurSpread) / (float)source.width;
79 | float offsetY = (.5F+iteration*blurSpread) / (float)source.height;
80 | GL.PushMatrix ();
81 | GL.LoadOrtho ();
82 |
83 | for (int i = 0; i < material.passCount; i++) {
84 | material.SetPass (i);
85 | Render4TapQuad( dest, offsetX, offsetY );
86 | }
87 | GL.PopMatrix ();
88 | }
89 |
90 | // Downsamples the texture to a quarter resolution.
91 | void DownSample4x (RenderTexture source, RenderTexture dest) {
92 | RenderTexture.active = dest;
93 | source.SetGlobalShaderProperty ("__RenderTex");
94 |
95 | float offsetX = 1.0f / (float)source.width;
96 | float offsetY = 1.0f / (float)source.height;
97 |
98 | GL.PushMatrix ();
99 | GL.LoadOrtho ();
100 | for (int i = 0; i < material.passCount; i++)
101 | {
102 | material.SetPass (i);
103 | Render4TapQuad( dest, offsetX, offsetY );
104 | }
105 | GL.PopMatrix ();
106 | }
107 |
108 | // Called by the camera to apply the image effect
109 | void OnRenderImage (RenderTexture source, RenderTexture destination) {
110 | RenderTexture buffer = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
111 | RenderTexture buffer2 = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
112 |
113 | // Copy source to the 4x4 smaller texture.
114 | DownSample4x (source, buffer);
115 |
116 | // Blur the small texture
117 | bool oddEven = true;
118 | for(int i = 0; i < iterations; i++)
119 | {
120 | if( oddEven )
121 | FourTapCone (buffer, buffer2, i);
122 | else
123 | FourTapCone (buffer2, buffer, i);
124 | oddEven = !oddEven;
125 | }
126 | if( oddEven )
127 | ImageEffects.Blit(buffer, destination);
128 | else
129 | ImageEffects.Blit(buffer2, destination);
130 |
131 | RenderTexture.ReleaseTemporary(buffer);
132 | RenderTexture.ReleaseTemporary(buffer2);
133 | }
134 |
135 | static void Render4TapQuad( RenderTexture dest, float offsetX, float offsetY ) {
136 | GL.Begin( GL.QUADS );
137 |
138 | // Direct3D needs interesting texel offsets!
139 | Vector2 off = Vector2.zero;
140 | if( dest != null )
141 | off = dest.GetTexelOffset() * 0.75f;
142 |
143 | Set4TexCoords( off.x, off.y, offsetX, offsetY );
144 | GL.Vertex3( 0,0, .1f );
145 |
146 | Set4TexCoords( 1.0f + off.x, off.y, offsetX, offsetY );
147 | GL.Vertex3( 1,0, .1f );
148 |
149 | Set4TexCoords( 1.0f + off.x, 1.0f + off.y, offsetX, offsetY );
150 | GL.Vertex3( 1,1,.1f );
151 |
152 | Set4TexCoords( off.x, 1.0f + off.y, offsetX, offsetY );
153 | GL.Vertex3( 0,1,.1f );
154 |
155 | GL.End();
156 | }
157 |
158 | static void Set4TexCoords( float x, float y, float offsetX, float offsetY ) {
159 | GL.MultiTexCoord2( 0, x - offsetX, y - offsetY );
160 | GL.MultiTexCoord2( 1, x + offsetX, y - offsetY );
161 | GL.MultiTexCoord2( 2, x + offsetX, y + offsetY );
162 | GL.MultiTexCoord2( 3, x - offsetX, y + offsetY );
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneTimeline.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | public enum DragEvent {
27 | Move,
28 | ResizeLeft,
29 | ResizeRight
30 | }
31 |
32 | class CutsceneTimeline : ICutsceneGUI
33 | {
34 | readonly CutsceneEditor ed;
35 |
36 | public const int scrubLargeJump = 10;
37 | public const int scrubSmallJump = 1;
38 |
39 | readonly ICutsceneGUI navigation;
40 | readonly ICutsceneGUI tracksView;
41 | readonly ICutsceneGUI trackControls;
42 | readonly ICutsceneGUI trackInfo;
43 |
44 | public const float timelineZoomMin = 1f;
45 | public const float timelineZoomMax = 100f;
46 | public const float trackInfoWidth = 160f;
47 |
48 | public CutsceneTimeline (CutsceneEditor ed)
49 | {
50 | this.ed = ed;
51 |
52 | navigation = new CutsceneNavigation(ed);
53 | tracksView = new CutsceneTracksView(ed);
54 | trackControls = new CutsceneTrackControls(ed);
55 | trackInfo = new CutsceneTrackInfo(ed);
56 | }
57 |
58 | ///
59 | /// Displays the timeline's GUI.
60 | ///
61 | /// The timeline's Rect.
62 | public void OnGUI (Rect rect)
63 | {
64 | CutsceneGUILayout.Area(delegate {
65 |
66 | float rightColWidth = GUI.skin.verticalScrollbar.fixedWidth;
67 | float middleColWidth = rect.width - CutsceneTimeline.trackInfoWidth - rightColWidth;
68 |
69 | ed.timelineMin = CutsceneTimeline.timelineZoomMin * (middleColWidth / ed.scene.duration);
70 | ed.timelineZoom = Mathf.Clamp(ed.timelineZoom, ed.timelineMin, CutsceneTimeline.timelineZoomMax);
71 |
72 | // Navigation bar
73 | Rect navigationRect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.toolbar, GUILayout.Width(rect.width));
74 | navigation.OnGUI(navigationRect);
75 |
76 | // Begin Tracks
77 | CutsceneEditorGUILayout.Horizontal(delegate {
78 |
79 | // Track info
80 | //Rect trackInfoRect = GUILayoutUtility.GetRect(trackInfoWidth, rect.height - navigationRect.yMax - GUI.skin.horizontalScrollbar.fixedHeight);
81 | Rect trackInfoRect = new Rect(0, 0, CutsceneTimeline.trackInfoWidth, 9999);
82 | trackInfo.OnGUI(trackInfoRect);
83 |
84 | // Track controls
85 | float trackControlsHeight = GUI.skin.horizontalScrollbar.fixedHeight;
86 | Rect trackControlsRect = new Rect(0, rect.height - trackControlsHeight, CutsceneTimeline.trackInfoWidth, trackControlsHeight);
87 | trackControls.OnGUI(trackControlsRect);
88 |
89 | // Tracks
90 | Rect tracksRect = new Rect(trackInfoRect.xMax, navigationRect.yMax, middleColWidth + rightColWidth, rect.height - navigationRect.yMax);
91 | tracksView.OnGUI(tracksRect);
92 |
93 | }, GUILayout.Width(rect.width), GUILayout.ExpandHeight(true));
94 |
95 | if (Event.current.type == EventType.KeyDown) { // Key presses
96 | ed.HandleKeyboardShortcuts(Event.current);
97 | }
98 |
99 | }, rect);
100 | }
101 |
102 | ///
103 | /// Moves the playhead.
104 | ///
105 | /// The position to move the playhead to.
106 | void MovePlayheadToPosition (float playheadPos)
107 | {
108 | ed.scene.playhead = playheadPos / ed.timelineZoom;
109 | }
110 |
111 | ///
112 | /// Splits a clip into two separate ones at the specified time.
113 | ///
114 | /// The time at which to split the clip.
115 | /// The track the clip is sitting on.
116 | /// The clip to split.
117 | /// The new clip.
118 | public static CutsceneClip SplitClipAtTime (float splitPoint, CutsceneTrack track, CutsceneClip clip)
119 | {
120 | CutsceneClip newClip = clip.GetCopy();
121 |
122 | // Make sure the clip actually spans over the split point
123 | if (splitPoint < clip.timelineStart || splitPoint > clip.timelineStart + clip.duration) {
124 | EDebug.Log("Cutscene Editor: cannot split clip; clip does not contain the split point");
125 | return null;
126 | }
127 |
128 | clip.SetOutPoint(clip.inPoint + (splitPoint - clip.timelineStart));
129 | newClip.SetInPoint(clip.outPoint);
130 | newClip.SetTimelineStart(splitPoint);
131 |
132 | track.clips.Add(newClip);
133 |
134 | Event.current.Use();
135 | EDebug.Log("Cutscene Editor: splitting clip at time " + splitPoint);
136 |
137 | return newClip;
138 | }
139 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Effects/ImageEffects.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | /// Blending modes use by the ImageEffects.Blit functions.
4 | public enum BlendMode {
5 | Copy,
6 | Multiply,
7 | MultiplyDouble,
8 | Add,
9 | AddSmoooth,
10 | Blend
11 | }
12 |
13 | /// A Utility class for performing various image based rendering tasks.
14 | [AddComponentMenu("")]
15 | public class ImageEffects {
16 | static Material[] m_BlitMaterials = new Material[6];
17 |
18 | static public Material GetBlitMaterial (BlendMode mode) {
19 | int index = (int)mode;
20 |
21 | if (m_BlitMaterials[index] != null)
22 | return m_BlitMaterials[index];
23 |
24 | // Blit Copy Material
25 | m_BlitMaterials[0] = new Material (
26 | "Shader \"BlitCopy\" {\n" +
27 | " SubShader { Pass {\n" +
28 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
29 | " SetTexture [__RenderTex] { combine texture}" +
30 | " }}\n" +
31 | "Fallback Off }"
32 | );
33 | // Blit Multiply
34 | m_BlitMaterials[1] = new Material (
35 | "Shader \"BlitMultiply\" {\n" +
36 | " SubShader { Pass {\n" +
37 | " Blend DstColor Zero\n" +
38 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
39 | " SetTexture [__RenderTex] { combine texture }" +
40 | " }}\n" +
41 | "Fallback Off }"
42 | );
43 | // Blit Multiply 2X
44 | m_BlitMaterials[2] = new Material (
45 | "Shader \"BlitMultiplyDouble\" {\n" +
46 | " SubShader { Pass {\n" +
47 | " Blend DstColor SrcColor\n" +
48 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
49 | " SetTexture [__RenderTex] { combine texture }" +
50 | " }}\n" +
51 | "Fallback Off }"
52 | );
53 | // Blit Add
54 | m_BlitMaterials[3] = new Material (
55 | "Shader \"BlitAdd\" {\n" +
56 | " SubShader { Pass {\n" +
57 | " Blend One One\n" +
58 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
59 | " SetTexture [__RenderTex] { combine texture }" +
60 | " }}\n" +
61 | "Fallback Off }"
62 | );
63 | // Blit AddSmooth
64 | m_BlitMaterials[4] = new Material (
65 | "Shader \"BlitAddSmooth\" {\n" +
66 | " SubShader { Pass {\n" +
67 | " Blend OneMinusDstColor One\n" +
68 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
69 | " SetTexture [__RenderTex] { combine texture }" +
70 | " }}\n" +
71 | "Fallback Off }"
72 | );
73 | // Blit Blend
74 | m_BlitMaterials[5] = new Material (
75 | "Shader \"BlitBlend\" {\n" +
76 | " SubShader { Pass {\n" +
77 | " Blend SrcAlpha OneMinusSrcAlpha\n" +
78 | " ZTest Always Cull Off ZWrite Off Fog { Mode Off }\n" +
79 | " SetTexture [__RenderTex] { combine texture }" +
80 | " }}\n" +
81 | "Fallback Off }"
82 | );
83 | for( int i = 0; i < m_BlitMaterials.Length; ++i ) {
84 | m_BlitMaterials[i].hideFlags = HideFlags.HideAndDontSave;
85 | m_BlitMaterials[i].shader.hideFlags = HideFlags.HideAndDontSave;
86 | }
87 | return m_BlitMaterials[index];
88 | }
89 |
90 |
91 | /// Copies one render texture onto another.
92 | /// This function copies /source/ onto /dest/, optionally using a custom blend mode.
93 | /// If /blendMode/ is left out, the default operation is simply to copy one texture on to another.
94 | /// This function will copy the whole source texture on to the whole destination texture. If the sizes differ,
95 | /// the image in the source texture will get stretched to fit.
96 | /// The source and destination textures cannot be the same.
97 | public static void Blit (RenderTexture source, RenderTexture dest, BlendMode blendMode) {
98 | Blit (source, new Rect (0,0,1,1), dest, new Rect (0,0,1,1), blendMode);
99 | }
100 | public static void Blit (RenderTexture source, RenderTexture dest) {
101 | Blit (source, dest, BlendMode.Copy);
102 | }
103 |
104 | /// Copies one render texture onto another.
105 | public static void Blit (RenderTexture source, Rect sourceRect, RenderTexture dest, Rect destRect, BlendMode blendMode) {
106 | // Make the destination texture the target for all rendering
107 | RenderTexture.active = dest;
108 | // Assign the source texture to a property from a shader
109 | source.SetGlobalShaderProperty ("__RenderTex");
110 | // Set up the simple Matrix
111 | GL.PushMatrix ();
112 | GL.LoadOrtho ();
113 | Material blitMaterial = GetBlitMaterial(blendMode);
114 | for (int i = 0; i < blitMaterial.passCount; i++) {
115 | blitMaterial.SetPass (i);
116 | DrawQuad();
117 | }
118 | GL.PopMatrix ();
119 | }
120 |
121 |
122 | public static void BlitWithMaterial (Material material, RenderTexture source, RenderTexture destination) {
123 | RenderTexture.active = destination;
124 | material.SetTexture("_MainTex", source);
125 |
126 | GL.PushMatrix ();
127 | GL.LoadOrtho ();
128 |
129 | for (int i = 0; i < material.passCount; i++) {
130 | material.SetPass (i);
131 | ImageEffects.DrawQuad();
132 | }
133 | GL.PopMatrix ();
134 | }
135 |
136 |
137 | public static void RenderDistortion (Material material, RenderTexture source, RenderTexture destination, float angle, Vector2 center, Vector2 radius) {
138 | Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 0, angle), Vector3.one);
139 |
140 | material.SetMatrix("_RotationMatrix", rotationMatrix);
141 | material.SetVector("_CenterRadius", new Vector4(center.x,center.y,radius.x,radius.y) );
142 | material.SetFloat("_Angle", angle * Mathf.Deg2Rad);
143 |
144 | ImageEffects.BlitWithMaterial( material, source, destination );
145 | }
146 |
147 |
148 | public static void DrawQuad() {
149 | GL.Begin (GL.QUADS);
150 | GL.TexCoord2( 0.0f, 0.0f ); GL.Vertex3( 0.0f, 0.0f, 0.1f );
151 | GL.TexCoord2( 1.0f, 0.0f ); GL.Vertex3( 1.0f, 0.0f, 0.1f );
152 | GL.TexCoord2( 1.0f, 1.0f ); GL.Vertex3( 1.0f, 1.0f, 0.1f );
153 | GL.TexCoord2( 0.0f, 1.0f ); GL.Vertex3( 0.0f, 1.0f, 0.1f );
154 | GL.End();
155 | }
156 |
157 | public static void DrawGrid (int xSize, int ySize) {
158 | GL.Begin (GL.QUADS);
159 |
160 | float xDelta = 1.0F / xSize;
161 | float yDelta = 1.0F / ySize;
162 |
163 | for (int y=0;y
50 | /// Displays the timecode bar with vertical lines indicating the time and the playhead.
51 | ///
52 | /// The timecode bar's Rect.
53 | public void OnGUI (Rect rect)
54 | {
55 | GUI.BeginGroup(rect);
56 |
57 | // Create a button that looks like a toolbar
58 | if (GUI.RepeatButton(new Rect(0, 0, rect.width, rect.height), GUIContent.none, EditorStyles.toolbar)) {
59 | float position = Event.current.mousePosition.x + ed.timelineScrollPos.x;
60 | ed.scene.playhead = position / ed.timelineZoom;
61 |
62 | // Show a visual notification of the position
63 | GUIContent notification = new GUIContent("Playhead " + ed.scene.playhead.ToString("N2"));
64 | ed.ShowNotification(notification);
65 |
66 | ed.Repaint();
67 | //SceneView.RepaintAll();
68 | } else {
69 | // TODO Investigate if attempting to remove the notification every frame like this is wasteful
70 | ed.RemoveNotification();
71 | }
72 |
73 | DrawTicks();
74 | DrawLabels();
75 | DrawPlayhead();
76 | DrawInOutPoints();
77 |
78 | GUI.EndGroup();
79 | }
80 |
81 | ///
82 | /// Draws vertical lines representing time increments.
83 | ///
84 | void DrawTicks ()
85 | {
86 | Handles.color = tickColor;
87 |
88 | // Draw short ticks every second
89 | for (float i = 0; i < ed.scene.duration * ed.timelineZoom; i += ed.timelineZoom) {
90 | float xPos = i - ed.timelineScrollPos.x;
91 | Handles.DrawLine(new Vector3(xPos, 0, 0), new Vector3(xPos, shortTickHeight));
92 | }
93 |
94 | // Draw tall ticks every ten seconds
95 | for (float i = 0; i < ed.scene.duration * ed.timelineZoom; i += ed.timelineZoom * 10) {
96 | float xPos = i - ed.timelineScrollPos.x;
97 | Handles.DrawLine(new Vector3(xPos, 0, 0), new Vector3(xPos, tallTickHeight));
98 | }
99 | }
100 |
101 | ///
102 | /// Draws labels indicating the time.
103 | ///
104 | void DrawLabels ()
105 | {
106 | for (float i = 0; i < 1000; i += 10) {
107 | float xPos = (i * ed.timelineZoom) - ed.timelineScrollPos.x;
108 | GUIContent label = new GUIContent(i + "");
109 | Vector2 dimensions = EditorStyles.miniLabel.CalcSize(label);
110 | Rect labelRect = new Rect(xPos - (dimensions.x / 2), 2, dimensions.x, dimensions.y);
111 | GUI.Label(labelRect, label, EditorStyles.miniLabel);
112 | }
113 | }
114 |
115 | ///
116 | /// Draws the playhead.
117 | ///
118 | void DrawPlayhead ()
119 | {
120 | // Draw position indicator
121 | float pos = (ed.scene.playhead * ed.timelineZoom) - ed.timelineScrollPos.x;
122 | GUI.DrawTexture(new Rect(pos - 4, 0, 8, 8), positionIndicatorIcon);
123 |
124 | Handles.color = Color.black;
125 |
126 | // Vertical line
127 | Vector3 top = new Vector3(pos, 0);
128 | Vector3 bottom = new Vector3(pos, EditorStyles.toolbar.fixedHeight);
129 | Handles.DrawLine(top, bottom);
130 |
131 | // Zoom indicator block
132 | Handles.color = playheadBlockColor;
133 |
134 | for (int i = 1; i <= ed.timelineZoom; i++) {
135 | float xPos = pos + i;
136 | top = new Vector3(xPos, 4);
137 | bottom = new Vector3(xPos, EditorStyles.toolbar.fixedHeight - 1);
138 | Handles.DrawLine(top, bottom);
139 | }
140 | }
141 |
142 | ///
143 | /// Draws the in and out points.
144 | ///
145 | void DrawInOutPoints ()
146 | {
147 | Handles.color = inOutPointColour;
148 |
149 | DrawInPoint();
150 | DrawOutPoint();
151 | }
152 |
153 | ///
154 | /// Draws the in point.
155 | ///
156 | void DrawInPoint ()
157 | {
158 | float pos = (ed.scene.inPoint * ed.timelineZoom) - ed.timelineScrollPos.x;
159 |
160 | // Icon
161 | Rect indicatorRect = new Rect(pos, 0, 4, 8);
162 | GUI.DrawTexture(indicatorRect, inPointIndicatorIcon);
163 |
164 | // Tooltip
165 | GUI.Label(indicatorRect, inTooltip);
166 |
167 | // Vertical line
168 | Vector3 top = new Vector3(pos, 0);
169 | Vector3 bottom = new Vector3(pos, EditorStyles.toolbar.fixedHeight);
170 | Handles.DrawLine(top, bottom);
171 | }
172 |
173 | ///
174 | /// Draws the out point.
175 | ///
176 | void DrawOutPoint ()
177 | {
178 | float pos = (ed.scene.outPoint * ed.timelineZoom) - ed.timelineScrollPos.x;
179 |
180 | // Icon
181 | Rect indicatorRect = new Rect(pos - 4, 0, 4, 8);
182 | GUI.DrawTexture(indicatorRect, outPointIndicatorIcon);
183 |
184 | // Tooltip
185 | GUI.Label(indicatorRect, outTooltip);
186 |
187 | // Vertical line
188 | Vector3 top = new Vector3(pos, 0);
189 | Vector3 bottom = new Vector3(pos, EditorStyles.toolbar.fixedHeight);
190 | Handles.DrawLine(top, bottom);
191 | }
192 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneMediaWindow.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 |
26 | class CutsceneMediaWindow : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | readonly GUIContent[] mediaTabs = {
31 | new GUIContent("Shots", "Camera views."),
32 | new GUIContent("Actors", "Animated game objects."),
33 | new GUIContent("Audio", "Dialog, background music and sound effects."),
34 | new GUIContent("Subtitles", "Textual versions of dialog.")
35 | };
36 |
37 | Cutscene.MediaType currentMediaTab = Cutscene.MediaType.Shots;
38 | Vector2[] mediaScrollPos = new Vector2[4];
39 | CutsceneMedia selectedMediaItem;
40 |
41 | readonly GUIContent newMediaLabel = new GUIContent(EditorGUIUtility.LoadRequired("Cutscene Ed/icon_add.png") as Texture, "Add new media.");
42 | readonly GUIContent insertMediaLabel = new GUIContent("Insert", "Insert the selected shot onto the timeline.");
43 |
44 | public CutsceneMediaWindow (CutsceneEditor ed)
45 | {
46 | this.ed = ed;
47 | }
48 |
49 | ///
50 | /// Displays the media pane's GUI.
51 | ///
52 | /// The media pane's Rect.
53 | public void OnGUI (Rect rect)
54 | {
55 | GUILayout.BeginArea(rect, ed.style.GetStyle("Pane"));
56 |
57 | EditorGUILayout.BeginHorizontal();
58 |
59 | GUILayout.FlexibleSpace();
60 | currentMediaTab = (Cutscene.MediaType)GUILayout.Toolbar((int)currentMediaTab, mediaTabs, GUILayout.Width(CutsceneEditor.PaneTabsWidth(mediaTabs.Length)));
61 | GUILayout.FlexibleSpace();
62 |
63 | EditorGUILayout.EndHorizontal();
64 |
65 | switch (currentMediaTab) {
66 | case Cutscene.MediaType.Shots:
67 | // If the selected item is in a different tab, set it to null
68 | if (selectedMediaItem != null && selectedMediaItem.type != currentMediaTab) {
69 | selectedMediaItem = null;
70 | }
71 |
72 | EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
73 |
74 | if (GUILayout.Button(newMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
75 | ed.scene.NewShot();
76 | }
77 |
78 | GUI.enabled = IsMediaInsertable();
79 | if (GUILayout.Button(insertMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
80 | Insert(selectedMediaItem);
81 | }
82 | GUI.enabled = true;
83 |
84 | GUILayout.FlexibleSpace();
85 |
86 | EditorGUILayout.EndHorizontal();
87 |
88 | mediaScrollPos[(int)currentMediaTab] = EditorGUILayout.BeginScrollView(mediaScrollPos[(int)currentMediaTab], GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
89 | foreach (CutsceneShot shot in ed.scene.shots) {
90 |
91 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedMediaItem == shot ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
92 |
93 | GUIContent itemLabel = new GUIContent(shot.name, ed.mediaIcons[(int)Cutscene.MediaType.Shots]);
94 | GUILayout.Label(itemLabel);
95 |
96 | EditorGUILayout.EndHorizontal();
97 |
98 | HandleMediaItemClicks(shot, itemRect);
99 | }
100 | EditorGUILayout.EndScrollView();
101 |
102 | break;
103 |
104 | case Cutscene.MediaType.Actors:
105 | // If the selected item is in a different tab, set it to null
106 | if (selectedMediaItem != null && selectedMediaItem.type != currentMediaTab) {
107 | selectedMediaItem = null;
108 | }
109 |
110 | EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
111 |
112 | if (GUILayout.Button(newMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
113 | CutsceneAddActor.CreateWizard();
114 | }
115 |
116 | GUI.enabled = IsMediaInsertable();
117 | if (GUILayout.Button(insertMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
118 | Insert(selectedMediaItem);
119 | }
120 | GUI.enabled = true;
121 |
122 | GUILayout.FlexibleSpace();
123 |
124 | EditorGUILayout.EndHorizontal();
125 |
126 | mediaScrollPos[(int)currentMediaTab] = EditorGUILayout.BeginScrollView(mediaScrollPos[(int)currentMediaTab], GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
127 | foreach (CutsceneActor actor in ed.scene.actors) {
128 |
129 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedMediaItem == actor ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
130 |
131 | GUIContent itemLabel = new GUIContent(actor.anim.name, ed.mediaIcons[(int)Cutscene.MediaType.Actors]);
132 | GUILayout.Label(itemLabel);
133 |
134 | EditorGUILayout.EndHorizontal();
135 |
136 | HandleMediaItemClicks(actor, itemRect);
137 | }
138 | EditorGUILayout.EndScrollView();
139 |
140 | break;
141 |
142 | case Cutscene.MediaType.Audio:
143 | // If the selected item is in a different tab, set it to null
144 | if (selectedMediaItem != null && selectedMediaItem.type != currentMediaTab) {
145 | selectedMediaItem = null;
146 | }
147 |
148 | EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
149 |
150 | if (GUILayout.Button(newMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
151 | // Show a wizard that will take care of adding audio
152 | CutsceneAddAudio.CreateWizard();
153 | }
154 |
155 | GUI.enabled = IsMediaInsertable();
156 | if (GUILayout.Button(insertMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
157 | Insert(selectedMediaItem);
158 | }
159 | GUI.enabled = true;
160 |
161 | GUILayout.FlexibleSpace();
162 |
163 | EditorGUILayout.EndHorizontal();
164 |
165 | mediaScrollPos[(int)currentMediaTab] = EditorGUILayout.BeginScrollView(mediaScrollPos[(int)currentMediaTab], GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
166 | foreach (CutsceneAudio aud in ed.scene.audioSources) {
167 |
168 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedMediaItem == aud ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
169 |
170 | GUIContent itemLabel = new GUIContent(aud.name, ed.mediaIcons[(int)Cutscene.MediaType.Audio]);
171 | GUILayout.Label(itemLabel);
172 |
173 | EditorGUILayout.EndHorizontal();
174 |
175 | HandleMediaItemClicks(aud, itemRect);
176 | }
177 | EditorGUILayout.EndScrollView();
178 |
179 | break;
180 |
181 | case Cutscene.MediaType.Subtitles:
182 | // If the selected item is in a different tab, set it to null
183 | if (selectedMediaItem != null && selectedMediaItem.type != currentMediaTab) {
184 | selectedMediaItem = null;
185 | }
186 |
187 | EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
188 |
189 | if (GUILayout.Button(newMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
190 | // Show a wizard that will take care of adding audio
191 | CutsceneAddSubtitle.CreateWizard();
192 | }
193 |
194 | GUI.enabled = IsMediaInsertable();
195 | if (GUILayout.Button(insertMediaLabel, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) {
196 | Insert(selectedMediaItem);
197 | }
198 | GUI.enabled = true;
199 |
200 | GUILayout.FlexibleSpace();
201 |
202 | EditorGUILayout.EndHorizontal();
203 |
204 | mediaScrollPos[(int)currentMediaTab] = EditorGUILayout.BeginScrollView(mediaScrollPos[(int)currentMediaTab], GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
205 | foreach (CutsceneSubtitle subtitle in ed.scene.subtitles) {
206 |
207 | Rect itemRect = EditorGUILayout.BeginHorizontal(selectedMediaItem == subtitle ? ed.style.GetStyle("Selected List Item") : GUIStyle.none);
208 |
209 | GUIContent itemLabel = new GUIContent(ed.mediaIcons[(int)Cutscene.MediaType.Subtitles]);
210 | GUILayout.Label(itemLabel, GUILayout.ExpandWidth(false));
211 | subtitle.dialog = EditorGUILayout.TextField(subtitle.dialog);
212 |
213 | EditorGUILayout.EndHorizontal();
214 |
215 | HandleMediaItemClicks(subtitle, itemRect);
216 | }
217 | EditorGUILayout.EndScrollView();
218 |
219 | break;
220 |
221 | default:
222 | break;
223 | }
224 | GUILayout.EndArea();
225 |
226 | // Handle drag and drop events
227 | if (Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragPerform) {
228 | // Show a copy icon on the drag
229 | DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
230 |
231 | if (Event.current.type == EventType.DragPerform && rect.Contains(Event.current.mousePosition)) {
232 | DragAndDrop.AcceptDrag();
233 | Object[] draggedObjects = DragAndDrop.objectReferences;
234 |
235 | // Create the appropriate cutscene objects for each dragged object
236 | foreach (Object obj in draggedObjects) {
237 | if (obj is AudioClip) {
238 | ed.scene.NewAudio((AudioClip)obj);
239 | } else if (obj is GameObject && ((GameObject)obj).animation != null) {
240 | GameObject go = obj as GameObject;
241 | foreach (AnimationClip anim in AnimationUtility.GetAnimationClips(go.animation)) {
242 | ed.scene.NewActor(anim, go);
243 | }
244 |
245 | }
246 | EDebug.Log("Cutscene Editor: dropping " + obj.GetType());
247 | }
248 | }
249 | Event.current.Use();
250 | }
251 | }
252 |
253 | ///
254 | /// Handles left and right mouse clicks of media items.
255 | ///
256 | /// The item clicked on.
257 | /// The item's Rect.
258 | void HandleMediaItemClicks (CutsceneMedia item, Rect rect)
259 | {
260 | Vector2 mousePos = Event.current.mousePosition;
261 | if (Event.current.type == EventType.MouseDown && rect.Contains(mousePos)) {
262 | switch (Event.current.button) {
263 | case 0: // Left click
264 | selectedMediaItem = item;
265 | EditorGUIUtility.PingObject(item);
266 | break;
267 |
268 | case 1: // Right click
269 | EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/CutsceneObject/", new MenuCommand(item));
270 | break;
271 |
272 | default:
273 | break;
274 | }
275 | Event.current.Use();
276 | }
277 | }
278 |
279 | ///
280 | /// Determines whether or not the currently selected cutscene object can be inserted into the selected timeline.
281 | ///
282 | /// True if the selected clip and the selected track are the same, false otherwise.
283 | bool IsMediaInsertable ()
284 | {
285 | return selectedMediaItem != null && selectedMediaItem.type == ed.selectedTrack.type;
286 | }
287 |
288 | ///
289 | /// Inserts the given cutscene object into the timeline.
290 | ///
291 | /// The cutscene object to insert.
292 | void Insert (CutsceneMedia obj)
293 | {
294 | CutsceneClip newClip = new CutsceneClip(obj);
295 | newClip.timelineStart = ed.scene.playhead;
296 |
297 | // If there are no existing tracks, add a new one
298 | if (ed.scene.tracks.Length == 0) {
299 | ed.scene.AddTrack(newClip.type);
300 | }
301 |
302 | // Manage overlap with other clips
303 | CutsceneClip existingClip = ed.selectedTrack.ContainsClipAtTime(ed.scene.playhead);
304 | if (existingClip != null) {
305 | CutsceneClip middleOfSplit = CutsceneTimeline.SplitClipAtTime(ed.scene.playhead, ed.selectedTrack, existingClip);
306 | CutsceneTimeline.SplitClipAtTime(ed.scene.playhead + newClip.duration, ed.selectedTrack, middleOfSplit);
307 | ed.selectedTrack.clips.Remove(middleOfSplit);
308 | }
309 |
310 | ed.selectedTrack.clips.Add(newClip);
311 |
312 | EDebug.Log("Cutscene Editor: inserting " + newClip.name + " into timeline " + ed.selectedTrack + " at " + ed.scene.playhead);
313 | }
314 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneTracksView.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using UnityEditor;
25 |
26 | class CutsceneTracksView : ICutsceneGUI
27 | {
28 | readonly CutsceneEditor ed;
29 |
30 | readonly Texture overlay = EditorGUIUtility.LoadRequired("Cutscene Ed/overlay.png") as Texture;
31 | readonly Color inOutPointColour = Color.cyan;
32 |
33 | public CutsceneTracksView (CutsceneEditor ed)
34 | {
35 | this.ed = ed;
36 | }
37 |
38 | ///
39 | /// Displays the tracks GUI.
40 | ///
41 | /// The tracks' Rect.
42 | public void OnGUI (Rect rect)
43 | {
44 | // Display background
45 | Rect background = new Rect(rect.x, rect.y,
46 | rect.width - GUI.skin.verticalScrollbar.fixedWidth,
47 | rect.height - GUI.skin.horizontalScrollbar.fixedHeight);
48 | GUI.BeginGroup(background, GUI.skin.GetStyle("AnimationCurveEditorBackground"));
49 | GUI.EndGroup();
50 |
51 | float trackHeight = ed.style.GetStyle("Track").fixedHeight + ed.style.GetStyle("Track").margin.vertical;
52 | // TODO Make the track width take into account clips that are beyond the out point
53 | float tracksWidth = (ed.scene.outPoint + 10) * ed.timelineZoom;
54 | float tracksHeight = trackHeight * ed.scene.tracks.Length;
55 |
56 | Rect view = new Rect(0, 0,
57 | Mathf.Max(background.width + 1, tracksWidth),
58 | Mathf.Max(background.height + 1, tracksHeight));
59 |
60 | ed.timelineScrollPos = GUI.BeginScrollView(rect, ed.timelineScrollPos, view, true, true);
61 |
62 | // Zoom clicks
63 | if (ed.currentTool == Tool.Zoom && Event.current.type == EventType.MouseDown) {
64 | if (Event.current.alt && Event.current.shift) { // Zoom out all the way
65 | ed.timelineZoom = CutsceneTimeline.timelineZoomMin;
66 | } else if (Event.current.shift) { // Zoom in all the way
67 | ed.timelineZoom = CutsceneTimeline.timelineZoomMax;
68 | } else if (Event.current.alt) { // Zoom out
69 | ed.timelineZoom -= 10;
70 | } else { // Zoom in
71 | ed.timelineZoom += 10;
72 | }
73 |
74 | Event.current.Use();
75 | }
76 |
77 | // Draw track divider lines
78 | Handles.color = Color.grey;
79 | for (int i = 0; i < ed.scene.tracks.Length; i++) {
80 | Rect trackRect = new Rect(0, trackHeight * i, view.width, trackHeight);
81 |
82 | DisplayTrack(trackRect, ed.scene.tracks[i]);
83 | float yPos = (i + 1) * trackHeight - 1;
84 | Handles.DrawLine(new Vector3(0, yPos), new Vector3(view.width, yPos));
85 | }
86 |
87 | // Draw overlay over in area
88 | Rect inOverlay = new Rect(0, 0, ed.scene.inPoint * ed.timelineZoom, view.height);
89 | GUI.DrawTexture(inOverlay, overlay);
90 |
91 | // Draw overlay over out area
92 | Rect outOverlay = new Rect(ed.scene.outPoint * ed.timelineZoom, 0, 0, view.height);
93 | outOverlay.width = view.width - outOverlay.x;
94 | GUI.DrawTexture(outOverlay, overlay);
95 |
96 | DrawLines(view);
97 |
98 | GUI.EndScrollView();
99 | }
100 |
101 | ///
102 | /// Displays visual tracks upon which clips sit.
103 | ///
104 | void DisplayTrack (Rect rect, CutsceneTrack track)
105 | {
106 | GUI.enabled = track.enabled;
107 |
108 | for (int i = track.clips.Count - 1; i >= 0; i--) {
109 | DisplayClip(rect, track, track.clips[i]);
110 | }
111 |
112 | GUI.enabled = true;
113 |
114 | // Handle clicks
115 | Vector2 mousePos = Event.current.mousePosition;
116 | if (Event.current.type == EventType.MouseDown && rect.Contains(mousePos)) {
117 | switch (Event.current.button) {
118 | case 0: // Left mouse button
119 | ed.selectedTrack = track;
120 | ed.selectedClip = null;
121 | break;
122 | case 1: // Right mouse button
123 | EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/CutsceneTrack/", new MenuCommand(track));
124 | Event.current.Use();
125 | break;
126 | default:
127 | break;
128 | }
129 |
130 | Event.current.Use();
131 | }
132 | }
133 |
134 | ///
135 | /// Displays a clip.
136 | ///
137 | /// The Rect of the track the clip sits on.
138 | /// The track the clip sits on.
139 | /// The clip to display.
140 | void DisplayClip (Rect trackRect, CutsceneTrack track, CutsceneClip clip)
141 | {
142 | const float trimWidth = 5f;
143 |
144 | GUIStyle clipStyle = ed.style.GetStyle("Selected Clip");
145 | // Set the clip style if this isn't the selected clip (selected clips all share the same style)
146 | if (clip != ed.selectedClip) {
147 | switch (clip.type) {
148 | case Cutscene.MediaType.Shots:
149 | clipStyle = ed.style.GetStyle("Shot Clip");
150 | break;
151 | case Cutscene.MediaType.Actors:
152 | clipStyle = ed.style.GetStyle("Actor Clip");
153 | break;
154 | case Cutscene.MediaType.Audio:
155 | clipStyle = ed.style.GetStyle("Audio Clip");
156 | break;
157 | default: // Cutscene.MediaType.Subtitles
158 | clipStyle = ed.style.GetStyle("Subtitle Clip");
159 | break;
160 | }
161 | }
162 |
163 | Rect rect = new Rect((trackRect.x + clip.timelineStart) * ed.timelineZoom, trackRect.y + 1, clip.duration * ed.timelineZoom, clipStyle.fixedHeight);
164 |
165 | GUI.BeginGroup(rect, clipStyle);
166 |
167 | GUIContent clipLabel = new GUIContent(clip.name, "Clip: " + clip.name + "\nDuration: " + clip.duration + "\nTimeline start: " + clip.timelineStart + "\nTimeline end: " + (clip.timelineStart + clip.duration));
168 | Rect clipLabelRect = new Rect(clipStyle.contentOffset.x, 0, rect.width - clipStyle.contentOffset.x, rect.height);
169 | GUI.Label(clipLabelRect, clipLabel);
170 |
171 | GUI.EndGroup();
172 |
173 | // Handle mouse clicks
174 | Vector2 mousePos = Event.current.mousePosition;
175 | if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
176 | switch (Event.current.button) {
177 | case 0: // Left mouse button
178 | ed.selectedClip = clip;
179 | ed.selectedTrack = track;
180 | break;
181 | case 1: // Right mouse button
182 | EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/CutsceneClip/", new MenuCommand(clip));
183 | Event.current.Use();
184 | break;
185 | default:
186 | break;
187 | }
188 | }
189 |
190 | if (clip.setToDelete) {
191 | ed.selectedTrack.clips.Remove(clip);
192 | return;
193 | }
194 |
195 | // Don't allow actions to be performed on the clip if the track is disabled or locked
196 | if (!track.enabled || track.locked) {
197 | return;
198 | }
199 |
200 | switch (ed.currentTool) {
201 | case Tool.MoveResize:
202 | // Define edit areas, adding custom cursors when hovered over
203 |
204 | // Move
205 | Rect move = new Rect(rect.x + trimWidth, rect.y, rect.width - (2 * trimWidth), rect.height);
206 | EditorGUIUtility.AddCursorRect(move, MouseCursor.SlideArrow);
207 |
208 | // Resize left
209 | Rect resizeLeft = new Rect(rect.x, rect.y, trimWidth, rect.height);
210 | EditorGUIUtility.AddCursorRect(resizeLeft, MouseCursor.ResizeHorizontal);
211 |
212 | // Resize right
213 | Rect resizeRight = new Rect(rect.xMax - trimWidth, rect.y, trimWidth, rect.height);
214 | EditorGUIUtility.AddCursorRect(resizeRight, MouseCursor.ResizeHorizontal);
215 |
216 | if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
217 | ed.dragClip = clip;
218 |
219 | // Move
220 | if (move.Contains(Event.current.mousePosition)) {
221 | ed.dragEvent = DragEvent.Move;
222 | EDebug.Log("Cutscene Editor: starting clip move");
223 | // Resize left
224 | } else if (resizeLeft.Contains(Event.current.mousePosition)) {
225 | ed.dragEvent = DragEvent.ResizeLeft;
226 | EDebug.Log("Cutscene Editor: starting clip resize left");
227 | // Resize right
228 | } else if (resizeRight.Contains(Event.current.mousePosition)) {
229 | ed.dragEvent = DragEvent.ResizeRight;
230 | EDebug.Log("Cutscene Editor: starting clip resize right");
231 | }
232 |
233 | Event.current.Use();
234 | } else if (Event.current.type == EventType.MouseDrag && ed.dragClip == clip) {
235 | float shift = Event.current.delta.x / ed.timelineZoom;
236 |
237 | switch (ed.dragEvent) {
238 | case DragEvent.Move:
239 | float newPos = clip.timelineStart + shift;
240 |
241 | // Left collisions
242 | CutsceneClip leftCollision = track.ContainsClipAtTime(newPos, clip);
243 | if (leftCollision != null) {
244 | newPos = leftCollision.timelineStart + leftCollision.duration;
245 | }
246 |
247 | // Right collisions
248 | CutsceneClip rightCollision = track.ContainsClipAtTime(newPos + clip.duration, clip);
249 | if (rightCollision != null) {
250 | newPos = rightCollision.timelineStart - clip.duration;
251 | }
252 |
253 | if (newPos + clip.duration > ed.scene.duration) {
254 | newPos = ed.scene.duration - clip.duration;
255 | }
256 |
257 | clip.SetTimelineStart(newPos);
258 | break;
259 | case DragEvent.ResizeLeft:
260 | clip.SetTimelineStart(clip.timelineStart + shift);
261 | clip.SetInPoint(clip.inPoint + shift);
262 |
263 | // TODO Improve collision behaviour
264 | CutsceneClip leftResizeCollision = track.ContainsClipAtTime(clip.timelineStart, clip);
265 | if (leftResizeCollision != null) {
266 |
267 |
268 | clip.SetTimelineStart(leftResizeCollision.timelineStart + leftResizeCollision.duration);
269 | }
270 |
271 | break;
272 | case DragEvent.ResizeRight:
273 | float newOut = clip.outPoint + shift;
274 |
275 | // Right collisions
276 | CutsceneClip rightResizeCollision = track.ContainsClipAtTime(clip.timelineStart + clip.duration + shift, clip);
277 | if (rightResizeCollision != null) {
278 | newOut = rightResizeCollision.timelineStart - clip.timelineStart + clip.inPoint;
279 | }
280 |
281 | clip.SetOutPoint(newOut);
282 | break;
283 | default:
284 | break;
285 | }
286 |
287 | Event.current.Use();
288 | } else if (Event.current.type == EventType.MouseUp) {
289 | ed.dragClip = null;
290 | Event.current.Use();
291 | }
292 |
293 | break;
294 | case Tool.Scissors:
295 | // TODO Switch to something better than the text cursor, if possible
296 | EditorGUIUtility.AddCursorRect(rect, MouseCursor.Text);
297 |
298 | if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
299 | SplitClip(track, clip, Event.current.mousePosition);
300 | Event.current.Use();
301 | }
302 |
303 | break;
304 | default:
305 | break;
306 | }
307 | }
308 |
309 | ///
310 | /// Splits a clip into two separate ones.
311 | ///
312 | /// The track the clip is sitting on.
313 | /// The clip to split.
314 | /// The position of the mouse when the split operation occurred.
315 | /// The new clip.
316 | CutsceneClip SplitClip (CutsceneTrack track, CutsceneClip clip, Vector2 mousePosition)
317 | {
318 | float splitPoint = mousePosition.x / ed.timelineZoom;
319 | return CutsceneTimeline.SplitClipAtTime(splitPoint, track, clip);
320 | }
321 |
322 | ///
323 | /// Draws the in, out, and playhead lines.
324 | ///
325 | /// The timeline's Rect.
326 | void DrawLines (Rect rect)
327 | {
328 | DrawPlayhead(rect);
329 |
330 | Handles.color = inOutPointColour;
331 | DrawInLine(rect);
332 | DrawOutLine(rect);
333 | }
334 |
335 | ///
336 | /// Draws the playhead over the timeline.
337 | ///
338 | /// The timeline's Rect.
339 | void DrawPlayhead (Rect rect)
340 | {
341 | Handles.color = Color.black;
342 | float pos = ed.scene.playhead * ed.timelineZoom;
343 |
344 | Vector3 timelineTop = new Vector3(pos, 0);
345 | Vector3 timelineBottom = new Vector3(pos, rect.yMax);
346 | Handles.DrawLine(timelineTop, timelineBottom);
347 | }
348 |
349 | ///
350 | /// Draws the in point line over the timeline.
351 | ///
352 | /// The timeline's Rect.
353 | void DrawInLine (Rect rect)
354 | {
355 | float pos = ed.scene.inPoint * ed.timelineZoom;
356 |
357 | Vector3 top = new Vector3(pos, 0);
358 | Vector3 bottom = new Vector3(pos, rect.yMax);
359 | Handles.DrawLine(top, bottom);
360 | }
361 |
362 | ///
363 | /// Draws the out point line over the timeline.
364 | ///
365 | /// The timeline's Rect.
366 | void DrawOutLine (Rect rect)
367 | {
368 | float pos = ed.scene.outPoint * ed.timelineZoom;
369 |
370 | Vector3 top = new Vector3(pos, 0);
371 | Vector3 bottom = new Vector3(pos, rect.yMax);
372 | Handles.DrawLine(top, bottom);
373 | }
374 | }
--------------------------------------------------------------------------------
/Cutscene Ed/Scripts/Cutscene.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEngine;
24 | using System.Collections;
25 | using System.Collections.Generic;
26 |
27 | // Functions to be run when the cutscene starts and finishes
28 | public delegate void CutsceneStart();
29 | public delegate void CutscenePause();
30 | public delegate void CutsceneEnd();
31 |
32 | [RequireComponent(typeof(Animation))]
33 | public class Cutscene : MonoBehaviour
34 | {
35 | public float duration = 30f;
36 | public float inPoint = 0f;
37 | public float outPoint = 30f;
38 | public bool stopPlayer = true;
39 | public GameObject player;
40 |
41 | public GUIStyle subtitleStyle;
42 | public Rect subtitlePosition = new Rect(0, 0, 400, 200);
43 |
44 | public CutsceneStart startFunction { get; set; }
45 | public CutscenePause pauseFunction { get; set; }
46 | public CutsceneEnd endFunction { get; set; }
47 |
48 | public enum MediaType {
49 | Shots,
50 | Actors,
51 | Audio,
52 | Subtitles
53 | }
54 | public enum EffectType {
55 | Filters,
56 | Transitions
57 | }
58 | public CutsceneTrack[] tracks {
59 | get { return GetComponentsInChildren(); }
60 | }
61 | public CutsceneShot[] shots {
62 | get { return GetComponentsInChildren(); }
63 | }
64 | public CutsceneActor[] actors {
65 | get { return GetComponentsInChildren(); }
66 | }
67 | public CutsceneAudio[] audioSources {
68 | get { return GetComponentsInChildren(); }
69 | }
70 | public CutsceneSubtitle[] subtitles {
71 | get { return GetComponentsInChildren(); }
72 | }
73 |
74 | CutsceneSubtitle currentSubtitle;
75 |
76 | public float playhead {
77 | get { return animation["master"].time; }
78 | set { animation["master"].time = Mathf.Clamp(value, 0f, duration); }
79 | }
80 |
81 | [HideInInspector]
82 | public AnimationClip masterClip;
83 |
84 | void Start ()
85 | {
86 | SetupMasterAnimationClip();
87 | SetupTrackAnimationClips();
88 |
89 | DisableCameras();
90 | DisableAudio();
91 | }
92 |
93 | void OnGUI ()
94 | {
95 | /// Displays the current subtitle if there is one
96 | if (currentSubtitle == null) {
97 | return;
98 | }
99 |
100 | GUI.BeginGroup(subtitlePosition, subtitleStyle);
101 |
102 | GUILayout.Label(currentSubtitle.dialog, subtitleStyle);
103 |
104 | GUI.EndGroup();
105 | }
106 |
107 | ///
108 | /// Visually shows the cutscene in the scene view.
109 | ///
110 | void OnDrawGizmos ()
111 | {
112 | Gizmos.DrawIcon(transform.position, "Cutscene.png");
113 | }
114 |
115 | ///
116 | /// Sets the in and out points of the master animation clip.
117 | ///
118 | void SetupMasterAnimationClip ()
119 | {
120 | animation.RemoveClip("master");
121 |
122 | // Create a new event for when the scene starts
123 | AnimationEvent start = new AnimationEvent();
124 | start.time = inPoint;
125 | start.functionName = "SceneStart";
126 | masterClip.AddEvent(start);
127 |
128 | // Create a new event for when the scene finishes
129 | AnimationEvent finish = new AnimationEvent();
130 | finish.time = outPoint;
131 | finish.functionName = "SceneFinish";
132 | masterClip.AddEvent(finish);
133 |
134 | animation.AddClip(masterClip, "master");
135 | animation["master"].time = inPoint;
136 | }
137 |
138 | ///
139 | /// Adds each track's animation clip to the main animation.
140 | ///
141 | void SetupTrackAnimationClips ()
142 | {
143 | foreach (CutsceneTrack t in tracks) {
144 | if (t.enabled) {
145 | AnimationClip trackAnimationClip = t.track;
146 | string clipName = "track" + t.id;
147 | animation.AddClip(trackAnimationClip, clipName);
148 | animation[clipName].time = inPoint;
149 | }
150 | }
151 | }
152 |
153 | ///
154 | /// Turns off all child cameras so that they don't display before the cutscene starts.
155 | ///
156 | void DisableCameras ()
157 | {
158 | Camera[] childCams = GetComponentsInChildren();
159 | foreach (Camera cam in childCams) {
160 | cam.enabled = false;
161 | }
162 | }
163 |
164 | ///
165 | /// Turns off all child cameras except for the one specified.
166 | ///
167 | /// The camera to stay enabled.
168 | void DisableOtherCameras (Camera exemptCam)
169 | {
170 | Camera[] childCams = GetComponentsInChildren();
171 | foreach (Camera cam in childCams) {
172 | if (cam != exemptCam) {
173 | cam.enabled = false;
174 | }
175 | }
176 | }
177 |
178 | ///
179 | /// Keeps all child audio sources from playing once the game starts.
180 | ///
181 | void DisableAudio ()
182 | {
183 | AudioSource[] childAudio = GetComponentsInChildren();
184 | foreach (AudioSource audio in childAudio) {
185 | audio.playOnAwake = false;
186 | }
187 | }
188 |
189 | ///
190 | /// Starts playing the cutscene.
191 | ///
192 | public void PlayCutscene ()
193 | {
194 | // Set up and play the master animation
195 | animation["master"].layer = 0;
196 | animation.Play("master");
197 |
198 | // Set up and play each individual track
199 | for (int i = 0; i < tracks.Length; i++) {
200 | if (tracks[i].enabled) {
201 | animation["track" + tracks[i].id].layer = i + 1;
202 | animation.Play("track" + tracks[i].id);
203 | }
204 | }
205 | }
206 |
207 | ///
208 | /// Pauses the cutscene.
209 | ///
210 | public void PauseCutscene ()
211 | {
212 | pauseFunction();
213 | // TODO actually pause the cutscene
214 | }
215 |
216 | ///
217 | /// Called when the scene starts.
218 | ///
219 | void SceneStart ()
220 | {
221 | if (startFunction != null) {
222 | startFunction();
223 | }
224 |
225 | // Stop the player from being able to move
226 | if (player != null && stopPlayer) {
227 | EDebug.Log("Cutscene: deactivating player");
228 | player.SetActive(false);
229 | }
230 |
231 | DisableCameras();
232 | currentSubtitle = null;
233 |
234 | EDebug.Log("Cutscene: scene started at " + animation["master"].time);
235 | }
236 |
237 | ///
238 | /// Called when the scene ends.
239 | ///
240 | void SceneFinish ()
241 | {
242 | if (endFunction != null) {
243 | endFunction();
244 | }
245 |
246 | // Allow the player to move again
247 | if (player != null) {
248 | EDebug.Log("Cutscene: activating player");
249 | player.SetActive(true);
250 | }
251 |
252 | EDebug.Log("Cutscene: scene finished at " + animation["master"].time);
253 | }
254 |
255 | ///
256 | /// Shows the specified shot.
257 | ///
258 | /// The shot to show.
259 | void PlayShot (CutsceneClip clip)
260 | {
261 | Camera cam = ((CutsceneShot)clip.master).camera;
262 | cam.enabled = true;
263 |
264 | StartCoroutine(StopShot(cam, clip.duration));
265 |
266 | EDebug.Log("Cutscene: showing camera " + clip.name + " at " + animation["master"].time);
267 | }
268 |
269 | ///
270 | /// Stops the shot from playing at its out point.
271 | ///
272 | /// The shot to stop.
273 | /// The time at which to stop the shot.
274 | IEnumerator StopShot (Camera cam, float duration)
275 | {
276 | yield return new WaitForSeconds(duration);
277 | cam.enabled = false;
278 | EDebug.Log("Cutscene: stopping shot at " + animation["master"].time);
279 | }
280 |
281 | ///
282 | /// Plays the specified actor.
283 | ///
284 | /// The actor to play.
285 | void PlayActor (CutsceneClip clip)
286 | {
287 | CutsceneActor actor = ((CutsceneActor)clip.master);
288 | AnimationClip anim = actor.anim;
289 | GameObject go = ((CutsceneActor)clip.master).go;
290 |
291 | go.animation[anim.name].time = clip.inPoint;
292 |
293 | go.animation.Play(anim.name);
294 | StartCoroutine(StopActor(actor, clip.duration));
295 |
296 | EDebug.Log("Cutscene: showing actor " + clip.name + " at " + animation["master"].time);
297 | }
298 |
299 | ///
300 | /// Stops the actor from playing at its out point.
301 | ///
302 | /// The actor to stop.
303 | /// The time at which to stop the actor.
304 | IEnumerator StopActor (CutsceneActor actor, float duration)
305 | {
306 | yield return new WaitForSeconds(duration);
307 | actor.go.animation.Stop(actor.anim.name);
308 | EDebug.Log("Cutscene: stopping actor at " + animation["master"].time);
309 | }
310 |
311 | ///
312 | /// Plays the specified audio.
313 | ///
314 | /// The audio to play.
315 | void PlayAudio (CutsceneClip clip)
316 | {
317 | AudioSource aud = ((CutsceneAudio)clip.master).audio;
318 | aud.Play();
319 | aud.time = clip.inPoint; // Set the point at which the clip plays
320 | StartCoroutine(StopAudio(aud, clip.duration)); // Set the point at which the clip stops
321 |
322 | EDebug.Log("Playing audio " + clip.name + " at " + animation["master"].time);
323 | }
324 |
325 | ///
326 | /// Stops the audio from playing at its out point.
327 | ///
328 | /// The audio source to stop.
329 | /// The time at which to stop the audio.
330 | IEnumerator StopAudio (AudioSource aud, float duration)
331 | {
332 | yield return new WaitForSeconds(duration);
333 | aud.Stop();
334 | }
335 |
336 | ///
337 | /// Displays the specified subtitle.
338 | ///
339 | /// The subtitle to display.
340 | void PlaySubtitle (CutsceneClip clip)
341 | {
342 | currentSubtitle = (CutsceneSubtitle)clip.master;
343 | EDebug.Log("Displaying subtitle " + clip.name + " at " + animation["master"].time);
344 |
345 | StartCoroutine(StopSubtitle(clip.duration));
346 | }
347 |
348 | ///
349 | /// Stops the subtitle from displaying at its out point.
350 | ///
351 | /// The time at which to stop the audio.
352 | IEnumerator StopSubtitle (float duration)
353 | {
354 | yield return new WaitForSeconds(duration);
355 | currentSubtitle = null;
356 | }
357 |
358 | ///
359 | /// Stops all subtitles from displaying by setting the current subtitle to null.
360 | ///
361 | void StopSubtitle ()
362 | {
363 | currentSubtitle = null;
364 | }
365 |
366 | ///
367 | /// Called when the clip type is unknown.
368 | ///
369 | /// For debugging only; ideally this will never be called.
370 | void UnknownFunction (CutsceneClip clip)
371 | {
372 | EDebug.Log("Cutscene: unknown function call from clip " + clip.name);
373 | }
374 |
375 | ///
376 | /// Creates a new CutsceneShot object and attaches it to a new game object as a child of the Shots game object.
377 | ///
378 | /// The new CutsceneShot object.
379 | public CutsceneShot NewShot ()
380 | {
381 | GameObject shot = new GameObject("Camera", typeof(Camera), typeof(CutsceneShot));
382 | // Keep the camera from displaying before it's placed on the timeline
383 | shot.camera.enabled = false;
384 | // Set the parent of the new shot to the Shots object
385 | shot.transform.parent = transform.Find("Shots");
386 |
387 | EDebug.Log("Cutscene Editor: added new shot");
388 | return shot.GetComponent();
389 | }
390 |
391 | ///
392 | /// Creates a new CutsceneActor object and attaches it to a new game object as a child of the Shots game object.
393 | ///
394 | /// The new CutsceneActor object.
395 | public CutsceneActor NewActor (AnimationClip anim, GameObject go)
396 | {
397 | CutsceneActor actor = GameObject.Find("Actors").AddComponent();
398 | actor.name = anim.name;
399 | actor.anim = anim;
400 | actor.go = go;
401 |
402 | EDebug.Log("Cutscene Editor: adding new actor");
403 | return actor;
404 | }
405 |
406 | ///
407 | /// Creates a new CutsceneAudio object and attaches it to a new game object as a child of the Audio game object.
408 | ///
409 | /// The audio clip to be attached the CutsceneAudio object.
410 | /// The new CutsceneAudio object.
411 | public CutsceneAudio NewAudio (AudioClip clip)
412 | {
413 | GameObject aud = new GameObject(clip.name, typeof(AudioSource), typeof(CutsceneAudio));
414 | aud.audio.clip = clip;
415 | // Keep the audio from playing when the game starts
416 | aud.audio.playOnAwake = false;
417 | // Set the parent of the new audio to the "Audio" object
418 | aud.transform.parent = transform.Find("Audio");
419 |
420 | EDebug.Log("Cutscene Editor: added new audio");
421 | return aud.GetComponent();
422 | }
423 |
424 | ///
425 | /// Creates a new CutsceneSubtitle object and attaches it to the Subtitles game object.
426 | ///
427 | /// The dialog to be displayed.
428 | /// The new CutsceneSubtitle object.
429 | public CutsceneSubtitle NewSubtitle (string dialog)
430 | {
431 | CutsceneSubtitle subtitle = GameObject.Find("Subtitles").AddComponent();
432 | subtitle.dialog = dialog;
433 |
434 | EDebug.Log("Cutscene Editor: added new subtitle");
435 | return subtitle;
436 | }
437 |
438 | ///
439 | /// Attaches a new track component to the cutscene.
440 | ///
441 | /// The new cutscene track.
442 | public CutsceneTrack AddTrack (Cutscene.MediaType type)
443 | {
444 | int id = 0;
445 | // Ensure the new track has a unique ID
446 | foreach (CutsceneTrack t in tracks) {
447 | if (id == t.id) {
448 | id++;
449 | } else {
450 | break;
451 | }
452 | }
453 |
454 | CutsceneTrack track = gameObject.AddComponent();
455 | track.id = id;
456 | track.type = type;
457 | track.name = CutsceneTrack.DefaultName(type);
458 |
459 | EDebug.Log("Cutscene Editor: added new track of type " + type);
460 | return track;
461 | }
462 | }
463 |
--------------------------------------------------------------------------------
/Cutscene Ed/Editor/CutsceneEditor.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2010 Matthew Miner
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | * THE SOFTWARE.
21 | */
22 |
23 | using UnityEditor;
24 | using UnityEngine;
25 | using System.Collections;
26 | using System.Collections.Generic;
27 |
28 | ///
29 | /// The Cutscene Editor, where tracks and clips can be managed in a fashion similar to non-linear video editors.
30 | ///
31 | public class CutsceneEditor : EditorWindow
32 | {
33 | public static readonly System.Version version = new System.Version(0, 2);
34 |
35 | public Cutscene scene {
36 | get {
37 | Object[] scenes = Selection.GetFiltered(typeof(Cutscene), SelectionMode.TopLevel);
38 |
39 | if (scenes.Length == 0) {
40 | return null;
41 | }
42 |
43 | return scenes[0] as Cutscene;
44 | }
45 | }
46 |
47 | public GUISkin style { get; private set; }
48 |
49 | //ICutsceneGUI options;
50 | ICutsceneGUI media;
51 | ICutsceneGUI effects;
52 | ICutsceneGUI tools;
53 | ICutsceneGUI timeline;
54 |
55 | public static bool CutsceneSelected {
56 | get { return Selection.GetFiltered(typeof(Cutscene), SelectionMode.TopLevel).Length > 0; }
57 | }
58 |
59 | public static bool HasPro = SystemInfo.supportsImageEffects;
60 |
61 | // Icons:
62 |
63 | public readonly Texture[] mediaIcons = {
64 | EditorGUIUtility.LoadRequired("Cutscene Ed/media_shot.png") as Texture,
65 | EditorGUIUtility.LoadRequired("Cutscene Ed/media_actor.png") as Texture,
66 | EditorGUIUtility.LoadRequired("Cutscene Ed/media_audio.png") as Texture,
67 | EditorGUIUtility.LoadRequired("Cutscene Ed/media_subtitle.png") as Texture
68 | };
69 |
70 | // Timeline:
71 |
72 | public Tool currentTool = Tool.MoveResize;
73 |
74 | public Vector2 timelineScrollPos;
75 |
76 | public float timelineMin { get; set; }
77 |
78 | float _timelineZoom = CutsceneTimeline.timelineZoomMin;
79 | public float timelineZoom {
80 | get { return _timelineZoom; }
81 | set { _timelineZoom = Mathf.Clamp(value, CutsceneTimeline.timelineZoomMin, CutsceneTimeline.timelineZoomMax); }
82 | }
83 |
84 | CutsceneTrack _selectedTrack;
85 | public CutsceneTrack selectedTrack {
86 | get {
87 | if (_selectedTrack == null) {
88 |
89 | // If there are no tracks, add a new one
90 | if (scene.tracks.Length == 0) {
91 | scene.AddTrack(Cutscene.MediaType.Shots);
92 | }
93 |
94 | _selectedTrack = scene.tracks[0];
95 | }
96 |
97 | return _selectedTrack;
98 | }
99 | set { _selectedTrack = value; }
100 | }
101 |
102 | public CutsceneClip selectedClip;
103 | public DragEvent dragEvent = DragEvent.Move;
104 | public CutsceneClip dragClip;
105 |
106 | // Menu items:
107 |
108 | ///
109 | /// Adds "Cutscene Editor" to the Window menu.
110 | ///
111 | [MenuItem("Window/Cutscene Editor")]
112 | public static void OpenEditor ()
113 | {
114 | // Get existing open window or if none, make a new one
115 | GetWindow(false, "Cutscene Editor").Show();
116 | }
117 |
118 | ///
119 | /// Validates the Cutscene Editor menu item.
120 | ///
121 | /// The item will be disabled if no cutscene is selected.
122 | [MenuItem("Window/Cutscene Editor", true)]
123 | static bool ValidateOpenEditor ()
124 | {
125 | return CutsceneSelected;
126 | }
127 |
128 | ///
129 | /// Adds the option to create a cutscene from the GameObject > Create Other menu.
130 | ///
131 | /// The new cutscene.
132 | [MenuItem("GameObject/Create Other/Cutscene")]
133 | static void CreateCutscene ()
134 | {
135 | // Create the new cutscene game object
136 | GameObject newSceneGO = new GameObject("Cutscene", typeof(Cutscene));
137 | Cutscene newScene = newSceneGO.GetComponent();
138 |
139 | // Add some tracks to get the user started
140 | newScene.AddTrack(Cutscene.MediaType.Shots);
141 | newScene.AddTrack(Cutscene.MediaType.Actors);
142 | newScene.AddTrack(Cutscene.MediaType.Audio);
143 | newScene.AddTrack(Cutscene.MediaType.Subtitles);
144 |
145 | // Create the cutscene's media game objects
146 | GameObject shots = new GameObject("Shots");
147 | GameObject actors = new GameObject("Actors");
148 | GameObject audio = new GameObject("Audio");
149 | GameObject subtitles = new GameObject("Subtitles");
150 |
151 | // Make the media game objects a child of the cutscene
152 | shots.transform.parent = newScene.transform;
153 | actors.transform.parent = newScene.transform;
154 | audio.transform.parent = newScene.transform;
155 | subtitles.transform.parent = newScene.transform;
156 |
157 | // Create the master animation clip
158 | AnimationClip masterClip = new AnimationClip();
159 | newScene.masterClip = masterClip;
160 | newScene.animation.AddClip(masterClip, "master");
161 |
162 | newScene.animation.playAutomatically = false;
163 | newScene.animation.wrapMode = WrapMode.Once;
164 |
165 | EDebug.Log("Cutscene Editor: created a new cutscene");
166 | }
167 |
168 | ///
169 | /// Adds the option to create a cutscene trigger to the GameObject > Create Other menu.
170 | ///
171 | /// The trigger's collider.
172 | [MenuItem("GameObject/Create Other/Cutscene Trigger")]
173 | static Collider CreateCutsceneTrigger ()
174 | {
175 | // Create the new cutscene trigger game object
176 | GameObject triggerGO = new GameObject("Cutscene Trigger", typeof(BoxCollider), typeof(CutsceneTrigger));
177 | triggerGO.collider.isTrigger = true;
178 | return triggerGO.collider;
179 | }
180 |
181 | ///
182 | /// Adds the option to create a new shot track in the Component > Cutscene > Track menu.
183 | ///
184 | [MenuItem("Component/Cutscene/Track/Shot")]
185 | static void CreateShotTrack ()
186 | {
187 | Selection.activeGameObject.GetComponent().AddTrack(Cutscene.MediaType.Shots);
188 | }
189 |
190 | ///
191 | /// Validates the Shot menu item.
192 | ///
193 | /// The item will be disabled if no cutscene is selected.
194 | [MenuItem("Component/Cutscene/Track/Shot", true)]
195 | static bool ValidateCreateShotTrack ()
196 | {
197 | return CutsceneSelected;
198 | }
199 |
200 | ///
201 | /// Adds the option to create a new actor track in the Component > Cutscene > Track menu.
202 | ///
203 | [MenuItem("Component/Cutscene/Track/Actor")]
204 | static void CreateActorTrack ()
205 | {
206 | Selection.activeGameObject.GetComponent().AddTrack(Cutscene.MediaType.Actors);
207 | }
208 |
209 | ///
210 | /// Validates the Actor menu item.
211 | ///
212 | /// The item will be disabled if no cutscene is selected.
213 | [MenuItem("Component/Cutscene/Track/Actor", true)]
214 | static bool ValidateCreateActorTrack ()
215 | {
216 | return CutsceneSelected;
217 | }
218 |
219 | ///
220 | /// Adds the option to create a new audio track in the Component > Cutscene > Track menu.
221 | ///
222 | [MenuItem("Component/Cutscene/Track/Audio")]
223 | static void CreateAudioTrack ()
224 | {
225 | Selection.activeGameObject.GetComponent().AddTrack(Cutscene.MediaType.Audio);
226 | }
227 |
228 | ///
229 | /// Validates the Audio menu item.
230 | ///
231 | /// The item will be disabled if no cutscene is selected.
232 | [MenuItem("Component/Cutscene/Track/Audio", true)]
233 | static bool ValidateCreateAudioTrack ()
234 | {
235 | return CutsceneSelected;
236 | }
237 |
238 | ///
239 | /// Adds the option to create a new subtitle track in the Component > Cutscene > Track menu.
240 | ///
241 | [MenuItem("Component/Cutscene/Track/Subtitle")]
242 | static void CreateSubtitleTrack ()
243 | {
244 | Selection.activeGameObject.GetComponent().AddTrack(Cutscene.MediaType.Subtitles);
245 | }
246 |
247 | ///
248 | /// Validates the Subtitle menu item.
249 | ///
250 | /// The item will be disabled if no cutscene is selected.
251 | [MenuItem("Component/Cutscene/Track/Subtitle", true)]
252 | static bool ValidateCreateSubtitleTrack ()
253 | {
254 | return CutsceneSelected;
255 | }
256 |
257 | void OnEnable ()
258 | {
259 | style = EditorGUIUtility.LoadRequired("Cutscene Ed/cutscene_editor_style.guiskin") as GUISkin;
260 |
261 | if (style == null) {
262 | Debug.LogError("GUISkin for Cutscene Editor missing");
263 | return;
264 | }
265 |
266 | //options = new CutsceneOptions(this);
267 | media = new CutsceneMediaWindow(this);
268 | effects = new CutsceneEffectsWindow(this);
269 | tools = new CutsceneTools(this);
270 | timeline = new CutsceneTimeline(this);
271 | }
272 |
273 | ///
274 | /// Displays the editor GUI.
275 | ///
276 | void OnGUI ()
277 | {
278 | if (style == null) {
279 | style = EditorGUIUtility.LoadRequired("Cutscene Ed/cutscene_editor_style.guiskin") as GUISkin;
280 | }
281 |
282 | // If no cutscene is selected, present the user with the option to create one
283 | if (scene == null) {
284 | if (GUILayout.Button("Create New Cutscene", GUILayout.ExpandWidth(false))) {
285 | CreateCutscene();
286 | }
287 | } else { // Otherwise present the cutscene editor
288 | float windowHeight = style.GetStyle("Pane").fixedHeight;
289 |
290 | // Options window
291 | //Rect optionsRect = new Rect(0, 0, position.width / 3, windowHeight);
292 | //options.OnGUI(optionsRect);
293 |
294 | // Media window
295 | Rect mediaRect = new Rect(2, 2, position.width / 2, windowHeight);
296 | media.OnGUI(mediaRect);
297 |
298 | // Effects window
299 | Rect effectsRect = new Rect(mediaRect.xMax + 2, 2, position.width - mediaRect.xMax - 4, windowHeight);
300 | effects.OnGUI(effectsRect);
301 |
302 | // Cutting tools
303 | Rect toolsRect = new Rect(0, mediaRect.yMax, position.width, 25);
304 | tools.OnGUI(toolsRect);
305 |
306 | // Timeline
307 | Rect timelineRect = new Rect(0, toolsRect.yMax, position.width, position.height - toolsRect.yMax);
308 | timeline.OnGUI(timelineRect);
309 | }
310 | }
311 |
312 | // Context menus:
313 |
314 | ///
315 | /// Deletes a piece of media by invoking a context menu item.
316 | ///
317 | /// The context menu command.
318 | [MenuItem("CONTEXT/CutsceneObject/Delete")]
319 | static void DeleteCutsceneMedia (MenuCommand command)
320 | {
321 | DeleteCutsceneMedia(command.context as CutsceneMedia);
322 | }
323 |
324 | ///
325 | /// Deletes a piece of media.
326 | ///
327 | /// The media to delete.
328 | /// This has to be in CutsceneEditor rather than CutsceneTimeline because it uses the DestroyImmediate function, which is only available to classes which inherit from UnityEngine.Object.
329 | static void DeleteCutsceneMedia (CutsceneMedia obj)
330 | {
331 | bool delete = true;
332 |
333 | // Display a dialog to prevent accidental deletions
334 | if (EditorPrefs.GetBool("Cutscene Warn Before Delete", true)) {
335 | delete = EditorUtility.DisplayDialog("Delete Object", "Are you sure you wish to delete this object? Changes cannot be undone.", "Delete", "Cancel");
336 | }
337 |
338 | // Only delete the cutscene object if the user chose to
339 | if (delete) {
340 | Debug.Log("Cutscene Editor: deleting media " + obj.name);
341 | if (obj.type == Cutscene.MediaType.Actors || obj.type == Cutscene.MediaType.Subtitles) { // Delete the CutsceneObject component
342 | DestroyImmediate(obj);
343 | } else { // Delete the actual game object
344 | DestroyImmediate(obj.gameObject);
345 | }
346 | }
347 | }
348 |
349 | ///
350 | /// Deletes a track by invoking a context menu item.
351 | ///
352 | /// The context menu command.
353 | /// True if the track was successfully deleted, false otherwise.
354 | [MenuItem("CONTEXT/CutsceneTrack/Delete Track")]
355 | static bool DeleteTrack (MenuCommand command)
356 | {
357 | return DeleteTrack(command.context as CutsceneTrack);
358 | }
359 |
360 | ///
361 | /// Deletes a track.
362 | ///
363 | /// The track to delete.
364 | /// True if the track was successfully deleted, false otherwise.
365 | static bool DeleteTrack (CutsceneTrack track)
366 | {
367 | bool delete = true;
368 |
369 | // Display a dialog to prevent accidental deletions
370 | if (EditorPrefs.GetBool("Cutscene Warn Before Delete", true)) {
371 | delete = EditorUtility.DisplayDialog("Delete Track", "Are you sure you wish to delete this track? Changes cannot be undone.", "Delete", "Cancel");
372 | }
373 |
374 | if (delete) {
375 | DestroyImmediate(track);
376 | }
377 |
378 | return delete;
379 | }
380 |
381 | ///
382 | /// Deletes a clip by invoking a context menu item.
383 | ///
384 | /// The context menu command.
385 | /// True if the clip was successfully deleted, false otherwise.
386 | [MenuItem("CONTEXT/CutsceneClip/Delete Clip")]
387 | static bool DeleteClip (MenuCommand command)
388 | {
389 | return DeleteClip(command.context as CutsceneClip);
390 | }
391 |
392 | ///
393 | /// Deletes a clip.
394 | ///
395 | /// The clip to delete.
396 | /// True if the clip was successfully deleted, false otherwise.
397 | static bool DeleteClip (CutsceneClip clip)
398 | {
399 | bool delete = true;
400 |
401 | // Display a dialog to prevent accidental deletions
402 | if (EditorPrefs.GetBool("Cutscene Warn Before Delete", true)) {
403 | delete = EditorUtility.DisplayDialog("Delete Clip", "Are you sure you wish to delete this clip? Changes cannot be undone.", "Delete", "Cancel");
404 | }
405 |
406 | clip.setToDelete = delete;
407 | return delete;
408 | }
409 |
410 | ///
411 | /// Selects the track at the specified index.
412 | ///
413 | /// The track to select.
414 | void SelectTrackAtIndex (int index)
415 | {
416 | if (scene.tracks.Length > 0 && index > 0 && index <= scene.tracks.Length) {
417 | selectedTrack = scene.tracks[index - 1];
418 | EDebug.Log("Cutscene Editor: track " + index + " is selected");
419 | }
420 | }
421 |
422 | ///
423 | /// Determines which key command is pressed and responds accordingly.
424 | ///
425 | /// The keyboard event.
426 | /// True if the keyboard shortcut exists, false otherwise.
427 | public void HandleKeyboardShortcuts (Event keyDownEvent)
428 | {
429 | KeyCode key = keyDownEvent.keyCode;
430 |
431 | // Tools:
432 |
433 | // Move/resize
434 | if (key == CutsceneHotkeys.MoveResizeTool.key) {
435 | currentTool = Tool.MoveResize;
436 | EDebug.Log("Cutscene Editor: switching to Move/Resize tool");
437 | // Scissors
438 | } else if (key == CutsceneHotkeys.ScissorsTool.key) {
439 | currentTool = Tool.Scissors;
440 | EDebug.Log("Cutscene Editor: switching to Scissors tool");
441 | // Zoom
442 | } else if (key == CutsceneHotkeys.ZoomTool.key) {
443 | currentTool = Tool.Zoom;
444 | EDebug.Log("Cutscene Editor: switching to Zoom tool");
445 | }
446 |
447 | // Timeline navigation:
448 |
449 | // Set in point
450 | else if (key == CutsceneHotkeys.SetInPont.key) {
451 | scene.inPoint = scene.playhead;
452 | EDebug.Log("Cutscene Editor: setting in point");
453 | // Set out point
454 | } else if (key == CutsceneHotkeys.SetOutPoint.key) {
455 | scene.outPoint = scene.playhead;
456 | EDebug.Log("Cutscene Editor: setting out point");
457 | // Scrub left
458 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("left"))) {
459 | scene.playhead -= CutsceneTimeline.scrubSmallJump;
460 | EDebug.Log("Cutscene Editor: moving playhead left");
461 | // Scrub left large
462 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("#left"))) {
463 | scene.playhead -= CutsceneTimeline.scrubLargeJump;
464 | EDebug.Log("Cutscene Editor: moving playhead left");
465 | // Scrub right
466 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("right"))) {
467 | scene.playhead += CutsceneTimeline.scrubSmallJump;
468 | EDebug.Log("Cutscene Editor: moving playhead right");
469 | // Scrub right large
470 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("#right"))) {
471 | scene.playhead += CutsceneTimeline.scrubLargeJump;
472 | EDebug.Log("Cutscene Editor: moving playhead right");
473 | // Go to previous split point
474 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("up"))) {
475 | scene.playhead = selectedTrack.GetTimeOfNextSplit(scene.playhead);
476 | EDebug.Log("Cutscene Editor: moving playhead to previous split point");
477 | // Go to next split point
478 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("down"))) {
479 | scene.playhead = selectedTrack.GetTimeOfPreviousSplit(scene.playhead);
480 | EDebug.Log("Cutscene Editor: moving playhead to next split point");
481 | // Go to in point
482 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("#up"))) {
483 | scene.playhead = scene.inPoint;
484 | EDebug.Log("Cutscene Editor: moving playhead to next split point");
485 | // Go to out point
486 | } else if (keyDownEvent.Equals(Event.KeyboardEvent("#down"))) {
487 | scene.playhead = scene.outPoint;
488 | EDebug.Log("Cutscene Editor: moving playhead to next split point");
489 | }
490 |
491 | // Track selection:
492 |
493 | // Select track 1
494 | else if (key == CutsceneHotkeys.SelectTrack1.key) {
495 | SelectTrackAtIndex(1);
496 | // Select track 2
497 | } else if (key == CutsceneHotkeys.SelectTrack2.key) {
498 | SelectTrackAtIndex(2);
499 | // Select track 3
500 | } else if (key == CutsceneHotkeys.SelectTrack3.key) {
501 | SelectTrackAtIndex(3);
502 | // Select track 4
503 | } else if (key == CutsceneHotkeys.SelectTrack4.key) {
504 | SelectTrackAtIndex(4);
505 | // Select track 5
506 | } else if (key == CutsceneHotkeys.SelectTrack5.key) {
507 | SelectTrackAtIndex(5);
508 | // Select track 6
509 | } else if (key == CutsceneHotkeys.SelectTrack6.key) {
510 | SelectTrackAtIndex(6);
511 | // Select track 7
512 | } else if (key == CutsceneHotkeys.SelectTrack7.key) {
513 | SelectTrackAtIndex(7);
514 | // Select track 8
515 | } else if (key == CutsceneHotkeys.SelectTrack8.key) {
516 | SelectTrackAtIndex(8);
517 | // Select track 9
518 | } else if (key == CutsceneHotkeys.SelectTrack9.key) {
519 | SelectTrackAtIndex(9);
520 | }
521 |
522 | // Other:
523 |
524 | else {
525 | EDebug.Log("Cutscene Editor: unknown keyboard shortcut " + keyDownEvent);
526 | return;
527 | }
528 |
529 | // If we get to this point, a shortcut matching the user's keystroke has been found
530 | Event.current.Use();
531 | }
532 |
533 | public static float PaneTabsWidth (int count)
534 | {
535 | return count * 80f;
536 | }
537 | }
538 |
--------------------------------------------------------------------------------