Skip to main content

Barks

Short ambient lines characters say without player interaction. Guards muttering threats, merchants hawking wares, villagers chatting -- barks bring the world to life without opening a full dialogue UI.

Overview

The bark system has four components:

ComponentPurpose
BarkDataA single bark line (text, duration, audio, priority)
BarkCollectionScriptableObject containing an array of barks with selection logic
BarkerMonoBehaviour that triggers barks on NPCs
BarkUIWorld-space UI that displays bark text above characters
BarkUIPoolObject pool for efficient multi-character barking

BarkData

A serializable data class representing one bark line.

FieldTypeDefaultDescription
textstring--The bark text to display
characterIdstring--Speaker character ID (for name/portrait lookup)
durationfloat3fHow long to display (seconds)
priorityint0Queue priority (higher = shown first)
audioClipAudioClip--Unity audio clip to play
fmodEventPathstring--FMOD event path (used when global audio is FMOD)

Constructors

var bark = new BarkData();
var bark = new BarkData("Watch yourself!", 4f);
var bark = new BarkData("Welcome to my shop!", "merchant_01", 3f);

BarkCollection

A ScriptableObject that groups barks for an NPC. Create via Assets > Create > CraftWorks > DialogueCraft > Bark Collection.

FieldDescription
barksArray of BarkData entries
selectionModeHow to pick the next bark

Selection Modes

ModeEnumBehavior
RandomBarkSelectionMode.RandomPick a random bark each time
SequentialBarkSelectionMode.SequentialCycle through in order, wrapping
FirstBarkSelectionMode.FirstAlways use the first bark
BarkData next = collection.GetNext();  // Returns bark based on selectionMode
collection.Reset(); // Reset sequential index to 0

Barker Component

The main MonoBehaviour for making NPCs bark. Add it to any character GameObject.

[AddComponentMenu("CraftWorks/DialogueCraft/Bark/Barker")]

Inspector Settings

Bark Settings

FieldDescription
characterIdCharacter ID for this barker (applied to barks missing a characterId)
barkCollectionBarkCollection ScriptableObject to pull barks from
customBarksInline list of BarkData (used when no collection is assigned)

Triggers

FieldDefaultDescription
barkOnTriggerEnterfalseBark when a tagged object enters the trigger collider
requiredTag"Player"Only trigger for objects with this tag
randomBarksfalsePeriodically bark at random intervals
minInterval10fMinimum seconds between random barks (5-120)
maxInterval30fMaximum seconds between random barks (5-300)

Cooldown

FieldDefaultDescription
cooldown5fMinimum seconds between any two barks (0-30)

UI

FieldDescription
dedicatedBarkUIOptional per-character BarkUI. If not set, uses the global BarkUIPool.
uiOffsetWorld-space offset from the barker's position (default: (0, 2, 0))

Events

EventSignatureDescription
OnBarkUnityEvent<BarkData>Fired when a bark is triggered

Trigger Modes

Proximity trigger: Enable barkOnTriggerEnter and add a Collider (set to trigger) on the same GameObject. Works with both 3D (OnTriggerEnter/OnTriggerExit) and 2D (OnTriggerEnter2D/OnTriggerExit2D) colliders.

Random interval: Enable randomBarks. The barker schedules the next bark at a random time between minInterval and maxInterval. Cooldown still applies.

Manual trigger: Call Bark() from code or UnityEvents.

Bark Resolution

When Bark() is called, the barker resolves a BarkData:

  1. If barkCollection is assigned, calls barkCollection.GetNext()
  2. Otherwise, picks randomly from customBarks
  3. If the bark has no characterId, the barker's characterId is applied

API

var barker = GetComponent<Barker>();

// Trigger a bark from the configured collection/custom list
barker.Bark();

// Bark a specific text
barker.Bark("Halt! Who goes there?", duration: 4f);

// Bark specific data
barker.Bark(new BarkData("Fine day for a sale!", "merchant", 3f));

// Stop the current bark
barker.StopBark();

// Check cooldown
if (barker.CanBark)
{
barker.Bark();
}

UI Resolution

The barker resolves a BarkUI in this order:

  1. dedicatedBarkUI -- A specific BarkUI assigned in the Inspector
  2. Global BarkUIPool -- Found via FindObjectOfType<BarkUIPool>()
  3. Any BarkUI in the scene -- Fallback via FindObjectOfType<BarkUI>()

