岡オカ営業所 ホームへ

Tickメソッドの中でMainForm.OpenScenarioを呼び出してはいけない

公開 2025/04/16

新しいシナリオを開始することができる MainForm.OpenScenario メソッド。 連続する複数シナリオを自動で切り替えたり、特定条件を満たしたときにのみ隠しシナリオを出現させたりするのに便利ですが、 BveEXプラグインのTickメソッドでこのメソッドを呼び出すとエラーが発生してしまいます。

例えば、次のコードを実行するとエラーとなります。

public class PluginMain : AssemblyPluginBase
{
    // ...略

    public override void Tick(TimeSpan elapsed)
    {
        // 12 時になったらシナリオを開きたい
        if (12 <= BveHacker.Scenario.TimeManager.Time.TotalHours)
        {
            BveHacker.MainForm.OpenScenario("シナリオファイルへのパス");
        }
    }

    // ...略
}

原因を簡潔に言うと、MainForm.OpenScenario メソッドを実行するとシナリオ関連のオブジェクトが解放されるものの、 Tick メソッドの実行終了後、BVE本体の処理が解放済のオブジェクトにアクセスしてしまうことによるものと思われます。

解決策

メインフォームの Paint イベントを購読し、その中で MainForm.OpenScenario メソッドを呼び出してください。

public class PluginMain : AssemblyPluginBase
{
    public PluginMain(PluginBuilder builder) : base(builder)
    {
        BveHacker.MainFormSource.Paint += OnPaint;
    }

    public override void Dispose()
    {
        // イベントの購読解除を忘れずに
        BveHacker.MainFormSource.Paint -= OnPaint;
    }

    private void OnPaint(object sender, PaintEventArgs e)
    {
        // 12 時になったらシナリオを開く
        if (BveHacker.IsScenarioCreated && 12 <= BveHacker.Scenario.TimeManager.Time.TotalHours)
        {
            BveHacker.MainForm.OpenScenario("シナリオファイルへのパス");
        }
    }

    // ...略
}

こうすることで、MainForm.OpenScenario メソッドの実行によって解放されたオブジェクトへBVE本体の処理がアクセスしてしまうことなく、正常にシナリオを終了・新たに読み込まれるようになります。

こちらも参考にどうぞ

ブログ トップへ戻る