Should I dynamic Create Subtitle Panel in Run-time?

Announcements, support questions, and discussion for the Dialogue System.
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

Hi, I really love your asset, but it has high learning curve.

So, I don't know how to work with it exactly the way you design yet.

When a conversation has the potential to involve many characters, I think that a pre-set subtitle panel at fixed position is inefficient right?

Also, there is this weird behavior, and I don't know if it's a bug or not, I'm trying to test your "VN Template Standard Dialogue UI" with this conversation:
1. Actor: Chiyo, Conversant: Rora, Dialogue Text: Hello, Sequence: SetPanel(, 1, immediate); {{default}}
2. Actor: Rora, Conversant: Chiyo, Dialogue Text: Hello, Sequence: SetPanel(, 0, immediate); {{default}}
3. Actor: Rino, Conversant: Chiyo, Dialogue Text: Hello, Sequence: SetPanel(, 2, immediate); {{default}}
4. (END) Actor: Chiyo, Conversant: Rora, Sequence: SpineAnimation(Attack,,,false); SpineAnimation(Idle)@1; SpineAnimation(Die,listener,,false)@0.3

At step 3, when Rino appear, the Rora portrait disappear at the same time, then appear again at step 4.
And about Step 4, the reason why I hardcode it like that is I tried follow your "Example 3: Sending Messages" but it's not working for SpineAnimation, the Message "Done" instantly sent without execute spine animation "Attack": SpineAnimation(Attack,,,false)->Message(Done); SpineAnimation(Idle)@Message(Done); SpineAnimation(Die,listener,,false)@Message(Done);

Also, above is I'm testing SpineAnimation with SD Model which is object outside of Canvas as Actor and Conversant, I wonder what about the case using directly object inside Canvas as Actor and Conversant, like Spine2d Portrait?

Here is some question I need to ask:
1. Should I dynamic create Subtitle Panel at run-time and assign Actor to it?
2. Does current sequence already support move portrait?
3. Currently, for every Actor in conversation, I need to create a game object and assign Dialogue Actor to it, then chose the correct Actor, otherwise the sequence will throw error "Dialogue System: Sequencer: SetPanel(, Panel2): No actor named". Did I do it correctly?

So, basically, what I'm confusing when using your asset is I'm not sure what advanced action already supported, and what need to custom implement and how to exactly implement it in correct way to match with your system, there is not many advanced Example about 2D Visual Novel style.
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

Because the post is long and mark as spam so I split it into 2 reply
Below is the continue:

Let me tell you what my goal is:
1. Conversation can dynamically deal with unlimited Actor, when new Actor join in, old Actor Portrait can freely Move, spare space for them, or move back to old position when someone leave conversation, example for case 4 actor: sometime split equally on scene, sometimes it's look like 2 vs 2, 2 on left 2 on right, etc...
2. Sometime Actor portrait can use that Move with parameter to do some special action like jumping around or run off screen really fast.
3. Both SD model (for using outside Canvas) and Illustration Portraits (for using inside Canvas) are Spine2D animation with Idle, Laugh, Shaking, etc... with extra animation effect like a moving sweat, angry mark, etc... I really want to avoid using Unity Animator as much as possible because Spine2D give me more freedom.

Simply put it, my goal is on the Level of Blue Archive style.

At first, I indented to buy NaniNovel because it focuses on VN, but when I take a look as your asset, you use Node Graph with Variable, Event Trigger, Lua, etc... which is suitable for my taste as Coder, so I hope you can guide me the correct way to use your asset to achieve my goal.
User avatar
Tony Li
Posts: 23251
Joined: Thu Jul 18, 2013 1:27 pm

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by Tony Li »

Hi,

Thanks for using the Dialogue System!

The Dialogue System Extras page has a VN style dialogue UI example (direct download) that may be helpful. It doesn't use Spine, but the concept is the same.

If you have a chance to try it out and have any further questions, would you please post a mockup image of how you'd like your UI setup to work?
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

Thank for your reply, I have just wake up.

I tried the example you mentioned, by using [panel=x] instead of SetPanel(, x, immediate), it solved the bug of character Rora disappear on Step 3 I encountered.

But it's only demonstrating how to swap the panel, it hasn't covered the thing I asked yet, so let me ask the list of question again:
1. Should I predefine all the subtitle panel beforehand, or I can dynamically create it in run-time?
2. Has your system already supported moving portrait to target position?
3. Similar to AnimatorPlay which work for speaker/listener's portrait (I watched your "Dialogue System for Unity 2.x Dialogue UI Tutorial 3 - Animated Portraits" and I tried all sample scene related to animating in Extras page), as I see currently, Dialogue Actor script only support assign static portrait and portrait animator controller. Is there an equivalent version of spine? Does your system already support the SkeletonGraphic (Unity UI Canvas) used as Actor's Portrait? and the sequencer to control SkeletonGraphic portrait?

What I need for question 3 is same as how I call sequence SpineAnimation for Actor, it works normally, I just need a version for Actor's Portrait.
User avatar
Tony Li
Posts: 23251
Joined: Thu Jul 18, 2013 1:27 pm

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by Tony Li »