BarkUI Component

World-space UI that displays bark text above characters. Typically placed on a World Space Canvas.

Inspector Settings

UI References

FieldDescription
textComponentTextMeshProUGUI for bark text (required)
backgroundPanelOptional background GameObject (hidden when no bark active)
nameLabelOptional TextMeshProUGUI for the character name

Positioning

FieldDefaultDescription
offset(0, 2, 0)Offset from follow target (overridden by Barker's uiOffset)
faceCameratrueBillboard toward camera each frame
targetCameraMain CameraCamera to face (auto-finds Camera.main)

Animation

FieldDefaultDescription
fadeDuration0.3fFade in/out duration (seconds)
useTypewriterfalseReveal text character by character
typewriterSpeed30fCharacters per second (when typewriter enabled)

Audio

FieldDescription
audioSourceAudioSource for playing bark audio clips

Lifecycle

When Show(bark, target) is called:

  1. Starts following target transform at the configured offset
  2. Sets up text, character name, and background
  3. Plays audio (FMOD event or Unity AudioClip depending on global setting)
  4. Fades in over fadeDuration
  5. If useTypewriter is enabled, reveals text character by character (supports inline speed/pause tags)
  6. Waits for bark.duration seconds
  7. Fades out over fadeDuration
  8. Hides and marks itself as available

API

var barkUI = GetComponent<BarkUI>();

barkUI.Show(barkData, npcTransform); // Show bark above NPC
barkUI.Hide(); // Immediately hide

bool active = barkUI.IsShowing; // Check if displaying

Character Name Display

If nameLabel is assigned and the bark has a characterId, the UI looks up the character in DialogueCraftSettings.Characters and displays displayName. If no character is found, the raw characterId is shown. If no characterId is set, the name label is hidden.

BarkUIPool

Manages a pool of BarkUI instances for scenes with multiple barking NPCs. Without a pool, multiple barkers would fight over a single BarkUI.

Setup

  1. Create a BarkUI prefab (World Space Canvas with BarkUI, TextMeshProUGUI, optional background).
  2. Add a BarkUIPool component to a scene GameObject.
  3. Assign the prefab and configure pool size.

Inspector Settings

FieldDefaultDescription
barkUIPrefab--Prefab to instantiate (required)
initialPoolSize5Pre-created instances on Awake (1-20)
maxPoolSize10Hard limit on pool growth (1-50)
queueBarkstrueQueue barks when no UI available
maxQueueSize5Maximum queued barks (0-20)

How It Works

  • On Awake(), the pool instantiates initialPoolSize BarkUI children.
  • When a Barker requests a UI via GetBarkUI(), the pool returns the first instance where IsShowing == false.
  • If all instances are busy and the pool is below maxPoolSize, a new instance is created.
  • If at max capacity and queueBarks is enabled, barks are queued and dispatched each frame as UIs become available.

API

var pool = FindObjectOfType<BarkUIPool>();

// Get an available UI (returns null if pool full and queue disabled)
BarkUI ui = pool.GetBarkUI();

// Show a bark (auto-queues if no UI available)
pool.ShowBark(barkData, targetTransform);

// Manually queue
pool.QueueBark(barkData, targetTransform);

// Hide all active barks and clear the queue
pool.HideAll();

Runtime API Summary

Triggering Barks from Code

// Through a Barker component
barker.Bark();
barker.Bark("Custom text", 4f);
barker.Bark(customBarkData);

// Through a BarkUIPool (no Barker needed)
pool.ShowBark(new BarkData("Alert!", "guard", 3f), guardTransform);

// Direct BarkUI control
barkUI.Show(barkData, npcTransform);
barkUI.Hide();

Audio

Bark audio follows the global audio backend setting:

  • Unity: Plays bark.audioClip through BarkUI.audioSource
  • FMOD: Plays bark.fmodEventPath via AudioProviderManager.Provider.PlayOneShot()

Configure the global backend in DialogueCraft Settings > Audio Source (AudioSourceType.Unity or AudioSourceType.FMOD).

Events

Use the Barker.OnBark UnityEvent to react to barks in other systems:

barker.OnBark.AddListener((BarkData bark) =>
{
// Update quest journal, trigger animation, etc.
Debug.Log($"{bark.characterId} says: {bark.text}");
});