-
Notifications
You must be signed in to change notification settings - Fork 19
/
LevelManager.cs
149 lines (128 loc) · 5.29 KB
/
LevelManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
using System.Collections.Generic;
using Oculus.Voice;
using Unity.XR.CoreUtils;
using UnityEngine;
/// <summary>
/// Base class for Level/Story logic
/// </summary>
namespace Whisperer
{
public abstract class LevelManager : MonoBehaviour
{
[SerializeField] protected bool _levelLogicEnabled = true;
[SerializeField] protected Vector3 _rigStartPosition;
[Header("References")]
[SerializeField]
protected GameObject _transcriptionUIPrefab;
[SerializeField] protected AppVoiceExperience _appVoiceExperience;
[SerializeField] protected RigHandsControl _hands;
[SerializeField] protected SpeakGestureWatcher _speakGestureWatcher;
[SerializeField] protected List<Listenable> _allListenableScripts;
[SerializeField] protected List<AnimationEvents> _allAnimationEvents;
protected bool _loaderReady,
_inTransition;
protected virtual void Start()
{
LevelLoader.Instance.OnLevelWillBeginUnload.AddListener(LevelWillUnload);
LevelLoader.Instance.OnLevelLoadComplete.AddListener(LevelLoadComplete);
FindObjectOfType<XROrigin>().transform.SetPositionAndRotation(_rigStartPosition, Quaternion.identity);
/// Set up references
_appVoiceExperience = FindObjectOfType<AppVoiceExperience>();
_speakGestureWatcher = FindObjectOfType<SpeakGestureWatcher>();
_hands = FindObjectOfType<RigHandsControl>();
if (LevelLoader.Instance.IsLoading)
{
_allListenableScripts = new List<Listenable>(FindObjectsOfType<Listenable>());
_allListenableScripts.ForEach(listenable => listenable.InstantiateWitUI(_transcriptionUIPrefab));
}
}
protected virtual void OnValidate()
{
if (!_loaderReady) return;
SetLevelEnabled();
}
/// <summary>
/// Called automatically after a delay, by LevelLoader when all scenes are ready.<br></br>
/// Use this to begin logic, as Unity's Awake/Start often get called before all scenes are finished loading.
/// </summary>
public abstract void StartLevel();
protected virtual void LevelLoadComplete()
{
AudioManager.Instance.StopNarration();
AudioManager.Instance.StopAllSpatial();
AudioManager.Instance.MasterFader.PlayFrom0(2);
}
protected virtual void LevelWillUnload(float delay)
{
_inTransition = true;
AudioManager.Instance.StopNarration();
AudioManager.Instance.StopAllSpatial();
AudioManager.Instance.MasterFader.PlayFrom1(delay);
AudioManager.Instance.StopMusic(delay);
_hands.SetNone();
}
/// <summary>
/// Called whenever any listenable in the scene receives a response from Wit.
/// </summary>
/// <param name="listenable"></param>
/// <param name="intent"></param>
/// <param name="success"></param>
protected virtual void OnListenableResponse(ListenableEventArgs eventArgs)
{
}
/// <summary>
/// Called whenever any animation event in the scene is invoked.
/// </summary>
/// <param name="eventName"></param>
protected virtual void OnAnimationEvent(string eventName)
{
}
public void SetLoaderReady()
{
_loaderReady = true;
_inTransition = false;
SetLevelEnabled();
}
private void SetLevelEnabled()
{
if (_levelLogicEnabled && _loaderReady)
{
SetEventsSubcribed(true);
StartLevel();
}
else
{
SetEventsSubcribed(false);
StopAllCoroutines();
_hands.SetSpeak();
}
}
protected void SetEventsSubcribed(bool subscribed)
{
if (subscribed)
{
/// Subscribing to listenable response events in the scene
_allListenableScripts = new List<Listenable>(FindObjectsOfType<Listenable>());
_allListenableScripts.ForEach(listenable =>
listenable.OnResponseProcessed.AddListener(OnListenableResponse));
/// Subscribing to all animation events in the scene
_allAnimationEvents = new List<AnimationEvents>(FindObjectsOfType<AnimationEvents>());
_allAnimationEvents.ForEach(ae => ae.OnAnimationEvent.AddListener(OnAnimationEvent));
}
else
{
_allListenableScripts = new List<Listenable>(FindObjectsOfType<Listenable>());
_allListenableScripts.ForEach(listenable =>
listenable.OnResponseProcessed.RemoveListener(OnListenableResponse));
_allAnimationEvents = new List<AnimationEvents>(FindObjectsOfType<AnimationEvents>());
_allAnimationEvents.ForEach(ae => ae.OnAnimationEvent.RemoveListener(OnAnimationEvent));
}
}
}
}