Hi,

I will take a look at this and reply in the morning. Sorry for the delay. We were migrating to a faster web server today.
User avatar
Tony Li
Posts: 23251
Joined: Thu Jul 18, 2013 1:27 pm

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by Tony Li »

Hi,

I'm sorry again for the delay in replying.

> 1. Should I predefine all the subtitle panel beforehand, or I can dynamically create it in run-time?

Predefine them. They will each have a panel number. For example, the example scene in the Dialogue System's Spine Integration has 3 panels, and the example scene in DS_SpineExamplePortraitsSimpler_2021-06-12.unitypackage has 4 panels:

panels.png
panels.png (108.1 KiB) Viewed 4194 times

> 2. Has your system already supported moving portrait to target position?

Yes, see the DS_SpineExamplePortraitsSimpler_2021-06-12 example. The portraits move to different panels. (If you mean different screen positions that aren't subtitle panels, let me know. It doesn't have any built-in method to do that.)


> 3. Similar to AnimatorPlay which work for speaker/listener's portrait (I watched your "Dialogue System for Unity 2.x Dialogue UI Tutorial 3 - Animated Portraits" and I tried all sample scene related to animating in Extras page), as I see currently, Dialogue Actor script only support assign static portrait and portrait animator controller. Is there an equivalent version of spine? Does your system already support the SkeletonGraphic (Unity UI Canvas) used as Actor's Portrait? and the sequencer to control SkeletonGraphic portrait?

Yes, use the SpineAnimation() sequencer command.
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

Thank you for your reply,

1. Regarding point #2:
It's not just about swapping panels with a teleport-like effect. What I mean is that the portrait should move dynamically to a new position with an offset, using different types of motion—such as linear movement, bouncing, etc. Most dialogue systems with a visual novel (VN) focus typically support this kind of basic portrait animation.

When I built my own custom dialogue system for learning purposes, this was one of the first features I implemented. That’s why I asked this question—because I couldn’t find this functionality covered in the tutorials, even though this is a well-established asset that has been around for a long time and supports many features.

If it's not supported out-of-the-box, I assume I can implement it by creating a custom sequence using SequencerCommandTemplate, correct?

2. Regarding your answer to point #3:
Could you please explain it in more detail? The example involving Spine is a bit confusing.

According to the documentation, it mentions using:
- SpineDialogueActor
- SpineSubtitlePanel
- SpineSequencerReferences

However, the older example (DS_SpineExamplePortraitsSimpler_2021-06-12) uses:
- SpineDialogueActor
- VN Template Standard Dialogue UI

Meanwhile, the latest example from the Spine Support package uses custom components:
- SpineDialogueActorUI
- SpineDialogueUI
- SpineSubtitlePanel

Are SpineDialogueActorUI and SpineDialogueUI important for production use? Or are they just example scripts meant for demonstration, since they’re placed in the Example folder (which is usually excluded from final builds)?

Additionally, I didn’t see any implementation of focus/unfocus states in the Spine examples. Is there a built-in solution for this, or would that require extra implementation?

Finally, what is the recommended combination of scripts (actor, UI, panel, etc.) to use together in a real project?
To clarify again, here is my goal:
- The actor's portrait is a SkeletonGraphic, and expressions are controlled via Spine animation.
- The Spine portrait can move freely around the screen with an offset, using different movement styles.
- The Spine portrait can support focus and unfocus states like regular 2D portraits in conversation.

If any of these features require custom implementation, please let me know, along with the recommended approach.
User avatar
Tony Li
Posts: 23251
Joined: Thu Jul 18, 2013 1:27 pm

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by Tony Li »

Hi,

> It's not just about swapping panels with a teleport-like effect. What I mean is that the portrait should move dynamically to a new position with an offset, using different types of motion—such as linear movement, bouncing, etc. ...
> If it's not supported out-of-the-box, I assume I can implement it by creating a custom sequence using SequencerCommandTemplate, correct?

Yes, if that's something you want, you can write a custom sequencer command. The Dialogue System has a Tweener class that you can use to tween values from one value to another (e.g., linear, ease, etc.). But the typical way is to use spine animation and the SpineAnimation() sequencer command to move the actor. (This assumes you're able to create an animation in Spine that moves the actor.)

See the additional setup in Additional Setup Options for additional info about setting up animations.


> Are SpineDialogueActorUI and SpineDialogueUI important for production use? Or are they just example scripts meant for demonstration, since they’re placed in the Example folder (which is usually excluded from final builds)?

Don't get thrown by the fact that these scripts are in Example. You can use them if you want, and they're built for production use. They allow you to use SkeletonGraphics (which are Unity UI elements) instead of SkeletonAnimations if you prefer. If you're using them, you can use custom conversation fields "Panel # Actor" and "Panel # Start Visible". For example, if you set "Panel 0 Actor" to actor ID 1, which is typically the Player, it will put the player in panel 0.

