サンプルプログラム/hello, world

Last-modified: 2017-01-17 (火) 22:12:34

初歩的なゲーム内スクリプトとして、プログラマブルブロックとテキストパネルを1対1で、文字列を書き込むスクリプトを作ってみましょう。

hello_world.jpg


概要

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

種類と数備考
Text panel×1名前を「Text panel Test」にしておく
Show text on screenをオンにしておく
Programmable Block×1内容は下記で解説

スクリプトを準備する前に、プログラマブルブロックとテキストパネルのOwner(所有権者)が「両方ともMe」または「両方ともNobody」になっていることを確認しておきましょう。

これは、敵のブロックをプレイヤーが操作できないのと同様に、操作する側のブロックが、操作される側のブロックを操作して良い立場でないと動かないからです。

サンプルプログラムの完成形

先に全体像を提示しておきます。

public void Main(string argument) {
    IMyTextPanel target;
    target = GridTerminalSystem.GetBlockWithName("Text panel Test") as IMyTextPanel;
    target.WritePublicText("hello, world", false);
}

このスクリプトを、上記の準備ができている船やステーションにあるプログラマブルブロックのエディタに書くかペーストし、「Remember & Exit」で保存して「Run」(実行)ボタンをクリックすると、「Text panel Test」という名前になっているテキストパネルに「hello, world」と表示します。

解説

プログラムが空の状態から書いていく形で解説します。

準備

プログラマブルブロックの「Edit」ボタンをクリックしてエディタを開きます。デフォルトで色々書かれていますが、とりあえず使わない部分とコメントを省いて残るのは下記部分です。まずはこれをエディタにコピペするか、これだけを残して削除しましょう。

public void Main(string argument) {
}

現時点では、プログラマブルブロックを実行(Run)した際に、このMainメソッドという部分の波括弧{}の中に書かれたコードが上から順に実行されるという点だけ把握していればOKです。

2~3行目:ブロックの取得

2行目:ブロックを入れるための変数を作る

変数の型 変数の名前;

ブロックのインターフェースネーム 変数の名前;

IMyTextPanel target;

2行目では、操作したいブロックを入れるための変数を、任意の名前で作っています。

データを変数に入れて扱うことをゲーム内に例えるなら、ツールやブロックをツールバーの好きなボックスに入れてキーボードから選択できるようにすることや、ターミナルメニューでブロックに適切な名前を付けてツールバー設定から見つけられるようにすることが近い…かもしれません。

変数を作る際は、どんな操作をしていいのかをプログラムが判別できるように、どんな種類のデータが入るのかを示す「変数の型」を名前の前で宣言する必要があります。

Space Engineersのゲーム内スクリプトでブロックを扱う場合、そのブロックのInterface name(インターフェースネーム)(ブロックの種類名とは別の、プログラムで扱うための名前)を型として書きます。

今回扱いたいのはテキストパネルなので、公式ガイドから「Text panel」の「Interface name」を探すと「IMyTextPanel」であることが分かります。なので、これを型名として設定しました。

変数の名前は、今回は操作したい目標物ということで「target」(ターゲット)としました。

余談ですが、IMyTextPanelは公式ガイドの書き方ではテキストパネルだけを扱う物ですが、追加されたLCD Panelなどの同系列ブロックもIMyTextPanelで扱うことができるので、ブロック名をちゃんとすればLCDパネルなども今回のスクリプトで操作することができます。

3行目:ブロックを変数に入れる

変数の名前 = GridTerminalSystem.GetBlockWithName(ブロックの名前) as インターフェースネーム;

target = GridTerminalSystem.GetBlockWithName("Text Panel Test") as IMyTextPanel;

3行目では、「=」を使用して、右辺の処理の結果を、左辺の変数の内容として設定します。

まず、結果を入れる変数として、2行目で作成した「target」変数を指定しています。


続いて右辺の処理についてです。

GridTerminalSystem.GetBlockWithName() as ~は、括弧()内の文字列に完全に一致する名前のブロックを、asの後で指定した種類のブロックとして取得する処理です。もし同じ船に同名のブロックが複数存在すれば、最初に見つかったものだけが取得されます。なお、大文字と小文字が区別されることに注意が必要です*1

今回は「Text panel Test」としたので、ブロック名がそれに完全に一致するブロックを取得します。

もちろん、必要に応じてこの部分を変更すれば、好きな名前のブロックで利用することができます。

引用符の有無については「任意の文字列をプログラム内で使うために直接書くときは二重引用符""で囲う」とだけ今のところは覚えておきましょう。

インターフェースネームは、先ほど「target」変数に指定したのと同じく「IMyTextPanel」に設定しました。

