Characters
Characters are actors used to represent scene entities that are placed on top of the backgrounds.
A character actor is defined with a name, appearance, visibility, transform (position, rotation, scale) and look direction. It can change appearance, visibility, transform and look direction over time.
Characters' behavior can be configured using Naninovel -> Configuration -> Characters
context menu; for available options see configuration guide. The characters' resources manager can be accessed using Naninovel -> Resources -> Characters
context menu.
In case you have a lot of characters and/or appearances per character and it's inconvenient to assign them all via editor menu, use actor record assets (Create -> Naninovel -> Actor Record -> Character
) which support multi-editing and organizing the records with folders; check the video below for an example.
It's possible to use addressable asset system to associate resources with actor records without using editor menus. Eg, to associate a "Happy" appearance with "Kohaku" character, assign the texture asset following address: Naninovel/Characters/Kohaku/Happy
and assign Naninovel
label to the asset in addressable group configuration. Be aware, that addressable provider is not used in editor by default; you can allow it by enabling Allow Addressable In Editor
property in resource provider configuration menu. Find more info on using addressable provider in the resource providers documentation.
In naninovel scripts, characters are mostly 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,10
TIP
Consider using Scene Assistant extension to help with positioning the actors on scene.
Poses
Each character has Poses
property allowing 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` character,
; 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 transition:DropFade time:3
Notice, that when a pose is used as appearance, you can still override individual parameters, eg:
; Given `SuperAngry` pose is defined for `Kohaku` character,
; applies all the parameters specified in the pose state,
; except tint, which is overridden in the command.
@char Kohaku.SuperAngry tint:#ff45cb
In 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 template 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:UpRight
Per-actor poses have priority over shared poses meaning if actor pose name is equal to a shared pose, actor's pose will be used. This allows overriding shared poses for specific actors when necessary.
Display Names
In the character configuration, given Has Name
is enabled, you can set a Display Name
for specific characters. When set, display name will be shown in the printer name label UI, instead of the character's ID. This allows using compound character names, that contains spaces and special characters (which is not allowed for IDs).
Alternatively, the names can be specified with "CharacterNames" managed text document, which is automatically created when running 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 custom variable to dynamically change it throughout the game via naninovel scripts. To bind a display name, specify name of the custom 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="Mistery 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 player pick their display name using @input
command:
@input PlayerName summary:"Choose your name."
@stop
Player: You can call me {PlayerName}.
The content of the curly braces is actually treated as a full-fledged script 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 questions 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" custom variable and "nameSet" variable will be set to "true" when 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}
@stop
; 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` custom variable.
@stop
When Has Name
is disabled, neither display name, nor character ID will be displayed in the printer UI. This is useful for narrator characters, which could have a linked printer, but their ID shouldn't be displayed.
Name Labels
While display names discussed above are recommended in most cases, sometimes you may want to change 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
parameter of the @print
command:
; Even though "Kohaku" character may have custom display name
; set in configuration, print this line with "Someone" as name.
@print "Lorem ipsum." author:Kohaku as:"Someone"
; Print the line with "All Together" displayed as author name
; and make all visible characters author of the printed text.
@print "Lorem ipsum!" author:* as:"All Together"
; Similar, but make only "Kohaku" and "Yuko" the authors.
@print "Lorem ipsum?" author:Kohaku,Yuko 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 CharacaterId avatar:AvatarName
To set a default avatar for a character, give the avatar texture resource name that equals to CharacterID/Default
; eg, 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
, eg:
@char CharacaterId !visible
In 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 is a standalone feature, that "injects" an arbitrary image to a compatible text printer. In case you want an actual character appear inside a text printer (or a custom UI), check render actor to texture feature.
Speaker Highlight
When enabled in the character configuration, will set specified poses to the character based on whether the last printed message is associated with it. The video below demonstrates the feature with a previous version of Naninovel, where it was possible to apply only tint color for speakers; setup with the current version is similar, but instead tint color, specify a pose name.
Lip Sync
Event Driven
Animatable character implementations (generic, layered, Live2D, etc) provide On Started Speaking
and On Finished Speaking
Unity events. When such 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 (eg, 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.
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 difference in which format you originally store the resources in the project. Find more information on how Unity manage 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 (eg, 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 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 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 (eg, 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.
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 naninovel script.
For more information on available dicing options and usage examples, refer to the extension docs: https://dicing.elringus.com/guide/unity.
Layered Characters
The layered implementation allows composing characters from multiple layers and then toggle them individually or in groups via naninovel scripts at runtime.
TIP
Layered actor implementation has been evolving and is currently the most flexible with support for all the rendering features (in contrast to generic). Even if you don't want to use layer expressions, but instead control the appearance with Unity's Animator or other custom systems; or need to render non-trivial objects such as particle systems and/or utilize third-party renderers, check render only and camera rendering options available for layered actors before reserving to generic or custom implementation.
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 renderer-derived component (eg, SpriteRenderer
, MeshRenderer
, eg) is considered a layer; other objects 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 naninovel script (more on that later).
NOTE
Only "simple" draw mode for Sprite Renderer
is supported in default (non-camera) render mode; when choosing other modes they'll be rendered as it was set to simple.
To hide specific layers from being visible by default, disable renderer components (not the game objects).
The white frame drawn over the prefab is used to describe the actor canvas, which will be rendered to a render texture at runtime. Make sure to minimize the empty areas inside the frame by moving the layers and groups to prevent wasting texture memory and for anchoring to work correctly. To set a custom canvas size (eg, in case some layers are animated and can stretch out of the default canvas), add Render Canvas
component to the root object and set Size
property.
You can scale the root game object to fine-tune the default size of the actor.
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.
TIP
When using sprites, set Mesh Type
to Full Rect
in the texture import settings to prevent rendering issues.
Don't forget to add the created layered prefab to the character resources (Naninovel -> Resources -> Characters
). Choose "Naninovel.LayeredCharacter" implementation and drop prefab to the "Resource" field when configuring the resource record.
To control the layered characters in naninovel 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>Uniform
To 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>Cool
To select a layer outside of any groups (a child of the root prefab object), just skip the group part, eg:
; Given "Halo" layer object is placed under the prefab root, disable it.
@char CharId.-Halo
It'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 (eg, @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.
The video below demonstrates how to set up a layered character and control it via naninovel commands.
NOTE
@char Miho.Shoes>
command displayed in the video will actually select the "Shoes" group (disabling all the neighbor groups), not hide it. Correct command to hide a group is @char Miho.Shoes-
.
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>Short
While 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.
Be aware, that the layer objects are not directly rendered by Unity cameras at runtime; instead, they're rendered once upon each composition (appearance) change to a temporary render texture, which is then fed to a custom mesh visible to the Naninovel camera. This setup is required to prevent semi-transparency overdraw issues and to support transition animation effects.
In case you wish to apply an animation or other dynamic behaviour to the layered character, enable Animated
property found on Layered Character Behaviour
component. When the property is enabled, the layers will be rendered each frame (instead once per appearance change).
Outsourcing Appearance Management
You may find layered implementation useful for supporting various built-in render features (semi-transparency overdraw handling, transition effects, blur and depth-of-field support, etc), but would like to use external tools for managing appearance of the actor, such as Unity's Animator. By default, layered behaviour will use layered expressions when notifying about appearance changes via On Appearance Changed
event, which may not be desired in such case.
Enabling Render Only
option will disable layer-related behaviour and make the event report the appearance as it's specified in script commands. You will also have to specify Default Appearance
on the behaviour component to prevent it from evaluating default appearance based on the initial prefab layer composition.
Camera Rendering
In case your character prefab contains non-trivial renderers like particle systems, trails, sprite masks or custom/third-party renderers, you can still use them with layered implementation by assigning a camera to Render Camera
field of Layered Behaviour
component (the camera has to be inside character's prefab).
When assigned, instead of custom render procedure, the actor will use the camera to render contents, which lifts all the inherent limitations, such as lacking stencil support. The drawback is, in order to ensure the content is only rendered to the actor texture (and doesn't "leak" to the main camera), you'll have to reserve camera layers specifically for rendering this kind of actor.
There a total of 32 layers available in Unity, while 8 of them are reserved for engine internals. You can use remaining layers as you wish (they're unused by default). To allow Naninovel use a layer for rendering layered actors in camera mode, give the layer name starting with Naninovel
; eg: Naninovel 1
, Naninovel 2
and so on.
Total number of layers to add depends on the max amount of unique camera-rendered layered actors spawned at any given time, no matter visible or not. When layered actor is rendered, it holds a layer from the pool. When the actor is hidden, it releases the layer, allowing it to be re-used by other actors. However, the actors are also rendered on appearance change, which happen when they're initially added to scene (even if they're hidden) or when game is loaded or rolled-back, so layer pool size has to accommodate total number of camera-rendered actors spawned at a time, and not just amount of such actors visible at a time. To destroy (de-spawn) an actor after hiding it, use @remove
command.
After adding the layers, assign Custom Camera Prebab
in Naninovel's camera configuration with a camera prefab, which has culling mask with the Naninovel ...
layers disabled. This is required to prevent the "raw" layered actors from leaking into the main Naninovel camera. Note that the assigned camera should be a dedicated camera prefab, not the camera you've used inside layered actor prefabs.
While in camera rendering mode, game objects of the layered actor prefab are considered layers when they have Layered Actor Layer
component attached, other objects are considered groups. After attaching the component, configure what should happen when camera layer is held and released with On Layer Held
and On Layer Released
Unity events. Typically, you'd assign the held layer to the host game object and enable associated renderer and disable the renderer when released (to make sure the object is not picked by other cameras).
Layer active state is also reflected differently in camera mode: instead of renderer component enabled state, game object's active state is used. To set up default appearance of the actor, enable/disable game objects.
TIP
When layer contains lots of children, it would be tedious to set the layer held/release events for each of them individually. In this case use custom event handler to apply the changes in batch. Check the example on applying the changes to all the children renderers of a layer.
Make sure Render Canvas
component is attached to the layer actor prefab root, as it's required for the camera mode. It works similar to normal render mode, restricting render texture size, so keep it compact.
In case extra layers are required for rendering the actor (for example, a layer dedicated for Unity's Lights 2D), add them via Camera Mask
property found on the layered behaviour component. Naninovel will preserve specified layers in the camera culling mask when rendering the actor.
EXAMPLE
Find example on 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 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 user to implement the underlying behaviour, eg 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 example on 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 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 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, add NANINOVEL_ENABLE_LIVE2D
define in player settings to activate Naninovel module which provides integration between Spine and the engine.
NOTE
This integration with third-party commercial product serve mostly as an example on how you can make Naninovel work with another tool. While we're committed to keep 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.
Live2D model prefab used as the resource for the implementation should have a Live2DController
component attached to the root object. Appearance changes are routed to the animator component as SetTrigger commands appearance being the trigger name. Eg, if you have a "Kaori" Live2D character prefab and want to invoke a trigger with name "Surprise", use the following command:
@char Kaori.Surprise
Note, 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 underlying animator state machine yourself.
NOTE
Current actual version of Cubism SDK for Unity is working directly with Animator
component; expressions and poses (exported as expression.json and pose.json), that were previously used in Cubism 2.x are now deprecated and not supported by Naninovel's extension for Live2D.
When Live2D's CubismLookController
and CubismMouthController
components are present and setup on the Live2D model prefab, Live2DController
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.
In case the model appears too small or large, set an initial scale for the root Live2D prefab game object as shown in the video guide.
Internally, Live2D 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. Naninovel will attempt to evaluate size of the render canvas automatically, but in case the model contains animated parts that are moved outside of the initial bounds, the parts will be clipped. To prevent that, add Render Canvas
component to the root game object of the Live2D prefab and set the desired size of the canvas manually. Enable gizmos to preview current render canvas size while in prefab mode.
Be aware, that larger the size, the more memory will the texture consume, so keep it as small, as possible.
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 naninovel 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, add NANINOVEL_ENABLE_SPINE
define in player settings to activate Naninovel module which provides integration between Spine and the engine.
NOTE
This integration with third-party commercial product serve mostly as an example on how you can make Naninovel work with another tool. While we're committed to keep 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 naninovel scripts 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 behaviour (eg, 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 current the size while in prefab mode. Be aware, that larger the size, the more memory will the texture 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 can 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 (eg, 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, eg:
@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 as well serialize with the actor state and restore on game load or rollback.