コルーチンではシナリオジャンプができなくなる現象について

256 views
Skip to first unread message

mikazuki

unread,
Aug 10, 2018, 2:14:58 AM8/10/18
to 宴ユーザーグループ
Unityの習熟度: 独学3年
宴のバージョン: 3.4.3
UnityのバージョンとOS: Unity2017.4.6f1 Windows

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

下記のように、プログラムからシナリオラベルを呼び出すメソッドを使用しております。

public void ScnarioJump(string scenarioLabel)
{
Debug.Log("scenarioLabel:" + scenarioLabel);
//シナリオジャンプ        
//WaitCsutomの解除する命令文
engine.UiManager.IsInputTrigCustom = true;

//指定したシナリオラベルにジャンプする命令文
engine.JumpScenario(scenarioLabel);
}

通常のメソッドから上記ScnarioJumpメソッドを呼び出すと、シナリオジャンプできるのですが、コルーチン(IEnumerator)から上記メソッドを呼び出したり、あるいはコルーチンの中に直接
engine.UiManager.IsInputTrigCustom = true;
engine.JumpScenario(scenarioLabel);
を記述すると、シナリオジャンプすることができません。

IEnumerator Scenario(string scenarioLabel)
{
            
yield return new WaitForSeconds(2.0f);
     

//WaitCsutomの解除する命令文
engine.UiManager.IsInputTrigCustom = true;

//指定したシナリオラベルにジャンプする命令文
engine.JumpScenario(scenarioLabel);             //ジャンプできません
     
}



通常のメソッド同様、コルーチンからもシナリオジャンプする方法がございましたらご教示ください。
何卒よろしくお願い申し上げます。

マッドネスラボ

unread,
Aug 10, 2018, 4:57:05 AM8/10/18
to utag...@googlegroups.com
確認しましたが、不具合を再現できませんでした。
おそらくですが、コルーチンの扱い自体に問題があるのだと思います。

JumpScenarioの直前にDebug.Logやブレークポイントを置くなどして、本当にその箇所まで到達しているか確認してください。
その箇所まで到達していない場合は、次のような原因が考えられます。

・コルーチンをStartCoroutineで呼んでいない
StartCoroutineをしたあとに、コンポーネントのenableをfalseにしたり、そのコンポーネントのGameObjectのActiveをfalseにしている(Unityの仕様でコルーチンは強制終了します)

mikazuki

unread,
Aug 10, 2018, 6:25:51 AM8/10/18
to 宴ユーザーグループ
ご返信いただきありがとうございます。
こちらでもDebug.Logを置いて、到達しているかどうか確認したのですが、engine.JumpScenario(scenarioLabel);まで到達しているようです。
もし宴に関係しない質問であったら申し訳ないのですが、再現するプロジェクトを作成させていただきました。


<再現手順>
1.ゲームを再生し「はじめから」を押すと、メッセージウィンドウにメッセージが表示されます。
2.クリックすると、GuiActiveにより、Hierarchyウィンドウ > AdvEngine > MainGameTestゲームオブジェクトがアクティブになります。
3.MainGameTestゲームオブジェクトにアタッチされているMainGameTest.csのOnEnableより、コルーチンとInvokeが開始されます。
4.コルーチンとInvokeではシナリオジャンプできませんが、MainGameTest.csの22行目のコメントアウトをなくし、通常のメソッドからシナリオジャンプを行うと、目的のシナリオラベルにジャンプできます。


お手数おかけして恐縮ですが、ご助言いただけますと幸いです。
何卒よろしくお願い申し上げます。

mikazuki

unread,
Aug 10, 2018, 6:29:58 AM8/10/18
to 宴ユーザーグループ
大変申し訳ございません、先ほどお送りしたプロジェクトに不備がございました。
再度送り直しさせていただきます。

マッドネスラボ

unread,
Aug 10, 2018, 2:15:15 PM8/10/18
to 宴ユーザーグループ
確認しました。
これ、本当に難しいんですが、
原因はこっちのほうです。
        engine.UiManager.IsInputTrigCustom = true;
これをコルーチンで呼び出しても、そのフレームでの入力受付に対しての処理自体がすでにもう終わっているので結果的に入力がされていない状態になります。

通常のUnityでは
・入力処理
・Update
・コルーチン
の順番で実行されます。

宴のWaitCustomの場合は
・入力処理(場合によってはIsInputTrigCustom =trueに)
・Update(場合によってはIsInputTrigCustom =trueに)
・コルーチン(IsInputTrigCustomのチェック)
の順番で実行されます。

コルーチンの中でIsInputTrigCustom =trueをしてしまうと
・入力処理
・Update
・宴が呼び出すコルーチン(IsInputTrigCustomのチェック)
・自作スクリプトでのコルーチン(IsInputTrigCustom =true)
の順番で実行されるので、すでにチェックが終わっているので入力処理が間にあいません。


「宴が呼び出すコルーチン」と「自作スクリプトでのコルーチン」の順番が制御できればまだいいんですが、
Unityの仕様では、コルーチン同士の実行順の制御は基本的にできないようで、おそらく呼び出した順番になるのだと思います。
(ドキュメントがなかったので不正確です)


対策としては、
1、WaitCustomのかわりに、PauseScenarioコマンドを使う
PauseScenarioは会話シーンなどで使う場合に用意したコマンドです。

これを呼ぶと、プログラム上ではJumpScenarioが呼ばれるか、engine.ResumeScenario() が呼ばれるまでシナリオの進行を止めます。

2、いったんシナリオを終わらせてからジャンプ
engine.EndScenario();
engine.JumpScenario("ジャンプしたいシナリオ");
とする。ただし、この場合は表示されているものなどはすべてリセットされます。

上記などで対策してみてください。

mikazuki

unread,
Aug 10, 2018, 6:47:30 PM8/10/18
to 宴ユーザーグループ
お教えいただきありがとうございます。
WaitCustomのかわりにPauseScenarioコマンドを使うことで、目的の動作を行うことができるようになりました。
(ゲーム内でパラメータを操作しているため、2.の方法ではなく1.の方法を選択しました。)

宴(Excel)でゲームを止める際、いつもWaitCustomを使用しているのですが、今開発しているゲームではしばしばコルーチンを使用することがございますので、今後はPauseScenarioコマンドを使用しようと考えております。
その際、PauseScenarioコマンドを使用する箇所は最小限にしておいた方が良いでしょうか?(=コルーチンを使用する箇所のみPauseScenarioコマンドを使用し、コルーチンを使用しない部分はWaitCustomのままにしておいた方が良いでしょうか?)
それとも、宴(Excel)内のWaitCustomを全てPauseScenarioコマンドに置き換えても特に問題ないでしょうか。

何卒よろしくお願い申し上げます。

マッドネスラボ

unread,
Aug 10, 2018, 7:09:11 PM8/10/18
to 宴ユーザーグループ
WaitCusotomと解除の方法が違う点だけ注意してください。
それ以外では特に問題ないかと思います。

mikazuki

unread,
Aug 10, 2018, 7:10:44 PM8/10/18
to 宴ユーザーグループ
かしこまりました。ありがとうございます。
Reply all
Reply to author
Forward
0 new messages