Characters
Characters are actors used to represent scene entities placed on top of the backgrounds.
A character actor is defined with a name, appearance, visibility, transform (position, rotation, scale) and look direction.
Characters' behavior can be configured using Naninovel -> Configuration -> Characters context menu or with an actor record; for available options see configuration guide. The characters' resources manager can be accessed using Naninovel -> Resources -> Characters context menu.
In scenario scripts, characters are controlled with @char command:
; Shows character with name "Sora" with a default appearance.
@char Sora
; Same as above, but sets appearance to "Happy".
@char Sora.Happy
; Same as above, but also positions the character 45% away from the left
; border of the scene and 10% away from the bottom border;
; also makes him look to the left.
@char Sora.Happy look:left pos:45,10Actor Records
If you have many characters and it's inconvenient to assign them all via the editor menu, use actor record assets (Create -> Naninovel -> Actor Record -> Character). They support multi-editing and allow you to organize records with folders. Check the video below for an example.
Poses
Each character has a Poses property allowing you to specify named states (poses).
Pose name can be used as appearance in @char command to apply all the selected parameters specified in the pose at once, instead of specifying them individually via the command parameters.
; Given "SuperAngry" pose is defined for "Kohaku",
; applies all the selected parameters specified in the pose.
@char Kohaku.SuperAngry
; Same as above, but using "DropFade" transition over 3 seconds.
@char Kohaku.SuperAngry via:DropFade time:3Notice that when a pose is used as appearance, you can still override individual parameters, e.g.:
; Given "SuperAngry" pose is defined for "Kohaku",
; applies all the parameters specified in the pose state,
; except tint, which is overridden in the command.
@char Kohaku.SuperAngry tint:#ff45cbIn the character and background configurations you can also find Shared Poses — these poses are shared between all the respective actors. Example use cases for shared poses are re-using speaking/non-speaking templates or creating pre-defined stages respective to camera.
Both per-actor and shared poses can also be applied via dedicated pose parameter:
@char Kohaku.Happy pose:DownLeft
@char Yuko.Surprise pose:UpCenter
@char Misaki pose:UpRightPer-actor poses have priority over shared poses meaning if an actor pose name is equal to a shared pose, the actor's pose will be used. This allows overriding shared poses for specific actors when necessary.
Display Names
In the character configuration, when Has Name is enabled, you can set a Display Name for specific characters. When set, the display name will be shown in the printer name label UI instead of the character's ID. This allows using compound character names that contain spaces and special characters (which are not allowed for IDs).
Alternatively, the names can be specified with "CharacterNames" managed text document, which is automatically created when running the generate managed text resources task. Use this to localize display names and/or edit them outside of Unity editor. Records in the managed text document have priority over display names set in actor configuration and will override them.
It's possible to bind a display name to a scenario variable to dynamically change it throughout the game via scenario scripts. To bind a display name, specify the name of the scenario variable wrapped in curly braces in the character configuration menu.
You can then change the variable value in the scripts and it will also change the display name:
@set PlayerName="Mystery Man"
Player: ...
@set PlayerName="Dr. Stein"
Player: You can call me Dr. Stein.It's also possible to use the name binding feature to allow the player to pick their display name using @input command:
@input PlayerName summary:"Choose your name."
Player: You can call me {PlayerName}.The content of the curly braces is actually treated as a full-fledged scenario expression, allowing complex scenarios for evaluating the display name. For example, you may want to keep a pre-defined localizable display name for a character until some point and then let the player pick a custom name.
Let's say the character in question has "Char1" ID, pre-defined name is stored as T_PredefinedName managed text record, the value entered by the player will be stored as name scenario variable and nameSet variable will be set to true when the player has set the name. Assign the following expression to the Display Name property: { nameSet ? name : T_PredefinedName }.
Then use the following scenario script:
@char Char1
Char1: My name is now pre-defined by `T_PredefinedName` managed text record.
Char1: It's localizable; try changing the locale and it will update accordingly.
Char1: Now, we'll make the player input a custom name.
; Notice the default input value assigned via `value` parameter:
; it's retrieved from managed text and is localizable as well.
@input name summary:"Choose your name." value:{T_DefaultName}
; Here we set the variable that is used in the expression
; for display name to decide where to get the value from.
@set nameSet=true
Char1: My display name is now bound to `name` scenario variable.When Has Name is disabled, neither the display name nor the character ID will be displayed in the printer UI. This is useful for narrator characters, which could have a linked printer but whose ID shouldn't be displayed.
Name Labels
While display names discussed above are recommended in most cases, sometimes you may want to change the name of the actor for a few lines or make multiple actors authors of the same line. Setting up a dedicated actor or variable display name for each such occurrence would be impractical. Instead, consider using as generic parameter:
; Even though "Kohaku" character may have custom display name
; set in configuration, print this line with "Someone" as name.
Kohaku: Lorem ipsum.[< as:"Someone"]
; Print the line with "All Together" displayed as author name
; and make all visible characters author of the printed text.
*: Lorem ipsum![< as:"All Together"]
; Similar, but make only "Kohaku" and "Yuko" the authors.
Kohaku,Yuko: Lorem ipsum?[< as:"Kohaku and Yuko"]— as parameters are localizable and will be exposed in the script localization documents for translation. Additionally, speaker highlighting feature will recognize * and , specified in author ID and highlight all/selected characters as speakers.
Message Colors
When Use Character Color is enabled in the character configuration, printer text messages and name labels will be tinted in the specified colors when the corresponding character ID is specified in a @print command or generic text line.
The following video demonstrates how to use display names and character colors.
Avatar Textures
You can assign avatar textures to characters using avatar parameter of @char command. Avatars will be shown by the compatible text printers when they print a text message that is associated with the character.
Currently, only Wide and Chat built-in printers (as well as their TMPro-counterparts) support the avatars feature. In order to support the feature in a custom printer, assign a game object with Author Image component to Author Avatar Image property of Revealable Text Printer Panel component.
To use any given avatar, you have to first add it to the avatar resources and give it a name. You can do this via Avatar Resources property in the characters configuration menu.
NOTE
Avatar names can be arbitrary and don't have to contain an existing character ID or appearance. This is only required when you want to associate an avatar with a character so that it's shown automatically.
You can then show a specific avatar texture like this:
@char CharacterId avatar:AvatarNameTo set a default avatar for a character, give the avatar texture resource a name that equals CharacterID/Default; e.g., to set a default avatar for character with ID Kohaku name the avatar resource Kohaku/Default. Default avatars will be shown automatically, even when avatar parameter is not specified in the @char commands.
It's also possible to associate avatars with specific character appearances, so that when character changes appearance, the avatar will also change automatically. For this, name the avatar resources using the following format: CharacterID/CharacterAppearance, where CharacterAppearance is the name of the appearance for which to map the avatar resource.
To show only the avatar of a character inside a text printer, but hide the character itself, set visible parameter of the @char command to false, e.g.:
@char CharacterId !visibleIn case you're constantly changing avatars while the character itself should remain hidden, consider disabling Auto Show On Modify in the characters configuration menu; when disabled, you won't have to specify !visible to change any parameters of the character while it's hidden.
NOTE
The avatars are not directly connected with character appearances and shouldn't be considered as a way to represent a character on scene. Avatars are a standalone feature that "injects" an arbitrary image into a compatible text printer. In case you want an actual character to appear inside a text printer (or a custom UI), check render actor to texture feature.
Speaker Highlight
When enabled in the character configuration, speaker highlight will set specified poses to the character based on whether the last printed message is associated with it. This allows automatically highlighting the "speaking" characters, usually by tinting or scaling.
When applying the same highlight poses for multiple characters, it's recommended to use Shared Poses found in the root of the character's configuration.
Lip Sync
Event Driven
Animatable character implementations (generic, layered, Live2D, etc.) provide On Started Speaking and On Finished Speaking Unity events. When such a character becomes or ceases to be the author of a printed message (or rather when the message is fully revealed), the events will be invoked allowing you to trigger any custom logic, like starting or stopping mouth animation of the controlled character.
When auto voicing feature is enabled, the events will be driven by the voice-over; otherwise, printed text messages will activate the events. In the latter case, you'll probably want to manually mute the events (e.g., to prevent mouth animation when punctuation marks are printed); for such cases, use @lipSync command.
Audio Driven
In case you'd like to drive character mouth animation by the actual waves of the voice audio clips, use Voice Source option in the character configuration. When a prefab with Unity's Audio Source component is assigned, Naninovel will instantiate the prefab under the character object and play the voice of the character via the audio source component.
By having access to a dedicated audio source component used for character voice, you can hook a custom solution to analyze the waves of the played audio and drive mouth animation accordingly. There are multiple third-party solutions that can help achieve that. For example, Live2D's Cubism Audio Mouth Input component or SALSA.
Linked Printer
It's possible to associate a text printer with a character using Linked Printer property.
When linked, the printer will automatically be used to handle messages authored by the character.
Be aware that @print commands (that are also used under the hood when printing generic text lines) make associated printers default and hide other visible printers by default. When printers are linked to characters, print commands will automatically change the currently visible and default text printer while printing text associated with the corresponding characters. It's possible to prevent this behavior by disabling Auto Default property in printer actor configuration menu; when disabled you'll have to manually show/hide and switch default printers with @printer commands.
TIP
Link a printer with narrator character and disable Has Name to make narrated text linked with a printer, so that you won't have to use @printer to switch back to non-character (default) printer all the time.
To link and unlink printers at runtime, use the @linkPrinter and @unlinkPrinter commands. Additionally, it's possible to temporarily link all authors to a specific printer by nesting commands under @printer.
; Use 'Fullscreen' by default for unauthored lines.
@linkPrinter Fullscreen to:DefaultAuthor
; 'Kohaku' will use the 'Wide' printer by default.
@linkPrinter Wide to:Kohaku
This is printed with 'Fullscreen'.
Kohaku: And I'm printing with 'Wide'!
; Enforce 'Dialogue' for nested commands.
@printer Dialogue
This is printed with 'Dialogue'.
Kohaku: I have to use 'Dialogue' now.
Back to 'Fullscreen'.
Kohaku: And I can use my 'Wide' again!
; Unlink whatever printer is linked to 'Kohaku'.
@unlinkPrinter from:Kohaku
This is not affected and is still using 'Fullscreen'.
Kohaku: Who took my 'Wide'?! Printing with 'Fullscreen'...Default Author
When using linked printers for your regular characters, you may want generic text lines and @print commands without an explicit author to fall back to a dedicated printer. This avoids having to specify a narrator ID for every such line or switching printers manually with the @printer command.
To enable this behavior, create a character record with DefaultAuthor ID, set its implementation to NarratorCharacter and disable HasName option. This character will then serve as the fallback author for any un-authored text and apply its linked printer automatically.
Placeholder Characters
The placeholder implementation is the default one and is intended for scenario drafting when you do not yet have any visual assets to represent a character. It uses actor metadata such as the identifier, display name and colors to procedurally generate the character placeholder.
Below is an example of a placeholder background with a couple of placeholder characters on top. Notice the currently speaking character is highlighted by an increased scale and opacity.
Sprite Characters
Sprite implementation of the character actors is the most common and simple one; it uses a set of texture assets wrapped over a quad mesh (sprite) to represent appearances of the character. The textures can be based on .jpg, .png, .tiff, .psd or any other image file format supported by Unity.
TIP
Choose file formats that are most comfortable for your development workflow. When building the project, Unity will automatically convert all the source resources (textures, audio, video, etc.) to the formats most suitable for the target platform, so it won't make a difference in which format you originally store the resources in the project. Find more information on how Unity manages project assets in the official documentation.
Initial (unscaled) size of the sprite character mesh on scene depends on the reference resolution (camera configuration), character's Pixel Per Unit property (set for each character actor in the configuration menu) and source texture resolution.
To achieve best render quality and optimal performance, it's generally advised to keep the default Pixel Per Unit value (100) for all the characters and control the desired initial character size via texture resolution. For example, given reference resolution in your game is the default 1920x1080 pixels, to make a character occupy the whole screen height, set height of the character's texture (e.g., by resizing it via Photoshop or other image editor) to 1080 pixels; to make another character occupy 2/3 of the screen height, set the height to 1080 * 2/3 and so on.
Diced Sprite Characters
Built with an open source SpriteDicing package, DicedSpriteCharacter implementation allows you to significantly reduce build size and texture memory by reusing texture areas of the character sprites.
Install the package via Unity package manager: open package manager window (Window -> Package Manager), click "+" button, choose "Add package from git URL", enter the following URL:
https://github.com/elringus/sprite-dicing.git?path=/plugins/unity/Assets/SpriteDicing— to the input field and click "Add".
NOTE
Before installing a package from a Git repository, make sure a Git client is installed on your machine and Git executable path is set to the PATH system environment variable (usually performed automatically during the installation).
When "SpriteDicing" extension is installed via UPM, a Naninovel.DicedSpriteCharacter option will appear in the character implementations list.
DicedSpriteAtlas assets containing character appearances are used as the resources for the diced sprite characters. Each appearance is mapped by name to the diced sprites contained in the atlas.
TIP
Character metadata properties (e.g., pixels per unit, pivot) are applied to render texture used to represent the character on scene, while similar diced atlas properties are applied to the generated diced sprites. When changing atlas properties, don't forget to rebuild it for changes to take effect.
The following video guide covers creating and configuring diced sprite atlas, adding new diced character based on the created atlas and controlling the character from a scenario script.
For more information on available dicing options and usage examples, refer to the extension docs.
EXAMPLE
Find an example of setting up diced actors in the diced actor sample.
Universal Characters
Whenever you want your character to be more than a simple sprite, the universal implementation is the first option worth considering. It supports all the default renderers available in Unity: meshes, particles, skinned sprites, tilemaps, etc. Additionally, universal actor content is affected by lights and volumes.
Create a new universal character prefab from a template using the Create -> Naninovel -> Character -> Universal asset context menu, then enter prefab editing mode by double-clicking it. You will notice a Universal Character Behaviour component on the root object — it's the adapter between Naninovel and the prefab content.
You can build the prefab as you would any other in Unity — Naninovel will capture all the compatible renderers under the prefab root and composite them into the character render texture at runtime. Note the On Appearance Changed event on the component — use it to set up callbacks for appearance changes; for example, you can use Unity's Animator system to drive the animation of your character.
If an object you would like to include in the universal actor uses custom rendering features, such as 2D lights or procedural drawing, you can make it compatible by implementing the Naninovel.IUniversalActorDrawable interface in a component and attaching the component to the game object containing the custom content. For example, Live2D actors are implemented this way.
Layered Characters
The layered implementation is based on universal, but also has a Layer Actor Controller component, which allows composing characters from multiple layers and then toggling them individually or in groups via scenario scripts at runtime.
To create a layered character prefab, use Create -> Naninovel -> Character -> Layered asset context menu. Enter prefab editing mode to compose the layers. Several layers and groups will be created by default. You can use them or delete and add your own.
Each child game object of the root prefab object with a Layered Actor Layer component is considered a layer; other objects are considered groups. Aside from organization and transformation purposes, placing layers inside groups will allow you to select a single layer or disable/enable all the layers inside a group with a single expression in scenario script (more on that later).
When a layer game object also has a renderer, the renderer is automatically used to drive the layer state: it is disabled when the layer is disabled and vice versa. To hide specific layers by default, disable their renderer components (not the game objects). Alternatively, you can use the On Layer Enabled and On Layer Disabled events to drive the layer's enabled state.
TIP
When authoring layered character art in Photoshop, consider using Unity's PSD Importer package to automatically generate character prefab preserving all the layers and their positions. To preserve the layers hierarchy, make sure to enable Use Layer Grouping option in the import settings.
To control the layered characters in scenario scripts, use @char command in the same way as with the other character implementations. The only difference is how you set the appearance: instead of a single ID, use the layer composition expression. There are three expression types:
- Enable a single layer in group:
group>layer - Enable a layer:
group+layer - Disable a layer:
group-layer
For example, consider a "Miho" character, which has a "Body" group with three layers: "Uniform", "SportSuit" and "Pajama". To enable "Uniform" layer and disable all the others, use the following command:
@char Miho.Body>UniformTo enable or disable a layer without affecting any other layers in the group, use "+" and "-" respectively instead of ">". You can also specify multiple composition expressions splitting them with commas:
; Enable glasses, disable hat, select "Cool" emotion.
@char CharId.Head/Accessories+BlackGlasses,Head-Hat,Head/Emotions>CoolTo select a layer outside any groups (a child of the root prefab object), just skip the group part, e.g.:
; Given "Halo" layer object is placed under the prefab root, disable it.
@char CharId.-HaloIt's also possible to affect all the layers inside a group (and additionally its neighbors when using select expression) by omitting layer name in composition expression:
; Disable all the layers in "Body/Decoration" group.
@char CharId.Body/Decoration-
; Enable all the existing layers.
@char CharId.+
; Given "Poses/Light" and "Poses/Dark" groups, enable all the layers
; inside "Light" group and disable layers inside "Dark" group.
@char CharId.Poses/Light>The above expressions will affect not only the direct descendants of the target groups, but all the layers contained in the underlying groups, recursively.
When an appearance is not specified (e.g., @char CharId without previously setting any appearance), a default appearance will be used; default appearance of the layered characters equals to how the layered prefab looks in the editor.
It's possible to map composition expressions to keys via Composition Map property of Layered Character Behaviour component:
— the keys can then be used to specify layered actor appearance:
; Equal to "Body>Uniform,Hair/Back>Straight,Hair/Front>Straight,Shoes>Grey".
@char Miho.Uniform
; Equal to "Hair/Back>Straight,Hair/Front>Straight".
@char Miho.StraightHair
; It's also possible to combine keys and expressions.
@char Miho.Uniform,Hair/Front>ShortWhile editing layered character prefab, it's possible to preview mapped composition expressions by right-clicking a map record and selecting "Preview Composition". Another menu item — "Paste Current Composition" — will generate current composition expression string of the character (based on enabled/disabled sprite renderers in the hierarchy) and paste it to the inspected record; use it to quickly map current prefab state to a composition item.
EXAMPLE
Find an example of setting up layered actors in the layered actor sample.
Generic Characters
Generic character is the most flexible character actor implementation. It's based on a prefab with a Generic Character Behaviour component attached to the root object. Appearance changes and all the other character parameters are routed as Unity events allowing you to implement the behavior of the underlying object in any way you wish.
NOTE
Generic actor implementations just route events from the scenario scripts and it's up to the user to implement the underlying behavior, e.g., how the actor should react to the appearance or visibility change commands, whether and how it will support speaker highlight feature, etc. Don't expect most of the actor-related features to work automatically with the generic implementations.
To create generic character prefab from a template, use Create -> Naninovel -> Character -> Generic context asset menu.
Check the following video tutorial for an example of setting up a 3D rigged model as a generic character and routing appearance changes to the rig animations via Animator component. Be aware that the video is captured with an old Naninovel version and some properties and component names are different now; see the above docs for the up-to-date information.
TIP
Unity's Animator component could fail to register SetTrigger when the game object is enabled/disabled in the same frame; in case you use GameObject.SetActive to handle visibility changes (as it's shown in the above tutorial), consider enabling/disabling the child objects with renderers instead.
EXAMPLE
Check the generic actor sample, where generic character implementation is used to host a 3D animated model.
Video Characters
Video characters use looped video clip assets to represent the appearance.
For the supported video formats for each platform see Unity docs for video sources.
When using video with an alpha channel (transparency), see the guide on the supported formats.
To prevent a specific appearance from looping, append NoLoop (case-insensitive) to the appearance name.
Live2D Characters
Live2D character implementation uses assets created with Live2D Cubism 2D modeling and animation software.
In order to be able to use this implementation you have to first install Live2D Cubism SDK for Unity. Consult official Live2D docs for the installation and usage instructions.
After Live2D SDK for Unity is installed, click Naninovel/Extensions/Enable Live2D editor menu item to activate Naninovel module which provides integration between Live2D and the engine.
NOTE
This integration with a third-party commercial product serves mostly as an example of how you can make Naninovel work with another tool. While we're committed to keeping the sample integration compatible with Live2D updates and changes, please be aware that the functionality will remain bare minimum and we won't be able to provide any support or help on using another product with Naninovel beyond the scope of the sample.
The actor's Live2D resource is expected to have a Live2D Character Behaviour component attached to the root object. Appearance changes are routed to the animator component as SetTrigger commands, appearance being the trigger name. E.g., if you have a "Kaori" Live2D character prefab and want to invoke a trigger with name "Surprise", use the following command:
@char Kaori.SurpriseNote that the above command will only attempt to invoke a SetTrigger with "Surprise" argument on the animator controller attached to the prefab; you have to compose the underlying animator state machine yourself.
When Live2D's Cubism Look Controller and Cubism Mouth Controller components are present and set up on the Live2D model prefab, Live2D Character Behaviour can optionally use them to control look direction and mouth animation (aka lip sync feature) of the character. Consult Live2D documentation on eye tracking and lip sync for the setup details.
The following video guide covers exporting a Live2D character from Cubism Editor, configuring the prefab, creating a simple animator state machine and controlling the character from a scenario script.
EXAMPLE
Check the Live2D sample, where a Live2D character is used with Naninovel.
Spine Characters
Spine character implementation uses assets created with Spine 2D modeling and animation software.
In order to be able to use this implementation you have to first install Spine runtime for Unity. Consult the official docs for the installation and usage instructions.
After Spine runtime for Unity is installed, click Naninovel/Extensions/Enable Spine editor menu item to activate Naninovel module which provides integration between Spine and the engine.
NOTE
This integration with a third-party commercial product serves mostly as an example of how you can make Naninovel work with another tool. While we're committed to keeping the sample integration compatible with Spine updates and changes, please be aware that the functionality will remain bare minimum and we won't be able to provide any support or help on using another product with Naninovel beyond the scope of the sample.
Spine character prefab used as the resource for the implementation should have a Spine Controller component attached to the root object. Appearance changes from scenario script commands (such as @char) are routed to the controller's On Appearance Changed events similar to generic implementation. You can handle the events as you wish; for example, use Spine's SetAnimation method or invoke a trigger in Unity's animator controller.
TIP
It's possible to use a custom component inherited from Spine Controller. This way you'll be able to override the virtual methods and associated behavior (e.g., handle appearance change with a specific duration or transition parameters).
Internally, Spine model is rendered to a texture, which is then projected to the screen. This is required to prevent semi-transparency overdraw artifacts when fading the character. To specify the texture size, use Render Canvas component (attached automatically when adding Spine Controller). Enable gizmos to preview the current size while in prefab mode. Be aware that the larger the size, the more memory the texture will consume, so keep it as small as possible.
NOTE
Spine's Skeleton Render Separator (multi-render) workflow is not supported; to integrate that workflow with Naninovel, create a custom character implementation.
EXAMPLE
Check the spine sample, where a Spine character is used with Naninovel.
Narrator Characters
Narrator characters don't have any presence on scene (appearances, position, look direction, tint, etc.), but are still able to author printed messages and have the related configuration options (display name, message color, linked printer, etc.).
Render to Texture
It's possible to render character and background actors of all the implementations (except generic) to a texture asset, which can then be assigned to a custom UI, printer, material or any other compatible source.
Assign the render texture asset via actor configuration with Render Texture property. When a texture is assigned, the actor won't appear as a game object on scene, but will rather be rendered to the texture. Render Rectangle property allows specifying a region of the actor to render into texture.
NOTE
When using addressables package, Unity can't properly track asset references, which may cause render texture duplication in build preventing the feature from working correctly. Either manually handle the references (via AssetReference API) or use Get Actor Render Texture component as illustrated below.
When an actor is rendered to a texture, transformations (position, rotation, scale) and some other modifications won't have any effect. Instead, transform the host object of the render texture (e.g., image in case the texture is assigned to UI raw image component).
The video below demonstrates how to render a Live2D character to a texture, which is assigned to custom text printer. The printer is linked to the character, so the character will automatically show and hide with the printer when the associated text messages are processed.
All the other character and background implementation types (except generic) can be set up to render to texture similar to Live2D example.
Multiple Appearances
Generic, Live2D and Spine actors support multiple appearances applied at once, e.g.:
@char Kohaku.Body/Pose1,Face/Smile— will invoke Body/Pose1 and Face/Smile appearance change events. Use this to trigger multiple animator triggers simultaneously to set up complex animation states. All the appearances will also serialize with the actor state and restore on game load or rollback.