![](https://static.wixstatic.com/media/ea798a_45d15e9c75c847578ff54470f42acb51~mv2.jpg/v1/fill/w_1920,h_1080,al_c,q_90,enc_avif,quality_auto/ea798a_45d15e9c75c847578ff54470f42acb51~mv2.jpg)
ミサイルで敵を撃墜!
発射台のプログラマブルブロックに発射コマンドを送ると、ミサイルは 1 機ずつ順次発射されます。発射コマンドは、"Launch" に続いて目標ポイントの X, Y, Z 座標がコンマで区切られて続く文字列で、この文字列をコマンドライン引数として以下の「発射台プログラム」を実行します。
発射台プログラム
1| int counter = 0;
2| bool Launching = false;
3| string targetx = "";
4| string targety = "";
5| string targetz = "";
6|
7| public void Main(string argument, UpdateType updateSource)
8| {
9| string pb_name = "";
10| IMyProgrammableBlock PB;
11|
12| var com = argument.Split(',');
13|
14| if (com[0] == "Launch"){
15| Launching = true;
16| targetx = com[1];
17| targety = com[2];
18| targetz = com[3];
19| Runtime.UpdateFrequency = UpdateFrequency.Update10;
20| }
21|
22| if (Launching){
23| pb_name = "PB"+(counter+1).ToString();
24| PB = GridTerminalSystem.GetBlockWithName(pb_name) as IMyProgrammableBlock;
25| PB.TryRun("Launch, " + targetx + ", " + targety + ", " + targetz);
26|
27| counter++;
28|
29| if (counter > 24){
30| Runtime.UpdateFrequency = UpdateFrequency.None;
31| Launching = false;
32| counter = 0;
33| }
34| }
35| }
発射コマンドを受けた発射台プログラムはさらに、各ミサイルに 1 台搭載されているプログラマブルブロックに対し、順次発射コマンドを目標座標と共に送信します(23 - 25 行)。この各ミサイルへの発射コマンドの送信は、Runtime.UpdateFrequency (19 行) を設定することで 10 ticks 毎に繰り返し実行され、25 機すべてを発射した後、周期実行を停止 (30 行) して発射シーケンスを終了します。
ミサイルプログラム
1| Vector3D targetGPS;
2| bool Operating = false;
3| IMyShipMergeBlock merge;
4| List<IMyThrust> thrusters = new List<IMyThrust>();
5| List<IMyGyro> gyros = new List<IMyGyro>();
6|
7| public void Main(string argument, UpdateType updateSource)
8| {
9| var command = argument.Split(',');
10|
11| if (command[0] == "Launch"){
12| Runtime.UpdateFrequency = UpdateFrequency.Update1;
13| targetGPS.X = float.Parse(command[1]);
14| targetGPS.Y = float.Parse(command[2]);
15| targetGPS.Z = float.Parse(command[3]);
16| Launch();
17| Operating = true;
18| }
19|
20| if (Operating)
21| Operation();
22| }
23|
24| private void Launch()
25| {
26| merge = GridTerminalSystem.GetBlockWithName("MB1") as IMyShipMergeBlock;
27| merge.ApplyAction("OnOff_Off");
28|
29| GridTerminalSystem.GetBlocksOfType(thrusters);
30| foreach(var thruster in thrusters)
31| thruster.SetValue("Override", 900000f);
32|
33| GridTerminalSystem.GetBlocksOfType(gyros);
34| }
35|
36| private void Operation()
37| {
38| Vector3D destV = targetGPS - Me.GetPosition();
39| Vector3D LV = Me.WorldMatrix.Left;
40| Vector3D DV = Me.WorldMatrix.Down;
41| float scaling_factor = 10;
42| destV.Normalize();
43|
44| double angleL = Math.Acos(LV.X*destV.X + LV.Y*destV.Y + LV.Z*destV.Z);
45| double angleD = Math.Acos(DV.X*destV.X + DV.Y*destV.Y + DV.Z*destV.Z);
46|
47| foreach(var gy in gyros){
48| gy.SetValue("Override", true);
49| gy.SetValue("Yaw", (Single)(scaling_factor*(Math.PI/2-angleL)));
50| gy.SetValue("Pitch", (Single)(-scaling_factor*(Math.PI/2-angleD)));
51| }
52| }
発射コマンドを受け取った各ミサイルは、ミサイルを発射台に固定しているマージブロックを切り離し (26 - 27 行) 、スラスターを全開にして飛び立ちます (29 - 31 行)。その後、1 tick 毎にミサイルの姿勢制御を繰り返して目標に向かって飛行します。目標への方向と現在のミサイルの向きのズレを計算し、ジャイロにこのズレ角度が 0 に近づくような入力をすることで、ミサイルが常に目標の方向を向けて飛行するように姿勢制御しています。