fr.jeanf.questsystem 0.0.61 → 0.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,13 +28,13 @@ Transform:
28
28
  m_PrefabInstance: {fileID: 0}
29
29
  m_PrefabAsset: {fileID: 0}
30
30
  m_GameObject: {fileID: 5258580714634048286}
31
- serializedVersion: 2
32
31
  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
33
32
  m_LocalPosition: {x: 7.37, y: 1, z: 6.08}
34
33
  m_LocalScale: {x: 3, y: 3, z: 3}
35
34
  m_ConstrainProportionsScale: 0
36
35
  m_Children: []
37
36
  m_Father: {fileID: 0}
37
+ m_RootOrder: -2
38
38
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
39
39
  --- !u!33 &7682207879693783699
40
40
  MeshFilter:
@@ -171,7 +171,8 @@ MonoBehaviour:
171
171
  progress: 0
172
172
  clearToStart: 0
173
173
  QuestProgress: {fileID: 11400000, guid: d6b05e1957994c8449fb72e849a2a3d6, type: 2}
174
- StartQuestEventChannel: {fileID: 11400000, guid: c510c1e4d26428740b3e329cca98e5d1,
175
- type: 2}
176
174
  QuestInitialCheck: {fileID: 11400000, guid: 4f5235d1ff779064cabee9ca65296d7f, type: 2}
175
+ resetChannel: {fileID: 11400000, guid: f5878d9ead688634e8a37cb28026e722, type: 2}
177
176
  requirementCheck: {fileID: 11400000, guid: a4dae407f780f974abbf43c280515876, type: 2}
177
+ loadRequiredScenesEventChannel: {fileID: 0}
178
+ unlockDoorsEventChannel: {fileID: 0}
@@ -47,37 +47,6 @@ namespace jeanf.questsystem
47
47
  this.questSO = questQuestSo;
48
48
  this.state = questState;
49
49
  this.questStepStates = questStepStates;
50
-
51
- //if the quest step states and prefabs are different lengths,
52
- //something has changed during development and the saved data is out of sync.
53
- //if (this.questStepStates.Length != this.questSO.questSteps.Length)
54
- //{
55
- // Debug.LogWarning("Quest Step Prefabs and Quest Step States are "
56
- // + "of different lengths. This indicates something changed "
57
- // + "with the QuestInfo and the saved data is now out of sync. "
58
- // + "Reset your data - as this might cause issues. QuestId: " + this.questSO.id);
59
- //}
60
50
  }
61
-
62
-
63
-
64
- //public void StoreQuestStepState(QuestStepState questStepState, int stepIndex)
65
- //{
66
- // if (stepIndex < questStepStates.Count)
67
- // {
68
- // questStepStates[stepIndex].state = questStepState.state;
69
- // }
70
- // else
71
- // {
72
- // Debug.LogWarning("Tried to access quest step data, but stepIndex was out of range: "
73
- // + "Quest Id = " + questSO.id + ", Step Index = " + stepIndex);
74
- // }
75
- //}
76
-
77
- //public QuestData GetQuestData()
78
- //{
79
- // return new QuestData(state, currentQuestStepIndex, questStepStates);
80
- //}
81
-
82
51
  }
83
52
  }
