Skip to content

Commit

Permalink
Update layered portrait documentation (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jowan-Spooner authored Jul 12, 2024
1 parent f3be56e commit fa6e044
Show file tree
Hide file tree
Showing 15 changed files with 41 additions and 123 deletions.
164 changes: 41 additions & 123 deletions documentation/layered-portraits.md
Original file line number Diff line number Diff line change
@@ -1,152 +1,87 @@


<div class="header-banner pineapple">
<div class="header-label pineapple">Layered Portraits</div>
</div>

*This page describes how to create layered portraits.*
*This page describes how to create and use layered portrait scenes.*

## 📜 Content

[toc]

## 1. Introduction

If you want to have a character with multiple layers, like a body, a head, and
a mouth, you can use the **Layered Portrait** feature.

Dialogic uses the concept of Godot scenes to create portraits. The layered portrait feature provides us with a GDScript that you can use for this purpose.

If you are eager to learn more about the requirements for creating a custom portrait, please refer to the [Custom Portraits](custom-portraits.md) page.
If you want to have a character with multiple layers, like a body, a head, and a mouth, you can use the custom **Layered Portrait** scene. This scene allows creating a character from many sprites and then allows showing, hiding and switching between these sprites **from the timeline!**

If you are eager to learn more about how dialogic uses scenes to create portraits and the requirements for creating a custom portrait, please refer to the [Custom Portraits](custom-portraits.md) page.

## 2. Rundown

You will learn to create a new character, add a new portrait, and then create a
new Godot scene for the custom scene of this portrait.\
Finally, you will learn how to control the layers of the portrait using the
timeline.
First, you will learn how to create a new layered portrait scene and set it up correctly.

Finally, you will learn how to control the layers of the portrait using the timeline.

## 2.1. Preparation

I will use a character named `Agustina`, if you want to follow along, you can download the assets from [https://dejinyucu.itch.io/agustina-visual-novel-sprite](https://dejinyucu.itch.io/agustina-visual-novel-sprite).\
Heads up: The character is available as a PSD file; you will have to pick the
layers and export them as image files.


## 3. Creating a new Character

First, head over to the Dialogic Character tab. You will need to create
yourself a new character or edit an existing one.

Each character can have multiple portraits. You can add a new portrait or use
an existing one.

Heading over to the last segment of the Character Editor, you will find the
preview and the **Portrait Settings**.\
Unfold the **Scene** option, and you will see a file picker. We will head back
here once the scene file is done, set it.

![Character Editor: Scene Picker](media/layered_portrait/portrait_settings_scene_empty.png)


## 4. Creating a Portrait Scene

Now, we want to create a new scene in the **FileSystem** tab of Godot.
We recommend creating a new folder for your portrait scenes, so you can keep
your project organized.

Right-click on the folder and hover **Create New**, and click **Scene...** on the
follow-up menu.
I will use a character named `Agustina`, if you want to follow along, you can download the assets from [https://dejinyucu.itch.io/agustina-visual-novel-sprite](https://dejinyucu.itch.io/agustina-visual-novel-sprite).

Select the **Root Type**, we recommend using the **Node** option, selecting the
`CanvasGroup` type.
*Heads up: The character is available as a PSD file; you will have to pick the layers and export them as image files.*

The `CanvasGroup` type allows Godot to treat all layers as a single image,
preventing the layers from fading in and out separately.
You will also have to have a character. You can use an existing one or create a new one for this. On that character (in the Character Editor) add or select a portrait.

The **Scene Name** is up to you, but once again, we recommend keeping your
project organized with a consistent naming scheme.
## 3. Creating the Base Layered Portrait Scene

![Creating a new scene](media/layered_portrait/create_scene.png)
In the Character Editors "Portrait Settings" section, head to the **Scene** section.

Once you press **OK**, your new scene will be opened in the **Scene** tab of
Godot. Switch to the **2D** tab in the upper-middle of Godot, and you will see
your new scene.
![Portrait Setting Scene Empty](media/layered_portrait/portrait_setting_scene_empty.jpg)

![Layered Scene: Empty](media/layered_portrait/layered_scene_empty.png)
Click the little arrows icon to change the portrait scene.

## 4.1. Adding the Layered Portrait GDScript
In the popup that opens select the `Layered Portrait` and then click `Customize This Scene`.

To use your scene as a layered portrait, we will add a built-in
GDScript to the root node of your scene.
![Custom Portrait Selection Popup](media/layered_portrait/custom_portrait_selection_popup.jpg)

Right-click on the root node and hover over **Attach Script**.
This will promt you to save the new scene somewhere in the file system. Navigate to a place that makes sense in your file oranization and adjust the file name if necessary. Then click `Save`.

![Layered Scene: Attach Script](media/layered_portrait/layered_scene_attach_script.png)
You can now open this scene with the little arrow icon button (or from the file system).

You can copy the following path and paste it into the **Path** field:
![Portrait Setting Scene Set](media/layered_portrait/portrait_setting_scene_set.jpg)

```
res://addons/dialogic/Modules/Character/LayeredPortrait/layered_portrait.gd
```

![Attach Node Script](media/layered_portrait/attach_node_script_window.png)

Press **Load** and... that's it! You have now added the Layered Portrait
scripting logic; now onto the fun part!

```admonish info
The script may open in the **Script** tab of Godot or an external editor,
feel free to ignore this and move back to the **2D** tab.\
It's not recommended to edit this file without copying it to your own project's
folder.
```

## 4.2. Adding the Layers

Your layered portrait can have multiple layers. We recommend using `Node2D` as
grouping layers, and `Sprite2D` as the actual layers.
## 4. Filling the scene

There is no limitation what Node Types you use for your layers.
At the beginning the scene will have only a few nodes to get you started:

This will require some manual work, but it gives you control over how the
layers are organized. The node paths will be used in the
**Layer Command Syntax**; we will cover this in a later section.
![](media/layered_portrait/scene_empty.jpg)

You will usually have a "Base" layer, which should be the first Sprite we add. So we select the first Sprite, rename it to "Base", and drag our base texture into the inspectors `Texture` property.

Here is my scene structure:
For anything you have "variations" of, in this case for example the Eyes, Eyebrows, Mouths and Clothes, you'll want to have a "Group", like the one that is already in the scene. A group will later allow us to easily switch between these variations.

![Layered Scene: Complete](media/layered_portrait/layered_scene_complete.png)
By adding more Groups (Node2D) and Sprites (Sprite2D), naming them properly (we will use these later) and setting the textures, we will get something like this:

I left some of the layers hidden to define the default look of the portrait.
![](media/layered_portrait/scene_final.jpg)

## 4.3. Setting the Layered Portrait Scene
*Note: The Sprites of the Augustina example all fill the same rectangle. This means they are automatically all correctly positioned on top of each other. If your sprites cover different regions of the character, you might have to manually move them to be positioned correctly.*

Remember the file picker in the Character editor? Now is the time to use it!
Copy the path of your scene file and paste it into the file picker or navigate
to your scene file.

![Scene Picker: Layered Portrait](media/layered_portrait/portrait_settings_scene_set.png)

Once you have selected your scene file, you should be able to see your portrait
in the Character Editor's Preview.
Save the scene and head back to the character editor. If everything went right, you should now see your scene there:

![](media/layered_portrait/finished_portrait_in_editor.jpg)

## 5. Controlling the Layers
Hurray!

As of right now, you can use the `Character` event to control the layers.
The functionality is limited to the `join` and `update` variants of this event.
## 5. Controlling the Layers from the timeline

In Dialogic, this event accepts a parameter called `extra_data`. Using the Layer
Command Syntax, you can control the portraits from timelines using the
`extra_data`.
You can control these layers from the character event (when joining or updating). Any communication with the portrait scene happens via the `extra_data` parameter, for example like this:

Take a look at this example:
```tml
join agustina (Layered) 2 [animation="Heartbeat" extra_data="set Mouth/Smile"]
join Agustina center [extra_data="set Mouth/Happy"]
[wait_input]
update Agustina [extra_data="set Eyes/Wink, set Mouth/Laugh, set Clothes/Outfit2"]
```

In the visual editor you can use the same commands in the "Extra Data" field.

## 5.1. Layer Command Syntax

Here is a list of valid commands you can use in the `extra_data` parameter:
Expand Down Expand Up @@ -177,29 +112,12 @@ update agustina [extra_data="show Glasses/Normal, set Emote/Shock"]

# 6. FAQ

## 6.1. My Portrait is hovering above the Scene Ground

Make sure all of your layers have the correct size.

The Layered Portrait will use the size of all layers combined. If one layer is
extending further down than the others, it may appear floating above the ground
if the layer is not enabled.

Try enabling all of your layers and select all nodes, you will be able to see
all boundaries in the editor window of your scene.


## 6.2 My Portrait's Position is heavily off

If you use a `Control` (and comparable types), ensure that its position aligns
with the root's position. Otherwise, the overall coverage of your portrait
will be visually unpredictable in the editor.
## 6.1. My Portrait's Position is wrong

The layered portrait calculate the combined size of all the layers. If your layers have different sizes/positions, make sure no layer extends further then needed. Try enabling all of your layers and select all nodes, you will be able to see all boundaries in the editor window of your scene.

## 6.3 Do I have to use `CanvasGroup` as Root Node?
By default the Layered Portraits scripts `fix_offset` parameter (in the inspector under Layered Portrait/Private/fix_offset) is on. This will adjust the position based on the first sprite on the assumption that it will be the base sprite. For many portraits that makes it easier, but for more granular control you can turn it off. In that case your sprites should be positioned so that the top-left corner of your character is at the scene origin!

No, but if you use any transitions on your layered sprite, the player will see
every single layer fading at once.
## 6.2 Do I have to use `CanvasGroup` as Root Node?

If you have a Skin Layer covered mostly by a Dress Layer, you will see the Skin
and Dress layer fading in and out separately.
No, but it's the best at handling transitions.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit fa6e044

Please sign in to comment.