Skip to main content

Prefab Characters

ConvoCore supports 3D prefab characters in addition to flat sprites. Where a sprite representation stores a set of images, a prefab representation stores a reference to a Unity prefab. The prefab is a real GameObject that can be spawned into a scene, driven by an Animator, and fully integrated into your world.

This section covers the full workflow: how prefab characters are placed, how they receive expressions, and how to choose between the two display modes ConvoCore provides.


The Two Paths

Prefab characters work differently depending on whether your dialogue exists in canvas space or world space. ConvoCore ships with a dedicated UI class for each case.

Your Conversation

├─── 2D / Canvas ───▶ ConvoCoreSampleUICanvas
│ - Slot anchors on a Canvas
│ - Sprites and prefabs side-by-side
│ - Fixed screen-space positions

└─── 3D / World ────▶ ConvoCoreSampleUI3D
- Character Behaviour ScriptableObjects
- Characters live in the scene
- Placement is the behaviour's job

Canvas path

Characters sit inside a Canvas. Each character slot is a RectTransform anchor point that the spawner parents prefab instances under. Sprite and prefab characters can both appear on the same dialogue line. The canvas UI handles both types without any extra configuration.

Canvas
├── ConvoCoreSampleUICanvas

├── Slot anchors (RectTransform)
│ ├── SlotLeft ────▶ CharacterA (prefab instance)
│ │ └── ConvoCoreAnimatorDisplay
│ │
│ └── SlotRight ───▶ CharacterB (sprite rendered into Image)

└── Dialogue Text, Speaker Name, Choices, ...

Best for: visual novel layouts, 2D games, UI-layer portraits, any setup where characters are screen-space elements.

3D world path

Characters live in the 3D scene. Character behavioursConvoCoreCharacterBehaviour ScriptableObjects assigned to each character's configuration entry — handle all placement decisions: where to spawn characters, how they move, and when they are removed from the scene. Common built-in options cover authored world positions, camera-relative placement, following a moving target, and characters already standing in the scene. The UI has no slot concept and delegates all placement to the behaviours.

ConvoCoreSampleUI3D
│ conversation starts
├──▶ behaviour.OnConversationBegin()
│ set up markers, spawn points, or store initial state

│ each dialogue line
├──▶ behaviour.ResolvePresence(rep, context, spawner)
│ returns IConvoCoreCharacterDisplay
│ └── display.BindRepresentation()
│ └── display.ApplyExpression()

│ conversation ends
└──▶ behaviour.OnConversationEnd()
release spawned instances, restore scene state

Behaviours are assigned per configuration entry on the PrefabCharacterRepresentationData asset. Each entry holds a list of behaviours, so a "CloseUp" entry and a "Distant" entry on the same character can each use different behaviours — and the active set transitions automatically when the entry changes between lines.

Best for: RPG dialogue, cinematic scenes, first-person games, VR, any setup where characters exist as world objects.


Choosing a Path

SituationUse
Characters rendered inside a CanvasConvoCoreSampleUICanvas
Characters exist as GameObjects in the sceneConvoCoreSampleUI3D
Mixing sprite portraits and prefab characters on the same lineConvoCoreSampleUICanvas
Characters need to move to specific world positionsConvoCoreSampleUI3D + WorldPointBehaviour
Characters follow the playerConvoCoreSampleUI3D + FollowTargetBehaviour
Characters are already placed in the scene by the developerConvoCoreSampleUI3D + ExternalBehaviour
First-person or VR, character positioned relative to the cameraConvoCoreSampleUI3D + CameraRelativeBehaviour
note

Both paths use the same PrefabCharacterRepresentationData asset and the same display components (ConvoCoreAnimatorDisplay, ConvoCoreBlendShapeDisplay, etc.). What differs is how the spawned character gets positioned in the world.


Key Components

Shared across both paths

ComponentWhat it does
PrefabCharacterRepresentationDataScriptableObject. Holds configuration entries, prefab references, and expression mappings.
ConvoCorePrefabRepresentationSpawnerMonoBehaviour. Spawns, pools, and resolves prefab instances. One per UI.
ConvoCorePrefabPoolMonoBehaviour. Object pool for prefab instances. Managed by the spawner.
ConvoCoreSceneCharacterRegistryMonoBehaviour. Registers scene-resident characters by ID so behaviours can find them without spawning anything.
ConvoCoreSceneCharacterRegistrantMonoBehaviour. Drop on any scene character to register it with the registry.

Canvas path only

ComponentWhat it does
ConvoCoreSampleUICanvasThe full canvas UI: text, choices, sprite slots, and prefab slot anchors.

3D path only

ComponentWhat it does
ConvoCoreSampleUI3DThe world-space UI: text and choices only. Delegates character placement to behaviours on each configuration entry.
ConvoCoreCharacterBehaviourAbstract ScriptableObject base class. Subclass determines where and how characters appear.
ConvoCoreSpawnPointMonoBehaviour scene marker. Place on any GameObject; WorldPointBehaviour resolves it by ID.
ConvoCoreSpawnPointRegistryMonoBehaviour. Tracks all active ConvoCoreSpawnPoint instances by ID at runtime.

On the character prefab

ComponentWhat it does
ConvoCoreAnimatorDisplayDrives Animator parameters in response to expressions. Most common 3D case.
ConvoCoreBlendShapeDisplayDrives SkinnedMeshRenderer blend shape weights in response to expressions.
ConvoCoreActionOnlyDisplayPassthrough. Runs BaseExpressionAction ScriptableObjects only; adds no built-in visual change.
ConvoCoreSimpleFadeImplements fade-in and fade-out on a Renderer or CanvasGroup. Drop-on, configure duration.

How Expression Application Works

Regardless of which path you use, the expression application sequence is the same:

  1. The ConvoCore runner processes a dialogue line and determines which characters are present.
  2. The UI calls spawner.ResolveCharacter() (canvas) or behaviour.ResolvePresence() (3D) to obtain an IConvoCoreCharacterDisplay for each character.
  3. The UI calls display.BindRepresentation(representationAsset) on the returned display. The display builds an internal lookup table keyed by expression display name at this point.
  4. The UI calls display.ApplyExpression(expressionId) with the GUID of the expression selected in the YAML line.
  5. The display component translates the GUID into a concrete visual change: an Animator parameter, a blend shape weight, or nothing (if ConvoCoreActionOnlyDisplay).
  6. PrefabCharacterRepresentationData.ApplyExpression() also runs, which fires any BaseExpressionAction ScriptableObjects attached to the expression mapping. Display component changes and ScriptableObject actions run together.
YAML dialogue line
├── CharacterID: "Guard"
└── Expression: "Angry"


PrefabCharacterRepresentationData (ScriptableObject asset)
└── Expression Mappings
└── "Angry"
├──▶ BaseExpressionAction[] (audio, VFX, events, etc.)
│ fired by the representation asset

└──▶ IConvoCoreCharacterDisplay (component on the prefab)
└── ConvoCoreAnimatorDisplay
└── Animator.SetInteger("EmotionState", 2)
note

Expression display names are used as the join key between the PrefabCharacterRepresentationData asset and the display component's inspector mappings. The GUID is only used at runtime lookup. This means you configure display components using the same human-readable name you gave the expression in the representation asset.


Next Steps

I want to…Go here
Set up canvas-space prefab charactersCanvas UI →
Set up world-space prefab characters3D UI →
Understand character behaviour types and when to use eachCharacter Behaviours →
Configure expression driving on a prefabDisplay Components →