@@ -11,6 +11,8 @@ namespace jeanf.questsystem
11
11
  {
12
12
  public class QuestItem : MonoBehaviour, IDebugBehaviour, IValidatable
13
13
  {
14
+
15
+ #region interface variables
14
16
  public bool isDebug
15
17
  {
16
18
  get => _isDebug;
@@ -20,28 +22,30 @@ namespace jeanf.questsystem
20
22
 
21
23
  [SerializeField] private bool _isDebug = false;
22
24
  [SerializeField] private bool _startQuestOnEnable = false;
25
+ #endregion
23
26
 
27
+ #region Step Dictionaries
24
28
  [Tooltip("Visual feedback for the quest state")] [Header("Quest")]
25
29
  [SerializeField] [Validation("A reference to a questSO is required")] private QuestSO questSO;
26
30
  private Dictionary<string, QuestStep> stepMap = new Dictionary<string, QuestStep>();
27
31
  private Dictionary<string, QuestStep> activeSteps = new Dictionary<string, QuestStep>();
28
32
  private Dictionary<string, QuestStep> completedSteps = new Dictionary<string, QuestStep>();
29
33
  private List<QuestStep> rootSteps = new List<QuestStep>();
34
+ #endregion
30
35
 
31
- public delegate void ValidateStep(string stepId);
32
-
33
- public static ValidateStep ValidateStepEvent;
34
-
35
-
36
- [ReadOnly] [Range(0, 1)] [SerializeField]
37
- private float progress = 0.0f;
38
36
 
37
+ #region main data
39
38
  [SerializeField] [ReadOnly]
40
39
  private bool clearToStart = false;
41
-
42
40
  private string questId;
43
41
  private QuestState currentQuestState;
42
+ [ReadOnly][Range(0, 1)][SerializeField]
43
+ private float progress = 0.0f;
44
+ #endregion
44
45
 
46
+ #region events
47
+ public delegate void ValidateStep(string stepId);
48
+ public static ValidateStep ValidateStepEvent;
45
49
  // these events are Located in Assets/Resources/Quests/Channels - it is searched for at Awake time.
46
50
  // if they do not exist simply right click in the hierarchy and find >InitializeQuestSystem<
47
51
  [Header("Listening on:")]
@@ -53,10 +57,10 @@ namespace jeanf.questsystem
53
57
  private StringEventChannelSO requirementCheck;
54
58
  [SerializeField][Validation("A reference to the LoadRequiredScenesEventChannel SO is required")] StringListEventChannelSO loadRequiredScenesEventChannel;
55
59
  [SerializeField] IntEventChannelSO unlockDoorsEventChannel;
56
-
57
-
60
+ #endregion
61
+
58
62
 
59
- #region Awake/Enable/Disable
63
+ #region Standard Unity Methods
60
64
  private void Awake()
61
65
  {
62
66
  questId = questSO.id;
@@ -67,7 +71,10 @@ namespace jeanf.questsystem
67
71
  rootSteps.Add(questSO.rootSteps[i]);
68
72
  }
69
73
  }
70
-
74
+ private void Reset()
75
+ {
76
+ Init(questId);
77
+ }
71
78
  private void OnEnable()
72
79
  {
73
80
  Subscribe();
@@ -76,7 +83,6 @@ namespace jeanf.questsystem
76
83
  }
77
84
  private void OnDisable() => Unsubscribe();
78
85
  private void OnDestroy() => Unsubscribe();
79
-
80
86
  private void Subscribe()
81
87
  {
82
88
  resetChannel.OnEventRaised += Reset;
@@ -88,7 +94,6 @@ namespace jeanf.questsystem
88
94
  QuestStep.stepActive += UpdateStepStatus;
89
95
  QuestStep.childStep += AddStepToStepMap;
90
96
  }
91
-
92
97
  private void Unsubscribe()
93
98
  {
94
99
  resetChannel.OnEventRaised -= Reset;
@@ -104,11 +109,6 @@ namespace jeanf.questsystem
104
109
  }
105
110
  #endregion
106
111
 
107
- private void Reset()
108
- {
109
- Init(questId);
110
- }
111
-
112
112
  #region Instantiations & Loading
113
113
  public void InstantiateQuestStep(string id)
114
114
  {
@@ -116,10 +116,10 @@ namespace jeanf.questsystem
116
116
  if (stepMap[id].stepStatus != QuestStepStatus.Inactive) return;
117
117
  if (activeSteps.ContainsKey(id)) return;
118
118
 
119
+
119
120
  Instantiate(stepMap[id], this.transform, true);
120
- //if(!activeSteps.ContainsKey(id)) activeSteps.Add(id,Instantiate(stepMap[id], this.transform, true));
121
- }
122
121
 
122
+ }
123
123
  private void LoadDependencies()
124
124
  {
125
125
  loadRequiredScenesEventChannel.RaiseEvent(questSO.ScenesToLoad);
@@ -129,43 +129,22 @@ namespace jeanf.questsystem
129
129
  unlockDoorsEventChannel.RaiseEvent(roomToUnlock);
130
130
  }
131
131
  }
132
- #endregion
133
-
134
- public void UpdateStepStatus(string id, QuestStepStatus status)
135
- {
136
- switch (status)
137
- {
138
- case QuestStepStatus.Completed when activeSteps.ContainsKey(id):
139
- // put step in completed list
140
- activeSteps.Remove(id);
141
- completedSteps.Add(id, stepMap[id]);
142
- break;
143
- case QuestStepStatus.Active when !activeSteps.ContainsKey(id):
144
- // put step in active list
145
- activeSteps.Add(id, stepMap[id]);
146
- break;
147
- case QuestStepStatus.Inactive:
148
- // do nothing
149
- default:
150
- // do nothing
151
- return;
152
- }
153
- }
154
-
155
132
  private void AddStepToStepMap(QuestStep step)
