Browse Source

Added Dialog Audio component to play writing sound effects

master
chrisgregan 9 years ago
parent
commit
4dbca8d0ba
  1. 127
      Assets/Fungus/Narrative/Scripts/DialogAudio.cs
  2. 4
      Assets/Fungus/Narrative/Scripts/SayDialog.cs
  3. 4
      Assets/Fungus/UI/Scripts/Commands/Write.cs
  4. 105
      Assets/Fungus/UI/Scripts/Writer.cs
  5. 2002
      Assets/Tests/Narrative/NarrativeTests.unity

127
Assets/Fungus/Narrative/Scripts/DialogAudio.cs

@ -1,34 +1,77 @@
using UnityEngine; using UnityEngine;
using System.Collections; using System.Collections;
using System.Collections.Generic;
namespace Fungus namespace Fungus
{ {
/* /*
* Manages audio effects for Dialogs * Manages audio effects for Dialogs
*/ */
public class DialogAudio : MonoBehaviour public class DialogAudio : MonoBehaviour, IWriterListener
{ {
// If none is specifed then we use any AudioSource on the gameobject, and if that doesn't exist we create one.
[Tooltip("AudioSource to use for playing sound effects.")]
public AudioSource audioSource; public AudioSource audioSource;
public AudioClip audioClip;
public float volume;
public bool loop;
public virtual void Play() public enum AudioMode
{
Beeps, // Use short beep sound effects
SoundEffect, // Use long looping sound effect
}
[Tooltip("Type of sound effect to play when writing text")]
public AudioMode audioMode = AudioMode.Beeps;
[Tooltip("List of beeps to randomly select when playing beep sound effects")]
public List<AudioClip> beeps = new List<AudioClip>();
[Tooltip("Long playing sound effect to play when writing text")]
public AudioClip soundEffect;
[Tooltip("Loop the sound effect")]
public bool loop = true;
[Tooltip("Volume level of writing sound effects")]
[Range(0,1)]
public float volume = 1f;
protected float targetVolume = 0f;
protected virtual void Start()
{
if (audioSource == null)
{
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
}
}
audioSource.volume = 0f;
}
public virtual void Play(AudioClip audioClip)
{ {
if (audioSource == null || if (audioSource == null ||
audioClip == null) (soundEffect == null && audioClip == null))
{ {
return; return;
} }
audioSource.clip = audioClip; if (audioClip != null)
{
audioSource.clip = audioClip;
}
else
{
audioSource.clip = soundEffect;
}
audioSource.loop = loop; audioSource.loop = loop;
// Fade in the audio at start audioSource.volume = 0f;
LeanTween.value(audioSource.gameObject, 0f, volume, 0.1f).setOnUpdate( (value) => { targetVolume = 1f;
audioSource.volume = value;
});
audioSource.Play(); audioSource.Play();
} }
@ -40,12 +83,8 @@ namespace Fungus
return; return;
} }
// Fade out the audio // There's an audible click if you call audioSource.Pause() so instead just drop the volume to 0.
// There's an audible click if you call audioSource.Pause() so instead just targetVolume = 0f;
// drop the volume to 0.
LeanTween.value(audioSource.gameObject, volume, 0f, 0.1f).setOnUpdate( (value) => {
audioSource.volume = value;
});
} }
public virtual void Stop() public virtual void Stop()
@ -55,14 +94,10 @@ namespace Fungus
return; return;
} }
// Fade out the audio // There's an audible click if you call audioSource.Stop() so instead we just switch off
LeanTween.value(audioSource.gameObject, audioSource.volume, 0f, 0.1f).setOnUpdate( (value) => { // looping and let the audio stop automatically at the end of the clip
audioSource.volume = value; targetVolume = 0f;
}).setOnComplete( () => { audioSource.loop = false;
// There's an audible click if you call audioSource.Stop() so instead we just switch off
// looping and let the audio stop automatically at the end of the clip
audioSource.loop = false;
});
} }
public virtual void Resume() public virtual void Resume()
@ -72,12 +107,40 @@ namespace Fungus
return; return;
} }
audioSource.volume = volume; targetVolume = 1f;
if (!audioSource.isPlaying) }
{
audioSource.loop = loop; protected virtual void Update()
audioSource.Play(); {
} audioSource.volume = Mathf.MoveTowards(audioSource.volume, targetVolume, Time.deltaTime * 5f);
}
//
// IWriterListener implementation
//
public virtual void OnStart(AudioClip audioClip)
{
Play(audioClip);
}
public virtual void OnPause()
{
Pause();
}
public virtual void OnResume()
{
Resume();
}
public virtual void OnEnd()
{
Stop ();
}
public virtual void OnCharacter()
{
} }
} }

4
Assets/Fungus/Narrative/Scripts/SayDialog.cs

@ -113,11 +113,11 @@ namespace Fungus
GetCanvasGroup().alpha = 0f; GetCanvasGroup().alpha = 0f;
} }
public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, Action onComplete) public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip audioClip, Action onComplete)
{ {
this.fadeWhenDone = fadeWhenDone; this.fadeWhenDone = fadeWhenDone;
GetWriter().Write(text, clearPrevious, waitForInput, onComplete); GetWriter().Write(text, clearPrevious, waitForInput, audioClip, onComplete);
} }
protected virtual void LateUpdate() protected virtual void LateUpdate()

4
Assets/Fungus/UI/Scripts/Commands/Write.cs

