Yarn-Pile
Yarn-Pile copied to clipboard
A visual novel/point-and-click game template using Yarn Spinner and Unity 2020.
Yarn Pile
A visual novel/point-and-click game template using Yarn Spinner ('develop' branch) and Unity 2020.
WebGL Example


Installation
- Download this project
- Open in Unity
- Install DOTween
Features
General
Smart Syntax
- No need to explicitly state which character is saying what - if there's no character name, assumes previous
- Example:
Alice: Hi Hi, Alice is still talking Bob: Now Bob's talking!
- Example:
- Attributes mid-dialogue using BBcode-like syntax
- Example:
I'm [shake s=2]shaking[/shake]
- See
TextAttributeHandler.cs
- Example:
- Support for Rich Text tags for Text Mesh Pro (except color)
- Example:
Player: Look! <size=150%>Big</size> text!
- Example:
Auto-Save/Load
See CustomStorage.cs
, SaveData.cs
UI/UX
- Longer pauses on punctuation
- Supports keyboard controls
- Cursor enlargens when hovering over clickable
Yarn Commands/Functions
Scene-specific
View Image
- Requires
VisualsManager.cs
in scene loaded withLoad
command -
<<View {SPRITE NAME}>>
Show Characters
- Requires
CharacterManager.cs
in scene loaded withLoad
command -
<<Show {CHARACTER NAME} {EXPRESSION}>>
-
<<Change {CHARACTER NAME} {EXPRESSION}>>
-
<<Hide {CHARACTER NAME}>>
Global
Load Scene
-
<<Load {SCENE NAME}>>
Play Music
-
<<PlayMusic {AUDIOCLIP NAME}>>
-
<<StopMusic>>
Timed or Untimed Options
-
<<SetTimed false>>
-
<<SetTimer 2>>
Display Yarn Variables
- See
RelationshipUI.cs
,VarUI.cs
Display Inventory
-
<<Take {ITEM} 1>>
-
<<Drop {ITEM} 1>>
-
<<if has("{ITEM}") is true>>
Update In-Game Time UI
-
<<SetTime 9:45PM>>
-
<<AddMinutes 100>>
As well as others that are expected, like wait
, visited()
, etc.
How To Add _?
Scenes
- Create scene with name
{SCENE_NAME}
- Add Yarn node with title
{SCENE_NAME}
that contains setup commands (e.g.PlayMusic
,View
, etc) - Add objects/components necessary for your setup commands
See Office
scene as example.
Characters
- Add
{CHARACTER NAME}
toCharacterName
enum - Add to
CustomStorage.defaultVariables
dictionary where key is{CHARACTER NAME}
- Have
CharacterManager.cs
in scene where character will appear - Add
Character
prefab to scene where character will appear - Reference this prefab instance in
CharacterManager.characterUiDictionary
- Replace this prefab instance's animator controller with an animator override controller, overriding the
Character
controller - In the new override controller, override animations you want
See Ana
and Hunter
in Office
scene as examples.
Note: The new character will appear in the relationships UI. If this is not wanted, you can write logic for that in RelationshipUI.cs
.
Character Expressions
- Add
{EXPRESSION}
toExpression
enum - Add
{EXPRESSION}
trigger parameter toCharacter.controller
- Have new trigger lead to some animation (I have all the expression animations in Sprite Layer for now)
- For all characters that should show that expression, edit their override controllers
Items
- In
Scripts/Inventory/Items
folder, right click, thenCreate/ScriptableObjects/ItemData
- Populate fields accordingly. All elements in
yarnValues
will add or subtract to the corresponding yarn variable when added or removed from inventory. Important: All keys in Yarn Values must be keys inCustomStorage.defaultVariables
and represent a numerical yarn variable.
See Headphones
as example.
DialogueGroups
First:
- Update
DialogueType
enum accordingly - Update
TextAttributeHandler.SetDialogueGivenLine
If new DialogueGroup will show options:
- Duplicate
ThinkDialogue
inMain
scene. - Edit
CustomDialogueUI.cs.DoRunOptions
to have logic to show the new DialogueGroup.
Else:
- Duplicate
PlayerDialogue
inMain
scene.
Note: Notice OtherDialogue
in Main
doesn't have a Canvas
component so it can be parented to characters. If that's the intention, perhaps duplicate that DialogueGroup instead.
Attributes
- Update
TextAttributeHandler attributes
- Update
TextAttributeHandler.HandleAttribute
Note: If want to handle attribute before OnLineParsed
event is raised, look into CustomDialogueUI.TryParseCharacter
logic instead.
Parallax
Parallax effect can be achieved in several ways:
- Change Z position
- Change scale
- Change camera's field of view via Lens in
CinemachineVirtualCamera
Note: If parallaxing Unity UI, set canvas's Render Mode
to World Space
and set worldCamera
to BgCamera
.
Non-mouse Actions
All inputs are defined in UIActions.inputactions
.
ClosableUI
allows for shortcut keys for closing/opening by listening to the action named shortcutActionName
.
Tooltips
- In
Scripts/Inventory/Items
folder, right click, thenCreate/ScriptableObjects/TooltipData
- Populate fields. If the
title
field corresponds to anUIAction
action name, then the stringified action for the current input scheme will be displayed.
Save Data
SaveData.cs
contains all save data, and is serialized every time DialogueRunner.onDialogueComplete
is raised.
CustomStorage.cs
contains the logic for saving/loading SaveData
.
To modify:
- Edit
SaveData.cs
- Load data in either
UseSaveData
orUseSaveDataOnPlay
- Save data in either
SaveDataListeners
,SaveDataListenersOnPlay
, orPrepareSaveData
Limitations
- CharTween can tween at max 200 characters due to DOTween's max capacity. Thus either limit all dialogue lines to <=200 characters or refactor to have effects without CharTween
-
OptionsTimed.anim
must be around 1 second - Inline expressions don't work (see open issue)
- Option buttons must have tag "Options"
- UI, not part of a DialogueGroup, must have tag "UI"
- Background, middleground, and foreground cameras must be tagged accordingly, with the camera showing UI tagged as "MainCamera"
- For the cursor-enlargening-over-clickables effect to work, make sure only clickables are raycast targets
Credit
Thanks to @radiatoryang's examples, @Michsky's lomenui, and the Yarn Spinner team! I've wanted a dialogue framework that's thin and expandable yet still powerful for awhile now.
Licensing
Code
All scripts, shaders, and scene files are distributed under the MIT license.
Assets
All art assets are under exclusive copyright; they'll be used for future games. If they're used/sold, I will find you 👀
- setup:
- download alll dependenies (with chartween modifications)