セリフの同時再生について

65 views
Skip to first unread message

harvestgames

unread,
Jun 17, 2025, 9:34:27 PM6/17/25
to 宴ユーザーグループ

こんにちは。いつも大変お世話になっております。

おかげさまで、貴社の素晴らしい製品のお力を借りて、日々快適かつ楽しくゲーム開発を続けられております。

現在制作中のプロジェクトにおいて、Utageを使用して吹き出し型の会話演出を実装しております。
通常の会話では MessageWindow を切り替えながら会話を進めることで、ほとんどの演出が問題なく実現できています。

しかしながら、本作に登場する主人公とヒロインの甘酸っぱい恋愛模様を表現するために、
「お互いの気持ちが急いてセリフがかぶってしまい、慌てながらも照れた様子を見せる」といった、
可愛らしい掛け合いを描きたいと考えております。

短いセリフであれば PageCtrl の BrPage を用いて似たような演出が可能ですが、
今回は10文字を超える少し長めのセリフのため、同様の手法では再現が難しい状況です。

そこで、以下のような手法を思いついたのですが、Utageで対応可能かどうかご教示いただけますと幸いです。

  1. セリフがかぶる部分だけシナリオを分割し、メッセージ表示速度を最大に設定する

  2. 一方のセリフを TextAnimator TypeWriter で再生し、その直後にもう一方のセリフを再生する

お忙しいところ恐縮ですが、アドバイスをいただけますと幸いです。
今後ともどうぞよろしくお願い申し上げます。

マッドネスラボ

unread,
Jun 18, 2025, 12:45:14 AM6/18/25
to 宴ユーザーグループ
内部的にはテキストの文字送り等の部分は拡張すれば可能だとは思います。

>一方のセリフを TextAnimator TypeWriter で再生し、その直後にもう一方のセリフを再生する
外部のアセットの使い方なので実装方法はお任せしますが、それが自力で実装可能なのであればそれで問題ないと思います。
ただし、宴のText Animator対応の拡張プラグインは、宴の表示文字数に同期するようになっているので、その機能と衝突しないようにしてください。

テキストの表示文字数の制御は、
AdvUguiMessageWindowTMPの継承元の、AdvUguiMessageWindowのUpdateCurrentメソッドの中で行っています。
//現在のメッセージウィンドウの場合のみの更新
protected virtual void UpdateCurrent()
{
if (!IsCurrent) return;

if (Engine.UiManager.Status == AdvUiManager.UiStatus.Default)
{
if (Engine.UiManager.IsShowingMessageWindow)
{
//テキストの文字送り
NovelTextComponentWrapper.SetMaxVisibleCharacters(text, textPro, Engine.Page.CurrentTextLength);
}
LinkIcon();
}
}

IsCurrentは、現在のメッセージウィンドウかどうかになります。
現在のメッセ―ジウィンドウではない場合は、これがfalseになっているので、処理がretuneされます。
その間は、表示文字数が上書きを別のプログラムから制御しても大丈夫だと思います。
細かい制御が必要な場合は、AdvUguiMessageWindowTMPをさらに継承するなどして、UpdateCurrentメソッドをoverrideしたメソッドを作成し、表示文字数をカスタムできるようにする必要があります。





2025年6月18日水曜日 10:34:27 UTC+9 harvestgames:

harvestgames

unread,
Jun 19, 2025, 9:40:36 AM6/19/25
to 宴ユーザーグループ

ご回答いただき、誠にありがとうございます。

ご案内いただいた内容をもとに、専用のウィンドウを実装いたしました。

同様の機能を必要とされる他のユーザーの参考になればと思い、実装したコードをあわせて添付させていただきます。

また、TextMeshProを使用する中で、フォールバックが発生した際に TextMeshPro の子オブジェクトとして SubMeshUI が生成され、
テキストを更新してもこれが削除されずに残る問題を確認いたしました。

この現象に対応するために、MessageWindow の OnTextChanged 関数内で TextMeshPro の ForceUpdate などを試みましたが、
SubMeshUI は削除されず残ったままでした。

この問題は、どうやら TextMeshPro の根本的な仕様に起因しているように思われます。

そこで対策として、テキスト更新時に TextMeshPro オブジェクトを一旦非アクティブ化し、再度アクティブ化することで
不要な SubMeshUI が除去されることを確認し、それを補完するコードも併せて共有いたします。

いつも大変有用に活用させていただいております。
今後ともよろしくお願い申し上げます。


2025년 6월 18일 수요일 오후 1시 45분 14초 UTC+9에 マッドネスラボ님이 작성:
AdvUguiBubbleMessageWindowTMP.cs

harvestgames

