2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ArtNet で Unity のライトをリアルタイムに操作してみる

Last updated at Posted at 2023-03-21

以前、はてなブログの方に Unity で ArtNet を扱う内容に関して投稿しました。

Unity で ArtNet を受け取るプログラムとエディタ拡張を GitHub で Public に公開したので、今回はその内容についての記事を書こうかなと思います。

ArtNet とは

概要

ArtNet は舞台照明などの制御で使われるプロトコルです。舞台照明などの制御は DMX512-A で制御するのが一般的ですが、DMX は1本のケーブルで 512 チャンネルで、各チャンネル 0~255(8bit) の値で制御することができます。この DMX を Ethernet を介してやり取りできるようにしたものが ArtNet になります。

ArtNet は UDP 6454 番ポートが使われます。また、基本的なパケット構造は以下の様な形になります。

image.png

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 のライトをリアルタイムで操作できるようになります。

qiita_artnet_unity.gif

まとめ

Unity でライトのパラメータを変更する場合、Timeline などを使いますが、
舞台照明などの制御で使われるプロトコルの ArtNet を使うことで、物理照明と Unity を連動させることが可能になります。

実装内容は一部抜粋して書きましたが、ソースコードは GitHub にて公開しています。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?