以前、はてなブログの方に Unity で ArtNet を扱う内容に関して投稿しました。
Unity で ArtNet を受け取るプログラムとエディタ拡張を GitHub で Public に公開したので、今回はその内容についての記事を書こうかなと思います。
ArtNet とは
概要
ArtNet は舞台照明などの制御で使われるプロトコルです。舞台照明などの制御は DMX512-A で制御するのが一般的ですが、DMX は1本のケーブルで 512 チャンネルで、各チャンネル 0~255(8bit) の値で制御することができます。この DMX を Ethernet を介してやり取りできるようにしたものが ArtNet になります。
ArtNet は UDP 6454 番ポートが使われます。また、基本的なパケット構造は以下の様な形になります。
0~7 バイト目は UDP パケットが ArtNet のパケットかどうかを識別するための場所になっています。この値は、Art-Net\0
の固定値になっています。
8~9 バイト目は OpCode(operation code) になっています。また、この値は little endian になっています。この OpCode で ArtNet で使用されるコマンドの識別を行います。OpCode の例として、DMX データを表す OpDmx(0x5000)
や ArtNet ノードの存在を確認するための OpPoll(0x2000)
があります。
10 バイト目以降は OpCode によって内容が異なります。
OpCode が OpDmx(DMXパケット) の場合、10~11 バイト目はプロトコルバージョン、12 バイト目は シーケンス番号、14~15 バイト目には Universe 番号が入ります。
18 バイト目以降から DMX の値が順に入れられているのですが、16~17 バイト目には、18 バイト目以降の DMX の長さが格納されています。
他の OpCode など、より詳細は以下の公式ドキュメントに書かれています。
実装
Unity(C#) で ArtNet のパケットを受け取り、各 OpCode に対応する Class のコンストラクタで初期化を行う実装部分を抜き出すと、以下の様な感じになります。
(UDP パケットの受信、各 OpCode に対応するクラスは省略しています)
namespace ArtNet.Packets
{
public abstract class ArtNetPacket
{
private const string ArtNetId = "Art-Net\0";
private const byte FixedArtNetPacketLength = 10;
private static readonly byte[] IdentificationIds = Encoding.ASCII.GetBytes(ArtNetId);
public static ArtNetPacket Create(byte[] buffer)
{
if (!Validate(buffer)) return null;
return GetOpCode(buffer) switch
{
OpCode.Poll => new PollPacket(buffer),
OpCode.PollReply => new PollReplyPacket(buffer),
OpCode.Dmx => new DmxPacket(buffer),
_ => null
};
}
private static bool Validate(IReadOnlyList<byte> buffer)
{
if (buffer.Count < FixedArtNetPacketLength) return false;
return !IdentificationIds.Where((t, i) => buffer[i] != t).Any();
}
private static Enums.OpCode GetOpCode(IReadOnlyList<byte> buffer)
{
return (Enums.OpCode) (buffer[8] + (buffer[9] << 8));
}
}
}
namespace ArtNet.Enums
{
public enum OpCode : ushort
{
Poll = 0x2000,
PollReply = 0x2100,
Dmx = 0x5000
}
}
UDP で受け取ったデータを OpCode の値で分岐させ、OpCode に対応するクラスに変換しています。この後、OpCode に合わせ、必要な処理を追加していくと、Unity のライトをリアルタイムで操作できるようになります。
まとめ
Unity でライトのパラメータを変更する場合、Timeline などを使いますが、
舞台照明などの制御で使われるプロトコルの ArtNet を使うことで、物理照明と Unity を連動させることが可能になります。
実装内容は一部抜粋して書きましたが、ソースコードは GitHub にて公開しています。