unread,
Jun 19, 2025, 9:42:08 AM6/19/25
to 宴ユーザーグループ
  参考までにお伝えしますと、TextAnimatorは使用せず、Utageのテキスト表示ロジックを使用しております。  

2025년 6월 19일 목요일 오후 10시 40분 36초 UTC+9에 harvestgames님이 작성:

マッドネスラボ

unread,
Jun 19, 2025, 10:56:07 AM6/19/25
to 宴ユーザーグループ
コードの共有ありがとうございます!

SubMeshUIは、UnityのTextMeshProのフォールバック機能を使っていると自動的に発生するものなので、 そういう仕様と考えてよいかと思います。
https://madnesslabo.net/utage/?page_id=13068#i-4

TextMeshProが使用するフォントアセットがフォールバックを使っていると、
複数のフォントテクスチャなどを使うので、描画オブジェクトも複数必要になる・・・といったイメージになるかと思います。


2025年6月19日木曜日 22:42:08 UTC+9 harvestgames:

harvestgames

unread,
Jun 19, 2025, 11:10:00 AM6/19/25
to 宴ユーザーグループ

おっしゃる通りです。
ただし、TextMeshProがリアルタイムでテキストを更新する際、フォントフォールバックに伴う SubMeshUI の処理がやや不完全であるように思われます。

フォールバックが発生した際に、以下のリンク先の記事にもあるように、
テキストが重なって表示される現象が発生し、見た目にも非常に良くないため、修正を試みました。

https://discussions.unity.com/t/unwanted-submesh-text-persistence/727758/2

4080139--355918--tmp3.PNG


2025년 6월 19일 목요일 오후 11시 56분 7초 UTC+9에 マッドネスラボ님이 작성:

harvestgames

unread,
Jun 19, 2025, 11:28:43 AM6/19/25
to 宴ユーザーグループ

あ、そしてお伝えし忘れておりましたが、セリフを同時に再生するロジックの処理手順は以下の通りです。

  1. シナリオ内で AdvCommandTimeCtrlText コマンドを、AdvUguiBubbleMessageWindowTMP を継承した MessageWindow に割り当てます。
     > Arg6には、セリフのウェイト時間を設定します。

  2. 続くセリフは、通常のセリフ再生コマンドを記述します。

このロジックにはいくつか致命的な課題がございます。

  1. 可能であれば SendMessage を使って実装したかったのですが、Utage内部の AdvCommandText のロジックをできる限り再利用し、互換性のある機能を実現したかったため、これを継承した AdvCommandTimeCtrlText を作成しました。

  2. そのため、AdvCommandParser に AdvCommandTimeCtrlText を使用するためのコマンド定義を追加する必要がありました。

  3. 完全に同時進行させるよりも、一部のセリフを先に再生し、次のセリフに繋げるような演出が非常に魅力的に感じたため、Arg6を利用しています。
     > しかし AdvCommandText を継承している関係上、Arg6は AdvCommandText と AdvCommandTimeCtrlText の両方に影響を与えてしまう、扱いづらい変数となっています。


このような制限があるため、公式的なサポート機能として提供するには、既存のUtageフォーマットに適した形で再設計する必要があると考えます。

あくまで私自身の環境に合わせて独自に修正・実装したものですので、
この機能を利用される場合は、ユーザー側でUtageの仕組みに対する十分な理解と、適切なソリューションかどうかの検討が必要となります。

2025년 6월 20일 금요일 오전 12시 10분 0초 UTC+9에 harvestgames님이 작성:
AdvCommandTimeCtrlText.cs

harvestgames

unread,
Jun 19, 2025, 11:35:25 AM6/19/25
to 宴ユーザーグループ
こちらはシナリオ内で設定した例となります。
TimeCtrlText は AdvCommandTimeCtrlText のコマンドIDです。  

1.JPG
2025년 6월 20일 금요일 오전 12시 28분 43초 UTC+9에 harvestgames님이 작성:

マッドネスラボ

unread,
Jun 19, 2025, 1:44:57 PM6/19/25
to 宴ユーザーグループ
ありがとうございます。

>このような制限があるため、公式的なサポート機能として提供するには、既存のUtageフォーマットに適した形で再設計する必要があると考えます。
>あくまで私自身の環境に合わせて独自に修正・実装したものですので、
はい。その方針は正しいと思います。
宴のテキスト表示コマンドはキャラクター表示コマンドと重複してしまっているため、
独立性が低く拡張性も低くなってしまっているので、直接的に拡張するのはちょっと限界がきています。

なので、既存のコマンドに特殊な処理を加えたい場合は、カスタムコマンドを使う今回のアプローチが一番良いかと思います。



2025年6月20日金曜日 0:35:25 UTC+9 harvestgames:
Reply all
Reply to author
Forward
0 new messages