@ -75,12 +75,12 @@ namespace Fungus
if (!waitUntilFinished) if (!waitUntilFinished)
{ {
writer.Write(newText, clearText, false, null); writer.Write(newText, clearText, false, null, null);
Continue(); Continue();
} }
else else
{ {
writer.Write(newText, clearText, false, writer.Write(newText, clearText, false, null,
() => { Continue (); } () => { Continue (); }
); );
} }

105
Assets/Fungus/UI/Scripts/Writer.cs

@ -7,6 +7,28 @@ using System;
namespace Fungus namespace Fungus
{ {
/**
* Implement this interface to be notified about Writer events
*/
public interface IWriterListener
{
// Called when the Writer starts writing new text
// An optional audioClip sound effect can be supplied (e.g. for voiceover)
void OnStart(AudioClip audioClip);
// Called when the Writer has paused writing text (e.g. on a {wi} tag)
void OnPause();
// Called when the Writer has resumed writing text
void OnResume();
// Called when the Writer has finshed writing text
void OnEnd();
// Called every time the Writer writes a character
void OnCharacter();
}
public class Writer : MonoBehaviour, IDialogInputListener public class Writer : MonoBehaviour, IDialogInputListener
{ {
[Tooltip("Gameobject containing a Text, Inout Field or Text Mesh object to write to")] [Tooltip("Gameobject containing a Text, Inout Field or Text Mesh object to write to")]
@ -43,6 +65,8 @@ namespace Fungus
protected string colorText = ""; protected string colorText = "";
protected bool inputFlag; protected bool inputFlag;
protected List<IWriterListener> writerListeners = new List<IWriterListener>();
public string text public string text
{ {
get get
@ -90,6 +114,16 @@ namespace Fungus
textUI = go.GetComponent<Text>(); textUI = go.GetComponent<Text>();
inputField = go.GetComponent<InputField>(); inputField = go.GetComponent<InputField>();
textMesh = go.GetComponent<TextMesh>(); textMesh = go.GetComponent<TextMesh>();
// Cache the list of child writer listeners
foreach (Component component in GetComponentsInChildren<Component>())
{
IWriterListener writerListener = component as IWriterListener;
if (writerListener != null)
{
writerListeners.Add(writerListener);
}
}
} }
public virtual bool HasTextObject() public virtual bool HasTextObject()
@ -204,7 +238,7 @@ namespace Fungus
} }
} }
public virtual void Write(string content, bool clear, bool waitForInput, Action onComplete) public virtual void Write(string content, bool clear, bool waitForInput, AudioClip audioClip, Action onComplete)
{ {
if (clear) if (clear)
{ {
@ -216,6 +250,9 @@ namespace Fungus
return; return;
} }
// If this clip is null then DialogAudio will play the default sound effect (if any)
NotifyStart(audioClip);
string tokenText = content; string tokenText = content;
if (waitForInput) if (waitForInput)
{ {
@ -408,6 +445,8 @@ namespace Fungus
inputFlag = false; inputFlag = false;
isWriting = false; isWriting = false;
NotifyEnd();
if (onComplete != null) if (onComplete != null)
{ {
onComplete(); onComplete();
@ -440,7 +479,7 @@ namespace Fungus
if (left.Length > 0 && if (left.Length > 0 &&
IsPunctuation(left.Substring(left.Length - 1)[0])) IsPunctuation(left.Substring(left.Length - 1)[0]))
{ {
yield return new WaitForSeconds(currentPunctuationPause); yield return StartCoroutine(DoWait(currentPunctuationPause));
} }
// Delay between characters // Delay between characters
@ -513,16 +552,36 @@ namespace Fungus
duration = 1f; duration = 1f;
} }
NotifyPause();
float timeRemaining = duration;
while (timeRemaining > 0f && !inputFlag)
{
timeRemaining -= Time.deltaTime;
yield return null;
}
NotifyResume();
}
protected virtual IEnumerator DoWait(float duration)
{
NotifyPause();
float timeRemaining = duration; float timeRemaining = duration;
while (timeRemaining > 0f && !inputFlag) while (timeRemaining > 0f && !inputFlag)
{ {
timeRemaining -= Time.deltaTime; timeRemaining -= Time.deltaTime;
yield return null; yield return null;
} }
NotifyResume();
} }
protected virtual IEnumerator DoWaitForInput(bool clear) protected virtual IEnumerator DoWaitForInput(bool clear)
{ {
NotifyPause();
inputFlag = false; inputFlag = false;
isWaitingForInput = true; isWaitingForInput = true;
@ -538,6 +597,8 @@ namespace Fungus
{ {
textUI.text = ""; textUI.text = "";
} }
NotifyResume();
} }
protected virtual bool IsPunctuation(char character) protected virtual bool IsPunctuation(char character)
@ -577,6 +638,46 @@ namespace Fungus
return go.GetComponent<AudioSource>(); return go.GetComponent<AudioSource>();
} }
protected virtual void NotifyStart(AudioClip audioClip)
{
foreach (IWriterListener writerListener in writerListeners)
{
writerListener.OnStart(audioClip);
}
}
protected virtual void NotifyPause()
{
foreach (IWriterListener writerListener in writerListeners)
{
writerListener.OnPause();
}
}
protected virtual void NotifyResume()
{
foreach (IWriterListener writerListener in writerListeners)
{
writerListener.OnResume();
}
}
protected virtual void NotifyEnd()
{
foreach (IWriterListener writerListener in writerListeners)
{
writerListener.OnEnd();
}
}
protected virtual void NotifyCharacter()
{
foreach (IWriterListener writerListener in writerListeners)
{
writerListener.OnCharacter();
}
}
// //
// IDialogInputListener implementation // IDialogInputListener implementation
// //

2002
Assets/Tests/Narrative/NarrativeTests.unity

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save