// Copyright (c) Pixel Crushers. All rights reserved. using UnityEngine; using System.Collections; namespace PixelCrushers.DialogueSystem { /// /// Adds and removes extra dialogue databases. /// [AddComponentMenu("")] // Use wrapper. public class ExtraDatabases : MonoBehaviour { /// /// Add the databases when this trigger occurs. /// public DialogueTriggerEvent addTrigger = DialogueTriggerEvent.OnStart; /// /// Remove the databases when this trigger occurs. /// public DialogueTriggerEvent removeTrigger = DialogueTriggerEvent.None; /// /// The databases to add/remove. /// public DialogueDatabase[] databases = new DialogueDatabase[0]; /// /// The condition that must be true for the trigger to fire. /// public Condition condition = new Condition(); /// /// As soon as one event (add or remove) has occurred, destroy this component. /// [Tooltip("As soon as one event (add or remove) has occurred, destroy this component.")] public bool once = false; /// /// Add/remove one database per frame instead of adding them all at the same time. /// Useful to avoid stutter when adding several databases. /// [Tooltip("Add/remove one database per frame instead of adding them all at the same time. Useful to avoid stutter when adding several databases.")] public bool onePerFrame = false; /// /// This event is called after ExtraDatabases has finished adding its list of databases /// to the DialogueManager's MasterDatabase. /// public static event System.Action addedDatabases = delegate { }; /// /// This event is called after ExtraDatabases has finished removing its list of databases /// from the DialogueManager's MasterDatabase. /// public static event System.Action removedDatabases = delegate { }; private bool m_trying = false; private void TryAddDatabases(Transform interactor, bool immediate) { if (!m_trying) { m_trying = true; try { if ((condition == null) || condition.IsTrue(interactor)) { AddDatabases(immediate); if (once) Destroy(this); } } finally { m_trying = false; } } } public void AddDatabases(bool immediate) { if (immediate) { AddDatabasesImmediate(); } else if (gameObject.activeInHierarchy && enabled) { StartCoroutine(AddDatabasesCoroutine()); } } private void AddDatabasesImmediate() { foreach (var database in databases) { AddDatabase(database); } addedDatabases(); } private IEnumerator AddDatabasesCoroutine() { foreach (var database in databases) { AddDatabase(database); yield return null; } addedDatabases(); } private void AddDatabase(DialogueDatabase database) { if (database != null) { if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Adding database " + database.name, this); DialogueManager.AddDatabase(database); } } private void TryRemoveDatabases(Transform interactor, bool immediate) { if (!m_trying) { m_trying = true; try { if ((condition == null) || condition.IsTrue(interactor)) { RemoveDatabases(immediate); if (once) Destroy(this); } } finally { m_trying = false; } } } public void RemoveDatabases(bool immediate) { if (immediate) { RemoveDatabasesImmediate(); } else if (gameObject.activeInHierarchy && enabled) { StartCoroutine(RemoveDatabasesCoroutine()); } } private void RemoveDatabasesImmediate() { foreach (var database in databases) { RemoveDatabase(database); } removedDatabases(); } private IEnumerator RemoveDatabasesCoroutine() { foreach (var database in databases) { RemoveDatabase(database); yield return null; } removedDatabases(); } private void RemoveDatabase(DialogueDatabase database) { if (database != null) { if (DialogueDebug.logInfo) Debug.Log("Dialogue System: Removing database " + database.name, this); DialogueManager.RemoveDatabase(database); } } public void Start() { if (addTrigger == DialogueTriggerEvent.OnStart) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnStart) TryRemoveDatabases(null, onePerFrame); } public void OnEnable() { if (addTrigger == DialogueTriggerEvent.OnEnable) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnEnable) TryRemoveDatabases(null, onePerFrame); } public void OnDisable() { if (addTrigger == DialogueTriggerEvent.OnDisable) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnDisable) TryRemoveDatabases(null, onePerFrame); } public void OnDestroy() { if (addTrigger == DialogueTriggerEvent.OnDestroy) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnDestroy) TryRemoveDatabases(null, onePerFrame); } public void OnUse(Transform actor) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnUse) TryAddDatabases(actor, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnUse) TryRemoveDatabases(actor, onePerFrame); } public void OnUse(string message) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnUse) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnUse) TryRemoveDatabases(null, onePerFrame); } public void OnUse() { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnUse) TryAddDatabases(null, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnUse) TryRemoveDatabases(null, onePerFrame); } public void OnTriggerEnter(Collider other) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnTriggerEnter) TryAddDatabases(other.transform, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnTriggerEnter) TryRemoveDatabases(other.transform, onePerFrame); } public void OnTriggerExit(Collider other) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnTriggerExit) TryAddDatabases(other.transform, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnTriggerExit) TryRemoveDatabases(other.transform, onePerFrame); } #if USE_PHYSICS2D || !UNITY_2018_1_OR_NEWER public void OnTriggerEnter2D(Collider2D other) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnTriggerEnter) TryAddDatabases(other.transform, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnTriggerEnter) TryRemoveDatabases(other.transform, onePerFrame); } public void OnTriggerExit2D(Collider2D other) { if (!enabled) return; if (addTrigger == DialogueTriggerEvent.OnTriggerExit) TryAddDatabases(other.transform, onePerFrame); if (removeTrigger == DialogueTriggerEvent.OnTriggerExit) TryRemoveDatabases(other.transform, onePerFrame); } #endif } }