ここまでのスクリプト

public void Main(string argument) {
    IMyTextPanel target;
    target = GridTerminalSystem.GetBlockWithName("Text panel Test") as IMyTextPanel;
}

現時点では、「『target』と名付けた変数に、『Text panel Test』という名前のブロックをテキストパネルであるという情報付きで入れて終了する」だけで何もしないスクリプトです。この後は、変数に入れたブロックを操作する処理を追加します。


省略した書き方

省略した書き方

上記では1行ごとの処理を1つにするために、変数を作る処理と変数に入れる処理を分けましたが、下記のように、変数を作ると同時にデータを入れることも可能です。サンプルの2行目と3行目を削除して、代わりにこの1行に変えても同じ動作になります。

IMyTextPanel target = GridTerminalSystem.GetBlockWithName("Text panel Test") as IMyTextPanel;

変数を作ると同時にブロックを入れる場合、変数の型は、自動で決めてくれる「var」という型で済ませることもできます。

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

4行目:空白行

4行目には何も書いていない行を挟んでいますが、これはブロックの取得とブロックの操作を分けて見やすくするためなので、無くしても増やしても特に問題はありません。

5行目:ブロックの操作(テキストの書き込み)

操作対象.WritePublicText(文字列, 追記するかどうか);

target.WritePublicText("hello, world", false);

5行目の処理、WritePublicTextは、操作したい対象の後にピリオドを挟んで書くことで、後ろの括弧()内でカンマより前に入れられた文字列を操作対象のPublic Textに書き込む、テキストパネル類のための処理です。

書き込む文字列は、今回は先ほどのブロック名と同様に直接設定しているので引用符で囲います。


カンマから後ろの部分では、true(真)とfalse(偽)の2つの値で状態を判別する、いわゆるフラグのような形式を使って、パネルに既に書かれている内容の後に追記するか、そうでないかを決めるようになっています。true(真)なら追記し、false(偽)ならパネルの内容を消去してから書き込みます。

今回は追記せずに更新する「false」を選びました。

これで、ページ上部で示した「『Text panel Test』という名前のテキストパネルのPublic Textに『hello, world』と書く」スクリプトが完成しました。

補足

ツールバーから実行する場合

このスクリプトは「argument」というものを使用していないので、操縦席やボタンパネルなどのツールバーに設定して使用する場合は、「Run with default argument」を割り当てます。

文字列の改行など

下記のように、helloとworldの間を消して、「\n」(左の半角バックスラッシュが、環境によって半角の¥マークに変化しているかもしれませんが、同じキー操作で入力でき、コピペしてもゲーム内ではちゃんとバックスラッシュに変わります。)を入れて動かしてみましょう。

target.WritePublicText("hello, world", false);

target.WritePublicText("hello\nworld", false);

すると、パネルの表示では

hello
world

といった風に改行されます。

バックスラッシュは、特殊な文字などを入れるための記号で、「\n」と書くとその2文字の代わりに、そこで改行が行われます。

他に主要なものとしては、意味があって使えない記号をそのまま使うための物があります。例えば二重引用符""で囲まれた中で二重引用符を書きたい時は「\"」と書けば、バックスラッシュ直後の"が、文字列の終わりの"として扱われないようにできます。また、バックスラッシュ自体を書きたい場合も同様に「\\」と2つ続けて書くことで、2個目の\が単なる\であることを表現し、表示できます。

まとめ

このページでは、1つのテキストパネルを名前で見つけ、文字列を書き込むスクリプトを解説しました。

ここまでの知識でも、まだプログラマブルブロック1つにつき1パターンですが、特定のテキストパネルを好きな文字列に書き換える操作が作れます。

例えば格納庫扉を開く時用と閉じる時用のタイマーにプログラマブルブロックを1つずつ組み込んで、それぞれでパネルに書き込む文字列を変えることで、指令室に置いたパネルに開いているか閉まっているかを表示するようなことが、とりあえず可能になります。

応用編リンク

おまけ

上記で少しだけ触れた、省略した書き方を使ったスクリプト全文。

変数の作成と代入を1行にまとめた例。

長くてレイアウトが崩れるので格納
public void Main(string argument) {
    IMyTextPanel target = GridTerminalSystem.GetBlockWithName("Text panel Test") as IMyTextPanel;
    target.WritePublicText("hello, world", false);
}

さらにvar型で済ませた例。

public void Main(string argument) {
    var target = GridTerminalSystem.GetBlockWithName("Text panel Test") as IMyTextPanel;
    target.WritePublicText("hello, world", false);
}

コメント


*1 特にLCD類は「Panel」のPの大小が一貫していないので…