156
133
  {
157
- if(isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
134
+ if (isDebug) Debug.Log($"--- Received request to add step {step.name} with id: {step.StepId} to stepMap.");
158
135
  if (!stepMap.ContainsKey(step.StepId))
159
136
  {
160
- if(isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
137
+ if (isDebug) Debug.Log($"--- Step [{step.StepId}] not found in stepMap, adding it.");
161
138
  stepMap.Add(step.StepId, step);
162
139
  }
163
140
  if (completedSteps.ContainsKey(step.StepId))
164
141
  {
165
- if(isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
142
+ if (isDebug) Debug.Log($"--- Step [{step.StepId}] already completed removing it from completeSteps so that we can go through it again.");
166
143
  completedSteps.Remove(step.StepId);
167
144
  }
168
145
  }
146
+ #endregion
147
+
169
148
  #region quest process
170
149
  private void Init(string id)
171
150
  {
@@ -196,7 +175,26 @@ namespace jeanf.questsystem
196
175
 
197
176
  LoadDependencies();
198
177
  }
199
-
178
+ public void UpdateStepStatus(string id, QuestStepStatus status)
179
+ {
180
+ switch (status)
181
+ {
182
+ case QuestStepStatus.Completed when activeSteps.ContainsKey(id):
183
+ // put step in completed list
184
+ activeSteps.Remove(id);
185
+ completedSteps.Add(id, stepMap[id]);
186
+ break;
187
+ case QuestStepStatus.Active when !activeSteps.ContainsKey(id):
188
+ // put step in active list
189
+ activeSteps.Add(id, stepMap[id]);
190
+ break;
191
+ case QuestStepStatus.Inactive:
192
+ // do nothing
193
+ default:
194
+ // do nothing
195
+ return;
196
+ }
197
+ }
200
198
  private void UpdateState()
201
199
  {
202
200
  if (isDebug) Debug.Log($"Updating State...");
@@ -232,14 +230,12 @@ namespace jeanf.questsystem
232
230
  throw new ArgumentOutOfRangeException();
233
231
  }
234
232
  }
235
-
236
233
  private void UpdateProgress(string id, float progress)
237
234
  {
238
235
  if (id != questId) return;
239
236
  this.progress = progress;
240
237
  if (isDebug) Debug.Log($"questid [{id}] progress = {progress * 100}%");
241
238
  }
242
-
243
239
  private void QuestStateChange(Quest quest)
244
240
  {
245
241
  // only update the quest state if this point has the corresponding quest
@@ -251,6 +247,7 @@ namespace jeanf.questsystem
251
247
  }
252
248
  #endregion
253
249
 
250
+ #region Complete all Steps
254
251
  public void ValidateCurrentlyActiveSteps()
255
252
  {
256
253
  var currentlyActiveSteps = activeSteps.Keys;
@@ -262,18 +259,15 @@ namespace jeanf.questsystem
262
259
  if(activeSteps.ContainsKey(stepKey)) ValidateStepEvent.Invoke(stepKey);
263
260
  }
264
261
  }
262
+ #endregion
265
263
 
266
264
  #region validation tools
267
265
 
268
- #if UNITY_EDITOR
266
+ #if UNITY_EDITOR
269
267
  public void OnValidate()
270
268
  {
271
269
  ValidityCheck();
272
270
  }
273
-
274
-
275
-
276
-
277
271
  public void LogActiveSteps()
278
272
  {
279
273
  Debug.Log($"There is {activeSteps.Count} active steps at the moment.");
@@ -283,7 +277,6 @@ namespace jeanf.questsystem
283
277
  }
284
278
  }
285
279
  #endif
286
-
287
280
  private void ValidityCheck()
