diff --git a/Assets/Fungus/Narrative/Editor/SayEditor.cs b/Assets/Fungus/Narrative/Editor/SayEditor.cs index 273b50c9..9f5e6518 100644 --- a/Assets/Fungus/Narrative/Editor/SayEditor.cs +++ b/Assets/Fungus/Narrative/Editor/SayEditor.cs @@ -78,7 +78,7 @@ namespace Fungus protected SerializedProperty showAlwaysProp; protected SerializedProperty showCountProp; protected SerializedProperty extendPreviousProp; - protected SerializedProperty fadeWhenDoneProp; + protected SerializedProperty fadeOutProp; protected SerializedProperty waitForClickProp; protected SerializedProperty setSayDialogProp; @@ -95,7 +95,7 @@ namespace Fungus showAlwaysProp = serializedObject.FindProperty("showAlways"); showCountProp = serializedObject.FindProperty("showCount"); extendPreviousProp = serializedObject.FindProperty("extendPrevious"); - fadeWhenDoneProp = serializedObject.FindProperty("fadeWhenDone"); + fadeOutProp = serializedObject.FindProperty("fadeOut"); waitForClickProp = serializedObject.FindProperty("waitForClick"); setSayDialogProp = serializedObject.FindProperty("setSayDialog"); @@ -188,7 +188,7 @@ namespace Fungus rightButton.fontSize = 10; rightButton.font = EditorStyles.toolbarButton.font; - EditorGUILayout.PropertyField(fadeWhenDoneProp); + EditorGUILayout.PropertyField(fadeOutProp); EditorGUILayout.PropertyField(waitForClickProp); EditorGUILayout.PropertyField(setSayDialogProp); diff --git a/Assets/Fungus/Narrative/Scripts/Commands/Say.cs b/Assets/Fungus/Narrative/Scripts/Commands/Say.cs index e1439171..ad8ac87e 100644 --- a/Assets/Fungus/Narrative/Scripts/Commands/Say.cs +++ b/Assets/Fungus/Narrative/Scripts/Commands/Say.cs @@ -37,7 +37,7 @@ namespace Fungus public bool extendPrevious = false; [Tooltip("Fade out the dialog box when writing has finished and not waiting for input.")] - public bool fadeWhenDone = true; + public bool fadeOut = true; [Tooltip("Wait for player to click before continuing.")] public bool waitForClick = true; @@ -75,7 +75,7 @@ namespace Fungus sayDialog.SetCharacter(character, flowchart); sayDialog.SetCharacterImage(portrait); - sayDialog.ShowDialog(true); + sayDialog.gameObject.SetActive(true); string displayText = storyText; @@ -90,7 +90,7 @@ namespace Fungus string subbedText = flowchart.SubstituteVariables(displayText); - sayDialog.Say(subbedText, !extendPrevious, waitForClick, voiceOverClip, delegate { + sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeOut, voiceOverClip, delegate { Continue(); }); } diff --git a/Assets/Fungus/Narrative/Scripts/MenuDialog.cs b/Assets/Fungus/Narrative/Scripts/MenuDialog.cs index 39d878bb..72845632 100644 --- a/Assets/Fungus/Narrative/Scripts/MenuDialog.cs +++ b/Assets/Fungus/Narrative/Scripts/MenuDialog.cs @@ -144,7 +144,7 @@ namespace Fungus SayDialog sayDialog = SayDialog.GetSayDialog(); if (sayDialog != null) { - sayDialog.ShowDialog(false); + sayDialog.FadeOut(); } } diff --git a/Assets/Fungus/Narrative/Scripts/SayDialog.cs b/Assets/Fungus/Narrative/Scripts/SayDialog.cs index 01973605..f1bc5a78 100644 --- a/Assets/Fungus/Narrative/Scripts/SayDialog.cs +++ b/Assets/Fungus/Narrative/Scripts/SayDialog.cs @@ -16,8 +16,7 @@ namespace Fungus public Image continueImage; public AudioClip continueSound; - public bool visibleAtStart; - public float fadeDuration = 1f; + public float fadeDuration = 0.25f; public Canvas dialogCanvas; public Text nameText; @@ -27,7 +26,11 @@ namespace Fungus public DialogAudio audioController = new DialogAudio(); protected Writer writer; + protected CanvasGroup canvasGroup; protected bool wasPointerClicked; + protected bool fadeWhenDone = true; + protected float targetAlpha = 0f; + protected float fadeCoolDownTimer = 0f; public static SayDialog GetSayDialog() { @@ -50,7 +53,6 @@ namespace Fungus go.SetActive(false); go.name = "SayDialog"; activeSayDialog = go.GetComponent(); - activeSayDialog.visibleAtStart = true; } } } @@ -74,48 +76,89 @@ namespace Fungus return writer; } - protected virtual void Start() + protected CanvasGroup GetCanvasGroup() { - // Set dialog visibilty at startup - CanvasGroup canvasGroup = dialogCanvas.GetComponent(); - if (visibleAtStart) + if (canvasGroup != null) { - canvasGroup.alpha = 1f; + return canvasGroup; } - else + + canvasGroup = GetComponent(); + if (canvasGroup == null) { - canvasGroup.alpha = 0f; + canvasGroup = gameObject.AddComponent(); } + + return canvasGroup; + } + + protected void Start() + { + // Dialog always starts invisible, will be faded in when writing starts + GetCanvasGroup().alpha = 0f; } - public virtual void Say(string text, bool clearPrevious, bool waitForInput, AudioClip voiceOverClip, Action onComplete) + public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, Action onComplete) { + this.fadeWhenDone = fadeWhenDone; + GetWriter().Write(text, clearPrevious, waitForInput, onComplete); } - protected virtual void Update() + protected virtual void LateUpdate() { + UpdateAlpha(); + if (continueImage != null) { continueImage.enabled = GetWriter().isWaitingForInput; } + + wasPointerClicked = false; } - protected virtual void LateUpdate() + public virtual void FadeOut() { - wasPointerClicked = false; + fadeWhenDone = true; } - - public virtual void ShowDialog(bool visible) + + protected virtual void UpdateAlpha() { - gameObject.SetActive(true); - - if (visible) + if (GetWriter().isWriting) { - // A new dialog is often shown as the result of a mouse click, so we need - // to make sure the previous click doesn't register on the new dialogue - wasPointerClicked = false; + targetAlpha = 1f; + fadeCoolDownTimer = 0.1f; } + else if (fadeWhenDone && fadeCoolDownTimer == 0f) + { + targetAlpha = 0f; + } + else + { + // Add a short delay before we start fading in case there's another Say command in the next frame or two. + // This avoids a noticeable flicker between consecutive Say commands. + fadeCoolDownTimer = Mathf.Max(0f, fadeCoolDownTimer - Time.deltaTime); + } + + CanvasGroup canvasGroup = GetCanvasGroup(); + float fadeDuration = GetSayDialog().fadeDuration; + if (fadeDuration <= 0f) + { + canvasGroup.alpha = targetAlpha; + } + else + { + float delta = (1f / fadeDuration) * Time.deltaTime; + float alpha = Mathf.MoveTowards(canvasGroup.alpha, targetAlpha, delta); + canvasGroup.alpha = alpha; + } + } + + public virtual void ResetPointerClicked() + { + // A new dialog is often shown as the result of a mouse click, so we need + // to make sure the previous click doesn't register on the new dialogue + wasPointerClicked = false; } public virtual void SetCharacter(Character character, Flowchart flowchart = null) diff --git a/Assets/Fungus/UI/Scripts/Writer.cs b/Assets/Fungus/UI/Scripts/Writer.cs index 6c65a981..3640de59 100644 --- a/Assets/Fungus/UI/Scripts/Writer.cs +++ b/Assets/Fungus/UI/Scripts/Writer.cs @@ -28,6 +28,10 @@ namespace Fungus [System.NonSerialized] public bool isWaitingForInput; + // This property is true when the writer is writing text or waiting (i.e. still processing tokens) + [System.NonSerialized] + public bool isWriting; + protected float currentWritingSpeed; protected float currentPunctuationPause; protected Text textUI; @@ -233,7 +237,9 @@ namespace Fungus colorText = ""; currentPunctuationPause = punctuationPause; currentWritingSpeed = writingSpeed; - + + isWriting = true; + foreach (TextTagParser.Token token in tokens) { bool exit = false; @@ -401,7 +407,9 @@ namespace Fungus break; } } - + + isWriting = false; + if (onComplete != null) { onComplete(); diff --git a/Assets/FungusExamples/Sherlock/TheExperiment.unity b/Assets/FungusExamples/Sherlock/TheExperiment.unity index a0b4b7e6..e71bdfb3 100644 --- a/Assets/FungusExamples/Sherlock/TheExperiment.unity +++ b/Assets/FungusExamples/Sherlock/TheExperiment.unity @@ -2610,24 +2610,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3a0bbe22c246e4c78ad8e9816cbae9d5, type: 3} m_Name: m_EditorClassIdentifier: - writingSpeed: 30 - writingSound: {fileID: 8300000, guid: f637c5ce9d10e45c7855ed89bfc6b97e, type: 3} - writingVolume: 1 - loopWritingSound: 1 - beepPerCharacter: 0 - slowBeepsAt: 10 - fastBeepsAt: 30 - punctuationPause: .200000003 - alwaysFadeDialog: 0 + continueImage: {fileID: 1330472049} + continueSound: {fileID: 0} fadeDuration: .25 - fadeEaseType: 0 dialogCanvas: {fileID: 981838191} nameText: {fileID: 43764834} storyText: {fileID: 1116800863} characterImage: {fileID: 515191726} - characterTypingSound: {fileID: 0} - continueImage: {fileID: 1330472049} - continueSound: {fileID: 0} --- !u!114 &981838188 MonoBehaviour: m_ObjectHideFlags: 0 @@ -3852,9 +3841,9 @@ MonoBehaviour: y: -1729.35046 width: 5969.4458 height: 2818.85034 - selectedBlock: {fileID: 1390555298} + selectedBlock: {fileID: 1390555440} selectedCommands: - - {fileID: 1390555297} + - {fileID: 1390555300} variables: - {fileID: 1390555396} description: 'Example scene from Sherlock: The Game Is On' @@ -3898,8 +3887,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 1 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555298 @@ -4004,7 +3992,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 fadeOut: 0 waitForClick: 0 setSayDialog: {fileID: 0} @@ -4152,8 +4139,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 0 setSayDialog: {fileID: 0} --- !u!114 &1390555307 @@ -4282,8 +4268,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 0 setSayDialog: {fileID: 0} --- !u!114 &1390555312 @@ -4354,7 +4339,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} @@ -4381,8 +4365,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555315 @@ -4408,8 +4391,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555316 @@ -4435,8 +4417,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555317 @@ -4462,8 +4443,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 1 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555318 @@ -4529,7 +4509,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} @@ -4556,8 +4535,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555322 @@ -4583,8 +4561,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555323 @@ -4610,8 +4587,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555324 @@ -4638,8 +4614,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555325 @@ -4676,8 +4651,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555327 @@ -4703,8 +4677,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555328 @@ -4730,8 +4703,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555329 @@ -4757,8 +4729,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555330 @@ -4784,8 +4755,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555331 @@ -4811,8 +4781,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555332 @@ -4838,8 +4807,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555333 @@ -4866,8 +4834,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555334 @@ -4893,7 +4860,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 1 fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} @@ -5323,8 +5289,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 1 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555351 @@ -5471,7 +5436,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} @@ -5731,8 +5695,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 1 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555367 @@ -5796,7 +5759,6 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} @@ -6140,8 +6102,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 1 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &1390555382 diff --git a/Assets/Tests/Narrative/NarrativeTests.unity b/Assets/Tests/Narrative/NarrativeTests.unity index 19dc9e31..935b4ff6 100644 --- a/Assets/Tests/Narrative/NarrativeTests.unity +++ b/Assets/Tests/Narrative/NarrativeTests.unity @@ -114,7 +114,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 61dddfdc5e0e44ca298d8f46f7f5a915, type: 3} m_Name: m_EditorClassIdentifier: - selectedFlowchart: {fileID: 736071350} + selectedFlowchart: {fileID: 24983358} --- !u!4 &11556238 Transform: m_ObjectHideFlags: 1 @@ -185,8 +185,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &24983356 @@ -216,8 +215,8 @@ MonoBehaviour: m_EditorClassIdentifier: nodeRect: serializedVersion: 2 - x: 67 - y: 70 + x: 66 + y: 71 width: 120 height: 40 itemId: 0 @@ -254,7 +253,7 @@ MonoBehaviour: height: 869 selectedBlock: {fileID: 24983357} selectedCommands: - - {fileID: 24983355} + - {fileID: 24983373} variables: [] description: stepPause: 0 @@ -462,8 +461,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 0 setSayDialog: {fileID: 0} --- !u!114 &24983369 @@ -800,6 +798,7 @@ GameObject: - 114: {fileID: 736071349} - 114: {fileID: 736071348} - 114: {fileID: 736071347} + - 114: {fileID: 736071352} m_Layer: 0 m_Name: Flowchart m_TagString: Untagged @@ -809,7 +808,7 @@ GameObject: m_IsActive: 1 --- !u!114 &736071347 MonoBehaviour: - m_ObjectHideFlags: 0 + m_ObjectHideFlags: 2 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 736071346} @@ -829,8 +828,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &736071348 @@ -861,7 +859,7 @@ MonoBehaviour: nodeRect: serializedVersion: 2 x: 66 - y: 69 + y: 70 width: 120 height: 40 itemId: 0 @@ -870,6 +868,7 @@ MonoBehaviour: eventHandler: {fileID: 736071348} commandList: - {fileID: 736071347} + - {fileID: 736071352} --- !u!114 &736071350 MonoBehaviour: m_ObjectHideFlags: 0 @@ -895,8 +894,7 @@ MonoBehaviour: width: 1114 height: 859 selectedBlock: {fileID: 736071349} - selectedCommands: - - {fileID: 736071347} + selectedCommands: [] variables: [] description: stepPause: 0 @@ -916,6 +914,31 @@ Transform: m_Children: [] m_Father: {fileID: 1929911610} m_RootOrder: 0 +--- !u!114 &736071352 +MonoBehaviour: + m_ObjectHideFlags: 2 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 736071346} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ec422cd568a9c4a31ad7c36d0572b9da, type: 3} + m_Name: + m_EditorClassIdentifier: + itemId: 2 + errorMessage: + indentLevel: 0 + storyText: Play audio beeps from dialog + description: + character: {fileID: 0} + portrait: {fileID: 0} + voiceOverClip: {fileID: 0} + showAlways: 1 + showCount: 1 + extendPrevious: 0 + fadeOut: 1 + waitForClick: 1 + setSayDialog: {fileID: 0} --- !u!1 &891159641 GameObject: m_ObjectHideFlags: 0 @@ -1129,8 +1152,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &891159650 @@ -1279,8 +1301,7 @@ MonoBehaviour: showAlways: 1 showCount: 1 extendPrevious: 0 - fadeIn: 0 - fadeOut: 0 + fadeOut: 1 waitForClick: 1 setSayDialog: {fileID: 0} --- !u!114 &891159663 @@ -2003,7 +2024,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!4 &1929911610 Transform: m_ObjectHideFlags: 0 @@ -2053,7 +2074,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &2084461895 Transform: m_ObjectHideFlags: 0