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本体の処理がアクセスしてしまうことなく、正常にシナリオを終了・新たに読み込まれるようになります。
こちらも参考にどうぞ
- 書籍『BveEXプラグイン開発 ~入門から活用まで~』 P.150:「第9章-1節 別のシナリオを開く」