BveHacker.Scenarioプロパティに注意!「シナリオの読込が完了していないため、Scenario プロパティの値は取得できません。」と表示されたら
公開 2025/04/15
更新 2025/04/16
表題のようなエラーが表示される場合、BVE本体がシナリオを読み込み終わる前に、BveEXプラグインからシナリオへアクセスしようとしてしまっています。
次のようなコードがありませんか?
Scenario scenario = BveHacker.Scenario;
// -- あるいは --
BveHacker.Scenario.~略
BveHacker.Scenario
プロパティは、BVE本体がシナリオを完全に読み込んで以降でないと、取得することはできません。
具体的には、例えばBveEXプラグインのコンストラクタはシナリオの読込完了前になります。よって次のコードを実行すると表題のエラーが発生します。
public class PluginMain : AssemblyPluginBase
{
private AssistantText TestText;
public PluginMain(PluginBuilder builder) : builder
{
// 始発駅の距離程を取得して、補助表示に出力したい
// しかし、シナリオの読込完了前に BveHacker.Scenario プロパティへアクセスしているのでエラーとなる
double firstStationLocation = BveHacker.Scenario.Map.Stations[0].Location;
// 補助表示を作成・追加
TestText = AssistantText.Create($"始発駅の距離程は {firstStationLocation} m です。");
BveHacker.Assistants.Items.Add(TestText);
}
public void Dispose()
{
// 補助表示を削除・解放
BveHacker.Assistants.Items.Remove(TestText);
TestText.Dispose();
}
// ...略
}
プラグインを読み込んだ直後にシナリオを取得するには
BveHacker.ScenarioCreated
イベント を購読してください。
このイベントは BveHacker.Scenario
プロパティが取得可能となる直前に発生し、その中でシナリオへアクセスすることができます。
プラグインの Tick
メソッドの冒頭で読込直後かどうかを判定しても良いのですが、こちらを使用した方がよりスマートに実装できるのでおすすめです。
上記のエラーとなるコードと同等のものを BveHacker.ScenarioCreated
イベントで実装すると、次のようになります。
// using BveEx.PluginHost; を追加
public class PluginMain : AssemblyPluginBase
{
private AssistantText TestText;
public PluginMain(PluginBuilder builder) : builder
{
// イベントの購読
BveHacker.ScenarioCreated += OnScenarioCreated;
}
public void Dispose()
{
// イベントの購読解除を忘れずに
BveHacker.ScenarioCreated -= OnScenarioCreated;
BveHacker.Assistants.Items.Remove(TestText);
TestText.Dispose();
}
private void OnScenarioCreated(ScenarioCreatedEventArgs e)
{
// このイベント内でシナリオへアクセスする場合も、BveHacker.Scenario プロパティはやはり使用不可なので注意
// シナリオは ScenarioCreatedEventArgs の Scenario プロパティから取得できる
double firstStationLocation = e.Scenario.Map.Stations[0].Location;
TestText = AssistantText.Create($"始発駅の距離程は {firstStationLocation} m です。");
BveHacker.Assistants.Items.Add(TestText);
}
// ...略
}
BveHacker.Scenario プロパティが使用可能かどうかを知るには
BveHacker.IsScenarioCreated
プロパティ から取得可能です。
public class PluginMain : AssemblyPluginBase
{
public PluginMain(PluginBuilder builder) : builder
{
BveHacker.ScenarioCreated += OnScenarioCreated;
// false になる
bool isScenarioCreated = BveHacker.IsScenarioCreated;
}
public void Dispose()
{
BveHacker.ScenarioCreated -= OnScenarioCreated;
// false になる
// ここでも BveHacker.Scenario プロパティを使用できないことには変わりないため
bool isScenarioCreated = BveHacker.IsScenarioCreated;
}
private void OnScenarioCreated(ScenarioCreatedEventArgs e)
{
// true になる
bool isScenarioCreated = BveHacker.IsScenarioCreated; // true になる
}
// ...略
}
こちらも参考にどうぞ
- 書籍『BveEXプラグイン開発 ~入門から活用まで~』 P.102:「第6章-1節 シナリオの読込が完了したタイミングを知る」
- BveEXサンプルプラグイン「SoundFactoryサンプル」 PluginMain.cs