288
281
  {
289
282
  const string searching = "attempting to find";
@@ -11,6 +11,8 @@ namespace jeanf.questsystem
11
11
  {
12
12
  public class QuestManager : MonoBehaviour, IDebugBehaviour, IValidatable
13
13
  {
14
+ #region variables
15
+ #region interface variables
14
16
  public bool isDebug
15
17
  {
16
18
  get => _isDebug;
@@ -19,23 +21,26 @@ namespace jeanf.questsystem
19
21
  public bool IsValid { get; private set; }
20
22
 
21
23
  [SerializeField] private bool _isDebug = false;
24
+ #endregion
22
25
 
23
- [FormerlySerializedAs("loadQuestState")] [Header("Config")] [SerializeField]
24
- private bool loadSavedQuestState = true;
25
-
26
+ #region event channels
26
27
  [Header("Broadcasting on:")]
27
28
  [SerializeField] [Validation("A reference to the questStatusUpdateChannel is required.")] private StringEventChannelSO questStatusUpdateChannel;
28
29
  [SerializeField] [Validation("A reference to the questProgress is required.")] private StringFloatEventChannelSO questProgress;
29
30
  [SerializeField] [Validation("A reference to the questInitialCheck channel is required.")] private StringEventChannelSO QuestInitialCheck;
30
-
31
31
  [Header("Listening on:")] [SerializeField] [Validation("A reference to the questStatusUpdateRequested is required.")] private StringEventChannelSO questStatusUpdateRequested;
32
+ #endregion
32
33
 
34
+ #region other variables
35
+ [FormerlySerializedAs("loadQuestState")] [Header("Config")] [SerializeField]
36
+ private bool loadSavedQuestState = true;
33
37
  private Dictionary<string, Quest> questMap;
34
-
35
-
36
- // quest start requirements
37
38
  private int currentPlayerLevel;
39
+ #endregion
40
+ #endregion
38
41
 
42
+ #region Methods
43
+ #region Standard Unity Methods
39
44
  private void Awake()
40
45
  {
41
46
  questMap = CreateQuestMap();
@@ -45,25 +50,16 @@ namespace jeanf.questsystem
45
50
  CheckIfQuestIsAlreadyLoaded(quest.Key);
46
51
  }
47
52
  }
48
-
49
53
  private void OnEnable()
50
54
  {
51
55
  GameEventsManager.instance.questEvents.onStartQuest += StartQuest;
52
- GameEventsManager.instance.questEvents.onFinishQuest += FinishQuest;
53
-
56
+ GameEventsManager.instance.questEvents.onFinishQuest += FinishQuest;
54
57
  //GameEventsManager.instance.questEvents.onQuestStepStateChange += QuestStepStateChange;
55
-
56
58
  GameEventsManager.instance.playerEvents.onPlayerLevelChange += PlayerLevelChange;
57
-
58
59
  questStatusUpdateRequested.OnEventRaised += ctx => CheckRequirementsMet(questMap[ctx]);
59
-
60
-
61
60
  }
62
-
63
-
64
61
  private void OnDisable() => Unsubscribe();
65
62
  private void OnDestroy() => Unsubscribe();
66
-
67
63
  private void Unsubscribe()
68
64
  {
69
65
  GameEventsManager.instance.questEvents.onStartQuest -= StartQuest;
@@ -74,7 +70,6 @@ namespace jeanf.questsystem
74
70
  GameEventsManager.instance.playerEvents.onPlayerLevelChange -= PlayerLevelChange;
75
71
 
76
72
  }
77
-
78
73
  private void Start()
79
74
  {
80
75
  foreach (Quest quest in questMap.Values)
@@ -83,25 +78,63 @@ namespace jeanf.questsystem
83
78
  GameEventsManager.instance.questEvents.QuestStateChange(quest);
84
79
  }
85
80
  }
86
-
87
-
88
- private void CheckIfQuestIsAlreadyLoaded(string id)
81
+ private void Update()
89
82
  {
90
- QuestInitialCheck.RaiseEvent(id);
83
+ // loop through ALL quests
84
+ foreach (Quest quest in questMap.Values)
85
+ {
86
+ // if we're now meeting the requirements, switch over to the CAN_START state
87
+ if (quest.state == QuestState.REQUIREMENTS_NOT_MET && CheckRequirementsMet(quest))
88
+ {
89
+ ChangeQuestState(quest.questSO.id, QuestState.CAN_START);
90
+ }
91
+ }
91
92
  }
92
-
93
- private void ChangeQuestState(string id, QuestState state)
93
+ private void OnApplicationQuit()
94
94
  {
95
- Quest quest = GetQuestById(id);
96
- quest.state = state;
97
- GameEventsManager.instance.questEvents.QuestStateChange(quest);
95
+ foreach (Quest quest in questMap.Values)
96
+ {
97
+ SaveQuest(quest);
98
+ }
98
99
  }
100
+ #endregion
99
101
 
100
- private void PlayerLevelChange(int level)
102
+ #region Quest Checks and getters
103
+ private Dictionary<string, Quest> CreateQuestMap()
101
104
  {
102
- currentPlayerLevel = level;
105
+ // loads all QuestInfoSO Scriptable Objects under the Assets/Resources/Quests folder
106
+ QuestSO[] allQuests = Resources.LoadAll<QuestSO>("Quests");
107
+ // Create the quest map
108
+ Dictionary<string, Quest> questMap = new Dictionary<string, Quest>();
109
+ foreach (QuestSO questSO in allQuests)
110
+ {
111
+ var id = questSO.id;
112
+ if (questMap.ContainsKey(id))
113
+ {
114
+ Debug.LogWarning("Duplicate ID found when creating quest map: " + questSO.id);
115
+ }
116
+ else
117
+ {
118
+ questMap.Add(id, LoadQuest(questSO));
119
+ }
120
+ if (isDebug) Debug.Log($"Adding {questSO.name} to the questmap, its id is: {questSO.id}");
121
+ }
122
+ return questMap;
123
+ }
124
+ private void CheckIfQuestIsAlreadyLoaded(string id)
125
+ {
126
+ QuestInitialCheck.RaiseEvent(id);
103
127
  }
128
+ public Quest GetQuestById(string id)
129
+ {
130
+ Quest quest = questMap[id];
131
+ if (quest == null)
132
+ {
133
+ Debug.LogError("ID not found in the Quest Map: " + id);
134
+ }
104
135
 
136
+ return quest;
137
+ }
105
138
  private bool CheckRequirementsMet(Quest quest)
106
139
  {
107
140
  // check player level requirements
@@ -115,25 +148,20 @@ namespace jeanf.questsystem
115
148
  meetsRequirements = false;
116
149
  }
117
150
  }
118
-
119
- if(isDebug) Debug.Log($"checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
151
+
152
+ if (isDebug) Debug.Log($"checking requirements for quest: {quest.questSO.name}, [{quest.questSO.id}], meetsRequirements: {meetsRequirements}");
120
153
 
121
154
  return meetsRequirements;
122
155
  }
123
-
124
- private void Update()
156
+ private void ChangeQuestState(string id, QuestState state)
125
157
  {
126
- // loop through ALL quests
127
- foreach (Quest quest in questMap.Values)
128
- {
129
- // if we're now meeting the requirements, switch over to the CAN_START state
130
- if (quest.state == QuestState.REQUIREMENTS_NOT_MET && CheckRequirementsMet(quest))
131
- {
132
- ChangeQuestState(quest.questSO.id, QuestState.CAN_START);
133
- }
134
- }
158
+ Quest quest = GetQuestById(id);
159
+ quest.state = state;
160
+ GameEventsManager.instance.questEvents.QuestStateChange(quest);
135
161
  }
162
+ #endregion
136
163
 
164
+ #region main process
137
165
  private void StartQuest(string id)
138
166
  {
139
167
  Quest quest = GetQuestById(id);
@@ -143,7 +171,6 @@ namespace jeanf.questsystem
143
171
  quest.messageChannel.RaiseEvent(quest.messageToSendOnInit);
144
172
  if(isDebug) Debug.Log($"quest id:{id} started, a message was attatched to the initialization: {quest.messageToSendOnInit}");
145
173
  }
146
-
147
174
  private void UpdateProgress(Quest quest)
148
175
  {
149
176
  var progress = 0;
@@ -151,7 +178,6 @@ namespace jeanf.questsystem
151
178
  if (isDebug) Debug.Log($"[{quest.questSO.id}] progress: {progress * 100}%", this);
152
179
  questProgress.RaiseEvent(quest.questSO.id, progress);
153
180
  }
154
-
155
181
  private void FinishQuest(string id)
156
182
  {
157
183
  Quest quest = GetQuestById(id);
@@ -163,58 +189,26 @@ namespace jeanf.questsystem
163
189
  SaveQuest(quest);
164
190
  if (!quest.sendMessageOnFinish) return;
165
191
  }
192
+ #endregion
166
193
 
194
+ #region rewards and progress
167
195
  private void ClaimRewards(Quest quest)
168
196
  {
169
197
  GameEventsManager.instance.scenarioEvents.ScenarioUnlocked(quest.questSO.unlockedScenario);
170
198
  }
171
199
 
172
- private Dictionary<string, Quest> CreateQuestMap()
173
- {
174
- // loads all QuestInfoSO Scriptable Objects under the Assets/Resources/Quests folder
175
- QuestSO[] allQuests = Resources.LoadAll<QuestSO>("Quests");
176
- // Create the quest map
177
- Dictionary<string, Quest> questMap = new Dictionary<string, Quest>();
178
- foreach (QuestSO questSO in allQuests)
179
- {
180
- var id = questSO.id;
181
- if (questMap.ContainsKey(id))
182
- {
183
- Debug.LogWarning("Duplicate ID found when creating quest map: " + questSO.id);
184
- }
185
- else
186
- {
187
- questMap.Add(id, LoadQuest(questSO));
188
- }
189
- if(isDebug) Debug.Log($"Adding {questSO.name} to the questmap, its id is: {questSO.id}");
190
- }
191
-
192
- return questMap;
193
- }
194
-
195
- public Quest GetQuestById(string id)
196
- {
197
- Quest quest = questMap[id];
198
- if (quest == null)
199
- {
200
- Debug.LogError("ID not found in the Quest Map: " + id);
201
- }
202
-
203
- return quest;
204
- }
205
-
206
- private void OnApplicationQuit()
200
+ private void PlayerLevelChange(int level)
207
201
  {
208
- foreach (Quest quest in questMap.Values)
209
- {
210
- SaveQuest(quest);
211
- }
202
+ currentPlayerLevel = level;
212
203
  }
204
+ #endregion
213
205
 
206
+ #region saving and loading
214
207
  private void SaveQuest(Quest quest)
215
208
  {
216
209
  try
217
210
  {
211
+ //Save; active steps + quest step status for each, completed steps, quest status, progress/playerLevel/?
218
212
  QuestData questData = null;
219
213
  //quest.GetQuestData();
220
214
  // serialize using JsonUtility, but use whatever you want here (like JSON.NET)
@@ -230,7 +224,6 @@ namespace jeanf.questsystem
230
224
  Debug.LogError("Failed to save quest with id " + quest.questSO.id + ": " + e);
231
225
  }
232
226
  }
233
-
234
227
  private Quest LoadQuest(QuestSO questSO)
235
228
  {
236
229
  Debug.Log($"attempting to load quest with id: [{questSO.id}]");
@@ -259,6 +252,9 @@ namespace jeanf.questsystem
259
252
 
260
253
  return quest;
261
254
  }
255
+ #endregion
256
+
257
+ #region Validation Tools
262
258
  private void ValidityCheck()
263
259
  {
264
260
  const string searching = "attempting to find";
@@ -334,5 +330,7 @@ namespace jeanf.questsystem
334
330
  ValidityCheck();
335
331
  #endif
336
332
  }
333
+ #endregion
334
+ #endregion
337
335
  }
