【C#】マイクラで矢を飛ばすプログラム

前回はプレイヤーにパーティクルを付与しつつ、爆発させるような魔法攻撃を再現しました。今回は矢を連続で打ち込むような攻撃をプログラムから実行してみます。(エミヤさんの例の技っぽいやつの再現です。)

こちら参考画像になります。

f:id:takunology:20210825124633p:plain

準備

1. コマンド

必要なコマンドは矢を召喚するコマンドと、矢を飛ばすコマンド、矢を消すコマンドです。矢は消さないとマイクラが重たくなるので、矢を撃って見えなくなる距離になったら消すようにしましょう。また、矢を1本ずつ制御したいのでNBTを使用して、召喚した矢1本1本に名前をつけます。

名前をつけるためには CustomName の NBT を使用します。書き方は CustomName:'{"text":"名前"}' です。また、矢は放置すると重力に従って落下してしまうため、NoGravity:true も付け加えておきましょう。これらを使用して、矢を召喚するコマンドはこのように書けます。

summon arrow ~ ~ ~ {NoGravity:true,CustomName:'{"text":"arrow01"}'}

次に、矢を撃つコマンドですが、data modify にて Motion NBTをつける事で任意の方向へ矢を飛ばすことができます。

data modify entity @e[name="arrow49",limit=1] Motion[2] set value 1.5

ここで、Motion[2] は z 座標です。Motion[0] にすると x 座標に撃ち出すことができます。

最後に、矢を消すコマンドです。ここでは kill コマンドを使用します。

kill @e[type=arrow]

これで準備完了です。

2. プログラム

あとは以上のコマンドを実行するようなプログラムを書きます。途中で、時間待機を挟むことで連続で撃ち出しているような演出にすることが出来ます。また、前回作成したパーティクル

プログラムを書く際には MinecraftConnection パッケージを導入してください。

www.nuget.org

ここからサンプルコードです。

using System;
using System.Collections.Generic;
using MinecraftConnection;

namespace Arrow
{
    class Program
    {
        static string address = "127.0.0.1";
        static ushort port = 25575;
        static string pass = "minecraft";
        static MinecraftCommands commands = new MinecraftCommands(address, port, pass);

        static List<string> EntityName = new List<string>();

        static void Main(string[] args)
        {
            var data = commands.GetPlayerData("takunology");
            SummonArrows(data.PositionX, data.PositionY, data.PositionZ, 50);
            commands.Wait(1000);
            Shoot(EntityName, 1.99);
            commands.Wait(3000);

            //矢を消す
            commands.SendCommand("kill @e[type=minecraft:arrow]");
        }

        //プレイヤーの周りに矢を召喚させる
        static void SummonArrows(int x, int y, int z, int count)
        {
            Random rnd = new Random();
            
            for (int i = 0; i < count; i++)
            {
                PrticleComposter(x, y, z);
                commands.SendCommand($"summon arrow {x + rnd.Next(-4, 4)} {y + rnd.Next(2, 5)} {z + rnd.Next(0, 2)} " + "{NoGravity:true,CustomName:'{\"text\":\"arrow" + i + "\"}'}");
                EntityName.Add($"arrow{i}");
                commands.Wait(20);
            }
        }

        //召喚した矢を撃つ
        static void Shoot(List<string> Arrows, double speed)
        {
            foreach(var item in Arrows)
            {
                commands.SendCommand("data modify entity @e[name=\"" + item + "\",limit=1] Motion[2] set value " + speed);
                commands.Wait(5);
            }
        }

        //パーティクル
        static void PrticleComposter(int x, int y, int z)
        {
            string name = "composter";
            double dx = 1.0, dy = 0.5, dz = 1.0;
            double speed = 1.0;
            int count = 20;
            commands.SendCommand($"particle {name} {x} {y} {z} {dx} {dy} {dz} {speed} {count}");
        }
    }
}

プレイヤー名や乱数などは皆さんの環境に合わせてください。

3. 実行結果

つ よ そ う 。

イベントのお知らせ

2021年8月27日(金)20:00 より、MS Tech Camp #10 を開催します!
今回は Azure Functions の .NET ランタイムとC#プログラミングを使用して、Minecraft で花火を打ち上げます。 Azure Functions や マイクラプログラミング(C#)に興味のある方、ぜひご参加ください!(Minecraft Java 版でも統合版でもご参加いただけます)

mspjp.connpass.com

夏の思い出に「マイクラ花火」いかがでしょうか?