ChitChat/Components/DialogueWriterComponent.cs
using Sandbox;
using System;
using System.Text;
namespace ChitChat;
[Title("Dialogue Writer")][Category("ChitChat")][Icon("history_edu")]
public sealed class DialogueWriterComponent : Component
{
[Property] public float PunctuationPauseDelay { get; set; } = 0.25f;
public Action onCharacterAdded;
public Action onWritingDone;
public bool IsWriting { get; private set; } = false;
private StringBuilder _dialogueBuilder = new();
private int _currentDialogueTextCharacterIndex = 0;
private float _writingTimer = 0.0f;
private float _currentWriteSpeed = 0.0f;
private float _defaultWritingSpeed = 0.0f;
private string m_Text;
private DialoguePanelComponent _uiComponent;
public void SetUIComponent(DialoguePanelComponent ui) => _uiComponent = ui;
public void StartWriting(string text, float writingSpeed)
{
_writingTimer = 0;
_currentDialogueTextCharacterIndex = 0;
_dialogueBuilder.Clear();
m_Text = text;
_defaultWritingSpeed = writingSpeed;
_currentWriteSpeed = writingSpeed;
IsWriting = true;
}
public void StopWriting()
{
IsWriting = false;
}
public void CompleteWriting()
{
_uiComponent.SetText(m_Text);
IsWriting = false;
}
protected override void OnUpdate()
{
if(!IsWriting)
return;
if (_writingTimer >= _currentWriteSpeed)
{
if (_currentDialogueTextCharacterIndex < m_Text.Length)
{
char dialogueChar = m_Text[_currentDialogueTextCharacterIndex];
_dialogueBuilder.Append(dialogueChar);
_currentDialogueTextCharacterIndex++;
//If the current character is a punctuation then change to punctuation writing delay
if (char.IsPunctuation(dialogueChar) && dialogueChar == '.')
{
_currentWriteSpeed = PunctuationPauseDelay;
}
else
_currentWriteSpeed = _defaultWritingSpeed;
//Fire event if the current character isn't white space or punctuation
if (!char.IsWhiteSpace(dialogueChar) && !char.IsPunctuation(dialogueChar))
{
onCharacterAdded?.Invoke();
}
_uiComponent.SetText(_dialogueBuilder.ToString());
}
else //Writing effect is finished
{
IsWriting = false;
onWritingDone?.Invoke();
return;
}
_writingTimer = 0;
}
else
{
_writingTimer += Time.Delta;
}
}
}