338
336
  }
@@ -13,15 +13,17 @@ namespace jeanf.questsystem
13
13
  [System.Serializable, NodeMenuItem("questSystem/QuestStep"), DefaultExecutionOrder(1)]
14
14
  public class QuestStep : MonoBehaviour, IDebugBehaviour
15
15
  {
16
+ #region Ids and status
16
17
  [field: Space(10)][field: ReadOnly][SerializeField] string stepId;
17
18
  public string StepId { get { return stepId; } }
18
19
 
19
20
  string questId;
20
21
  public string QuestId { get { return questId; } }
22
+ [field: ReadOnly][SerializeField] public QuestStepStatus stepStatus;
23
+ #endregion
21
24
 
22
-
23
- [field: ReadOnly] [SerializeField] public QuestStepStatus stepStatus;
24
25
 
26
+ #region timeline
25
27
  [Tooltip("This boolean has to be enabled if the quest step has an intro timeline.")]
26
28
  public bool isUsingIntroTimeline = false;
27
29
 
@@ -29,7 +31,9 @@ namespace jeanf.questsystem
29
31
  [SerializeField] private TimelineTriggerEventChannelSO _timelineTriggerEventChannelSo;
30
32
  [DrawIf("isUsingIntroTimeline", true, ComparisonType.Equals, DisablingType.DontDraw)]
31
33
  public PlayableAsset timeline;
34
+ #endregion
32
35
 
36
+ #region step trigger and completion
33
37
  [Header("Quest Step Progression events & Variables")]
34
38
  public List<QuestStep> questStepsToTrigger = new List<QuestStep>();
35
39
  public delegate void SendNextStepId(string id);
@@ -41,14 +45,18 @@ namespace jeanf.questsystem
41
45
  public static StepActive stepActive;
42
46
  public delegate void ChildStep(QuestStep step);
43
47
  public static ChildStep childStep;
44
-
48
+ #endregion
49
+
50
+ #region events
45
51
  [Header("Quest Tooltip")]
46
52
  [SerializeField] private QuestTooltipSO questTooltipSO;
47
53
 
48
54
  [Header("Event Channels")]
49
55
  [SerializeField] private StringEventChannelSO sendQuestStepTooltip;
50
56
  [SerializeField] private StringEventChannelSO stepValidationOverride;
51
-
57
+ #endregion
58
+
59
+ #region standard unity methods
52
60
  public void OnEnable()
53
61
  {
54
62
  Subscribe();
@@ -65,13 +73,14 @@ namespace jeanf.questsystem
65
73
  if(stepValidationOverride) stepValidationOverride.OnEventRaised += ValidateCurrentStep;
66
74
  }
67
75
 
68
- private void Unsubscribe()
76
+ protected virtual void Unsubscribe()
69
77
  {
70
78
  QuestItem.ValidateStepEvent -= ValidateCurrentStep;
71
79
  if(stepValidationOverride) stepValidationOverride.OnEventRaised -= ValidateCurrentStep;
72
80
  }
81
+ #endregion
73
82
 
74
-
83
+ #region step progress
75
84
  public void InitializeQuestStep()
76
85
  {
77
86
  // failsafe to avoid lauching the same step more than once at a time.
@@ -91,6 +100,7 @@ namespace jeanf.questsystem
91
100
  {
92
101
  if(isDebug) Debug.Log($"sending trigger to timeline: {timeline.name}, triggerValue: true");
93
102
  _timelineTriggerEventChannelSo.RaiseEvent(timeline, true);
103
+
94
104
  }
95
105
 
96
106
  if(isDebug) Debug.Log($"Step with id [{stepId}] has {questStepsToTrigger.Count} childSteps");
@@ -107,7 +117,6 @@ namespace jeanf.questsystem
107
117
  FinishQuestStep();
108
118
  }
109
119
 
110
-
111
120
  public void FinishQuestStep()
112
121
  {
113
122
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Changing status to completed", this);
@@ -118,23 +127,28 @@ namespace jeanf.questsystem
118
127
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending tooltip", this);
119
128
  sendQuestStepTooltip.RaiseEvent(string.Empty);
120
129
  }
121
- ;
122
130
 
123
- foreach(QuestStep questStep in questStepsToTrigger)
124
- {
125
- if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
126
- sendNextStepId?.Invoke(questStep.stepId);
127
- }
131
+
128
132
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepCompleted Event (delegate) with argument: {stepId}", this);
129
133
  stepCompleted?.Invoke(stepId);
130
- if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
134
+ if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Sending stepActive Event (delegate) with arguments: {stepId}, {stepStatus} ", this);
131
135
  stepActive?.Invoke(stepId, stepStatus);
132
136
 
137
+ foreach (QuestStep questStep in questStepsToTrigger)
138
+ {
139
+ if (isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Requesting to start next step: {questStep.stepId}", this);
140
+
141
+ //Si questStep.prerequisitesStep are in QuestItem.stepsCompleted
142
+ sendNextStepId?.Invoke(questStep.stepId);
143
+ }
144
+
145
+
133
146
  if(isDebug) Debug.Log($" ---- Step with id: {stepId} finished. Destroying the gameobject with name {this.name}", this);
134
147
  Destroy(this.gameObject);
135
148
  }
149
+ #endregion
136
150
 
137
-
151
+ #region tooltip
138
152
  protected void DisplayActiveQuestStep()
139
153
  {
140
154
  if (questTooltipSO != null)
@@ -142,8 +156,10 @@ namespace jeanf.questsystem
142
156
  sendQuestStepTooltip.RaiseEvent(questTooltipSO.Tooltip);
143
157
  }
144
158
  }