> Additionally, I didn’t see any implementation of focus/unfocus states in the Spine examples. Is there a built-in solution for this, or would that require extra implementation?

You can use Spine animations. Or, if you're using SkeletonGraphics, you can handle focus in the subtitle panel itself (e.g., a Canvas Group whose Alpha value is animated).

> Finally, what is the recommended combination of scripts (actor, UI, panel, etc.) to use together in a real project?

Since you're using SkeletonGraphics (not SkeletonAnimations):
  • Use a SpineDialogueUI instead of StandardDialogueUI on your dialogue UI.
  • Use SpineSubtitlePanel instead of StandardUISubtitlePanel on your subtitle panels.
  • To each of your characters, add a DialogueActor component and a SpineDialogueActorUI.
  • Use subtitle panel Show/Hide/Focus/Unfocus animations and/or SpineAnimation() sequencer commands. For your case, it sounds like SpineAnimation() commands will work best.
  • By default, subtitle panels' portrait images are designed with fixed positions. You will either need to use animation or make a subclass of SpineSubtitlePanel to handle animated movement of portrait image positions.
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

Thank you for your reply,

After carefully reviewing the system, I looked for any features that don’t have built-in support so I could implement them myself.

I prefer to stick as closely to your architecture as possible to avoid conflicts during future updates. With that in mind, I implemented the following structure, which I found works really well for SkeletonGraphic.

For dynamically assigning portraits and their animators (for Show/Hide/Focus/Unfocus), I followed a similar structure to how you assign sprite portraits. I created a Spine portrait using an empty SkeletonGraphic component placed next to the "Portrait Image", then used the following script on the actor:
```
/// <summary>
/// This addon for the DialogueActor component handles a Spine character avatar.
/// If a SpineSubtitlePanelCustom finds a SpineDialogueActorCustom, it uses its Show and Hide methods.
/// </summary>
[RequireComponent(typeof(DialogueActor))]
public class SpineDialogueActorCustom : MonoBehaviour
{
public SkeletonDataAsset SkeletonDataAsset;

public virtual void Show(StandardUISubtitlePanel subtitlePanel)
{
if (SkeletonDataAsset == null) return;

var skeletonGraphic = subtitlePanel.GetComponentInChildren<SkeletonGraphic>();
if (skeletonGraphic == null) return;
skeletonGraphic.skeletonDataAsset = SkeletonDataAsset;
skeletonGraphic.Initialize(true); // Rebuilds and redraws the skeleton properly
skeletonGraphic.enabled = true;
}

public virtual void Hide(StandardUISubtitlePanel subtitlePanel)
{
subtitlePanel.GetComponentInChildren<SkeletonGraphic>().enabled = false;
}
}
```
This script references SpineSubtitlePanel. I simply replaced "SpineDialogueActor" with "SpineDialogueActorCustom".

Boom! After replacing the "Portrait Animator Controller" in the Subtitle Panel with a "Spine Portrait Animator Controller" (which controls SkeletonGraphic instead of a regular Image), everything worked perfectly.

I control SkeletonGraphic.color the same way as Image.color, but with a slight workaround using the script below:
```
[RequireComponent(typeof(SkeletonGraphic))]
public class SkeletonGraphicColorBridge : MonoBehaviour
{
[Header("Use these in Animator")]
[ColorUsage(true, true)]
public Color bridgeColor = Color.white;

private SkeletonGraphic skeletonGraphic;

void Awake()
{
skeletonGraphic = GetComponent<SkeletonGraphic>();
}

void Update()
{
if (skeletonGraphic != null)
{
// Apply the bridge color every frame
skeletonGraphic.color = bridgeColor;
}
}
}
```
Since modifying SkeletonGraphic.color directly in the Animator doesn't work, I use this bridge script to control the color and sync it with SkeletonGraphic.color.

With this setup, conversations work just like before, with the subtitle animator handling everything. There's almost no conflict, and I didn’t need to modify any core system scripts.

Next, I just need to create a custom SpineSequencerReferences for extra animations, since I no longer assign Spine objects directly.

This is just how I got it working. If it fits your direction, I hope it might be something you consider integrating into your asset in the future—with your own improvements, of course.
bmringo
Posts: 11
Joined: Tue May 27, 2025 9:02 am

Re: Should I dynamic Create Subtitle Panel in Run-time?

Post by bmringo »

I forgot to mention an important detail about controlling SkeletonGraphic.

Spine’s color handling doesn’t work well with the default CanvasGroup.alpha. As the alpha approaches 0, it causes higher contrast before finally disappearing, which doesn't look good. Instead, we need to control the fade using SkeletonGraphic.color to ensure smooth behavior. The default method already works decently, but you may still notice some overlapping layers, which can make parts appear darker than intended when fade out. Spine provides a custom render texture solution that allows for much cleaner and more natural fade-outs.

As a result, I can now achieve smooth fade-in and fade-out effects, and the Focus/Unfocus transitions work perfectly by adjusting just the SkeletonGraphic.color with an RGB value of 0.25.
Post Reply