added yarn spinner package

This commit is contained in:
2026-08-14 13:27:17 +02:00
parent c140236bf7
commit c483bda3ea
573 changed files with 81459 additions and 0 deletions
@@ -0,0 +1,8 @@
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
## [1.0.0] - 2026-05-20
This is the first release of Classic RPG for Yarn Spinner.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: d155437c4b341477285cbb8274902255
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/CHANGELOG.md
uploadId: 968678
@@ -0,0 +1 @@
Classic RPG for Yarn Spinner is distributed under the terms of the Unity Asset Store Terms of Service and End User License Agreement, which is available here: https://unity.com/legal/as-terms.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 055aecaac898a267ca272ca176c386df
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/LICENSE.md
uploadId: 968678
@@ -0,0 +1,178 @@
# Classic RPG for Yarn Spinner
**Classic RPG** is a dialogue presenter for Yarn spinner that pays homage to the dialogue systems used in old school RPGs.
It shows a text box at the bottom of the screen that hosts lines of dialogue and choices. Text is shown with a character-by-character 'typewriter' effect, and the typewriter supports changing its speed or pausing. When the player hits the 'skip' input, the typewriter speeds up, and starts automatically skipping lines until it hits a stopping point. The presenter also has two different styles of box background, and lines can also have an icon associated with them. It also works with Cinemachine to re-position the camera when dialogue is running.
## Try it out!
Test out the Classic RPG presenter by installing the sample:
1. Open the Package Manager by choosing Window -> Packages -> Package Manager.
2. Select the 'Classic RPG for Yarn Spinner' package.
3. Select the 'Samples' tab.
4. Install the 'Classic RPG' sample. The sample will be copied into your project's Assets folder.
5. Inside the 'Scenes' folder that was copied over, open the 'ClassicRPG' scene, and hit Play. Use the `WASD` keys to move the character, and press the spacebar to talk to a character.
## How To Use Classic RPG
To use Classic RPG in your game's dialogue, follow these steps.
- In the Project tab, find the 'Classic RPG for Yarn Spinner' package, and navigate to 'Runtime/Prefabs'.
- Drag the 'Classic RPG Dialogue System' prefab into your scene.
- Add your Yarn Project to the dialogue system, turn on Start Automatically, and choose a node.
- Hit play, and enjoy your dialogue!
## Using Classic RPG's features
The central component to Classic RPG is the `RPGDialoguePresenter`, which manages the dialogue box, the typewriter, options, and most other parts of the presentation. You can find this component in the `Classic RPG Dialogue System` prefab, under `Canvas` -> `Dialogue Presenter`.
Many of the features of the `RPGDialoguePresenter` can be enabled and disabled via the use of feature flags, which are shown at the bottom of the component's Inspector.
### Line control hashtags
Classic RPG for Yarn Spinner uses several hashtags that affect the way that dialogue is shown.
#### `#end`
The `#end` hashtag signals that this line is the final line, and makes the 'next' button appear as a square. This tells the player that they've reached the end of the conversation and that something other than more dialogue is about to happen.
#### `noskip`
The `#noskip` hashtag signals that the line should not allow skipping, and should interrupt any skipping that is already taking place. See 'Skipping' below for more information.
#### `#icon:`
The `#icon:` hashtag signals that this line of dialogue should have an icon shown next to it. See 'Icons' below for more information.
#### `#lastline`
The `#lastline` hashtag signals that the next piece of content will be options, and that the dialogue presenter should show the content in the options view.
#### `center`
The `#center` hashtag signals that the text should be shown centered in the dialogue box, rather than the default of left-aligned.
### Audio
The dialogue presenter plays audio when the dialogue is interacted with. You can associate an audio clip with the following events:
- **Next Line**: Played when the player advances to the next line.
- **End Dialogue**: Played when the dialogue box finishes displaying a line of dialogue that is marked with the `#end` hashtag.
- **Leave Dialogue**: Played when the player advances past a line of dialogue that is marked with the `#end` hashtag.
- **Change Option:** Played when the player changes which option is currently highlighted.
### Options
Options are shown in the dialogue box, alongside the preceding line of dialogue. The box has room for 3-4 choices, depending on the length of the preceding line.
If you want to use a different dialogue presenter to handle your options, you can turn off the 'Use Options' feature. When the feature is off the dialogue presenter won't handle options.
### Icons
You can show an icon in the dialogue box through the use of the `#icon:` hashtag.
To show an icon, place a sprite in a folder named `Resources`. The folder can be anywhere in your project. The name of the sprite can also be anything you like, but can't include spaces or any punctuation that isn't a hyphen `-` or underscore `_`.
When the sprite is in the folder, you can use it in the dialogue box. For example, the demo scene has a sprite called `IconStick`, and it's used in the script like this:
```
You now own this fantastic stick! This wasn't a great investment. #icon:ItemStick
```
### Appearance Animation
The dialogue box appears on screen with a scaling-up animation that slightly overshoots before settling back down to normal size. You can adjust the timing of this animation in the Inspector, or disable the animation entirely.
### Action Button
The Action Button is a user interface element that appears at the top of the screen that indicates what action will be performed when the player performs the Interact input action. The dialogue presenter shows several verbs in the action button, such as 'Next' or 'Decide'. You can adjust the text that's shown by modifying the labels in the Inspector.
The action button can be shared between different systems. In the demo scene, the action button is also used by the character controller to show verbs like "Speak" when the player approaches a character.
### Letterbox
When dialogue starts, two black bars slide in from the top and bottom of the screen. These are simple black `Image` components that are layered below the other UI elements, which create more of a cinematic look. You can adjust the timing of the letterbox by selecting the Letterbox object and adjusting its Time property.
### Skipping
The `RPGDialoguePresenter` listens for an action from the Unity Input System that notifies that the user wants to start skipping dialogue. In the sample scene, this is bound to the `UI/Cancel` action that comes with the Yarn Spinner samples, and players generally expect it to be the "B" button on the Xbox and Switch controllers, the Circle button on a PlayStation controller, and the Escape key on a keyboard.
When the action is performed, the presenter tells the typewriter effect to start displaying text faster, and to automatically advance to the next line when it reaches the end. Once skipping has started, it continues until any of the following:
- A line of dialogue with the hashtag `#end` is reached.
- A line of dialogue with the hashtag `#noskip` is reached.
- Choices are displayed.
### Hiding the Dialogue Box
The dialogue box will automatically close when dialogue is complete. You might also want to hide the dialogue box in the middle of your dialogue; for example, if you want to show a custscene. To hide the box, use the `<<hide_dialogue>>` command:
```
<<hide_dialogue>>
```
This will close the box with an animation.
### Background styles
You can customise the image that the dialogue box uses to display its content. Out of the box, the presenter has two styles: `normal` (a semitransparent black box with rounded corners and hard edges), and `blue` (a semitransparent blurred blue box with soft edges.)
To define your own custom styles, add them to the Background Styles list.
To change the box's style in your Yarn Spinner script, use the `<<set_dialogue_style>>` command:
```
<<set_dialogue_style blue>>
```
**Note:** Generally, you'll want to dismiss the dialogue box with `<<hide_dialogue>>` before changing the dialogue style. If you don't, the box will change its style immediately, which can look jarring.
### Camera control
The camera control seen in the sample scene isn't actually part of the dialogue presenter, but instead are Unity events fired when dialogue starts and ends. These events signal to a `DialogueCameraManager` script to enable or disable a Cinemachine camera that has higher priority, which causes the camera to transition to the closer 'over-the-shoulder' view.
### Speed and Pausing
The dialogue box displays its content with a typewriter effect, which reveals the text gradually. You can adjust the speed of this typewriter in the Inspector by changing the Default Characters Per Second value. If the skipping feature is enabled, you can also adjust the speed that the typewriter runs at while skipping content.
#### Adjusting Speed
You can also modify the speed of the dialogue in the middle of a line, using the `[speed]` markup. This allows you to define a range that customises the number of characters that are shown per second.
```
I'm speaking [speed=5]slowly...[/speed] [speed=200]And now I'm speaking quickly![/speed]
```
If you set the `speed` value to 0, the characters within the markers will appear all at once.
If the dialogue box is skipping content (see 'Skipping' above), then `speed` markers are ignored.
#### Pausing
You can add pauses in the middle of the typewriter, using `[pause]` markup. This marker instructs the typewriter to pause for a given number of milliseconds before continuing.
```
It's time for the dramatic reveal... [pause /] classic RPGs are back!
```
If the dialogue box is skipping content (see 'Skipping' above), then `pause` markers are ignored.
### Colours
The dialogue box uses a Palette Marker Processor to allow adjusting the colour of text using markup. This is a feature that ships with Yarn Spinner; in the prefab that ships with Classic RPG for Yarn Spinner, we define three colours: `c0`, `c1` and `c2`, which are red, green and blue respectively.
```
I'm [c0]speaking[/c0] [c1]in[/c1] [c2]technicolour[/c2]!
```
To use your own colours and markers, create a new Palette asset by opening the Assets menu and choosing Yarn Spinner -> Markup Palette. Add the entries you want, and then select the Markup Processors object in the Classic RPG Dialogue System. Drag the Palette you just created into the Palette Marker Processor's 'Palette' field.
## Getting Support
We hope you enjoy using Classic RPG for Yarn Spinner, and can't wait to see what you make with it.
If you need help with Classic RPG for Yarn Spinner, or have feedback, join the Yarn Spinner Discord, or email us at `[email protected]`.
Thanks! 💚
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: abda9b702eea145df8227d903458a3ce
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/README.md
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 96353fb7b698741ae8d662d7b7953a7c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f3488922bcbbb48778fabf8bbede54b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: b9a0d33381c334b93a5a7252a2b6cc49
AudioImporter:
externalObjects: {}
serializedVersion: 8
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Audio/ClassicRPG-Audio-Change
Option.wav
uploadId: 968678
@@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: be560f32d1c6b4fd69cac495263fd427
AudioImporter:
externalObjects: {}
serializedVersion: 8
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Audio/ClassicRPG-Audio-Conversation
Segment End.wav
uploadId: 968678
@@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: b2a203366b1c74d03af60c98549a2524
AudioImporter:
externalObjects: {}
serializedVersion: 8
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Audio/ClassicRPG-Audio-Item
Get.wav
uploadId: 968678
@@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: fa95001b88c014aa98b28ad456d0bdb4
AudioImporter:
externalObjects: {}
serializedVersion: 8
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Audio/ClassicRPG-Audio-Leave
Conversation Positive.wav
uploadId: 968678
@@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: 0707cfa92df6e48ecba1071780410fcf
AudioImporter:
externalObjects: {}
serializedVersion: 8
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Audio/ClassicRPG-Audio-Next
Line.wav
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 34ba6bdae693746d6a952c80119524ea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LibertinusSans-Regular Atlas Material Dropshadow
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
m_Parent: {fileID: 7936743580164180666, guid: 21cfbe7984e0545c693a79b6a1f0f96e, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- UNDERLAY_ON
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs: []
m_Ints: []
m_Floats:
- _LightAngle: 0.96
- _OutlineWidth: 0
- _ScaleRatioC: 0.609375
- _UnderlayDilate: 0.2
- _UnderlayOffsetX: 1
- _UnderlayOffsetY: -0.38
- _UnderlaySoftness: 0
m_Colors:
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.98039216}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: f8af0e8e7fccc44518859d73b28a56e9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/LibertinusSans-Regular
Atlas Material Dropshadow.mat
uploadId: 968678
@@ -0,0 +1,298 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04, type: 3}
m_Name: LibertinusSans-Regular SDF
m_EditorClassIdentifier:
m_Version: 1.1.0
m_FaceInfo:
m_FaceIndex: 0
m_FamilyName: Libertinus Sans
m_StyleName: Regular
m_PointSize: 90
m_Scale: 1.15
m_UnitsPerEM: 1000
m_LineHeight: 102.600006
m_AscentLine: 80.46001
m_CapLine: 60
m_MeanLine: 40
m_Baseline: 0
m_DescentLine: -22.140001
m_SuperscriptOffset: 80.46001
m_SuperscriptSize: 0.5
m_SubscriptOffset: -22.140001
m_SubscriptSize: 0.5
m_UnderlineOffset: -8.820001
m_UnderlineThickness: 3.6000001
m_StrikethroughOffset: 16
m_StrikethroughThickness: 3.6000001
m_TabWidth: 23
m_Material: {fileID: 7936743580164180666}
m_SourceFontFileGUID: e2a8cd33a602448e9be7cb72405c9dca
m_CreationSettings:
sourceFontFileName:
sourceFontFileGUID: e2a8cd33a602448e9be7cb72405c9dca
faceIndex: 0
pointSizeSamplingMode: 0
pointSize: 90
padding: 9
paddingMode: 2
packingMode: 0
atlasWidth: 1024
atlasHeight: 1024
characterSetSelectionMode: 7
characterSequence:
referencedFontAssetGUID:
referencedTextAssetGUID:
fontStyle: 0
fontStyleModifier: 0
renderMode: 4165
includeFontFeatures: 0
m_SourceFontFile: {fileID: 12800000, guid: e2a8cd33a602448e9be7cb72405c9dca, type: 3}
m_SourceFontFilePath:
m_AtlasPopulationMode: 1
InternalDynamicOS: 0
m_GlyphTable: []
m_CharacterTable: []
m_AtlasTextures:
- {fileID: 6365361794914578184}
m_AtlasTextureIndex: 0
m_IsMultiAtlasTexturesEnabled: 0
m_GetFontFeatures: 1
m_ClearDynamicDataOnBuild: 1
m_AtlasWidth: 1024
m_AtlasHeight: 1024
m_AtlasPadding: 9
m_AtlasRenderMode: 4165
m_UsedGlyphRects: []
m_FreeGlyphRects:
- m_X: 0
m_Y: 0
m_Width: 1023
m_Height: 1023
m_FontFeatureTable:
m_MultipleSubstitutionRecords: []
m_LigatureSubstitutionRecords: []
m_GlyphPairAdjustmentRecords: []
m_MarkToBaseAdjustmentRecords: []
m_MarkToMarkAdjustmentRecords: []
m_ShouldReimportFontFeatures: 0
m_FallbackFontAssetTable: []
m_FontWeightTable:
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
fontWeights: []
normalStyle: 0
normalSpacingOffset: 0
boldStyle: 0.75
boldSpacing: 7
italicStyle: 35
tabSize: 10
m_fontInfo:
Name:
PointSize: 0
Scale: 0
CharacterCount: 0
LineHeight: 0
Baseline: 0
Ascender: 0
CapHeight: 0
Descender: 0
CenterLine: 0
SuperscriptOffset: 0
SubscriptOffset: 0
SubSize: 0
Underline: 0
UnderlineThickness: 0
strikethrough: 0
strikethroughThickness: 0
TabWidth: 0
Padding: 0
AtlasWidth: 0
AtlasHeight: 0
m_glyphInfoList: []
m_KerningTable:
kerningPairs: []
fallbackFontAssets: []
atlas: {fileID: 0}
--- !u!28 &6365361794914578184
Texture2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LibertinusSans-Regular Atlas
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_IsAlphaChannelOptional: 0
serializedVersion: 4
m_Width: 1
m_Height: 1
m_CompleteImageSize: 1
m_MipsStripped: 0
m_TextureFormat: 1
m_MipCount: 1
m_IsReadable: 1
m_IsPreProcessed: 0
m_IgnoreMipmapLimit: 1
m_MipmapLimitGroupName:
m_StreamingMipmaps: 0
m_StreamingMipmapsPriority: 0
m_VTOnly: 0
m_AlphaIsTransparency: 0
m_ImageCount: 1
m_TextureDimension: 2
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_Aniso: 1
m_MipBias: 0
m_WrapU: 0
m_WrapV: 0
m_WrapW: 0
m_LightmapFormat: 0
m_ColorSpace: 0
m_PlatformBlob:
image data: 1
_typelessdata: 00
m_StreamData:
serializedVersion: 2
offset: 0
size: 0
path:
--- !u!21 &7936743580164180666
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LibertinusSans-Regular Atlas Material
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Cube:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 6365361794914578184}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OutlineTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Ambient: 0.5
- _Bevel: 0.5
- _BevelClamp: 0
- _BevelOffset: 0
- _BevelRoundness: 0
- _BevelWidth: 0
- _BumpFace: 0
- _BumpOutline: 0
- _ColorMask: 15
- _CullMode: 0
- _Diffuse: 0.5
- _FaceDilate: 0
- _FaceUVSpeedX: 0
- _FaceUVSpeedY: 0
- _GlowInner: 0.05
- _GlowOffset: 0
- _GlowOuter: 0.05
- _GlowPower: 0.75
- _GradientScale: 10
- _LightAngle: 3.1416
- _MaskSoftnessX: 0
- _MaskSoftnessY: 0
- _OutlineSoftness: 0
- _OutlineUVSpeedX: 0
- _OutlineUVSpeedY: 0
- _OutlineWidth: 0
- _PerspectiveFilter: 0.875
- _Reflectivity: 10
- _ScaleRatioA: 0.9
- _ScaleRatioB: 0.73125
- _ScaleRatioC: 0.73125
- _ScaleX: 1
- _ScaleY: 1
- _ShaderFlags: 0
- _Sharpness: 0
- _SpecularPower: 2
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _TextureHeight: 1024
- _TextureWidth: 1024
- _UnderlayDilate: 0
- _UnderlayOffsetX: 0
- _UnderlayOffsetY: 0
- _UnderlaySoftness: 0
- _VertexOffsetX: 0
- _VertexOffsetY: 0
- _WeightBold: 0.75
- _WeightNormal: 0
m_Colors:
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 21cfbe7984e0545c693a79b6a1f0f96e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/LibertinusSans-Regular
SDF.asset
uploadId: 968678
@@ -0,0 +1,28 @@
fileFormatVersion: 2
guid: e2a8cd33a602448e9be7cb72405c9dca
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Libertinus Sans
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/LibertinusSans-Regular.ttf
uploadId: 968678
@@ -0,0 +1,112 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: SofiaSansExtraCondensed-SemiBold SDF Outline
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- UNDERLAY_ON
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Cube:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: -8275012461116792138, guid: 28e1e05964a194109b732fed675bc4a2, type: 2}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OutlineTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Ambient: 0.5
- _Bevel: 0.5
- _BevelClamp: 0
- _BevelOffset: 0
- _BevelRoundness: 0
- _BevelWidth: 0
- _BumpFace: 0
- _BumpOutline: 0
- _ColorMask: 15
- _CullMode: 0
- _Diffuse: 0.5
- _FaceDilate: 0
- _FaceUVSpeedX: 0
- _FaceUVSpeedY: 0
- _GlowInner: 0.05
- _GlowOffset: 0
- _GlowOuter: 0.05
- _GlowPower: 0.75
- _GradientScale: 10
- _LightAngle: 3.1416
- _MaskSoftnessX: 0
- _MaskSoftnessY: 0
- _OutlineSoftness: 0
- _OutlineUVSpeedX: 0
- _OutlineUVSpeedY: 0
- _OutlineWidth: 0
- _PerspectiveFilter: 0.875
- _Reflectivity: 10
- _ScaleRatioA: 0.9
- _ScaleRatioB: 0.73125
- _ScaleRatioC: 0.73125
- _ScaleX: 1
- _ScaleY: 1
- _ShaderFlags: 0
- _Sharpness: 0
- _SpecularPower: 2
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _TextureHeight: 1024
- _TextureWidth: 1024
- _UnderlayDilate: 1
- _UnderlayOffsetX: 0
- _UnderlayOffsetY: 0
- _UnderlaySoftness: 0
- _VertexOffsetX: 0
- _VertexOffsetY: 0
- _WeightBold: 0.75
- _WeightNormal: 0
m_Colors:
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 55bb879b7ac234ab2bd874103cb3b52a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/SofiaSansExtraCondensed-SemiBold
SDF Outline.mat
uploadId: 968678
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 28e1e05964a194109b732fed675bc4a2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/SofiaSansExtraCondensed-SemiBold
SDF.asset
uploadId: 968678
@@ -0,0 +1,28 @@
fileFormatVersion: 2
guid: 88b8b20d6e1284c969e15273ba891b93
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Sofia Sans Extra Condensed
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Fonts/SofiaSansExtraCondensed-SemiBold.ttf
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 098c7418d7d0249ca850f6af5a226ead
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,147 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Dialogue Icon
m_Shader: {fileID: -6465566751694194690, guid: f04d42093ca83466595107b4363d0b8c, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AddPrecomputedVelocity: 0
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _ColorMask: 15
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _Speed: 4
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _Surface: 0
- _UIMaskSoftnessX: 1
- _UIMaskSoftnessY: 1
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _ClipRect: {r: 0, g: 0, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _Color_1: {r: 0, g: 0.5030503, b: 1, a: 1}
- _Color_2: {r: 0, g: 0.7624998, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &8009966419948271471
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 9
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: f232687f02eb4436e9177ec321d888c8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Materials/Dialogue
Icon.mat
uploadId: 968678
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f04d42093ca83466595107b4363d0b8c
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Materials/Dialogue
Icon.shadergraph
uploadId: 968678
@@ -0,0 +1,59 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Scaling Icon (Animated)
m_Shader: {fileID: -6465566751694194690, guid: 56c4877d126c14fc59b948f53b7fb612, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Animating: 1
- _ColorMask: 15
- _Max_Scale: 1
- _Min_Scale: 0.75
- _Pulse_Speed: 3
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UIMaskSoftnessX: 1
- _UIMaskSoftnessY: 1
m_Colors:
- _ClipRect: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 4ddc4db16ad6a4f33b99be909e7793c7
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Materials/Scaling
Icon (Animated).mat
uploadId: 968678
@@ -0,0 +1,59 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Scaling Icon (Static)
m_Shader: {fileID: -6465566751694194690, guid: 56c4877d126c14fc59b948f53b7fb612, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Animating: 0
- _ColorMask: 15
- _Max_Scale: 1
- _Min_Scale: 0.75
- _Pulse_Speed: 3
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UIMaskSoftnessX: 1
- _UIMaskSoftnessY: 1
m_Colors:
- _ClipRect: {r: 0, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: c9561a438cac94b9f8d9b856438dc961
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Materials/Scaling
Icon (Static).mat
uploadId: 968678
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 56c4877d126c14fc59b948f53b7fb612
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Materials/Scaling
Icon.shadergraph
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e02f618b2dc8046fa81c231dcfa9766a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 3a350826231a5419d92fbc84703cc1a6
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Prefabs/Classic
RPG Dialogue System.prefab
uploadId: 968678
@@ -0,0 +1,295 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1773499811321850923
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2445287858656384339}
- component: {fileID: 5745989806210194926}
m_Layer: 5
m_Name: Option Item
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2445287858656384339
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1773499811321850923}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4736999306907731500}
- {fileID: 3745273615133119404}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 60}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &5745989806210194926
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1773499811321850923}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 93457c7ebf9394933a7868386c75deb7, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 0}
selectionIcon: {fileID: 8164640917862098270}
text: {fileID: 366932403872973422}
--- !u!1 &4762081831463968500
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3745273615133119404}
- component: {fileID: 594566762356710227}
- component: {fileID: 366932403872973422}
m_Layer: 5
m_Name: Label
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3745273615133119404
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4762081831463968500}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2445287858656384339}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 50, y: 0}
m_SizeDelta: {x: -100, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &594566762356710227
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4762081831463968500}
m_CullTransparentMesh: 1
--- !u!114 &366932403872973422
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4762081831463968500}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Yes
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 21cfbe7984e0545c693a79b6a1f0f96e, type: 2}
m_sharedMaterial: {fileID: 7936743580164180666, guid: 21cfbe7984e0545c693a79b6a1f0f96e, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4283629406
m_fontColor: {r: 0.36862746, g: 1, b: 0.32156864, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 45
m_fontSizeBase: 45
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &8164640917862098270
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4736999306907731500}
- component: {fileID: 1821274857437675894}
- component: {fileID: 8928232148855712291}
m_Layer: 5
m_Name: Selected
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4736999306907731500
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8164640917862098270}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2445287858656384339}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 45.3581, y: 45.3581}
m_Pivot: {x: 1, y: 0.5}
--- !u!222 &1821274857437675894
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8164640917862098270}
m_CullTransparentMesh: 1
--- !u!114 &8928232148855712291
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8164640917862098270}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 2100000, guid: f232687f02eb4436e9177ec321d888c8, type: 2}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 5d373ff8842344b4e9f9428eda90056f, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 24ae04b2819e546e0a228821af970f99
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Prefabs/Option
Item.prefab
uploadId: 968678
@@ -0,0 +1,37 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 992e2b513670a4d089c2e58d4c48e8c8, type: 3}
m_Name: Palette
m_EditorClassIdentifier:
BasicMarkers:
- Marker: c0
CustomColor: 1
Color: {r: 1, g: 0.43529412, b: 0.32156864, a: 1}
Boldened: 0
Italicised: 0
Underlined: 0
Strikedthrough: 0
- Marker: c1
CustomColor: 1
Color: {r: 0.36862746, g: 1, b: 0.32156864, a: 1}
Boldened: 0
Italicised: 0
Underlined: 0
Strikedthrough: 0
- Marker: c2
CustomColor: 1
Color: {r: 0.3254902, g: 0.6745098, b: 1, a: 1}
Boldened: 0
Italicised: 0
Underlined: 0
Strikedthrough: 0
CustomMarkers: []
@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 576a9c9d446e3460687830008f7a0ed9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Prefabs/Palette.asset
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24f106bee07104c468da2a0cafbd6c0e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,110 @@
using UnityEngine;
using TMPro;
using Yarn.Unity.Attributes;
using System.Threading;
using UnityEngine.UI;
#nullable enable
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor.
namespace Yarn.Unity.Addons.ClassicRPG
{
/// <summary>
/// Manages the presentation and animation of a UI element on screen that
/// indicates to the player what will happen when the press the Interact
/// button.
/// </summary>
public class ActionButton : MonoBehaviour
{
/// <summary>
/// A TextMeshPro component that shows the text of the action button.
/// </summary>
[SerializeField, MustNotBeNull] TMP_Text label;
/// <summary>
/// The object to animate when the label changes.
/// </summary>
[SerializeField, MustNotBeNull] Transform pivot;
/// <summary>
/// The amount of time to take when animating the button.
/// </summary>
[SerializeField] float flipTime = 0.1f;
/// <summary>
/// A token source that we can use to cancel ongoing animations.
/// </summary>
CancellationTokenSource cancellationTokenSource = new();
public void Awake()
{
label.text = string.Empty;
}
public void SetText(string? newText)
{
// Cancel any ongoing animation and set up for a new one
cancellationTokenSource.Cancel();
cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken);
// Perform the animation
SetText(newText, cancellationTokenSource.Token);
}
private async void SetText(string? newText, CancellationToken cancellationToken)
{
newText ??= string.Empty;
if (label.text == newText)
{
// No text change needed; we don't need to animate
return;
}
try
{
// Flip away from the player
await Tween.Run(
0, 90, // Flip to 90 degrees
flipTime / 2, // Taking half of our animation time
Tween.EasingFunctions.Linear, // Move linearly
(a, b, t) =>
// Adjust rotation around X over time
pivot.eulerAngles = new Vector3(Mathf.Lerp(a, b, t), 0, 0),
cancellationToken
);
// Update the label
label.text = newText ?? string.Empty;
// Flip back towards the player
await Tween.Run(
-90, 0, // Now finish the flip, rotating back to the player
flipTime / 2,
Tween.EasingFunctions.Linear,
(a, b, t) =>
pivot.eulerAngles = new Vector3(Mathf.Lerp(a, b, t), 0, 0),
cancellationToken
);
}
catch (System.OperationCanceledException)
{
// no-op
}
}
}
#if UNITY_EDITOR
namespace Editor
{
using UnityEditor;
[CustomEditor(typeof(ActionButton))]
public class ActionButtonEditor : Yarn.Unity.Editor.YarnEditor { }
}
#endif
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fc1f787c44e814501a5fe05b3468f542
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/ActionButton.cs
uploadId: 968678
@@ -0,0 +1,106 @@
using System;
using System.Threading;
using UnityEngine;
using Yarn.Unity;
using Yarn.Unity.Attributes;
using Yarn.Unity.Samples;
#nullable enable
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor.
namespace Yarn.Unity.Addons.ClassicRPG
{
[ExecuteAlways]
public class Letterbox : MonoBehaviour
{
/// <summary>
/// The top letterbox image.
/// </summary>
[SerializeField, MustNotBeNull] RectTransform top;
/// <summary>
/// The bottom letterbox image.
/// </summary>
[SerializeField, MustNotBeNull] RectTransform bottom;
/// <summary>
/// The height of each of the letter box images when the letterbox
/// effect is active.
/// </summary>
[SerializeField] float size = 100f;
/// <summary>
/// The current percentage of the letterbox effect. 0 means fully
/// hidden, 1 means fully visible.
/// </summary>
[Range(0, 1f)]
[SerializeField] float factor;
/// <summary>
/// The time that the letterbox effect will take to appear.
/// </summary>
[Min(0)]
[SerializeField] float time = 0.25f;
CancellationTokenSource cancellationTokenSource = new();
public void Awake()
{
if (Application.isPlaying)
{
// Reset any factor that may have been set in the editor
UpdateAppearance(0);
}
}
void OnValidate()
{
if (Application.isEditor && Application.isPlaying == false)
{
// If we've changed our value in the editor and we aren't
// playing, immediately update the presentation style for
// preview purposes.
UpdateAppearance(factor);
}
}
public async YarnTask SetVisible(bool visible)
{
cancellationTokenSource.Cancel();
cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken);
float target = visible ? 1 : 0;
try
{
await Tween.Run(factor, target, time, Tween.EasingFunctions.Linear, (a, b, t) => UpdateAppearance(Mathf.Lerp(a, b, t)), cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
// Ignore cancellation - we'll just stop the animation immediately.
}
}
private void UpdateAppearance(float newFactor)
{
if (top == null || bottom == null) { return; }
top.sizeDelta = new Vector2(0, Mathf.Lerp(0, size, newFactor));
bottom.sizeDelta = new Vector2(0, Mathf.Lerp(0, size, newFactor));
factor = newFactor;
}
}
#if UNITY_EDITOR
namespace Editor
{
using UnityEditor;
[CustomEditor(typeof(Letterbox))]
public class LetterboxEditor : Yarn.Unity.Editor.YarnEditor { }
}
#endif
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2bde9f93bb3f74086a4556d28f44f10c
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/Letterbox.cs
uploadId: 968678
@@ -0,0 +1,46 @@
using UnityEngine;
using TMPro;
using Yarn.Unity.Attributes;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
#pragma warning disable CS8618
#nullable enable
namespace Yarn.Unity.Addons.ClassicRPG
{
public class OptionItem : Selectable, ISelectHandler, IDeselectHandler, ISubmitHandler
{
[SerializeField, MustNotBeNull] GameObject selectionIcon;
[SerializeField, MustNotBeNull] TMP_Text text;
public Action? onSubmit = null;
public Action? onSelected = null;
public bool Selected { get => selectionIcon.activeInHierarchy; set => selectionIcon.SetActive(value); }
public string Text { get => text.text; set => text.text = value; }
public TMP_Text TextView => text;
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
this.Selected = false;
}
public override void OnSelect(BaseEventData eventData)
{
base.OnSelect(eventData);
this.Selected = true;
onSelected?.Invoke();
}
public void OnSubmit(BaseEventData eventData)
{
onSubmit?.Invoke();
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 93457c7ebf9394933a7868386c75deb7
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/OptionItem.cs
uploadId: 968678
@@ -0,0 +1,837 @@
using UnityEngine;
using Yarn.Unity.Attributes;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using System.Collections.Generic;
#nullable enable
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor.
namespace Yarn.Unity.Addons.ClassicRPG
{
/// <summary>
/// A dialogue presenter that shows text in a classic console style.
/// </summary>
public class RPGDialoguePresenter : DialoguePresenterBase
{
#region Tags
/// <summary>
/// A hashtag that marks the line as the final one (and makes the 'next'
/// button appear as a square.)
/// </summary>
const string EndOfDialogueTag = "end";
/// <summary>
/// A hashtag prefix that marks the line has having an icon. The text
/// after the colon is used to find a sprite in the Resources folder.
/// </summary>
const string IconTag = "icon:";
/// <summary>
/// A hashtag that indicates that the next piece of content will be
/// options, and that the dialogue presenter should show the content in
/// the options view.
/// </summary>
const string NextLineIsOptionsTag = "lastline";
/// <summary>
/// A hashtag that indicates that the line should be centered in the
/// dialogue box.
/// </summary>
const string LineIsCenteredTag = "center";
/// <summary>
/// A hashtag that indicates that the line should not allow skipping,
/// and should interrupt any skipping that is already taking place.
/// </summary>
const string DontAllowSkippingContentTag = "noskip";
#endregion
#region Structure
/// <summary>
/// The canvas group containing the dialogue box.
/// </summary>
/// <remarks>This is used for fading the box in.</remarks>
[SerializeField, MustNotBeNull, ShowIf(nameof(useAppearanceAnimation))] CanvasGroup canvasGroup;
/// <summary>
/// The object that contains the dialogue box.
/// </summary>
/// <remarks>This is used for controlling the box's visibility, and for
/// animating its size.</remarks>
[SerializeField, MustNotBeNull] Transform container;
/// <summary>
/// The <see cref="Letterbox"/>, which is activated when dialogue begins
/// and deactivated when dialogue ends.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useLetterbox))] Letterbox letterbox;
#endregion
#region Input
[SerializeField, ShowIf(nameof(useSkipping))] UnityEngine.InputSystem.InputActionReference? skipAction;
#endregion
#region Style
[Header("Style")]
[SerializeField, MustNotBeNull, ShowIf(nameof(useBackgroundStyles))] Image backgroundImage;
[SerializeField, Indent, ShowIf(nameof(useBackgroundStyles))] SerializableDictionary<string, Sprite> backgroundStyles = new();
[SerializeField, Indent, ShowIf(nameof(useBackgroundStyles))] string defaultStyle = "normal";
#endregion
#region Timing
/// <summary>
/// The amount of time it takes for the dialogue box to appear.
/// </summary>
[Header("Timing")]
[SerializeField, ShowIf(nameof(useAppearanceAnimation))] float appearanceTime = 0.75f;
/// <summary>
/// The default rate of characters per second to display.
/// </summary>
/// <remarks>This may be modified by any <c>[speed]</c> tags in the
/// line.</remarks>
[SerializeField] float defaultCharactersPerSecond = 30f;
/// <summary>
/// The rate of characters to display when skipping.
/// </summary>
[SerializeField, ShowIf(nameof(useSkipping))] float skipCharactersPerSecond = 200f;
#endregion
#region Lines
/// <summary>
/// The object containing the UI components for showing lines.
/// </summary>
[Header("Lines")]
[SerializeField, MustNotBeNull] Transform lineComponents;
/// <summary>
/// The TextMeshPro object that displays the text of the line.
/// </summary>
[SerializeField, MustNotBeNull] TMPro.TMP_Text lineText;
/// <summary>
/// The <see cref="Image"/> that presents the line continuation sprite.
/// </summary>
[SerializeField, MustNotBeNull] Image lineCompleteImage;
/// <summary>
/// The sprite to show in <see cref="lineCompleteImage"/> when advancing
/// the dialogue will show more dialogue.
/// </summary>
[SerializeField, MustNotBeNull] Sprite continueSprite;
/// <summary>
/// The sprite to show in <see cref="lineCompleteImage"/> when advancing
/// the dialogue will close the dialogue.
/// </summary>
[SerializeField, MustNotBeNull] Sprite endDialogueSprite;
#endregion
#region Icons
/// <summary>
/// The object that contains the <see cref="iconImage"/>.
/// </summary>
[Header("Icon")]
[SerializeField, MustNotBeNull, ShowIf(nameof(useIcons))] Transform iconContainer;
/// <summary>
/// The <see cref="Image"/> that will be used to show any icon
/// associated with the line.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useIcons))] Image iconImage;
#endregion
#region Options
/// <summary>
/// The object containing the UI components for showing options, along
/// with lines that immediately precede options.
/// </summary>
[Header("Options")]
[SerializeField, MustNotBeNull, ShowIf(nameof(useOptions))] Transform optionComponents;
/// <summary>
/// The TextMeshPro component that shows lines immediately preceding
/// options.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useOptions))] TMPro.TMP_Text optionLineText;
/// <summary>
/// The object containing the list of available options.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useOptions))] Transform optionItemsContainer;
/// <summary>
/// The prefab to use for each option.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useOptions))] OptionItem itemPrefab;
#endregion Options
#region Action Button
[Header("Action Button")]
/// <summary>
/// The Action button, which indicates what will happen when the
/// 'interact' input action is performed.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useActionButton))] ActionButton actionButton;
/// <summary>
/// The text that should appear in the actions button when advancing the
/// dialogue will show more dialogue.
/// </summary>
[SerializeField, ShowIf(nameof(useActionButton))] string NextLineLabel = "Next";
/// <summary>
/// The text that should appear in the actions button when advancing the
/// dialogue will leave the dialogue.
/// </summary>
[SerializeField, ShowIf(nameof(useActionButton))] string LeaveConversationLabel = "Return";
/// <summary>
/// The text that should appear in the actions button when choosing
/// between options.
/// </summary>
[SerializeField, ShowIf(nameof(useActionButton))] string SelectOptionLabel = "Decide";
#endregion Action Button
#region Audio
/// <summary>
/// The <see cref="AudioSource"/> to use to play UI sounds with.
/// </summary>
[Header("Audio")]
[SerializeField, MustNotBeNull, ShowIf(nameof(useAudio))] AudioSource audioSource;
/// <summary>
/// The <see cref="AudioClip"/> to play when the player advances to the
/// next line.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useAudio))] AudioClip nextLineSound;
/// <summary>
/// The <see cref="AudioClip"/> to play when the player reaches the end
/// of the last line of the dialogue.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useAudio))] AudioClip endDialogueSound;
/// <summary>
/// The <see cref="AudioClip"/> to play when the player leaves the
/// dialogue.
/// </summary>
[SerializeField, MustNotBeNull, ShowIf(nameof(useAudio))] AudioClip leaveDialogueSound;
[SerializeField, MustNotBeNull, ShowIf(nameof(useAudio)), ShowIf(nameof(useOptions))] AudioClip changeOptionSelection;
#endregion Audio
#region Feature Flags
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useAudio;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useOptions;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useIcons;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useAppearanceAnimation;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useActionButton;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useLetterbox;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useSkipping;
[Group("Feature Flags"), SerializeField, ShowIf(nameof(ShowFeatureFlags))] bool useBackgroundStyles;
#endregion
public bool ShowFeatureFlags
{
get
{
#if UNITY_EDITOR
return Editor.DialogueViewEditorMenu.ShowFeatureFlags;
#else
return false;
#endif
}
}
#region Typewriter
private SpeedControllableLetterTypewriter typewriter = new();
public override IAsyncTypewriter? Typewriter => typewriter;
#endregion
private bool currentContentAllowsSkipping = true;
private bool typewriterIsSkipping = false;
private bool boxIsVisible = false;
protected void Awake()
{
// When we start up, do some initial setup
if (useAppearanceAnimation)
{
canvasGroup.alpha = 0f;
}
container.gameObject.SetActive(false);
boxIsVisible = false;
// Add a pause event processor to the typewriter so it knows how to
// handle the [pause] tag
typewriter.ActionMarkupHandlers.Add(new PauseEventProcessor());
// Set the initial characters per second from what we were
// configured with
typewriter.CharactersPerSecond = defaultCharactersPerSecond;
typewriter.SkipCharactersPerSecond = skipCharactersPerSecond;
}
#region Box Presentation
[YarnCommand("set_dialogue_style")]
public static void SetDialogueBoxStyle(string style)
{
foreach (var presenter in FindObjectsByType<RPGDialoguePresenter>(FindObjectsSortMode.None))
{
if (!presenter.useBackgroundStyles) { continue; }
if (presenter.backgroundStyles.TryGetValue(style, out var sprite))
{
presenter.backgroundImage.sprite = sprite;
}
else
{
Debug.LogError($"Can't set dialogue box style to '{style}': not a valid style name (must be {string.Join(" or ", presenter.backgroundStyles.Keys)})");
}
}
}
[YarnCommand("hide_dialogue")]
public static void HideDialogueBoxes()
{
foreach (var presenter in FindObjectsByType<RPGDialoguePresenter>(FindObjectsSortMode.None))
{
presenter.HideDialogueBox();
}
}
private async YarnTask ShowDialogueBox()
{
// Start showing our container, but hide the line and
// options inside it. We'll wait until we actually receive content
// to show before those appear.
container.gameObject.SetActive(true);
lineComponents.gameObject.SetActive(false);
if (useOptions)
{
optionComponents.gameObject.SetActive(false);
}
lineCompleteImage.gameObject.SetActive(false);
if (boxIsVisible)
{
// Early out if the box is already visible.
return;
}
boxIsVisible = true;
if (useAppearanceAnimation)
{
// Dialogue appears with a scaling 'pop' animation while fading in
var pop = Tween.Run(
Vector3.zero, // Start at zero
Vector3.one, // End at normal scale
appearanceTime, // Use our appearance time
Tween.EasingFunctions.OutBack, // Use an 'overshoot and return' easing function
(from, to, t) => container.localScale = Vector3.LerpUnclamped(from, to, t), // Affect scale
this.destroyCancellationToken // Cancel animation if this object is destroyed
);
var fade = Tween.Run(
0, // Start at zero
1, // End at full alpha
appearanceTime, // Use the same appearance time
Tween.EasingFunctions.Linear, // Use a linear easing funciton
(from, to, t) => canvasGroup.alpha = Mathf.Lerp(from, to, t), // Affect opacity
this.destroyCancellationToken // Cancel atnimation if this object is destroyed
);
// The animations are now started; wait for them to both finish
await pop;
await fade;
}
}
private void HideDialogueBox()
{
// Dialogue disppears in a single frame, so hide it immediately
container.gameObject.SetActive(false);
boxIsVisible = false;
// Stop any dialogue skipping in progress when we close the box.
typewriterIsSkipping = false;
}
#endregion
#region Dialogue Start and End
public override YarnTask OnDialogueStartedAsync()
{
if (useLetterbox)
{
// Start showing the letterbox. Don't show the dialogue box yet -
// we'll wait until we get dialogue content for that.
letterbox.SetVisible(true).Forget();
}
if (useBackgroundStyles)
{
// Always start dialogue in the normal style
if (backgroundStyles.TryGetValue(defaultStyle, out var sprite))
{
backgroundImage.sprite = sprite;
}
else
{
Debug.LogError($"Can't set background image to {defaultStyle}: no such style is defined");
}
}
// Stop any skipping that may have been happening earlier.
typewriterIsSkipping = false;
// Enable and configure the skip action, if it's present.
if (skipAction != null)
{
skipAction.action.Enable();
skipAction.action.performed += OnSkipActionPerformed;
}
// We're all done - return synchronously.
return YarnTask.CompletedTask;
}
public override YarnTask OnDialogueCompleteAsync()
{
HideDialogueBox();
if (useLetterbox)
{
// Dismiss the letterbox (it'll animate away, but we don't need to
// wait for that.)
letterbox.SetVisible(false).Forget();
}
// Disable the skip action, if it's present.
if (skipAction != null)
{
skipAction.action.Disable();
skipAction.action.performed -= OnSkipActionPerformed;
}
if (useActionButton && actionButton != null)
{
actionButton.SetText("");
}
// We're all done - return synchronously.
return YarnTask.CompletedTask;
}
#endregion
#region Line Presentation
public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token)
{
// Ensure that the dialogue box is visible
await ShowDialogueBox();
bool isOptions = false;
bool lineIsEnd = false;
Sprite? icon = null;
TMPro.HorizontalAlignmentOptions horizontalAlignment = TMPro.HorizontalAlignmentOptions.Left;
currentContentAllowsSkipping = useSkipping;
// Check for tags: is this the end of dialogue, a line before
// options, or a line with an icon?
foreach (var metadata in line.Metadata)
{
if (metadata == EndOfDialogueTag)
{
// This is a dialogue-ending line.
lineIsEnd = true;
}
else if (metadata == NextLineIsOptionsTag && useOptions)
{
// This is a line that appears right before options.
isOptions = true;
// Options interrupt text skipping, so stop it if that's
// happening.
currentContentAllowsSkipping = false;
}
else if (metadata == LineIsCenteredTag)
{
// This line is horizontally centered in the dialogue box.
horizontalAlignment = TMPro.HorizontalAlignmentOptions.Center;
}
else if (metadata == DontAllowSkippingContentTag)
{
currentContentAllowsSkipping = false;
}
else if (metadata.StartsWith(IconTag) && useIcons)
{
// The line has an icon. Try to find a sprite with a
// matching name.
var spriteName = metadata[IconTag.Length..];
icon = Resources.Load<Sprite>(spriteName);
if (icon == null)
{
Debug.LogWarning($"Failed to find icon " + spriteName);
}
}
}
// Cancel skipping if the line doesn't allow it.
typewriterIsSkipping &= currentContentAllowsSkipping && useSkipping;
// Give a warning if we've got redundant tags
if (lineIsEnd && isOptions)
{
Debug.LogWarning($"Lines should not have both #{EndOfDialogueTag} and #{NextLineIsOptionsTag} tags");
}
// If this is a set of options, clean up the last set
if (isOptions)
{
foreach (Transform item in optionItemsContainer)
{
Destroy(item.gameObject);
}
}
// Show either the line components or the option components
lineComponents.gameObject.SetActive(!isOptions);
if (useOptions)
{
optionComponents.gameObject.SetActive(isOptions);
}
// Hide the line complete image - we're just at the start of the
// line (or if it's options, we don't need to show it at all)
lineCompleteImage.gameObject.SetActive(false);
// Get the text from our line
var text = line.TextWithoutCharacterName.Text;
// Select which text view we're using and give it the text
var targetLineText = isOptions ? optionLineText : lineText;
targetLineText.text = text;
targetLineText.horizontalAlignment = horizontalAlignment;
if (useIcons)
{
// Update our icon view as necessary
iconContainer.gameObject.SetActive(icon != null);
iconImage.sprite = icon;
}
// Select which sprite to use when showing the line
lineCompleteImage.sprite = lineIsEnd ? endDialogueSprite : continueSprite;
// Get ready to show our content
typewriter.TextElement = targetLineText;
typewriter.PrepareForContent(line.TextWithoutCharacterName);
if (useActionButton)
{
// Show 'Next' in the action button while the line plays out
actionButton.SetText(NextLineLabel);
}
// Tell the typewriter to skip, if we're already skipping.
typewriter.SetSkippingContent(typewriterIsSkipping);
// Run the line!
await typewriter.RunTypewriter(line.TextWithoutCharacterName, token.HurryUpToken);
if (!isOptions)
{
if (!typewriterIsSkipping || lineIsEnd)
{
// We're not showing options. Show the continuation icon if
// we're not skipping, or this is an end line.
lineCompleteImage.gameObject.SetActive(true);
}
if (lineIsEnd)
{
// We're at the end of the dialogue, so show 'Return' in the
// action button and play the 'end of dialogue' sound.
if (useActionButton)
{
actionButton.SetText(LeaveConversationLabel);
}
if (useAudio)
{
audioSource.PlayOneShot(endDialogueSound);
}
// If we reach the end of the dialogue, we're also done skipping.
typewriterIsSkipping = false;
}
if (!typewriterIsSkipping)
{
// If we're not skipping, wait until the line has been
// dismissed.
await YarnTask.WaitUntilCanceled(token.NextContentToken);
}
// Signal to our typewriter that we're about to get rid of the
// line.
typewriter.ContentWillDismiss();
if (useAudio)
{
// Play an appropriate sound for advancing the dialogue.
if (lineIsEnd)
{
// We're leaving dialogue, so play the 'leaving dialogue' sound.
audioSource.PlayOneShot(leaveDialogueSound);
}
else if (!typewriterIsSkipping)
{
// We're advancing to the next line (and not skipping), so
// play the 'next line' sound.
audioSource.PlayOneShot(nextLineSound);
}
}
// Tidy up by dismissing our line components.
lineCompleteImage.gameObject.SetActive(false);
lineComponents.gameObject.SetActive(false);
}
else
{
// We're done showing the line that precedes options; leave it
// on screen. Wait one frame to prevent any hurry-up input
// actions from accidentally selecting content, and then report
// that we're done so that options appear next. Don't notify the
// typewriter that we're going to dismiss its content -
// RunOptionsAsync will do that when an option is selected.
await YarnTask.Yield();
}
}
#endregion
#region Option Presentation
public override async YarnTask<DialogueOption?> RunOptionsAsync(DialogueOption[] dialogueOptions, LineCancellationToken cancellationToken)
{
if (useOptions == false)
{
return null;
}
// We're showing options. These will appear alongside the previous
// line that ran before the options.
// Get rid of the line complete icon - it doesn't appear when we're
// showing options
lineCompleteImage.gameObject.SetActive(false);
// Show the option components
optionComponents.gameObject.SetActive(true);
// Get rid of any option items from the last time we did this
foreach (Transform item in optionItemsContainer)
{
Destroy(item.gameObject);
}
// Create a completion source we can use to be notified that a
// choice was made
YarnTaskCompletionSource<DialogueOption> completion = new();
// Start making our list of option items that will appear on screen
int optionsAdded = 0;
var optionsAndLines = new List<(Markup.MarkupParseResult lineText, OptionItem optionItem)>();
for (int i = 0; i < dialogueOptions.Length; i++)
{
// Get the option
DialogueOption? option = dialogueOptions[i];
if (option.IsAvailable == false)
{
// Don't show this option - it's unavailable
continue;
}
// Create the option item
var item = Instantiate(itemPrefab, optionItemsContainer);
item.Text = option.Line.TextWithoutCharacterName.Text;
item.Selected = false;
// If this is the first visible option, select it
if (optionsAdded == 0)
{
EventSystem.current.SetSelectedGameObject(item.gameObject);
}
// When the item is selected, set the result of our completion
// source. This will signal that the choice has been made, and
// we can continue.
item.onSubmit = () => completion.TrySetResult(option);
if (useAudio)
{
// When the item is selected, play the 'selection changed'
// sound
item.onSelected = () => audioSource.PlayOneShot(changeOptionSelection);
}
optionsAndLines.Add((option.Line.TextWithoutCharacterName, item));
item.Text = option.Line.TextWithoutCharacterName.Text;
if (!typewriterIsSkipping)
{
// If we're not skipping, set up each of the text views with
// the option item content, but hide it. (We do this so that
// the text is laid out correctly.)
item.TextView.maxVisibleCharacters = 0;
}
else
{
// If we are skipping, then ensure that all of the text is
// immediately visible.
item.TextView.maxVisibleCharacters = int.MaxValue;
}
optionsAdded += 1;
}
// If we're not skipping, reveal each of the options, one at a
// time. (If we are skipping, the text is already visible.)
if (!typewriterIsSkipping)
{
foreach (var (line, item) in optionsAndLines)
{
typewriter.TextElement = item.TextView;
typewriter.SetSkippingContent(this.typewriterIsSkipping);
typewriter.PrepareForContent(line);
await typewriter.RunTypewriter(line, cancellationToken.HurryUpToken);
typewriter.ContentWillDismiss();
}
}
if (useActionButton)
{
// Show the 'Decide' label in the action button
actionButton.SetText(SelectOptionLabel);
}
// Cancel any skipping that might be running, because we need user
// input to continue.
typewriterIsSkipping = false;
currentContentAllowsSkipping = false;
// Wait until a choice has been made. We'll get back the option that
// was chosen.
var selection = await completion.Task;
// The typewriter for the previous line will have displayed all of
// the content, and left it in a 'all done, ready to be dismissed'
// state. Notify that we're dismissing its contents now.
typewriter.ContentWillDismiss();
// We're no longer selecting anything
EventSystem.current.SetSelectedGameObject(null);
// Tidy up after ourselves by deleting the option items
foreach (Transform item in optionItemsContainer)
{
Destroy(item.gameObject);
}
if (useAudio)
{
// We're moving on to the next line, so play the next line sound
audioSource.PlayOneShot(nextLineSound);
}
// Hide the option components
optionComponents.gameObject.SetActive(false);
// Finally, return our selection back to the dialogue system
return selection;
}
#endregion
#region Line Skipping
private void OnSkipActionPerformed(InputAction.CallbackContext context)
{
// If our current content allows us to start skipping, set the flag
// and notify the typewriter.
if (currentContentAllowsSkipping)
{
typewriterIsSkipping = true;
typewriter.SetSkippingContent(true);
}
}
#endregion
}
#if UNITY_EDITOR
namespace Editor
{
using UnityEditor;
[CustomEditor(typeof(RPGDialoguePresenter))]
public class DialogueViewEditor : Yarn.Unity.Editor.YarnEditor { }
public readonly struct SessionBool
{
private readonly string Key;
public readonly bool DefaultValue;
public SessionBool(string key, bool defaultValue = false)
{
Key = key;
DefaultValue = defaultValue;
}
public static implicit operator bool(SessionBool sessionBool)
{
return sessionBool.Value;
}
public readonly bool Value
{
get => SessionState.GetBool(Key, DefaultValue);
set => SessionState.SetBool(Key, value);
}
}
public static class DialogueViewEditorMenu
{
const string MenuFeatureFlags = "Window/Yarn Spinner/Classic RPG/Show Feature Flags";
const string EditorStateFeatureFlags = "showFeatureFlags";
internal static SessionBool ShowFeatureFlags = new(EditorStateFeatureFlags, true);
// Add a menu item that you can click to add a check to the "MenuTest" menu item in MyMenu in the main menu.
[MenuItem(MenuFeatureFlags)]
static void ToggleFeatureFlags()
{
ShowFeatureFlags.Value = !ShowFeatureFlags.Value;
Menu.SetChecked(MenuFeatureFlags, ShowFeatureFlags);
}
}
}
#endif
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c1408e1ce69e8401280cd9cad77ff96d
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/RPGDialoguePresenter.cs
uploadId: 968678
@@ -0,0 +1,256 @@
#nullable enable
namespace Yarn.Unity.Addons.ClassicRPG
{
using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using TMPro;
using Yarn.Markup;
/// <summary>
/// An implementation of <see cref="IAsyncTypewriter"/> that delivers
/// characters one at a time, invokes any <see
/// cref="IActionMarkupHandler"/>s along the way as needed, and dynamically
/// adjusts its characters-per-second based on the presence of
/// <c>[speed]</c> tags in the line.
/// </summary>
public class SpeedControllableLetterTypewriter : IAsyncTypewriter
{
/// <summary>
/// The <see cref="TMP_Text"/> to display the text in.
/// </summary>
public TMP_Text? TextElement { get; set; }
/// <summary>
/// A collection of <see cref="IActionMarkupHandler"/> objects that
/// should be invoked as needed during the typewriter's delivery in <see
/// cref="RunTypewriter"/>, depending upon the contents of a line.
/// </summary>
public List<IActionMarkupHandler> ActionMarkupHandlers { get; set; } = new();
/// <summary>
/// The default number of characters per second to deliver.
/// </summary>
/// <remarks><para>If this value is zero, all characters are delivered
/// at once, subject to any delays added by the markup handlers in <see
/// cref="ActionMarkupHandlers"/>.</para><para>This value may be
/// modified in the middle of a line by the <c>[speed]</c>
/// tag.</para></remarks>
public float CharactersPerSecond { get; set; } = 0f;
public float SkipCharactersPerSecond { get; set; } = 0f;
const string SpeedTag = "speed";
private List<SpeedRange> speedRanges = new();
private bool isSkippingContent = false;
private struct SpeedRange
{
public float CharactersPerSecond;
public int Start;
public int Length;
public SpeedRange(int start, int length, float charactersPerSecond)
{
Start = start;
Length = length;
CharactersPerSecond = charactersPerSecond;
}
}
private double GetCurrentSecondsPerCharacter()
{
double baselineSecondsPerCharacter = 0;
double targetCharactersPerSecond = isSkippingContent ? SkipCharactersPerSecond : CharactersPerSecond;
if (targetCharactersPerSecond > 0)
{
baselineSecondsPerCharacter = 1.0 / targetCharactersPerSecond;
}
return baselineSecondsPerCharacter;
}
/// <inheritdoc/>
public async YarnTask RunTypewriter(Markup.MarkupParseResult line, CancellationToken cancellationToken)
{
if (TextElement == null)
{
Debug.LogWarning($"Can't show text as typewriter, because {nameof(TextElement)} was not provided");
}
else
{
TextElement.maxVisibleCharacters = 0;
TextElement.text = line.Text;
// Let every markup handler know that display is about to begin
foreach (var markupHandler in ActionMarkupHandlers)
{
markupHandler.OnLineDisplayBegin(line, TextElement);
}
// Get the count of visible characters from TextMesh to exclude markup characters
var visibleCharacterCount = TextElement.GetTextInfo(line.Text).characterCount;
// Start with a full time budget so that we immediately show the first character
double accumulatedDelay = GetCurrentSecondsPerCharacter();
// Go through each character of the line and let the
// processors know about it
for (int i = 0; i < visibleCharacterCount; i++)
{
var thisCharacterDuration = GetCurrentSecondsPerCharacter();
// Are we in a speed range? Update our secondsPerCharacter if so, but only if we're not skipping.
if (!isSkippingContent)
{
foreach (var speedRange in this.speedRanges)
{
if (i >= speedRange.Start && i <= speedRange.Start + speedRange.Length)
{
// We're in a speed range.
if (speedRange.CharactersPerSecond > 0)
{
thisCharacterDuration = 1.0f / speedRange.CharactersPerSecond;
}
else
{
thisCharacterDuration = 0;
}
break;
}
}
}
// If we don't already have enough accumulated time budget
// for a character, wait until we do (or until we're
// cancelled)
while (!cancellationToken.IsCancellationRequested
&& (accumulatedDelay < thisCharacterDuration))
{
var timeBeforeYield = Time.timeAsDouble;
await YarnTask.Yield();
var timeAfterYield = Time.timeAsDouble;
accumulatedDelay += timeAfterYield - timeBeforeYield;
}
// Tell every markup handler that it is time to process the
// current character. If we're skipping, pass them an
// already cancelled token, so that they complete quickly.
var actionMarkupCancellation = isSkippingContent ? new CancellationToken(true) : cancellationToken;
foreach (var processor in ActionMarkupHandlers)
{
await processor
.OnCharacterWillAppear(i, line, actionMarkupCancellation)
.SuppressCancellationThrow();
}
TextElement.maxVisibleCharacters += 1;
accumulatedDelay -= thisCharacterDuration;
}
// We've finished showing every character (or we were
// cancelled); ensure that everything is now visible.
TextElement.maxVisibleCharacters = visibleCharacterCount;
}
// Let each markup handler know the line has finished displaying
foreach (var markupHandler in ActionMarkupHandlers)
{
markupHandler.OnLineDisplayComplete();
}
}
public void PrepareForContent(Markup.MarkupParseResult line)
{
if (TextElement == null)
{
return;
}
TextElement.maxVisibleCharacters = 0;
TextElement.text = line.Text;
isSkippingContent = false;
foreach (var processor in ActionMarkupHandlers)
{
processor.OnPrepareForLine(line, TextElement);
}
speedRanges.Clear();
// grabbing out any pauses and speed ranges inside the line
foreach (var attribute in line.Attributes)
{
if (attribute.Name == SpeedTag)
{
float charactersPerSecond;
if (attribute.Properties.TryGetValue(SpeedTag, out MarkupValue value))
{
// depending on the property value we need to take a different path this is because they have made it an integer or a float which are roughly the same.
// But they also might have done something weird and we need to handle that
switch (value.Type)
{
case MarkupValueType.Integer:
charactersPerSecond = value.IntegerValue;
break;
case MarkupValueType.Float:
charactersPerSecond = value.FloatValue;
break;
default:
Debug.LogWarning($"{SpeedTag} property in line \"{line.Text}\" is of type {value.Type}, which is not allowed. Defaulting to all-at-once.");
charactersPerSecond = 0;
break;
}
}
else
{
// No characters per second provided; default to 'all at once'.
charactersPerSecond = 0;
}
speedRanges.Add(new SpeedRange(attribute.Position, attribute.Length, charactersPerSecond));
}
}
}
public void ContentWillDismiss()
{
// we tell all action processors that the line is finished and is about to go away
foreach (var processor in ActionMarkupHandlers)
{
processor.OnLineWillDismiss();
}
}
/// <summary>
/// Sets whether the typewriter is in 'skipping' mode, in which it
/// displays its content quickly, makes action markup complete more
/// quickly, and ignores speed tags.
/// </summary>
/// <param name="typewriterIsSkipping">Whether the typewriter is in
/// skipping mode.</param>
/// <remarks>This flag is reset to <see langword="false"/> when <see
/// cref="PrepareForContent(MarkupParseResult)"/> is called.</remarks>
internal void SetSkippingContent(bool typewriterIsSkipping)
{
isSkippingContent = typewriterIsSkipping;
}
public void ContentDidDismiss()
{
if (TextElement != null)
{
TextElement.maxVisibleCharacters = 0;
}
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f0712a45a70b64856945f8e83c00ce8f
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/SpeedControllableLetterTypewriter.cs
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6931cd7ba3dcc461d948de1b09b16709
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,101 @@
using UnityEngine;
using System.Threading;
public static class Tween
{
public delegate void TweenAction<T>(T from, T to, float factor);
public static class EasingFunctions
{
public static float InOutQuad(float t)
{
return t < 0.5 ? 2 * t * t : 1 - Mathf.Pow(-2 * t + 2, 2) / 2;
}
public static float Linear(float t)
{
return t;
}
public static float InBack(float t)
{
var c1 = 1.70158f;
var c3 = c1 + 1;
return c3 * t * t * t - c1 * t * t;
}
public static float OutBack(float t)
{
var c1 = 1.70158f;
var c3 = c1 + 1;
return 1 + c3 * Mathf.Pow(t - 1, 3) + c1 * Mathf.Pow(t - 1, 2);
}
}
public delegate float EasingFunction(float x);
public static Yarn.Unity.YarnTask Run<T>(T from, T to, float time, TweenAction<T> action, CancellationToken cancellationToken = default)
{
return Run(from, to, time, EasingFunctions.Linear, action, cancellationToken);
}
public static Yarn.Unity.YarnTask Run<T>(T from, T to, float time, EasingFunction easing, TweenAction<T> action, CancellationToken cancellationToken = default)
{
return Run(from, to, time, easing, action, 0, cancellationToken);
}
public static async Yarn.Unity.YarnTask Run<T>(T from, T to, float time, EasingFunction easing, TweenAction<T> action, float delay = 0, CancellationToken cancellationToken = default)
{
if (time <= 0 || Application.isPlaying == false)
{
// Synchronously jump to the end of the tween if time is zero, or if we're not in play mode
action(from, to, 1);
return;
}
action(from, to, 0);
if (delay > 0)
{
await Yarn.Unity.YarnTask.Delay(System.TimeSpan.FromSeconds(delay));
}
float timeElapsed = 0;
#if UNITY_EDITOR
// Tweens kicked off by in-editor interactions might have a
// larger-than-normal delta time, so delay a few frames before starting
// to measure it
var startFrame = Time.frameCount;
await Yarn.Unity.YarnTask.WaitUntil(() => Time.frameCount >= startFrame + 10);
#endif
var lastTime = Time.time;
while (timeElapsed < time && cancellationToken.IsCancellationRequested == false)
{
var deltaTime = Time.time - lastTime;
timeElapsed += deltaTime;
lastTime = Time.time;
var factor = Mathf.Clamp01(timeElapsed / time);
factor = easing(factor);
action(from, to, factor);
await Yarn.Unity.YarnTask.Yield();
}
action(from, to, 1);
}
public static Color LerpColorAlpha(Color color, float alphaFrom, float alphaTo, float t)
{
var c = color;
c.a = Mathf.Lerp(alphaFrom, alphaTo, t);
return c;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9c5e0a8005e1446fca7c528c1c6df418
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Scripts/Tweening/Tweening.cs
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f707ddc61e7304705833b62283bead5c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 3e5ef60f36bb64db091355393653ac65
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/ActionButton.png
uploadId: 968678
@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 218d13bfb40024029911e9abab7ee45a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/DialogueBox-Background-Black.png
uploadId: 968678
@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 0e5f00fac583b49a9a3bad3c19583e2a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/DialogueBox-Background-Blue.png
uploadId: 968678
Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B

@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 1fa8466b42bd748f9b138aec6fe00614
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/Icon-EndDialogue.png
uploadId: 968678
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 3d864d365a0c0431ca863a7018424a53
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 1
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/Icon-HealthHeart.png
uploadId: 968678
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 602280965322b4cc898e206d3c25359a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/Icon-NextLine.png
uploadId: 968678
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 5d373ff8842344b4e9f9428eda90056f
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/Sprites/Icon-OptionSelection.png
uploadId: 968678
@@ -0,0 +1,33 @@
{
"name": "YarnSpinner.Addons.ClassicRPG",
"rootNamespace": "",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:34aa492b82754644eac2f903cd496268",
"GUID:3a299c53e4c683b4eb4a04c9ad9e648f",
"UniTask",
"GUID:4307f53044263cf4b835bd812fc161a4",
"GUID:c21a60a15edb64663af9bd55f8834863"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "1.0.0",
"define": "USE_INPUTSYSTEM"
},
{
"name": "com.unity.ugui",
"expression": "2",
"define": "USE_TMP"
}
],
"noEngineReferences": false
}
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 91ccb70abcc5e4fa5b1dcaa9855635c5
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Runtime/YarnSpinner.Addons.ClassicRPG.asmdef
uploadId: 968678
@@ -0,0 +1,85 @@
Classic RPG for Yarn Spinner makes use of the following third-party material, the use of which is gratefully acknowledged:
Libertinus Sans
Copyright 2025 The Libertinus Sans Project Authors (https://github.com/googlefonts/libertinus)
This Font Software is licensed under the SIL Open Font License, Version 1.1 . This license is copied below, and is also available with a FAQ at: https://openfontlicense.org
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
---
Sofia Sans Extra Condensed
Copyright 2019 The Sofia Sans Project Authors (https://github.com/lettersoup/Sofia-Sans)
This Font Software is licensed under the SIL Open Font License, Version 1.1 . This license is copied below, and is also available with a FAQ at: https://openfontlicense.org
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: c06d3522a63bb42b1add337eb227609c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/Third-Party Notices.txt
uploadId: 968678
@@ -0,0 +1,29 @@
{
"name": "dev.yarnspinner.unity.addons.classicrpg",
"version": "3.2.0",
"displayName": "Classic RPG for Yarn Spinner",
"description": "A classic RPG dialogue presenter for Yarn Spinner for Unity.",
"unity": "6000.0",
"dependencies": {
"dev.yarnspinner.unity": "3.2.0",
"com.unity.cinemachine": "3.1.7",
"com.unity.inputsystem": "1.19.0"
},
"keywords": [
"Dialogue",
"Yarn"
],
"author": {
"name": "Yarn Spinner Pty Ltd",
"url": "https://yarnspinner.dev"
},
"hideInEditor": false,
"type": "tool",
"samples": [
{
"displayName": "Classic RPG",
"description": "Demonstrates using the Classic RPG dialogue presenter. NOTE: You must install the free Yarn Spinner Samples package before installing this sample!",
"path": "Samples~/ClassicRPG"
}
]
}
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 16baa42b05a6d4fd79e02d76ade41795
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.classicrpg/package.json
uploadId: 968678
@@ -0,0 +1,8 @@
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
## [1.0.0] - 2026-05-20
This is the first release of Snaaake for Yarn Spinner.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: e2970021f5a4e4e94ba93a3b5be801c6
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/CHANGELOG.md
uploadId: 968678
@@ -0,0 +1 @@
Snaaake for Yarn Spinner is distributed under the terms of the Unity Asset Store Terms of Service and End User License Agreement, which is available here: https://unity.com/legal/as-terms.
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 6029371209fbfb4e2bcdd4642c53c2e9
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/LICENSE.md
uploadId: 968678
@@ -0,0 +1,71 @@
# Snaaake for Yarn Spinner
**Snaaake** is a dialogue presenter for Yarn spinner that pays homage to the dialogue in classic action games. It shows two characters in a 'radio' view, with retro effect. As characters speak their voice-over lines, the characters play a talking animation, and a subtitle view shows the corresponding text. An animated 'signal level' graphic appears between them during the conversation.
## Try it out!
Test out the Snaaake presenter by installing the sample:
1. Open the Package Manager by choosing Window -> Packages -> Package Manager.
2. Select the 'Snaaake for Yarn Spinner' package.
3. Select the 'Samples' tab.
4. Install the 'Snaaake' sample. The sample will be copied into your project's Assets folder.
5. Open the 'Snaaake' scene that was copied over, and hit Play.
## How To Use Snaaake
To use Snaaake in your game's dialogue, follow these steps.
- In the Project tab, find the 'Snaaake for Yarn Spinner' package, and navigate to 'Runtime/Prefabs'.
- Drag the 'Snaaake Dialogue System' prefab into your scene.
- Add your Yarn Project to the dialogue system, turn on Start Automatically, and choose a node.
- Hit play, and enjoy your dialogue!
## Structure
The Snaaake dialogue presenter is composed of several components.
### Talking Head Character
A `TalkingHeadCharacter` is a ScriptableObject that contains a number of sprites. The first sprite will be used as the 'idle' frame, and the rest will be used while talking.
### Talking Head Character View
A `TalkingHeadCharacterView` presents sprites from a `TalkingHeadCharacter`, and can be signalled whether the speaking animation should be playing or not.
### Talking Head Dialogue Presenter
The `TalkingHeadDialoguePresenter` manages a collection of named `TalkingHeadCharacterView`s, a collection of available `TalkingHead and keeps track of which character is being presented in which view, and which character is speaking the current line. It also monitors an AudioSource's volume levels; when the level is over a threshold, the view that's showing the currently speaking character is signalled to show a speaking animation.
### Subtitle Dialogue Presenter
The `SubtitleDialoguePresenter` is a simple presenter that shows the text of the current line in a TextMeshPro text view.
### VO Dialogue Presenter
The Snaaake dialogue presenter includes a Yarn Spinner `VoiceOverDialoguePresenter` that plays the audio associated with the line. (This component is built-in to Yarn Spinner, and is made use of by this custom presenter.)
## Defining Characters
To define a character, create a new `TalkingHeadCharacter` object by opening Assets menu and choosing Create -> Yarn Spinner -> Snaaake -> Talking Head Character. Name it whatever you like, and add the sprites you want to use.
**Note:** The sprites you use can be any resolution, but they _must_ be square in order for the pixellation effect to work correctly.
Next, select the Snaaake Dialogue Presenter, find the Talking Heads Dialogue Presenter component, and click the `+` button next to the Characters list. Set the name of the character to the value you use to refer to them in your Yarn Spinner script, and set the value to the `TalkingHeadCharacter` asset you just created.
## Using Characters in Dialogue
To make a character appear in a slot, use the `set_slot` command in your scripts. The prefab that comes with Snaaake has two slots: left, and right. You can define your own slots, or add more slots, by modifying the Character Slots list in the Talking Heads Dialogue Presenter.
```
// Put the TalkingHeadsCharacter named 'Player' in the 'left' slot.
<<set_slot Player left>>
```
You can change which character is in which slot at any time. Make sure to assign characters to slots before any of their lines play, or the system won't know where to show them.
## Notes
- Snaaake expects all lines to have an audio file. When the audio for a line finishes, the next line will play. If a line doesn't have audio, it will be skipped.
- You can adjust the style of the retro effect by creating a custom material that uses the retro shader. Simply create a new Material, set its shader to 'Yarn Spinner/Snaaake Retro', and assign it to the Material of the Image on the Character. You can adjust the tint colour, pixellation, dither amount, posterisation, and more.
- To make post-processing effects like Bloom work, you'll need to assign your camera to the canvas. To do this, open the 'Snaaake Dialogue System' prefab in your scene, and find the 'Snaaake Dialogue Presenter -> Canvas' object. Drag your scene's main camera into the Camera slot. (Make sure that your Camera has post-processing enabled!)
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: b9c4d68fadde64c8b8e4d25d3f632b39
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/README.md
uploadId: 968678
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 54136020f2c1c4f19b2b00d75c610fb8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 43b62b79447494c4086e887ddcbd5da5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,298 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!28 &-6305474512521559428
Texture2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: DSEG7Classic-Bold Atlas
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_IsAlphaChannelOptional: 0
serializedVersion: 4
m_Width: 1
m_Height: 1
m_CompleteImageSize: 1
m_MipsStripped: 0
m_TextureFormat: 1
m_MipCount: 1
m_IsReadable: 1
m_IsPreProcessed: 0
m_IgnoreMipmapLimit: 1
m_MipmapLimitGroupName:
m_StreamingMipmaps: 0
m_StreamingMipmapsPriority: 0
m_VTOnly: 0
m_AlphaIsTransparency: 0
m_ImageCount: 1
m_TextureDimension: 2
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_Aniso: 1
m_MipBias: 0
m_WrapU: 0
m_WrapV: 0
m_WrapW: 0
m_LightmapFormat: 0
m_ColorSpace: 0
m_PlatformBlob:
image data: 1
_typelessdata: 00
m_StreamData:
serializedVersion: 2
offset: 0
size: 0
path:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04, type: 3}
m_Name: DSEG7Classic-Bold SDF
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TMP_FontAsset
m_Version: 1.1.0
m_FaceInfo:
m_FaceIndex: 0
m_FamilyName: DSEG7 Classic
m_StyleName: Bold
m_PointSize: 90
m_Scale: 1
m_UnitsPerEM: 1000
m_LineHeight: 98.100006
m_AscentLine: 90
m_CapLine: 86
m_MeanLine: 86
m_Baseline: 0
m_DescentLine: 0
m_SuperscriptOffset: 90
m_SuperscriptSize: 0.5
m_SubscriptOffset: 0
m_SubscriptSize: 0.5
m_UnderlineOffset: -13.500001
m_UnderlineThickness: 4.5
m_StrikethroughOffset: 34.4
m_StrikethroughThickness: 4.5
m_TabWidth: 18
m_Material: {fileID: 6884716131310289754}
m_SourceFontFileGUID: 91e7d6b1fe3fa491eb896dc861616cb7
m_CreationSettings:
sourceFontFileName:
sourceFontFileGUID: 91e7d6b1fe3fa491eb896dc861616cb7
faceIndex: 0
pointSizeSamplingMode: 0
pointSize: 90
padding: 9
paddingMode: 2
packingMode: 0
atlasWidth: 1024
atlasHeight: 1024
characterSetSelectionMode: 7
characterSequence:
referencedFontAssetGUID:
referencedTextAssetGUID:
fontStyle: 0
fontStyleModifier: 0
renderMode: 4165
includeFontFeatures: 0
m_SourceFontFile: {fileID: 12800000, guid: 91e7d6b1fe3fa491eb896dc861616cb7, type: 3}
m_SourceFontFilePath:
m_AtlasPopulationMode: 1
InternalDynamicOS: 0
m_GlyphTable: []
m_CharacterTable: []
m_AtlasTextures:
- {fileID: -6305474512521559428}
m_AtlasTextureIndex: 0
m_IsMultiAtlasTexturesEnabled: 0
m_GetFontFeatures: 1
m_ClearDynamicDataOnBuild: 1
m_AtlasWidth: 1024
m_AtlasHeight: 1024
m_AtlasPadding: 9
m_AtlasRenderMode: 4165
m_UsedGlyphRects: []
m_FreeGlyphRects:
- m_X: 0
m_Y: 0
m_Width: 1023
m_Height: 1023
m_FontFeatureTable:
m_MultipleSubstitutionRecords: []
m_LigatureSubstitutionRecords: []
m_GlyphPairAdjustmentRecords: []
m_MarkToBaseAdjustmentRecords: []
m_MarkToMarkAdjustmentRecords: []
m_ShouldReimportFontFeatures: 0
m_FallbackFontAssetTable: []
m_FontWeightTable:
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
fontWeights: []
normalStyle: 0
normalSpacingOffset: 0
boldStyle: 0.75
boldSpacing: 7
italicStyle: 35
tabSize: 10
m_fontInfo:
Name:
PointSize: 0
Scale: 0
CharacterCount: 0
LineHeight: 0
Baseline: 0
Ascender: 0
CapHeight: 0
Descender: 0
CenterLine: 0
SuperscriptOffset: 0
SubscriptOffset: 0
SubSize: 0
Underline: 0
UnderlineThickness: 0
strikethrough: 0
strikethroughThickness: 0
TabWidth: 0
Padding: 0
AtlasWidth: 0
AtlasHeight: 0
m_glyphInfoList: []
m_KerningTable:
kerningPairs: []
fallbackFontAssets: []
atlas: {fileID: 0}
--- !u!21 &6884716131310289754
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: DSEG7Classic-Bold Atlas Material
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Cube:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: -6305474512521559428}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OutlineTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Ambient: 0.5
- _Bevel: 0.5
- _BevelClamp: 0
- _BevelOffset: 0
- _BevelRoundness: 0
- _BevelWidth: 0
- _BumpFace: 0
- _BumpOutline: 0
- _ColorMask: 15
- _CullMode: 0
- _Diffuse: 0.5
- _FaceDilate: 0
- _FaceUVSpeedX: 0
- _FaceUVSpeedY: 0
- _GlowInner: 0.05
- _GlowOffset: 0
- _GlowOuter: 0.05
- _GlowPower: 0.75
- _GradientScale: 10
- _LightAngle: 3.1416
- _MaskSoftnessX: 0
- _MaskSoftnessY: 0
- _OutlineSoftness: 0
- _OutlineUVSpeedX: 0
- _OutlineUVSpeedY: 0
- _OutlineWidth: 0
- _PerspectiveFilter: 0.875
- _Reflectivity: 10
- _ScaleRatioA: 0.9
- _ScaleRatioB: 0.73125
- _ScaleRatioC: 0.73125
- _ScaleX: 1
- _ScaleY: 1
- _ShaderFlags: 0
- _Sharpness: 0
- _SpecularPower: 2
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _TextureHeight: 1024
- _TextureWidth: 1024
- _UnderlayDilate: 0
- _UnderlayOffsetX: 0
- _UnderlayOffsetY: 0
- _UnderlaySoftness: 0
- _VertexOffsetX: 0
- _VertexOffsetY: 0
- _WeightBold: 0.75
- _WeightNormal: 0
m_Colors:
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
m_BuildTextureStacks: []
m_AllowLocking: 1
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 67979057ca5724a699640a538d186367
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/Runtime/Fonts/DSEG7Classic-Bold
SDF.asset
uploadId: 968678
@@ -0,0 +1,28 @@
fileFormatVersion: 2
guid: 91e7d6b1fe3fa491eb896dc861616cb7
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- DSEG7 Classic
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/Runtime/Fonts/DSEG7Classic-Bold.ttf
uploadId: 968678
@@ -0,0 +1,298 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &-6703381836575571422
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ScienceGothic_SemiCondensed-Light Atlas Material
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Cube:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 8965678434025470537}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OutlineTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Ambient: 0.5
- _Bevel: 0.5
- _BevelClamp: 0
- _BevelOffset: 0
- _BevelRoundness: 0
- _BevelWidth: 0
- _BumpFace: 0
- _BumpOutline: 0
- _ColorMask: 15
- _CullMode: 0
- _Diffuse: 0.5
- _FaceDilate: 0
- _FaceUVSpeedX: 0
- _FaceUVSpeedY: 0
- _GlowInner: 0.05
- _GlowOffset: 0
- _GlowOuter: 0.05
- _GlowPower: 0.75
- _GradientScale: 10
- _LightAngle: 3.1416
- _MaskSoftnessX: 0
- _MaskSoftnessY: 0
- _OutlineSoftness: 0
- _OutlineUVSpeedX: 0
- _OutlineUVSpeedY: 0
- _OutlineWidth: 0
- _PerspectiveFilter: 0.875
- _Reflectivity: 10
- _ScaleRatioA: 0.9
- _ScaleRatioB: 0.73125
- _ScaleRatioC: 0.73125
- _ScaleX: 1
- _ScaleY: 1
- _ShaderFlags: 0
- _Sharpness: 0
- _SpecularPower: 2
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _TextureHeight: 1024
- _TextureWidth: 1024
- _UnderlayDilate: 0
- _UnderlayOffsetX: 0
- _UnderlayOffsetY: 0
- _UnderlaySoftness: 0
- _VertexOffsetX: 0
- _VertexOffsetY: 0
- _WeightBold: 0.75
- _WeightNormal: 0
m_Colors:
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04, type: 3}
m_Name: ScienceGothic_SemiCondensed-Light SDF
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TMP_FontAsset
m_Version: 1.1.0
m_FaceInfo:
m_FaceIndex: 0
m_FamilyName: Science Gothic SemiCondensed
m_StyleName: Light
m_PointSize: 90
m_Scale: 1
m_UnitsPerEM: 2000
m_LineHeight: 132.84001
m_AscentLine: 97.920006
m_CapLine: 63
m_MeanLine: 45
m_Baseline: 0
m_DescentLine: -34.920002
m_SuperscriptOffset: 97.920006
m_SuperscriptSize: 0.5
m_SubscriptOffset: -34.920002
m_SubscriptSize: 0.5
m_UnderlineOffset: -11.25
m_UnderlineThickness: 4.5
m_StrikethroughOffset: 18
m_StrikethroughThickness: 4.5
m_TabWidth: 24
m_Material: {fileID: -6703381836575571422}
m_SourceFontFileGUID: 6a556a43741e648f5a8c0c26c9b2d1cf
m_CreationSettings:
sourceFontFileName:
sourceFontFileGUID: 6a556a43741e648f5a8c0c26c9b2d1cf
faceIndex: 0
pointSizeSamplingMode: 0
pointSize: 90
padding: 9
paddingMode: 2
packingMode: 0
atlasWidth: 1024
atlasHeight: 1024
characterSetSelectionMode: 7
characterSequence:
referencedFontAssetGUID:
referencedTextAssetGUID:
fontStyle: 0
fontStyleModifier: 0
renderMode: 4165
includeFontFeatures: 0
m_SourceFontFile: {fileID: 12800000, guid: 6a556a43741e648f5a8c0c26c9b2d1cf, type: 3}
m_SourceFontFilePath:
m_AtlasPopulationMode: 1
InternalDynamicOS: 0
m_GlyphTable: []
m_CharacterTable: []
m_AtlasTextures:
- {fileID: 8965678434025470537}
m_AtlasTextureIndex: 0
m_IsMultiAtlasTexturesEnabled: 0
m_GetFontFeatures: 1
m_ClearDynamicDataOnBuild: 1
m_AtlasWidth: 1024
m_AtlasHeight: 1024
m_AtlasPadding: 9
m_AtlasRenderMode: 4165
m_UsedGlyphRects: []
m_FreeGlyphRects:
- m_X: 0
m_Y: 0
m_Width: 1023
m_Height: 1023
m_FontFeatureTable:
m_MultipleSubstitutionRecords: []
m_LigatureSubstitutionRecords: []
m_GlyphPairAdjustmentRecords: []
m_MarkToBaseAdjustmentRecords: []
m_MarkToMarkAdjustmentRecords: []
m_ShouldReimportFontFeatures: 0
m_FallbackFontAssetTable: []
m_FontWeightTable:
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
- regularTypeface: {fileID: 0}
italicTypeface: {fileID: 0}
fontWeights: []
normalStyle: 0
normalSpacingOffset: 0
boldStyle: 0.75
boldSpacing: 7
italicStyle: 35
tabSize: 10
m_fontInfo:
Name:
PointSize: 0
Scale: 0
CharacterCount: 0
LineHeight: 0
Baseline: 0
Ascender: 0
CapHeight: 0
Descender: 0
CenterLine: 0
SuperscriptOffset: 0
SubscriptOffset: 0
SubSize: 0
Underline: 0
UnderlineThickness: 0
strikethrough: 0
strikethroughThickness: 0
TabWidth: 0
Padding: 0
AtlasWidth: 0
AtlasHeight: 0
m_glyphInfoList: []
m_KerningTable:
kerningPairs: []
fallbackFontAssets: []
atlas: {fileID: 0}
--- !u!28 &8965678434025470537
Texture2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ScienceGothic_SemiCondensed-Light Atlas
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_IsAlphaChannelOptional: 0
serializedVersion: 4
m_Width: 1
m_Height: 1
m_CompleteImageSize: 1
m_MipsStripped: 0
m_TextureFormat: 1
m_MipCount: 1
m_IsReadable: 1
m_IsPreProcessed: 0
m_IgnoreMipmapLimit: 1
m_MipmapLimitGroupName:
m_StreamingMipmaps: 0
m_StreamingMipmapsPriority: 0
m_VTOnly: 0
m_AlphaIsTransparency: 0
m_ImageCount: 1
m_TextureDimension: 2
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_Aniso: 1
m_MipBias: 0
m_WrapU: 0
m_WrapV: 0
m_WrapW: 0
m_LightmapFormat: 0
m_ColorSpace: 0
m_PlatformBlob:
image data: 1
_typelessdata: 00
m_StreamData:
serializedVersion: 2
offset: 0
size: 0
path:
@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: afc75f8b1c4494bafa8fa17d86981e18
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/Runtime/Fonts/ScienceGothic_SemiCondensed-Light
SDF.asset
uploadId: 968678
@@ -0,0 +1,28 @@
fileFormatVersion: 2
guid: 6a556a43741e648f5a8c0c26c9b2d1cf
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- Science Gothic SemiCondensed
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267061
packageName: Yarn Spinner+ for Unity, the friendly dialogue and narrative tool
packageVersion: 3.2.8
assetPath: Packages/dev.yarnspinner.unity.addons.snaaake/Runtime/Fonts/ScienceGothic_SemiCondensed-Light.ttf
uploadId: 968678

Some files were not shown because too many files have changed in this diff Show More