159
+ #endregion
145
160
 
146
- #if UNITY_EDITOR
161
+ #region validation
162
+ #if UNITY_EDITOR
147
163
  private void OnValidate()
148
164
  {
149
165
  if (stepId == string.Empty || stepId == null) GenerateId();
@@ -155,16 +171,20 @@ namespace jeanf.questsystem
155
171
  UnityEditor.EditorUtility.SetDirty(this);
156
172
  }
157
173
 
158
- #endif
159
-
174
+ #endif
175
+ #endregion
160
176
 
177
+ #region debug
161
178
  public bool isDebug { get => _isDebug; set => _isDebug = value; }
162
179
  private bool _isDebug = true;
180
+ #endregion
163
181
 
182
+ #region Status
164
183
  public QuestStepStatus GetStatus()
165
184
  {
166
185
  return stepStatus;
167
186
  }
187
+ #endregion
168
188
  }
169
189
 
170
190
  public enum QuestStepStatus
@@ -0,0 +1,30 @@
1
+ #if UNITY_EDITOR
2
+ using UnityEngine;
3
+ using UnityEditor;
4
+ using GraphProcessor;
5
+
6
+ public class QuestGraphWindow : BaseGraphWindow
7
+ {
8
+ [MenuItem("QuestGraph/01_DefaultGraph")]
9
+ public static BaseGraphWindow Open()
10
+ {
11
+ var graphWindow = GetWindow<QuestGraphWindow>();
12
+
13
+ graphWindow.Show();
14
+
15
+ return graphWindow;
16
+ }
17
+
18
+ protected override void InitializeWindow(BaseGraph graph)
19
+ {
20
+ // Set the window title
21
+ titleContent = new GUIContent("Default Graph");
22
+
23
+ // Here you can use the default BaseGraphView or a custom one (see section below)
24
+ var graphView = new BaseGraphView(this);
25
+
26
+ rootView.Add(graphView);
27
+ }
28
+
29
+ }
30
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 4783b98f3c3c6da49b8d8a1dc5b2bd52
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,11 @@
1
+ using UnityEngine;
2
+ using GraphProcessor;
3
+ using jeanf.questsystem;
4
+
5
+ public class QuestStepNode : BaseNode
6
+ {
7
+ [Input(name = "A")]
8
+ private QuestStep StepsRequiredForCompletion;
9
+ [Output(name = "Out")]
10
+ private QuestStep StepsTriggeredOnCompletion;
11
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: feb5db492d0ac36459e73370531d6f8c
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 7b22fa752a8ac804aa1053eac644fb47
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -7,7 +7,9 @@
7
7
  "GUID:e8958e6939af7314a97769de4be4ce25",
8
8
  "GUID:db1b0a3157155ad47996061dbcc07bbb",
9
9
  "GUID:ca937d03ee5dd4d699091438dc0f3ae6",
10
- "GUID:a432eb0a70c5c4a37ab50d59671586f8"
10
+ "GUID:a432eb0a70c5c4a37ab50d59671586f8",
11
+ "GUID:b8e24fd1eb19b4226afebb2810e3c19b",
12
+ "GUID:002c1bbed08fa44d282ef34fd5edb138"
11
13
  ],
