サンプルプログラム/グループに入ったドアの状態をチェックする

Last-modified: 2018-08-26 (日) 23:33:37

ターミナルで設定したグループを利用して、グループに入っているブロックだけを取得して扱う方法の解説です。

概要・準備

電源のほかに必要なブロックと設定

ブロックの設定
ブロック備考
テキストパネル×1名前は「Text panel Out
Show text on screenをオンにしておく
プログラマブルブロック×1このスクリプトを保存しておく
タイマーブロック×1プログラマブルブロックの
Run with default argument
ドア×複数グループ「Test Door
 
タイマーの設定
項目内容
Delay1秒など任意
ブロックアクション
プログラマブルブロックRun with default argument
同じタイマー自身Start

概要

スクリプトの完成形

public void Main(string argument) {
   var group1 = GridTerminalSystem.GetBlockGroupWithName("Test Door");
   var DoorList = new List<IMyDoor>();
   group1.GetBlocksOfType(DoorList);
   string outText = "";
   foreach (var targetDoor in DoorList) {
       string name = targetDoor.CustomName;
       string statusText = "Close";
       if(targetDoor.Open) {
           statusText = "Open";
       }
       outText += name + " : " + statusText + "\n";
   }
   var panel = GridTerminalSystem.GetBlockWithName("Text panel Out") as IMyTextPanel;
   panel.WritePublicText(outText, false);
}

機能・動作

実行されるたびに、「Test Door」グループに入っているドア全ての名前と状態を取得し、「Text panel Out」という名前のテキストパネルに下記のような形式で書き出します。

Door : Open
Door 2 : Close
Door 3 : Close

タイマーブロックを使って一定時間ごとに繰り返し実行すれば、ドアが開いているかを監視することができます。

解説

2~5行目:グループのブロックを全て取得して、その中から対象を取得する

2行目:指定した名前のグループに所属するブロックを全て取得する

var 変数名 = 探す範囲.GetBlockGroupWithName(グループ名);

var group1 = GridTerminalSystem.GetBlockGroupWithName("Test Door");

左辺でブロックのリストが入る変数を作っています。今回はグループのブロックをまとめて入れるので、「group1」としました。

次に右辺の処理です。GetBlockGroupWithNameは、ピリオドの左の対象物から、括弧()内の文字列と一致する名前のグループに入っているブロックを全て取得します。

探す範囲は複数のドアを開閉する ver2と同様で、その船のブロック全体を指す「GridTerminalSystem」を設定します。

グループの名前は、「Test Door」としました。


文字が流れるテキストパネルなどのように、argumentの中身を使うようなことももちろん可能です。

4行目:ドアを入れるリストを作る

var リストの変数名 = new List<インターフェースネーム>();

var DoorList = new List<IMyDoor>();

複数のドアを開閉する ver2と同様に、今回もDoorを入れられるリストを任意の名前で作ります。

リストの名前は「DoorList」にしました。

5行目:グループからドアをリストに入れる

探す対象範囲.GetBlocksOfType(リストの変数名);

group1.GetBlocksOfType(DoorList);

複数のドアを開閉する ver2と同様の、リストに入れられる種類のブロックを全てリストに入れる処理ですが、探す対象範囲として、先ほどグループで取得したブロック群が入っている変数group1を指定しました。

これにより、先ほど変数group1に入れられた、「Test」グループのブロック全ての中から、変数targetDoorsに入れることができる種類のブロックが、つまり「Testグループに入っているDoor」が変数targetDoorsに入ります。

7行目:書き込む内容の準備

変数の型 変数の名前 = 内容;

string outText = "";

まず、string(文字列)型の変数を用意し、中身を「空白も入っていない空っぽの文字列」にしました。

9行目:繰り返し処理部分

foreach (var targetDoor in DoorList) {
    //毎回の内容
}

foreach文ですべてのブロックを扱うために繰り返させるのは、複数のドアを開閉する ver2と同様です。

targetDoorsの中身を一つずつ、変数doorに入れて処理していきます。

繰り返しの中身

10行目:ドアの名前を取得

変数の型 変数の名前 = 対象.CustomName;

string name = targetDoor.CustomName;

複数のドアを開閉する ver2の応用編と同様に、string(文字列)型の変数nameを作り、変数targetDoorに入っているドアの名前を取得して入れています。

12~15行目:ドアの状態の文字列を作る

これはドアの状態をチェックするの応用編1とほとんど同じです。

string statusText = "Close";
if(targetDoor.Open) {
    statusText = "Open";
}

Openフィールドの読み取り結果はifの条件にそのまま使えるbool型なので、一旦変数に入れるのを省略して、if文の括弧()にそのまま入れている点だけが異なります。


string(文字列)型の変数statusTextを作って「Close」と書いておき、変数targetDoorに入っているドアが開いていればOpenに書き換えています。

17行目:1行分の文字列を繋いでoutTextに書き足す。

outText += name + " : " + statusText + "\n";

その周回で取得した情報で「ドア名 : 開閉状態」の文字列を作り、書き込み内容に追加します。


+=演算子は、左辺の変数を、左辺の元の内容に右辺の結果を足した結果に置き換えます。文字列の場合は、右辺の内容を後ろに繋ぐことになります。

今回の場合、outTextに入っている文字列の後ろに、「nameの中身」と「 : 」と「statusTextの中身」と「改行」を繋いだ1行分のデータを追加しています。

どちらが理解しやすいかは個人差があるので、+=を使用しなかった場合の書き方を下記に示します。

outText = outText + name + " : " + statusText + "\n";

先ほど変数outTextを作った際に「=""」で中身を空の文字列にしたのは、空の文字列すら入っていない新品の変数には「+=」で繋ぐことができないからです。

20行目~:テキストパネルに書き込む

ここは他のサンプルでやってきたことと同じです。

20行目:パネルの取得

var panel = GridTerminalSystem.GetBlockWithName("Text panel Out") as IMyTextPanel;

「Text Panel Out」という名前のパネルを取得して変数panelに入れます。

21行目:パネルへの書き込み

panel.WritePublicText(outText, false);

上の行で変数panelに入れたパネルのテキストを、outTextの内容に更新します。

コメント

  • 非常にわかりやすい解説をありがとうございます。おかげ様で、作っている船が完成しそうです。。 -- 2018-08-26 (日) 23:33:37