12
14
  "includePlatforms": [],
13
15
  "excludePlatforms": [],
package/package.json CHANGED
@@ -1,22 +1,20 @@
1
1
  {
2
- "name":"fr.jeanf.questsystem",
3
- "version":"0.0.61",
4
- "displayName":"Quest system",
5
- "description":"This package uses Scriptable Objects to define quests.",
2
+ "name": "fr.jeanf.questsystem",
3
+ "version": "0.0.63",
4
+ "displayName": "Quest system",
5
+ "description": "This package uses Scriptable Objects to define quests.",
6
6
  "unity": "2021.3",
7
7
  "keywords": [
8
8
  "jeanf",
9
9
  "quest system"
10
10
  ],
11
- "author":{
12
- "name":"Jean-François Robin",
13
- "email":"robin.jeanfrancois@gmail.com",
14
- "url":"https://jeanfrancoisrobin.art"
11
+ "author": {
12
+ "name": "Jean-François Robin",
13
+ "email": "robin.jeanfrancois@gmail.com",
14
+ "url": "https://jeanfrancoisrobin.art"
15
15
  },
16
16
  "dependencies": {
17
17
  "fr.jeanf.propertydrawer": "1.1.6"
18
18
  },
19
- "samples": [
20
-
21
- ]
19
+ "samples": []
22
20
  }